Skip to content

Commit a7d8816

Browse files
committed
Support of precursor-ion scans to all formats
1 parent 0017b9b commit a7d8816

File tree

5 files changed

+75
-54
lines changed

5 files changed

+75
-54
lines changed

Writer/MetadataWriter.cs

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class MetadataWriter
2525
private double maxMz = 0;
2626
private double minCharge = 100000000000000;
2727
private double maxCharge = 0;
28-
private readonly Dictionary<string, int> msTypes = new Dictionary<string, int>();
28+
private Dictionary<MSOrderType, int> msLevels = new Dictionary<MSOrderType, int>();
2929
private readonly ICollection<CVTerm> fragmentationTypes = new HashSet<CVTerm>(CVTerm.CvTermComparer);
3030

3131
/// <summary>
@@ -57,14 +57,9 @@ public void WriteMetadata(IRawDataPlus rawFile, int firstScanNumber, int lastSca
5757
// Get the scan event for this scan number
5858
var scanEvent = rawFile.GetScanEventForScanNumber(scanNumber);
5959

60-
// Keep track of the number of MS<MS level> spectra
61-
if (msTypes.ContainsKey(scanFilter.MSOrder.ToString()))
62-
{
63-
msTypes[scanFilter.MSOrder.ToString()] += 1;
64-
}
65-
else
66-
msTypes.Add(scanFilter.MSOrder.ToString(), 1);
67-
60+
// Get MS levels
61+
msLevels = WriterUtil.CountScanOrder(rawFile);
62+
6863
if (time > maxTime)
6964
maxTime = time;
7065
if (time < minTime)
@@ -174,22 +169,17 @@ private void WriteJsonMetada(IRawDataPlus rawFile, int firstScanNumber, int last
174169
rawFile.GetInstrumentData().HardwareVersion));
175170
}
176171

177-
178-
179172
// MS Data
180-
foreach (KeyValuePair<string, int> entry in msTypes)
181-
{
182-
if (entry.Key.Equals(MSOrderType.Ms.ToString()))
183-
metadata.addMSData(new CVTerm("PRIDE:0000481", "PRIDE", "Number of MS1 spectra",
184-
entry.Value.ToString()));
185-
if (entry.Key.Equals(MSOrderType.Ms2.ToString()))
186-
metadata.addMSData(new CVTerm("PRIDE:0000482", "PRIDE", "Number of MS2 spectra",
187-
entry.Value.ToString()));
188-
if (entry.Key.Equals(MSOrderType.Ms3.ToString()))
189-
metadata.addMSData(new CVTerm("PRIDE:0000483", "PRIDE", "Number of MS3 spectra",
190-
entry.Value.ToString()));
191-
}
192-
173+
if (msLevels[MSOrderType.Ms] > 0)
174+
metadata.addMSData(new CVTerm("PRIDE:0000481", "PRIDE", "Number of MS1 spectra",
175+
msLevels[MSOrderType.Ms].ToString()));
176+
if (msLevels[MSOrderType.Ms2] > 0)
177+
metadata.addMSData(new CVTerm("PRIDE:0000482", "PRIDE", "Number of MS1 spectra",
178+
msLevels[MSOrderType.Ms2].ToString()));
179+
if (msLevels[MSOrderType.Ms3] > 0)
180+
metadata.addMSData(new CVTerm("PRIDE:0000483", "PRIDE", "Number of MS1 spectra",
181+
msLevels[MSOrderType.Ms3].ToString()));
182+
193183
metadata.addMSData(new CVTerm("PRIDE:0000472", "PRIDE", "MS min charge",
194184
minCharge.ToString(CultureInfo.InvariantCulture)));
195185
metadata.addMSData(new CVTerm("PRIDE:0000473", "PRIDE", "MS max charge",
@@ -369,16 +359,14 @@ private void WriteTextMetadata(IRawDataPlus rawFile, int firstScanNumber, int la
369359
}
370360

371361
// MS Data
362+
//TODO other MS levels??
372363
output.Add("#MsData");
373-
foreach (KeyValuePair<string, int> entry in msTypes)
374-
{
375-
if (entry.Key.Equals(MSOrderType.Ms.ToString()))
376-
output.Add("Number of MS1 spectra=" + entry.Value);
377-
if (entry.Key.Equals(MSOrderType.Ms2.ToString()))
378-
output.Add("Number of MS2 spectra=" + entry.Value);
379-
if (entry.Key.Equals(MSOrderType.Ms3.ToString()))
380-
output.Add("Number of MS3 spectra=" + entry.Value);
381-
}
364+
if (msLevels[MSOrderType.Ms] > 0)
365+
output.Add("Number of MS1 spectra=" + msLevels[MSOrderType.Ms]);
366+
if (msLevels[MSOrderType.Ms2] > 0)
367+
output.Add("Number of MS2 spectra=" + msLevels[MSOrderType.Ms2]);
368+
if (msLevels[MSOrderType.Ms3] > 0)
369+
output.Add("Number of MS3 spectra=" + msLevels[MSOrderType.Ms3]);
382370

383371
output.AddRange(new List<string>
384372
{

Writer/MgfSpectrumWriter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
148148
{
149149
precursorReference = ConstructSpectrumTitle((int)Device.MS, 1, _precursorScanNumber);
150150
}
151-
else
151+
else if (ParseInput.MgfPrecursor)
152152
{
153153
Log.Error($"Cannot find precursor scan for scan# {scanNumber}");
154154
_precursorTree[-2] = new PrecursorInfo(0, msLevel, FindLastReaction(scanEvent, msLevel), null);

Writer/ParquetSpectrumWriter.cs

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
using System;
1+
using log4net;
2+
using Parquet.Serialization;
3+
using System;
24
using System.Collections.Generic;
35
using System.Reflection;
4-
using log4net;
5-
using Parquet.Serialization;
6-
using ThermoFisher.CommonCore.Data.Business;
6+
using System.Text.RegularExpressions;
77
using ThermoFisher.CommonCore.Data.FilterEnums;
88
using ThermoFisher.CommonCore.Data.Interfaces;
99
using ThermoRawFileParser.Util;
@@ -168,18 +168,41 @@ private List<MzParquet> ReadScan(IRawDataPlus raw, int scanNumber)
168168
mz = null
169169

170170
};
171-
172171
if (msLevel == 1)
173172
{
174173
// Keep track of scan number for precursor reference
175174
_precursorScanNumbers[""] = scanNumber;
176175
_precursorTree[scanNumber] = new PrecursorInfo();
176+
177177
}
178-
else if (msLevel > 1)
178+
else
179179
{
180-
// Keep track of scan number and isolation m/z for precursor reference
181-
var result = _filterStringIsolationMzPattern.Match(scanEvent.ToString());
182-
if (result.Success)
180+
Match result = null;
181+
182+
if (msLevel > 1)
183+
{
184+
// Keep track of scan number and isolation m/z for precursor reference
185+
result = _filterStringIsolationMzPattern.Match(scanEvent.ToString());
186+
}
187+
else if (msLevel == (int)MSOrderType.Par)
188+
{
189+
// Keep track of scan number and isolation m/z for precursor reference
190+
result = _filterStringParentMzPattern.Match(scanEvent.ToString());
191+
}
192+
else if (msLevel == (int)MSOrderType.Nl)
193+
{
194+
//fill later if necessary
195+
}
196+
else if (msLevel == (int)MSOrderType.Ng)
197+
{
198+
//fill later if necessary
199+
}
200+
else
201+
{
202+
throw new ArgumentOutOfRangeException($"Unknown msLevel: {msLevel}");
203+
}
204+
205+
if (result != null && result.Success)
183206
{
184207
if (_precursorScanNumbers.ContainsKey(result.Groups[1].Value))
185208
{
@@ -197,17 +220,17 @@ private List<MzParquet> ReadScan(IRawDataPlus raw, int scanNumber)
197220
}
198221
else //try getting it from the scan filter
199222
{
200-
precursor_scan = GetParentFromScanString(result.Groups[1].Value);
223+
precursor_scan = GetParentFromScanString(result == null ? "" : result.Groups[1].Value);
201224
}
202225

203226
//finding precursor scan failed
204-
if (precursor_scan == -2)
227+
if (precursor_scan == -2 || !_precursorTree.ContainsKey(precursor_scan))
205228
{
206229
Log.Warn($"Cannot find precursor scan for scan# {scanNumber}");
207-
_precursorTree[-2] = new PrecursorInfo(0, msLevel, FindLastReaction(scanEvent, msLevel), null);
230+
_precursorTree[precursor_scan] = new PrecursorInfo(0, msLevel, FindLastReaction(scanEvent, msLevel), null);
231+
ParseInput.NewWarn();
208232
}
209233

210-
//Parsing the last reaction
211234
try
212235
{
213236
try //since there is no direct way to get the number of reactions available, it is necessary to try and fail
@@ -232,20 +255,20 @@ private List<MzParquet> ReadScan(IRawDataPlus raw, int scanNumber)
232255

233256
// Get Precursor m/z and isolation window borders
234257
precursor_data = GetPrecursorData(precursor_scan, scanEvent, trailer_mz, trailer_isolationWidth, out var reactionCount);
235-
258+
236259
//save precursor information for later reference
237260
_precursorTree[scanNumber] = new PrecursorInfo(precursor_scan, msLevel, reactionCount, null);
238261
}
239262
catch (Exception e)
240263
{
241264
var extra = (e.InnerException is null) ? "" : $"\n{e.InnerException.StackTrace}";
242265

243-
Log.Warn($"Could not get precursor data for scan# {scanNumber} - precursor information for this and dependent scans will be empty\nException details:{e.Message}\n{e.StackTrace}\n{extra}");
266+
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}");
244267
ParseInput.NewWarn();
245268

246269
_precursorTree[scanNumber] = new PrecursorInfo(precursor_scan, 1, 0, null);
247-
}
248270

271+
}
249272
}
250273

251274
MZData mzData;
@@ -290,7 +313,7 @@ private List<MzParquet> ReadScan(IRawDataPlus raw, int scanNumber)
290313
MzParquet m;
291314
m.rt = (float)rt;
292315
m.scan = (uint)scanNumber;
293-
m.level = (uint)msLevel;
316+
m.level = msLevel > 0 ? (uint)msLevel: 0;
294317
m.intensity = (float)mzData.intensities[i];
295318
m.mz = (float)mzData.masses[i];
296319
m.isolation_lower = precursor_data.isolation_lower;

Writer/SpectrumWriter.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,19 @@ public static IReaction GetReaction(IScanEvent scanEvent, int scanNumber)
192192
try
193193
{
194194
var order = (int)scanEvent.MSOrder;
195-
reaction = scanEvent.GetReaction(order - 2);
195+
if (order < 0)
196+
{
197+
reaction = scanEvent.GetReaction(0);
198+
}
199+
else if (order > 1)
200+
{
201+
reaction = scanEvent.GetReaction(order - 2);
202+
}
203+
else
204+
{
205+
Log.Warn($"Attempting to get reaction for MS{order} scan# {scanNumber} failed");
206+
}
207+
196208
}
197209
catch (ArgumentOutOfRangeException)
198210
{

Writer/WriterUtil.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
64
using ThermoFisher.CommonCore.Data.FilterEnums;
75
using ThermoFisher.CommonCore.Data.Interfaces;
86

0 commit comments

Comments
 (0)