@@ -137,10 +137,11 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
137137
138138 if ( _rawFile . HasMsData )
139139 {
140- var nMS1 = rawFile . GetFilteredScanEnumerator ( "ms" ) . Count ( ) ;
141- var nMS = rawFile . RunHeaderEx . SpectraCount ;
140+ var scanCounts = WriterUtil . CountScanOrder ( _rawFile ) ;
141+ //Sum all scans with MSOrder > 1
142+ int nMSn = scanCounts . Sum ( o => ( int ) o . Key > 1 ? o . Value : 0 ) ;
142143 // MS1
143- if ( ParseInput . MsLevel . Contains ( 1 ) && nMS1 > 0 )
144+ if ( ParseInput . MsLevel . Contains ( 1 ) && scanCounts [ MSOrderType . Ms ] > 0 )
144145 content . Add ( new CVParamType
145146 {
146147 accession = "MS:1000579" ,
@@ -149,14 +150,38 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
149150 value = ""
150151 } ) ;
151152 // MSn
152- if ( ParseInput . MsLevel . Any ( n => n > 1 ) && nMS > nMS1 )
153+ if ( ParseInput . MsLevel . Any ( n => n > 1 ) && nMSn > 0 )
153154 content . Add ( new CVParamType
154155 {
155156 accession = "MS:1000580" ,
156157 name = "MSn spectrum" ,
157158 cvRef = "MS" ,
158159 value = ""
159160 } ) ;
161+ if ( scanCounts [ MSOrderType . Par ] > 0 )
162+ content . Add ( new CVParamType
163+ {
164+ accession = "MS:1000341" ,
165+ name = "precursor ion spectrum" ,
166+ cvRef = "MS" ,
167+ value = ""
168+ } ) ;
169+ if ( scanCounts [ MSOrderType . Nl ] > 0 )
170+ content . Add ( new CVParamType
171+ {
172+ accession = "MS:1000326" ,
173+ name = "constant neutral loss spectrum" ,
174+ cvRef = "MS" ,
175+ value = ""
176+ } ) ;
177+ if ( scanCounts [ MSOrderType . Ng ] > 0 )
178+ content . Add ( new CVParamType
179+ {
180+ accession = "MS:1000325" ,
181+ name = "constant neutral gain spectrum" ,
182+ cvRef = "MS" ,
183+ value = ""
184+ } ) ;
160185 // Ion current chromatogram
161186 content . Add ( OntologyMapping . GetChromatogramType ( "current" ) ) ;
162187 }
@@ -407,7 +432,7 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
407432 ParseInput . NewError ( ) ;
408433 }
409434
410- level = spectrum != null ? int . Parse ( spectrum . cvParam . Where ( p => p . accession == "MS:1000511" ) . First ( ) . value ) : 0 ;
435+ level = spectrum != null ? ( int ) _rawFile . GetScanEventForScanNumber ( scanNumber ) . MSOrder : 0 ;
411436
412437 if ( spectrum != null && ParseInput . MsLevel . Contains ( level ) ) //applying final MS filter
413438 {
@@ -1233,16 +1258,7 @@ private SpectrumType ConstructMSSpectrum(int scanNumber)
12331258 } ;
12341259
12351260 // Keep the CV params in a list and convert to array afterwards
1236- var spectrumCvParams = new List < CVParamType >
1237- {
1238- new CVParamType
1239- {
1240- name = "ms level" ,
1241- accession = "MS:1000511" ,
1242- value = msLevel . ToString ( ) ,
1243- cvRef = "MS"
1244- }
1245- } ;
1261+ var spectrumCvParams = new List < CVParamType > ( ) ;
12461262
12471263 // Trailer extra data list
12481264 ScanTrailer trailerData ;
@@ -1295,7 +1311,6 @@ private SpectrumType ConstructMSSpectrum(int scanNumber)
12951311 ionInjectionTime ) ;
12961312 spectrum . scanList = scanListType ;
12971313
1298-
12991314 if ( msLevel == 1 )
13001315 {
13011316 spectrumCvParams . Add ( new CVParamType
@@ -1306,6 +1321,14 @@ private SpectrumType ConstructMSSpectrum(int scanNumber)
13061321 value = ""
13071322 } ) ;
13081323
1324+ spectrumCvParams . Add ( new CVParamType
1325+ {
1326+ name = "ms level" ,
1327+ accession = "MS:1000511" ,
1328+ value = msLevel . ToString ( ) ,
1329+ cvRef = "MS"
1330+ } ) ;
1331+
13091332 // Keep track of scan number for precursor reference
13101333 _precursorScanNumbers [ "" ] = scanNumber ;
13111334 _precursorTree [ scanNumber ] = new PrecursorInfo ( ) ;
@@ -1314,12 +1337,20 @@ private SpectrumType ConstructMSSpectrum(int scanNumber)
13141337 else if ( msLevel > 1 )
13151338 {
13161339 spectrumCvParams . Add ( new CVParamType
1317- {
1340+ {
13181341 accession = "MS:1000580" ,
13191342 cvRef = "MS" ,
13201343 name = "MSn spectrum" ,
13211344 value = ""
1322- } ) ;
1345+ } ) ;
1346+
1347+ spectrumCvParams . Add ( new CVParamType
1348+ {
1349+ name = "ms level" ,
1350+ accession = "MS:1000511" ,
1351+ value = msLevel . ToString ( ) ,
1352+ cvRef = "MS"
1353+ } ) ;
13231354
13241355 // Keep track of scan number and isolation m/z for precursor reference
13251356 var result = _filterStringIsolationMzPattern . Match ( scanEvent . ToString ( ) ) ;
@@ -1393,6 +1424,114 @@ private SpectrumType ConstructMSSpectrum(int scanNumber)
13931424
13941425 }
13951426 }
1427+ else if ( msLevel == ( int ) MSOrderType . Par )
1428+ {
1429+ spectrumCvParams . Add ( new CVParamType
1430+ {
1431+ accession = "MS:1000341" ,
1432+ cvRef = "MS" ,
1433+ name = "precursor ion spectrum" ,
1434+ value = ""
1435+ } ) ;
1436+
1437+ // Keep track of scan number and isolation m/z for precursor reference
1438+ var result = _filterStringParentMzPattern . Match ( scanEvent . ToString ( ) ) ;
1439+ if ( result . Success )
1440+ {
1441+ if ( _precursorScanNumbers . ContainsKey ( result . Groups [ 1 ] . Value ) )
1442+ {
1443+ _precursorScanNumbers . Remove ( result . Groups [ 1 ] . Value ) ;
1444+ }
1445+
1446+ _precursorScanNumbers . Add ( result . Groups [ 1 ] . Value , scanNumber ) ;
1447+ }
1448+
1449+ //update precursor scan if it is provided in trailer data
1450+ var trailerMasterScan = trailerData . AsPositiveInt ( "Master Scan Number:" ) ;
1451+ if ( trailerMasterScan . HasValue )
1452+ {
1453+ _precursorScanNumber = trailerMasterScan . Value ;
1454+ }
1455+ else //try getting it from the scan filter
1456+ {
1457+ _precursorScanNumber = GetParentFromScanString ( result . Groups [ 1 ] . Value ) ;
1458+ }
1459+
1460+ //finding precursor scan failed
1461+ if ( _precursorScanNumber == - 2 || ! _precursorTree . ContainsKey ( _precursorScanNumber ) )
1462+ {
1463+ Log . Warn ( $ "Cannot find precursor scan for scan# { scanNumber } ") ;
1464+ _precursorTree [ _precursorScanNumber ] = new PrecursorInfo ( 0 , msLevel , FindLastReaction ( scanEvent , msLevel ) , new PrecursorType [ 0 ] ) ;
1465+ ParseInput . NewWarn ( ) ;
1466+ }
1467+
1468+ try
1469+ {
1470+ try //since there is no direct way to get the number of reactions available, it is necessary to try and fail
1471+ {
1472+ scanEvent . GetReaction ( _precursorTree [ _precursorScanNumber ] . ReactionCount ) ;
1473+ }
1474+ catch ( ArgumentOutOfRangeException ex )
1475+ {
1476+ Log . Debug ( $ "Using Tribrid decision tree fix for scan# { scanNumber } ") ;
1477+ //Is it a decision tree scheduled scan on tribrid?
1478+ if ( msLevel == _precursorTree [ _precursorScanNumber ] . MSLevel )
1479+ {
1480+ _precursorScanNumber = GetParentFromScanString ( result . Groups [ 1 ] . Value ) ;
1481+ }
1482+ else
1483+ {
1484+ throw new RawFileParserException (
1485+ $ "Tribrid decision tree fix failed - cannot get reaction# { _precursorTree [ _precursorScanNumber ] . ReactionCount } from { scanEvent . ToString ( ) } ",
1486+ ex ) ;
1487+ }
1488+ }
1489+
1490+ // Construct and set the precursor list element of the spectrum
1491+ spectrum . precursorList =
1492+ ConstructPrecursorList ( _precursorScanNumber , scanEvent , charge , monoisotopicMz , isolationWidth ,
1493+ SPSMasses , out var reactionCount ) ;
1494+
1495+ //save precursor information for later reference
1496+ _precursorTree [ scanNumber ] = new PrecursorInfo ( _precursorScanNumber , msLevel , reactionCount , spectrum . precursorList . precursor ) ;
1497+ }
1498+ catch ( Exception e )
1499+ {
1500+ var extra = ( e . InnerException is null ) ? "" : $ "\n { e . InnerException . StackTrace } ";
1501+
1502+ Log . Warn ( $ "Failed creating precursor list for scan# { scanNumber } - precursor information for this and dependent scans will be empty\n Exception details:{ e . Message } \n { e . StackTrace } \n { extra } ") ;
1503+ ParseInput . NewWarn ( ) ;
1504+
1505+ _precursorTree [ scanNumber ] = new PrecursorInfo ( _precursorScanNumber , 1 , 0 , new PrecursorType [ 0 ] ) ;
1506+
1507+ }
1508+ }
1509+ else if ( msLevel == ( int ) MSOrderType . Nl )
1510+ {
1511+ spectrumCvParams . Add ( new CVParamType
1512+ {
1513+ accession = "MS:1000326" ,
1514+ cvRef = "MS" ,
1515+ name = "constant neutral loss spectrum" ,
1516+ value = ""
1517+ } ) ;
1518+ // Keep track of scan number for precursor reference
1519+ _precursorScanNumbers [ "" ] = scanNumber ;
1520+ _precursorTree [ scanNumber ] = new PrecursorInfo ( ) ;
1521+ }
1522+ else if ( msLevel == ( int ) MSOrderType . Ng )
1523+ {
1524+ spectrumCvParams . Add ( new CVParamType
1525+ {
1526+ accession = "MS:1000325" ,
1527+ cvRef = "MS" ,
1528+ name = "constant neutral gain spectrum" ,
1529+ value = ""
1530+ } ) ;
1531+ // Keep track of scan number for precursor reference
1532+ _precursorScanNumbers [ "" ] = scanNumber ;
1533+ _precursorTree [ scanNumber ] = new PrecursorInfo ( ) ;
1534+ }
13961535 else
13971536 {
13981537 throw new ArgumentOutOfRangeException ( $ "Unknown msLevel: { msLevel } ") ;
0 commit comments