Skip to content

Commit 85d300a

Browse files
committed
SPS support
1 parent d68b4c7 commit 85d300a

File tree

1 file changed

+70
-18
lines changed

1 file changed

+70
-18
lines changed

Writer/MzMlSpectrumWriter.cs

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@ public class MzMlSpectrumWriter : SpectrumWriter
2727
private static readonly ILog Log =
2828
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
2929

30-
private const string FilterStringIsolationMzPattern = @"ms2 (.*?)@";
30+
private readonly Regex FilterStringIsolationMzPattern = new Regex(@"ms2 (.*?)@");
31+
32+
//tune version < 3 produces multiple trailer entry like "SPS Mass [number]"
33+
private readonly Regex SPSentry = new Regex(@"SPS Mass\s+\d+:");
34+
//tune version == 3 produces trailer entry "SPS Masses/Continued"
35+
private readonly Regex SPSentry3 = new Regex(@"SPS Masses(?:\s+Continued)?:");
3136

3237
private IRawDataPlus _rawFile;
3338

@@ -1146,7 +1151,7 @@ private SpectrumType ConstructMSSpectrum(int scanNumber)
11461151
int? charge = null;
11471152
double? monoisotopicMz = null;
11481153
double? ionInjectionTime = null;
1149-
double? isolationWidth = null;
1154+
List<double> SPSMasses = new List<double>();
11501155
for (var i = 0; i < trailerData.Length; i++)
11511156
{
11521157
if (trailerData.Labels[i] == "Charge State:")
@@ -1169,10 +1174,21 @@ private SpectrumType ConstructMSSpectrum(int scanNumber)
11691174
CultureInfo.CurrentCulture);
11701175
}
11711176

1172-
if (trailerData.Labels[i] == "MS" + (int) scanFilter.MSOrder + " Isolation Width:")
1177+
//tune version < 3 produced trailer entry like "SPS Mass #", one entry per mass
1178+
if (SPSentry.IsMatch(trailerData.Labels[i]))
11731179
{
1174-
isolationWidth = double.Parse(trailerData.Values[i], NumberStyles.Any,
1175-
CultureInfo.CurrentCulture);
1180+
var mass = Double.Parse(trailerData.Values[i]);
1181+
if (mass > 0) SPSMasses.Add(mass); //zero means mass does not exist
1182+
}
1183+
1184+
//tune version == 3 produces trailer entry "SPS Masses", comma separated list of masses
1185+
if (SPSentry3.IsMatch(trailerData.Labels[i]))
1186+
{
1187+
foreach (var mass in trailerData.Values[i].Trim().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
1188+
{
1189+
SPSMasses.Add(Double.Parse(mass));
1190+
}
1191+
11761192
}
11771193
}
11781194

@@ -1206,7 +1222,7 @@ private SpectrumType ConstructMSSpectrum(int scanNumber)
12061222
});
12071223

12081224
// Keep track of scan number and isolation m/z for precursor reference
1209-
var result = Regex.Match(scanEvent.ToString(), FilterStringIsolationMzPattern);
1225+
var result = FilterStringIsolationMzPattern.Match(scanEvent.ToString());
12101226
if (result.Success)
12111227
{
12121228
if (_precursorMs2ScanNumbers.ContainsKey(result.Groups[1].Value))
@@ -1219,7 +1235,7 @@ private SpectrumType ConstructMSSpectrum(int scanNumber)
12191235

12201236
// Construct and set the precursor list element of the spectrum
12211237
var precursorListType =
1222-
ConstructPrecursorList(scanEvent, charge, scanFilter.MSOrder, monoisotopicMz, isolationWidth);
1238+
ConstructPrecursorList(scanEvent, charge, scanFilter.MSOrder, monoisotopicMz, SPSMasses);
12231239
spectrum.precursorList = precursorListType;
12241240
break;
12251241
case MSOrderType.Ms3:
@@ -1230,8 +1246,7 @@ private SpectrumType ConstructMSSpectrum(int scanNumber)
12301246
name = "MSn spectrum",
12311247
value = ""
12321248
});
1233-
precursorListType = ConstructPrecursorList(scanEvent, charge, scanFilter.MSOrder, monoisotopicMz,
1234-
isolationWidth);
1249+
precursorListType = ConstructPrecursorList(scanEvent, charge, scanFilter.MSOrder, monoisotopicMz, SPSMasses);
12351250
spectrum.precursorList = precursorListType;
12361251
break;
12371252
default:
@@ -1772,19 +1787,20 @@ private SpectrumType ConstructPDASpectrum(int scanNumber, int instrumentNumber)
17721787
/// <param name="isolationWidth">the isolation width</param>
17731788
/// <returns>the precursor list</returns>
17741789
private PrecursorListType ConstructPrecursorList(IScanEventBase scanEvent, int? charge, MSOrderType msLevel,
1775-
double? monoisotopicMz, double? isolationWidth)
1790+
double? monoisotopicMz, List<double> SPSMasses)
17761791
{
17771792
// Construct the precursor
17781793
var precursorList = new PrecursorListType
17791794
{
1780-
count = "1",
1781-
precursor = new PrecursorType[1]
1795+
count = (Math.Max(SPSMasses.Count, 1)).ToString(),
1796+
precursor = new PrecursorType[Math.Max(SPSMasses.Count, 1)]
17821797
};
17831798

17841799
var spectrumRef = "";
17851800
int precursorScanNumber = _precursorMs1ScanNumber;
17861801
IReaction reaction = null;
17871802
var precursorMz = 0.0;
1803+
double? isolationWidth = null;
17881804
try
17891805
{
17901806
switch (msLevel)
@@ -1814,6 +1830,7 @@ private PrecursorListType ConstructPrecursorList(IScanEventBase scanEvent, int?
18141830
}
18151831

18161832
precursorMz = reaction.PrecursorMass;
1833+
isolationWidth = reaction.IsolationWidth;
18171834
}
18181835
catch (ArgumentOutOfRangeException)
18191836
{
@@ -1823,15 +1840,11 @@ private PrecursorListType ConstructPrecursorList(IScanEventBase scanEvent, int?
18231840
var precursor = new PrecursorType
18241841
{
18251842
selectedIonList =
1826-
new SelectedIonListType {count = 1.ToString(), selectedIon = new ParamGroupType[1]},
1843+
new SelectedIonListType {count = "1", selectedIon = new ParamGroupType[1]},
18271844
spectrumRef = spectrumRef
18281845
};
18291846

1830-
precursor.selectedIonList.selectedIon[0] =
1831-
new ParamGroupType
1832-
{
1833-
cvParam = new CVParamType[3]
1834-
};
1847+
precursor.selectedIonList.selectedIon[0] = new ParamGroupType();
18351848

18361849
// Selected ion MZ
18371850
var selectedIonMz = CalculateSelectedIonMz(reaction, monoisotopicMz, isolationWidth);
@@ -1886,6 +1899,7 @@ private PrecursorListType ConstructPrecursorList(IScanEventBase scanEvent, int?
18861899
{
18871900
cvParam = new CVParamType[3]
18881901
};
1902+
18891903
precursor.isolationWindow.cvParam[0] =
18901904
new CVParamType
18911905
{
@@ -2022,6 +2036,44 @@ private PrecursorListType ConstructPrecursorList(IScanEventBase scanEvent, int?
20222036

20232037
precursorList.precursor[0] = precursor;
20242038

2039+
//the first SPS mass seems to be the same as the one from reaction or scan filter
2040+
for (int n = 1; n < SPSMasses.Count; n++)
2041+
{
2042+
var SPSPrecursor = new PrecursorType
2043+
{
2044+
selectedIonList =
2045+
new SelectedIonListType { count = "1", selectedIon = new ParamGroupType[1] },
2046+
spectrumRef = spectrumRef
2047+
};
2048+
2049+
// Selected ion MZ only
2050+
SPSPrecursor.selectedIonList.selectedIon[0] =
2051+
new ParamGroupType
2052+
{
2053+
cvParam = new CVParamType[]
2054+
{
2055+
new CVParamType {
2056+
name = "selected ion m/z",
2057+
value = SPSMasses[n].ToString(),
2058+
accession = "MS:1000744",
2059+
cvRef = "MS",
2060+
unitCvRef = "MS",
2061+
unitAccession = "MS:1000040",
2062+
unitName = "m/z"
2063+
}
2064+
}
2065+
};
2066+
2067+
//All SPS masses have the same activation (i.e. it was calculated above)
2068+
SPSPrecursor.activation =
2069+
new ParamGroupType
2070+
{
2071+
cvParam = activationCvParams.ToArray()
2072+
};
2073+
2074+
precursorList.precursor[n] = SPSPrecursor;
2075+
}
2076+
20252077
return precursorList;
20262078
}
20272079

0 commit comments

Comments
 (0)