Skip to content

Commit 6ab19c4

Browse files
committed
Precursor Title in MGF
new flag -P|--mgfPrecursor
1 parent 8218f9c commit 6ab19c4

File tree

4 files changed

+73
-4
lines changed

4 files changed

+73
-4
lines changed

MainClass.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,11 @@ private static void RegularParametersParsing(string[] args)
429429
"MS Levels (i.e. MS1, MS2 etc) to include in the output, should be comma separated list of integers ( 1,2,3 ) or intervals ( 1-3 ), open end intervals ( 1- ) are allowed",
430430
v => parseInput.MsLevel = ParseMsLevel(v)
431431
},
432+
{
433+
"P|mgfPrecursor",
434+
"Write precursor scan in MGF file",
435+
v => parseInput.MGFPrecursor = v != null
436+
},
432437
{
433438
"u:|s3_url:",
434439
"Optional property to write directly the data into S3 Storage.",

ParseInput.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ public string RawFilePath
7777

7878
public HashSet<int> MsLevel { get; set; }
7979

80+
public bool MGFPrecursor { get; set; }
81+
8082
private S3Loader S3Loader { get; set; }
8183

8284
public string S3AccessKeyId { get; set; }

Writer/MgfSpectrumWriter.cs

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
using System;
22
using System.Globalization;
3+
using System.Linq;
34
using System.Reflection;
5+
using System.Text.RegularExpressions;
46
using log4net;
7+
using ThermoFisher.CommonCore.Data;
58
using ThermoFisher.CommonCore.Data.Business;
69
using ThermoFisher.CommonCore.Data.FilterEnums;
710
using ThermoFisher.CommonCore.Data.Interfaces;
11+
using ThermoRawFileParser.Util;
812

913
namespace ThermoRawFileParser.Writer
1014
{
@@ -16,6 +20,15 @@ public class MgfSpectrumWriter : SpectrumWriter
1620
private const string PositivePolarity = "+";
1721
private const string NegativePolarity = "-";
1822

23+
//filter string
24+
private const string FilterStringIsolationMzPattern = @"ms2 (.*?)@";
25+
26+
//precursor scan number for MS2 scans
27+
private int _precursorMs1ScanNumber;
28+
29+
// Precursor scan number (value) and isolation m/z (key) for reference in the precursor element of an MS3 spectrum
30+
private readonly LimitedSizeDictionary<string, int> _precursorMs2ScanNumbers = new LimitedSizeDictionary<string, int>(40);
31+
1932
// Precursor scan number for reference in the precursor element of an MS2 spectrum
2033

2134
public MgfSpectrumWriter(ParseInput parseInput) : base(parseInput)
@@ -36,7 +49,7 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
3649
{
3750
if (ParseInput.LogFormat == LogFormat.DEFAULT)
3851
{
39-
var scanProgress = (int) ((double) scanNumber / (lastScanNumber - firstScanNumber + 1) * 100);
52+
var scanProgress = (int)((double)scanNumber / (lastScanNumber - firstScanNumber + 1) * 100);
4053
if (scanProgress % ProgressPercentageStep == 0)
4154
{
4255
if (scanProgress != lastScanProgress)
@@ -60,6 +73,52 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
6073
// Get the scan event for this scan number
6174
var scanEvent = rawFile.GetScanEventForScanNumber(scanNumber);
6275

76+
// precursor reference
77+
var spectrumRef = "";
78+
79+
//keeping track of precursor scan
80+
switch (scanFilter.MSOrder)
81+
{
82+
case MSOrderType.Ms:
83+
84+
// Keep track of scan number for precursor reference
85+
_precursorMs1ScanNumber = scanNumber;
86+
87+
break;
88+
case MSOrderType.Ms2:
89+
// Keep track of scan number and isolation m/z for precursor reference
90+
var result = Regex.Match(scanEvent.ToString(), FilterStringIsolationMzPattern);
91+
if (result.Success)
92+
{
93+
if (_precursorMs2ScanNumbers.ContainsKey(result.Groups[1].Value))
94+
{
95+
_precursorMs2ScanNumbers.Remove(result.Groups[1].Value);
96+
}
97+
98+
_precursorMs2ScanNumbers.Add(result.Groups[1].Value, scanNumber);
99+
}
100+
101+
spectrumRef = ConstructSpectrumTitle((int)Device.MS, 1, _precursorMs1ScanNumber);
102+
break;
103+
104+
case MSOrderType.Ms3:
105+
var precursorMs2ScanNumber = _precursorMs2ScanNumbers.Keys.FirstOrDefault(
106+
isolationMz => scanEvent.ToString().Contains(isolationMz));
107+
if (!precursorMs2ScanNumber.IsNullOrEmpty())
108+
{
109+
spectrumRef = ConstructSpectrumTitle((int)Device.MS, 1, _precursorMs2ScanNumbers[precursorMs2ScanNumber]);
110+
}
111+
else
112+
{
113+
throw new InvalidOperationException("Couldn't find a MS2 precursor scan for MS3 scan " + scanEvent);
114+
}
115+
break;
116+
117+
default:
118+
break;
119+
}
120+
121+
63122
// don't include MS1 spectra
64123
if (ParseInput.MsLevel.Contains((int)scanFilter.MSOrder))
65124
{
@@ -70,7 +129,6 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
70129
Writer.WriteLine($"SCANS={scanNumber}");
71130
Writer.WriteLine(
72131
$"RTINSECONDS={(time * 60).ToString(CultureInfo.InvariantCulture)}");
73-
74132
// trailer extra data list
75133
var trailerData = rawFile.GetTrailerExtraInformation(scanNumber);
76134
int? charge = null;
@@ -92,7 +150,7 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
92150
CultureInfo.CurrentCulture);
93151
}
94152

95-
if (trailerData.Labels[i] == "MS" + (int) scanFilter.MSOrder + " Isolation Width:")
153+
if (trailerData.Labels[i] == "MS" + (int)scanFilter.MSOrder + " Isolation Width:")
96154
{
97155
isolationWidth = double.Parse(trailerData.Values[i], NumberStyles.Any,
98156
CultureInfo.CurrentCulture);
@@ -121,6 +179,8 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
121179
Writer.WriteLine($"CHARGE={charge}{polarity}");
122180
}
123181

182+
if(ParseInput.MGFPrecursor) Writer.WriteLine($"PRECURSORTITLE={spectrumRef}");
183+
124184
// write the filter string
125185
//Writer.WriteLine($"SCANEVENT={scanEvent.ToString()}");
126186

Writer/MzMlSpectrumWriter.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,10 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
334334
}
335335

336336
var spectrum = ConstructMSSpectrum(scanNumber);
337+
337338
var level = int.Parse(spectrum.cvParam.Where(p => p.accession == "MS:1000511").First().value);
338-
if (spectrum != null && ParseInput.MsLevel.Contains(level))
339+
340+
if (spectrum != null && ParseInput.MsLevel.Contains(level)) //applying MS level filter
339341
{
340342
spectrum.index = index.ToString();
341343
if (_doIndexing)

0 commit comments

Comments
 (0)