Skip to content

Commit 6621c5a

Browse files
committed
Merge branch 'pr/164' into 1.4.3
2 parents a32c99c + b4c28a1 commit 6621c5a

File tree

2 files changed

+88
-53
lines changed

2 files changed

+88
-53
lines changed

Writer/MzMlSpectrumWriter.cs

Lines changed: 87 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ public MzMlSpectrumWriter(ParseInput parseInput) : base(parseInput)
6868
_mzMlNamespace.Add(string.Empty, "http://psi.hupo.org/ms/mzml");
6969
_doIndexing = ParseInput.OutputFormat == OutputFormat.IndexMzML;
7070
_osOffset = Environment.NewLine == "\n" ? 0 : 1;
71+
_precursorScanNumbers[""] = -1;
72+
_precursorTree[-1] = new PrecursorInfo();
7173
}
7274

7375
/// <inheritdoc />
@@ -1275,7 +1277,7 @@ private SpectrumType ConstructMSSpectrum(int scanNumber)
12751277
});
12761278

12771279
// Keep track of scan number for precursor reference
1278-
_precursorScanNumbers[""] = scanNumber;
1280+
_precursorScanNumbers[""] = -1;
12791281
_precursorTree[scanNumber] = new PrecursorInfo();
12801282

12811283
}
@@ -1312,61 +1314,52 @@ private SpectrumType ConstructMSSpectrum(int scanNumber)
13121314
_precursorScanNumber = GetParentFromScanString(result.Groups[1].Value);
13131315
}
13141316

1315-
if (_precursorScanNumber > 0)
1317+
//finding precursor scan failed
1318+
if (_precursorScanNumber == -2)
13161319
{
1320+
Log.Warn($"Cannot find precursor scan for scan# {scanNumber}");
1321+
_precursorTree[-2] = new PrecursorInfo(0, msLevel, FindLastReaction(scanEvent, msLevel), new PrecursorType[0]);
1322+
}
13171323

1318-
try
1324+
try
1325+
{
1326+
try //since there is no direct way to get the number of reactions available, it is necessary to try and fail
13191327
{
1320-
try //since there is no direct way to get the number of reactions available, it is necessary to try and fail
1328+
scanEvent.GetReaction(_precursorTree[_precursorScanNumber].ReactionCount);
1329+
}
1330+
catch (ArgumentOutOfRangeException ex)
1331+
{
1332+
Log.Debug($"Using Tribrid decision tree fix for scan# {scanNumber}");
1333+
//Is it a decision tree scheduled scan on tribrid?
1334+
if (msLevel == _precursorTree[_precursorScanNumber].MSLevel)
13211335
{
1322-
scanEvent.GetReaction(_precursorTree[_precursorScanNumber].ReactionCount);
1336+
_precursorScanNumber = GetParentFromScanString(result.Groups[1].Value);
13231337
}
1324-
catch (ArgumentOutOfRangeException ex)
1338+
else
13251339
{
1326-
Log.Debug($"Using Tribrid decision tree fix for scan# {scanNumber}");
1327-
//Is it a decision tree scheduled scan on tribrid?
1328-
if (msLevel == _precursorTree[_precursorScanNumber].MSLevel)
1329-
{
1330-
_precursorScanNumber = GetParentFromScanString(result.Groups[1].Value);
1331-
}
1332-
else
1333-
{
1334-
throw new RawFileParserException(
1335-
$"Tribrid decision tree fix failed - cannot get reaction# {_precursorTree[_precursorScanNumber].ReactionCount} from {scanEvent.ToString()}",
1336-
ex);
1337-
}
1340+
throw new RawFileParserException(
1341+
$"Tribrid decision tree fix failed - cannot get reaction# {_precursorTree[_precursorScanNumber].ReactionCount} from {scanEvent.ToString()}",
1342+
ex);
13381343
}
1339-
1340-
// Construct and set the precursor list element of the spectrum
1341-
spectrum.precursorList =
1342-
ConstructPrecursorList(_precursorScanNumber, scanEvent, charge, monoisotopicMz, isolationWidth,
1343-
SPSMasses, out var reactionCount);
1344-
1345-
//save precursor information for later reference
1346-
_precursorTree[scanNumber] = new PrecursorInfo(_precursorScanNumber, msLevel, reactionCount, spectrum.precursorList.precursor);
13471344
}
1348-
catch (Exception e)
1349-
{
1350-
var extra = (e.InnerException is null) ? "" : $"\n{e.InnerException.StackTrace}";
1351-
1352-
Log.Warn($"Failed creating precursor list for scan# {scanNumber} - precursor information for this and dependent scans will be empty\nException details:{e.Message}\n{e.StackTrace}\n{extra}");
1353-
ParseInput.NewWarn();
13541345

1355-
_precursorTree[scanNumber] = new PrecursorInfo(_precursorScanNumber, 1, 0, new PrecursorType[0]);
1346+
// Construct and set the precursor list element of the spectrum
1347+
spectrum.precursorList =
1348+
ConstructPrecursorList(_precursorScanNumber, scanEvent, charge, monoisotopicMz, isolationWidth,
1349+
SPSMasses, out var reactionCount);
13561350

1357-
}
1358-
1351+
//save precursor information for later reference
1352+
_precursorTree[scanNumber] = new PrecursorInfo(_precursorScanNumber, msLevel, reactionCount, spectrum.precursorList.precursor);
13591353
}
1360-
else
1354+
catch (Exception e)
13611355
{
1362-
spectrum.precursorList = new PrecursorListType
1363-
{
1364-
count = "0",
1365-
precursor = new PrecursorType[0]
1366-
};
1356+
var extra = (e.InnerException is null) ? "" : $"\n{e.InnerException.StackTrace}";
1357+
1358+
Log.Warn($"Failed creating precursor list for scan# {scanNumber} - precursor information for this and dependent scans will be empty\nException details:{e.Message}\n{e.StackTrace}\n{extra}");
1359+
ParseInput.NewWarn();
1360+
1361+
_precursorTree[scanNumber] = new PrecursorInfo(_precursorScanNumber, 1, 0, new PrecursorType[0]);
13671362

1368-
Log.Error($"Failed finding precursor for {scanNumber}");
1369-
ParseInput.NewError();
13701363
}
13711364
}
13721365
else
@@ -1891,6 +1884,45 @@ private SpectrumType ConstructMSSpectrum(int scanNumber)
18911884
return spectrum;
18921885
}
18931886

1887+
private int FindLastReaction(IScanEvent scanEvent, int msLevel)
1888+
{
1889+
int lastReactionIndex = msLevel - 2;
1890+
1891+
//iteratively trying find the last available index for reaction
1892+
while(true)
1893+
{
1894+
try
1895+
{
1896+
scanEvent.GetReaction(lastReactionIndex + 1);
1897+
}
1898+
catch (ArgumentOutOfRangeException)
1899+
{
1900+
//stop trying
1901+
break;
1902+
}
1903+
1904+
lastReactionIndex++;
1905+
}
1906+
1907+
//supplemental activation flag is on -> one of the levels (not necissirily the last one) used supplemental activation
1908+
//check last two activations
1909+
if (scanEvent.SupplementalActivation == TriState.On)
1910+
{
1911+
var lastActivation = scanEvent.GetReaction(lastReactionIndex).ActivationType;
1912+
var beforeLastActivation = scanEvent.GetReaction(lastReactionIndex - 1).ActivationType;
1913+
1914+
if ((beforeLastActivation == ActivationType.ElectronTransferDissociation || beforeLastActivation == ActivationType.ElectronCaptureDissociation) &&
1915+
(lastActivation == ActivationType.CollisionInducedDissociation || lastActivation == ActivationType.HigherEnergyCollisionalDissociation))
1916+
return lastReactionIndex - 1; //ETD or ECD followed by HCD or CID -> supplemental activation in the last level (move the last reaction one step back)
1917+
else
1918+
return lastReactionIndex;
1919+
}
1920+
else //just use the last one
1921+
{
1922+
return lastReactionIndex;
1923+
}
1924+
}
1925+
18941926
private SpectrumType ConstructPDASpectrum(int scanNumber, int instrumentNumber)
18951927
{
18961928
// Get each scan from the RAW file
@@ -2153,21 +2185,25 @@ private PrecursorListType ConstructPrecursorList(int precursorScanNumber, IScanE
21532185
// Get precursors from earlier levels
21542186
var prevPrecursors = _precursorTree[precursorScanNumber];
21552187

2156-
var spectrumRef = "";
2188+
string spectrumRef = null;
21572189
int msLevel = (int)scanEvent.MSOrder;
21582190
IReaction reaction = null;
21592191
var precursorMz = 0.0;
21602192
reactionCount = prevPrecursors.ReactionCount;
21612193

2162-
spectrumRef = ConstructSpectrumTitle((int)Device.MS, 1, precursorScanNumber);
21632194
reaction = scanEvent.GetReaction(reactionCount);
2164-
2165-
precursorMz = reaction.PrecursorMass;
21662195

21672196
//if isolation width was not found in the trailer, try to get one from the reaction
21682197
if (isolationWidth == null) isolationWidth = reaction.IsolationWidth;
21692198
if (isolationWidth < 0) isolationWidth = null;
2170-
2199+
2200+
precursorMz = reaction.PrecursorMass;
2201+
2202+
if (precursorScanNumber > 0)
2203+
{
2204+
spectrumRef = ConstructSpectrumTitle((int)Device.MS, 1, precursorScanNumber);
2205+
}
2206+
21712207
var precursor = new PrecursorType
21722208
{
21732209
selectedIonList =
@@ -2204,7 +2240,7 @@ private PrecursorListType ConstructPrecursorList(int precursorScanNumber, IScanE
22042240
});
22052241
}
22062242

2207-
if (selectedIonMz > ZeroDelta)
2243+
if (selectedIonMz > ZeroDelta && precursorScanNumber > 0)
22082244
{
22092245
var selectedIonIntensity = CalculatePrecursorPeakIntensity(_rawFile, precursorScanNumber, reaction.PrecursorMass, isolationWidth,
22102246
ParseInput.NoPeakPicking.Contains(msLevel - 1));
@@ -2472,8 +2508,7 @@ private PrecursorListType ConstructPrecursorList(int precursorScanNumber, IScanE
24722508

24732509
private int GetParentFromScanString(string scanString)
24742510
{
2475-
var result = _filterStringIsolationMzPattern.Match(scanString);
2476-
var parts = Regex.Split(result.Groups[1].Value, " ");
2511+
var parts = Regex.Split(scanString, " ");
24772512

24782513
//find the position of the first (from the end) precursor with a different mass
24792514
//to account for possible supplementary activations written in the filter
@@ -2491,7 +2526,7 @@ private int GetParentFromScanString(string scanString)
24912526
return _precursorScanNumbers[parentFilter];
24922527
}
24932528

2494-
return -1; //unsuccessful parsing
2529+
return -2; //unsuccessful parsing
24952530
}
24962531

24972532
/// <summary>

Writer/PrecursorInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/// </summary>
66
public class PrecursorInfo
77
{
8-
//for future use
8+
//Current MSLevel
99
public int MSLevel { get; }
1010

1111
//precursor scan number, 0 - means not a precursor

0 commit comments

Comments
 (0)