diff --git a/RawFileParser.cs b/RawFileParser.cs index 8ac667d..9030ea4 100644 --- a/RawFileParser.cs +++ b/RawFileParser.cs @@ -136,20 +136,19 @@ private static void ProcessFile(ParseInput parseInput) // Get the number of instruments (controllers) present in the RAW file and set the // selected instrument to the MS instrument, first instance of it - rawFile.SelectInstrument(Device.MS, 1); - - rawFile.IncludeReferenceAndExceptionData = !parseInput.ExData; + var firstScanNumber = -1; + var lastScanNumber = -1; + if (rawFile.GetInstrumentCountOfType(Device.MS) != 0) + { + rawFile.SelectInstrument(Device.MS, 1); - // Get the first and last scan from the RAW file - var firstScanNumber = rawFile.RunHeaderEx.FirstSpectrum; - var lastScanNumber = rawFile.RunHeaderEx.LastSpectrum; + rawFile.IncludeReferenceAndExceptionData = !parseInput.ExData; - // Check for empty file - if (lastScanNumber < 1) - { - throw new RawFileParserException("Empty RAW file, no output will be produced"); + // Get the first and last scan from the RAW file + firstScanNumber = rawFile.RunHeaderEx.FirstSpectrum; + lastScanNumber = rawFile.RunHeaderEx.LastSpectrum; } - + if (parseInput.MetadataFormat != MetadataFormat.NONE) { MetadataWriter metadataWriter = new MetadataWriter(parseInput); diff --git a/Writer/MetadataWriter.cs b/Writer/MetadataWriter.cs index e7554ce..b224d1f 100644 --- a/Writer/MetadataWriter.cs +++ b/Writer/MetadataWriter.cs @@ -46,73 +46,74 @@ public MetadataWriter(ParseInput parseInput) /// public void WriteMetadata(IRawDataPlus rawFile, int firstScanNumber, int lastScanNumber) { - // Get the start and end time from the RAW file - var startTime = rawFile.RunHeaderEx.StartTime; - var endTime = rawFile.RunHeaderEx.EndTime; - - for (var scanNumber = firstScanNumber; scanNumber <= lastScanNumber; scanNumber++) + if (rawFile.SelectMsData()) { - var time = rawFile.RetentionTimeFromScanNumber(scanNumber); - - // Get the scan filter for this scan number - var scanFilter = rawFile.GetFilterForScanNumber(scanNumber); + for (var scanNumber = firstScanNumber; scanNumber <= lastScanNumber; scanNumber++) + { + var time = rawFile.RetentionTimeFromScanNumber(scanNumber); - // Get the scan event for this scan number - var scanEvent = rawFile.GetScanEventForScanNumber(scanNumber); + // Get the scan filter for this scan number + var scanFilter = rawFile.GetFilterForScanNumber(scanNumber); - // Keep track of the number of MS spectra - if (msTypes.ContainsKey(scanFilter.MSOrder.ToString())) - { - var value = msTypes[scanFilter.MSOrder.ToString()]; - value += 1; - msTypes[scanFilter.MSOrder.ToString()] = value; - } - else - msTypes.Add(scanFilter.MSOrder.ToString(), 1); + // Get the scan event for this scan number + var scanEvent = rawFile.GetScanEventForScanNumber(scanNumber); - if (time > maxTime) - maxTime = time; - if (time < minTime) - minTime = time; + // Keep track of the number of MS spectra + if (msTypes.ContainsKey(scanFilter.MSOrder.ToString())) + { + var value = msTypes[scanFilter.MSOrder.ToString()]; + value += 1; + msTypes[scanFilter.MSOrder.ToString()] = value; + } + else + msTypes.Add(scanFilter.MSOrder.ToString(), 1); - if (scanFilter.MSOrder == MSOrderType.Ms2) - { - fragmentationTypes.Add(ParseActivationType(scanFilter.GetActivation(0))); + if (time > maxTime) + maxTime = time; + if (time < minTime) + minTime = time; - if (scanEvent.ScanData == ScanDataType.Centroid || (scanEvent.ScanData == ScanDataType.Profile)) + if (scanFilter.MSOrder == MSOrderType.Ms2) { - try - { - var reaction = scanEvent.GetReaction(0); - var precursorMass = reaction.PrecursorMass; - if (precursorMass > maxMz) - maxMz = precursorMass; - if (precursorMass < minMz) - minMz = precursorMass; - } - catch (ArgumentOutOfRangeException) - { - Log.Warn("No reaction found for scan " + scanNumber); - _parseInput.NewWarn(); - } + fragmentationTypes.Add(ParseActivationType(scanFilter.GetActivation(0))); - // trailer extra data list - var trailerData = rawFile.GetTrailerExtraInformation(scanNumber); - for (var i = 0; i < trailerData.Length; i++) + if (scanEvent.ScanData == ScanDataType.Centroid || (scanEvent.ScanData == ScanDataType.Profile)) { - if (trailerData.Labels[i] == "Charge State:") + try + { + var reaction = scanEvent.GetReaction(0); + var precursorMass = reaction.PrecursorMass; + if (precursorMass > maxMz) + maxMz = precursorMass; + if (precursorMass < minMz) + minMz = precursorMass; + } + catch (ArgumentOutOfRangeException) { - if (int.Parse(trailerData.Values[i]) > maxCharge) - maxCharge = int.Parse(trailerData.Values[i]); + Log.Warn("No reaction found for scan " + scanNumber); + _parseInput.NewWarn(); + } - if (int.Parse(trailerData.Values[i]) < minCharge) - minCharge = int.Parse(trailerData.Values[i]); + // trailer extra data list + var trailerData = rawFile.GetTrailerExtraInformation(scanNumber); + for (var i = 0; i < trailerData.Length; i++) + { + if (trailerData.Labels[i] == "Charge State:") + { + if (int.Parse(trailerData.Values[i]) > maxCharge) + maxCharge = int.Parse(trailerData.Values[i]); + + if (int.Parse(trailerData.Values[i]) < minCharge) + minCharge = int.Parse(trailerData.Values[i]); + } } } } } } + + if (minCharge == 100000000000000) { minCharge = 0; @@ -145,10 +146,6 @@ public void WriteMetadata(IRawDataPlus rawFile, int firstScanNumber, int lastSca /// private void WriteJsonMetada(IRawDataPlus rawFile, int firstScanNumber, int lastScanNumber) { - // Get the start and end time from the RAW file - var startTime = rawFile.RunHeaderEx.StartTime; - var endTime = rawFile.RunHeaderEx.EndTime; - var metadata = new Metadata(); // File Properties @@ -164,65 +161,74 @@ private void WriteJsonMetada(IRawDataPlus rawFile, int firstScanNumber, int last } // Instrument Properties - metadata.addInstrumentProperty(new CVTerm("MS:1000494", "MS", "Thermo Scientific instrument model", - rawFile.GetInstrumentData().Model)); - metadata.addInstrumentProperty(new CVTerm("MS:1000496", "MS", "instrument attribute", - rawFile.GetInstrumentData().Name)); - metadata.addInstrumentProperty(new CVTerm("MS:1000529", "MS", "instrument serial number", - rawFile.GetInstrumentData().SerialNumber)); - metadata.addInstrumentProperty(new CVTerm("NCIT:C111093", "NCIT", "Software Version", - rawFile.GetInstrumentData().SoftwareVersion)); - if (!rawFile.GetInstrumentData().HardwareVersion.IsNullOrEmpty()) + if (rawFile.SelectMsData()) { - metadata.addInstrumentProperty(new CVTerm("AFR:0001259", "AFO", "firmware version", - rawFile.GetInstrumentData().HardwareVersion)); + metadata.addInstrumentProperty(new CVTerm("MS:1000494", "MS", "Thermo Scientific instrument model", + rawFile.GetInstrumentData().Model)); + metadata.addInstrumentProperty(new CVTerm("MS:1000496", "MS", "instrument attribute", + rawFile.GetInstrumentData().Name)); + metadata.addInstrumentProperty(new CVTerm("MS:1000529", "MS", "instrument serial number", + rawFile.GetInstrumentData().SerialNumber)); + metadata.addInstrumentProperty(new CVTerm("NCIT:C111093", "NCIT", "Software Version", + rawFile.GetInstrumentData().SoftwareVersion)); + if (!rawFile.GetInstrumentData().HardwareVersion.IsNullOrEmpty()) + { + metadata.addInstrumentProperty(new CVTerm("AFR:0001259", "AFO", "firmware version", + rawFile.GetInstrumentData().HardwareVersion)); + } } // MS Data - foreach (KeyValuePair entry in msTypes) + if (rawFile.SelectMsData()) { - if (entry.Key.Equals(MSOrderType.Ms.ToString())) - metadata.addMSData(new CVTerm("PRIDE:0000481", "PRIDE", "Number of MS1 spectra", - entry.Value.ToString())); - if (entry.Key.Equals(MSOrderType.Ms2.ToString())) - metadata.addMSData(new CVTerm("PRIDE:0000482", "PRIDE", "Number of MS2 spectra", - entry.Value.ToString())); - if (entry.Key.Equals(MSOrderType.Ms3.ToString())) - metadata.addMSData(new CVTerm("PRIDE:0000483", "PRIDE", "Number of MS3 spectra", - entry.Value.ToString())); - } + foreach (KeyValuePair entry in msTypes) + { + if (entry.Key.Equals(MSOrderType.Ms.ToString())) + metadata.addMSData(new CVTerm("PRIDE:0000481", "PRIDE", "Number of MS1 spectra", + entry.Value.ToString())); + if (entry.Key.Equals(MSOrderType.Ms2.ToString())) + metadata.addMSData(new CVTerm("PRIDE:0000482", "PRIDE", "Number of MS2 spectra", + entry.Value.ToString())); + if (entry.Key.Equals(MSOrderType.Ms3.ToString())) + metadata.addMSData(new CVTerm("PRIDE:0000483", "PRIDE", "Number of MS3 spectra", + entry.Value.ToString())); + } - metadata.addMSData(new CVTerm("PRIDE:0000472", "PRIDE", "MS min charge", - minCharge.ToString(CultureInfo.InvariantCulture))); - metadata.addMSData(new CVTerm("PRIDE:0000473", "PRIDE", "MS max charge", - maxCharge.ToString(CultureInfo.InvariantCulture))); - - metadata.addMSData(new CVTerm("PRIDE:0000474", "PRIDE", "MS min RT", - minTime.ToString(CultureInfo.InvariantCulture))); - metadata.addMSData(new CVTerm("PRIDE:0000475", "PRIDE", "MS max RT", - maxTime.ToString(CultureInfo.InvariantCulture))); - - metadata.addMSData(new CVTerm("PRIDE:0000476", "PRIDE", "MS min MZ", - minMz.ToString(CultureInfo.InvariantCulture))); - metadata.addMSData(new CVTerm("PRIDE:0000477", "PRIDE", "MS max MZ", - maxMz.ToString(CultureInfo.InvariantCulture))); - - // Scan Settings - metadata.addScanSetting(new CVTerm("MS:1000016", "MS", "scan start time", - startTime.ToString(CultureInfo.InvariantCulture))); - metadata.addScanSetting(new CVTerm("MS:1000011", "MS", "mass resolution", - rawFile.RunHeaderEx.MassResolution.ToString(CultureInfo.InvariantCulture))); - metadata.addScanSetting(new CVTerm("UO:0000002", "MS", "mass unit", - rawFile.GetInstrumentData().Units.ToString())); - metadata.addScanSetting(new CVTerm("PRIDE:0000478", "PRIDE", "Number of scans", - rawFile.RunHeaderEx.SpectraCount.ToString())); - metadata.addScanSetting(new CVTerm("PRIDE:0000479", "PRIDE", "MS scan range", - firstScanNumber + ":" + lastScanNumber)); - metadata.addScanSetting(new CVTerm("PRIDE:0000484", "PRIDE", "Retention time range", - startTime + ":" + endTime)); - metadata.addScanSetting(new CVTerm("PRIDE:0000485", "PRIDE", "Mz range", - rawFile.RunHeaderEx.LowMass + ":" + rawFile.RunHeaderEx.HighMass)); - metadata.addScanSetting(fragmentationTypes); + metadata.addMSData(new CVTerm("PRIDE:0000472", "PRIDE", "MS min charge", + minCharge.ToString(CultureInfo.InvariantCulture))); + metadata.addMSData(new CVTerm("PRIDE:0000473", "PRIDE", "MS max charge", + maxCharge.ToString(CultureInfo.InvariantCulture))); + + metadata.addMSData(new CVTerm("PRIDE:0000474", "PRIDE", "MS min RT", + minTime.ToString(CultureInfo.InvariantCulture))); + metadata.addMSData(new CVTerm("PRIDE:0000475", "PRIDE", "MS max RT", + maxTime.ToString(CultureInfo.InvariantCulture))); + + metadata.addMSData(new CVTerm("PRIDE:0000476", "PRIDE", "MS min MZ", + minMz.ToString(CultureInfo.InvariantCulture))); + metadata.addMSData(new CVTerm("PRIDE:0000477", "PRIDE", "MS max MZ", + maxMz.ToString(CultureInfo.InvariantCulture))); + + // Scan Settings + // Get the start and end time from the RAW file + var startTime = rawFile.RunHeaderEx.StartTime; + var endTime = rawFile.RunHeaderEx.EndTime; + metadata.addScanSetting(new CVTerm("MS:1000016", "MS", "scan start time", + startTime.ToString(CultureInfo.InvariantCulture))); + metadata.addScanSetting(new CVTerm("MS:1000011", "MS", "mass resolution", + rawFile.RunHeaderEx.MassResolution.ToString(CultureInfo.InvariantCulture))); + metadata.addScanSetting(new CVTerm("UO:0000002", "MS", "mass unit", + rawFile.GetInstrumentData().Units.ToString())); + metadata.addScanSetting(new CVTerm("PRIDE:0000478", "PRIDE", "Number of scans", + rawFile.RunHeaderEx.SpectraCount.ToString())); + metadata.addScanSetting(new CVTerm("PRIDE:0000479", "PRIDE", "MS scan range", + firstScanNumber + ":" + lastScanNumber)); + metadata.addScanSetting(new CVTerm("PRIDE:0000484", "PRIDE", "Retention time range", + startTime + ":" + endTime)); + metadata.addScanSetting(new CVTerm("PRIDE:0000485", "PRIDE", "Mz range", + rawFile.RunHeaderEx.LowMass + ":" + rawFile.RunHeaderEx.HighMass)); + metadata.addScanSetting(fragmentationTypes); + } // Sample Data if (!rawFile.SampleInformation.SampleName.IsNullOrEmpty()) @@ -296,10 +302,6 @@ private void WriteJsonMetada(IRawDataPlus rawFile, int firstScanNumber, int last /// private void WriteTextMetadata(IRawDataPlus rawFile, int firstScanNumber, int lastScanNumber) { - // Get the start and end time from the RAW file - var startTime = rawFile.RunHeaderEx.StartTime; - var endTime = rawFile.RunHeaderEx.EndTime; - // File Properties var output = new List { @@ -314,57 +316,66 @@ private void WriteTextMetadata(IRawDataPlus rawFile, int firstScanNumber, int la } // Instrument Properties - output.Add("#InstrumentProperties"); - output.AddRange(new List + if (rawFile.SelectMsData()) + { + output.Add("#InstrumentProperties"); + output.AddRange(new List { $"Instrument model=[MS, MS:1000494, Thermo Scientific instrument model, {rawFile.GetInstrumentData().Model}]", "Instrument name=" + rawFile.GetInstrumentData().Name, $"Instrument serial number=[MS, MS:1000529, instrument serial number, {rawFile.GetInstrumentData().SerialNumber}]", $"Software version=[NCIT, NCIT:C111093, Software Version, {rawFile.GetInstrumentData().SoftwareVersion}]", } - ); - if (!rawFile.GetInstrumentData().HardwareVersion.IsNullOrEmpty()) - { - output.Add("Firmware version=" + rawFile.GetInstrumentData().HardwareVersion); + ); + if (!rawFile.GetInstrumentData().HardwareVersion.IsNullOrEmpty()) + { + output.Add("Firmware version=" + rawFile.GetInstrumentData().HardwareVersion); + } } // MS Data - output.Add("#MsData"); - foreach (KeyValuePair entry in msTypes) + if (rawFile.SelectMsData()) { - if (entry.Key.Equals(MSOrderType.Ms.ToString())) - output.Add("Number of MS1 spectra=" + entry.Value); - if (entry.Key.Equals(MSOrderType.Ms2.ToString())) - output.Add("Number of MS2 spectra=" + entry.Value); - if (entry.Key.Equals(MSOrderType.Ms3.ToString())) - output.Add("Number of MS3 spectra=" + entry.Value); - } - - output.AddRange(new List + output.Add("#MsData"); + foreach (KeyValuePair entry in msTypes) { - "MS min charge=" + minCharge.ToString(CultureInfo.InvariantCulture), - "MS max charge=" + maxCharge.ToString(CultureInfo.InvariantCulture), - $"MS min RT={minTime.ToString(CultureInfo.InvariantCulture)}", - $"MS max RT={maxTime.ToString(CultureInfo.InvariantCulture)}", - $"MS min MZ={minMz.ToString(CultureInfo.InvariantCulture)}", - $"MS max MZ={maxMz.ToString(CultureInfo.InvariantCulture)}" + if (entry.Key.Equals(MSOrderType.Ms.ToString())) + output.Add("Number of MS1 spectra=" + entry.Value); + if (entry.Key.Equals(MSOrderType.Ms2.ToString())) + output.Add("Number of MS2 spectra=" + entry.Value); + if (entry.Key.Equals(MSOrderType.Ms3.ToString())) + output.Add("Number of MS3 spectra=" + entry.Value); } - ); - // Scan Settings - output.AddRange(new List - { - "#ScanSettings", - $"Scan start time={startTime.ToString(CultureInfo.InvariantCulture)}", - $"Mass resolution=[MS, MS:1000011, mass resolution, {rawFile.RunHeaderEx.MassResolution.ToString(CultureInfo.InvariantCulture)}]", - "Units=" + rawFile.GetInstrumentData().Units, - $"Number of scans={rawFile.RunHeaderEx.SpectraCount}", - $"Scan range={firstScanNumber};{lastScanNumber}", - $"Time range={startTime.ToString(CultureInfo.InvariantCulture)};{endTime.ToString(CultureInfo.InvariantCulture)}", - $"Mass range={rawFile.RunHeaderEx.LowMass.ToString(CultureInfo.InvariantCulture)};{rawFile.RunHeaderEx.HighMass.ToString(CultureInfo.InvariantCulture)}", - "Fragmentation types=" + String.Join(", ", fragmentationTypes.Select(f => f.value)) - } - ); + output.AddRange(new List + { + "MS min charge=" + minCharge.ToString(CultureInfo.InvariantCulture), + "MS max charge=" + maxCharge.ToString(CultureInfo.InvariantCulture), + $"MS min RT={minTime.ToString(CultureInfo.InvariantCulture)}", + $"MS max RT={maxTime.ToString(CultureInfo.InvariantCulture)}", + $"MS min MZ={minMz.ToString(CultureInfo.InvariantCulture)}", + $"MS max MZ={maxMz.ToString(CultureInfo.InvariantCulture)}" + } + ); + + // Scan Settings + // Get the start and end time from the RAW file + var startTime = rawFile.RunHeaderEx.StartTime; + var endTime = rawFile.RunHeaderEx.EndTime; + output.AddRange(new List + { + "#ScanSettings", + $"Scan start time={startTime.ToString(CultureInfo.InvariantCulture)}", + $"Mass resolution=[MS, MS:1000011, mass resolution, {rawFile.RunHeaderEx.MassResolution.ToString(CultureInfo.InvariantCulture)}]", + "Units=" + rawFile.GetInstrumentData().Units, + $"Number of scans={rawFile.RunHeaderEx.SpectraCount}", + $"Scan range={firstScanNumber};{lastScanNumber}", + $"Time range={startTime.ToString(CultureInfo.InvariantCulture)};{endTime.ToString(CultureInfo.InvariantCulture)}", + $"Mass range={rawFile.RunHeaderEx.LowMass.ToString(CultureInfo.InvariantCulture)};{rawFile.RunHeaderEx.HighMass.ToString(CultureInfo.InvariantCulture)}", + "Fragmentation types=" + String.Join(", ", fragmentationTypes.Select(f => f.value)) + } + ); + } // Sample Data output.Add("#SampleData"); diff --git a/Writer/MgfSpectrumWriter.cs b/Writer/MgfSpectrumWriter.cs index c347944..abc07ff 100644 --- a/Writer/MgfSpectrumWriter.cs +++ b/Writer/MgfSpectrumWriter.cs @@ -41,208 +41,211 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc ConfigureWriter(".mgf"); using (Writer) { - Log.Info("Processing " + (lastScanNumber - firstScanNumber + 1) + " scans"); - - var lastScanProgress = 0; - for (var scanNumber = firstScanNumber; scanNumber <= lastScanNumber; scanNumber++) + if (rawFile.SelectMsData()) { - if (ParseInput.LogFormat == LogFormat.DEFAULT) + Log.Info("Processing " + (lastScanNumber - firstScanNumber + 1) + " scans"); + + var lastScanProgress = 0; + for (var scanNumber = firstScanNumber; scanNumber <= lastScanNumber; scanNumber++) { - var scanProgress = (int) ((double) scanNumber / (lastScanNumber - firstScanNumber + 1) * 100); - if (scanProgress % ProgressPercentageStep == 0) + if (ParseInput.LogFormat == LogFormat.DEFAULT) { - if (scanProgress != lastScanProgress) + var scanProgress = (int)((double)scanNumber / (lastScanNumber - firstScanNumber + 1) * 100); + if (scanProgress % ProgressPercentageStep == 0) { - Console.Write("" + scanProgress + "% "); - lastScanProgress = scanProgress; + if (scanProgress != lastScanProgress) + { + Console.Write("" + scanProgress + "% "); + lastScanProgress = scanProgress; + } } } - } - _precursorScanNumber = 0; + _precursorScanNumber = 0; - // Get the scan from the RAW file - var scan = Scan.FromFile(rawFile, scanNumber); + // Get the scan from the RAW file + var scan = Scan.FromFile(rawFile, scanNumber); - // Get the retention time - var retentionTime = rawFile.RetentionTimeFromScanNumber(scanNumber); + // Get the retention time + var retentionTime = rawFile.RetentionTimeFromScanNumber(scanNumber); - // Get the scan filter for this scan number - var scanFilter = rawFile.GetFilterForScanNumber(scanNumber); + // Get the scan filter for this scan number + var scanFilter = rawFile.GetFilterForScanNumber(scanNumber); - // Get the scan event for this scan number - var scanEvent = rawFile.GetScanEventForScanNumber(scanNumber); + // Get the scan event for this scan number + var scanEvent = rawFile.GetScanEventForScanNumber(scanNumber); - // Trailer extra data list - ScanTrailer trailerData; + // Trailer extra data list + ScanTrailer trailerData; - try - { - trailerData = new ScanTrailer(rawFile.GetTrailerExtraInformation(scanNumber)); - } - catch (Exception ex) - { - Log.WarnFormat("Cannot load trailer infromation for scan {0} due to following exception\n{1}", scanNumber, ex.Message); - ParseInput.NewWarn(); - trailerData = new ScanTrailer(); - } - - // Get scan ms level - var msLevel = (int)scanFilter.MSOrder; - - // Construct the precursor reference string for the title - var precursorReference = ""; - - if (ParseInput.MgfPrecursor) - { - if (msLevel == 1) + try { - // Keep track of the MS1 scan number for precursor reference - _precursorScanNumbers[""] = scanNumber; + trailerData = new ScanTrailer(rawFile.GetTrailerExtraInformation(scanNumber)); } - else + catch (Exception ex) { - // Keep track of scan number and isolation m/z for precursor reference - var result = _filterStringIsolationMzPattern.Match(scanEvent.ToString()); - if (result.Success) - { - if (_precursorScanNumbers.ContainsKey(result.Groups[1].Value)) - { - _precursorScanNumbers.Remove(result.Groups[1].Value); - } + Log.WarnFormat("Cannot load trailer infromation for scan {0} due to following exception\n{1}", scanNumber, ex.Message); + ParseInput.NewWarn(); + trailerData = new ScanTrailer(); + } - _precursorScanNumbers.Add(result.Groups[1].Value, scanNumber); - } + // Get scan ms level + var msLevel = (int)scanFilter.MSOrder; + + // Construct the precursor reference string for the title + var precursorReference = ""; - //update precursor scan if it is provided in trailer data - var trailerMasterScan = trailerData.AsPositiveInt("Master Scan Number:"); - if (trailerMasterScan.HasValue) + if (ParseInput.MgfPrecursor) + { + if (msLevel == 1) { - _precursorScanNumber = trailerMasterScan.Value; + // Keep track of the MS1 scan number for precursor reference + _precursorScanNumbers[""] = scanNumber; } - else //try getting it from the scan filter + else { - var parts = Regex.Split(result.Groups[1].Value, " "); - - //find the position of the first (from the end) precursor with a different mass - //to account for possible supplementary activations written in the filter - var lastIonMass = parts.Last().Split('@').First(); - int last = parts.Length; - while (last > 0 && - parts[last - 1].Split('@').First() == lastIonMass) + // Keep track of scan number and isolation m/z for precursor reference + var result = _filterStringIsolationMzPattern.Match(scanEvent.ToString()); + if (result.Success) { - last--; + if (_precursorScanNumbers.ContainsKey(result.Groups[1].Value)) + { + _precursorScanNumbers.Remove(result.Groups[1].Value); + } + + _precursorScanNumbers.Add(result.Groups[1].Value, scanNumber); } - string parentFilter = String.Join(" ", parts.Take(last)); - if (_precursorScanNumbers.ContainsKey(parentFilter)) + //update precursor scan if it is provided in trailer data + var trailerMasterScan = trailerData.AsPositiveInt("Master Scan Number:"); + if (trailerMasterScan.HasValue) { - _precursorScanNumber = _precursorScanNumbers[parentFilter]; + _precursorScanNumber = trailerMasterScan.Value; + } + else //try getting it from the scan filter + { + var parts = Regex.Split(result.Groups[1].Value, " "); + + //find the position of the first (from the end) precursor with a different mass + //to account for possible supplementary activations written in the filter + var lastIonMass = parts.Last().Split('@').First(); + int last = parts.Length; + while (last > 0 && + parts[last - 1].Split('@').First() == lastIonMass) + { + last--; + } + + string parentFilter = String.Join(" ", parts.Take(last)); + if (_precursorScanNumbers.ContainsKey(parentFilter)) + { + _precursorScanNumber = _precursorScanNumbers[parentFilter]; + } + } + + if (_precursorScanNumber > 0) + { + precursorReference = ConstructSpectrumTitle((int)Device.MS, 1, _precursorScanNumber); + } + else + { + Log.Error($"Failed finding precursor for {scanNumber}"); + ParseInput.NewError(); } } + } - if (_precursorScanNumber > 0) + if (ParseInput.MsLevel.Contains(msLevel)) + { + var reaction = GetReaction(scanEvent, scanNumber); + + Writer.WriteLine("BEGIN IONS"); + if (!ParseInput.MgfPrecursor) { - precursorReference = ConstructSpectrumTitle((int)Device.MS, 1, _precursorScanNumber); + Writer.WriteLine($"TITLE={ConstructSpectrumTitle((int)Device.MS, 1, scanNumber)}"); } else { - Log.Error($"Failed finding precursor for {scanNumber}"); - ParseInput.NewError(); + Writer.WriteLine( + $"TITLE={ConstructSpectrumTitle((int)Device.MS, 1, scanNumber)} [PRECURSOR={precursorReference}]"); } - } - } - if (ParseInput.MsLevel.Contains(msLevel)) - { - var reaction = GetReaction(scanEvent, scanNumber); - - Writer.WriteLine("BEGIN IONS"); - if (!ParseInput.MgfPrecursor) - { - Writer.WriteLine($"TITLE={ConstructSpectrumTitle((int) Device.MS, 1, scanNumber)}"); - } - else - { + Writer.WriteLine($"SCANS={scanNumber}"); Writer.WriteLine( - $"TITLE={ConstructSpectrumTitle((int) Device.MS, 1, scanNumber)} [PRECURSOR={precursorReference}]"); - } - - Writer.WriteLine($"SCANS={scanNumber}"); - Writer.WriteLine( - $"RTINSECONDS={(retentionTime * 60).ToString(CultureInfo.InvariantCulture)}"); + $"RTINSECONDS={(retentionTime * 60).ToString(CultureInfo.InvariantCulture)}"); - int? charge = trailerData.AsPositiveInt("Charge State:"); - double? monoisotopicMz = trailerData.AsDouble("Monoisotopic M/Z:"); - double? isolationWidth = - trailerData.AsDouble("MS" + msLevel + " Isolation Width:"); + int? charge = trailerData.AsPositiveInt("Charge State:"); + double? monoisotopicMz = trailerData.AsDouble("Monoisotopic M/Z:"); + double? isolationWidth = + trailerData.AsDouble("MS" + msLevel + " Isolation Width:"); - if (reaction != null) - { - var selectedIonMz = - CalculateSelectedIonMz(reaction, monoisotopicMz, isolationWidth); + if (reaction != null) + { + var selectedIonMz = + CalculateSelectedIonMz(reaction, monoisotopicMz, isolationWidth); - Writer.WriteLine("PEPMASS=" + - selectedIonMz.ToString(CultureInfo.InvariantCulture)); - } + Writer.WriteLine("PEPMASS=" + + selectedIonMz.ToString(CultureInfo.InvariantCulture)); + } - // Charge - if (charge != null) - { - // Scan polarity - var polarity = PositivePolarity; - if (scanFilter.Polarity == PolarityType.Negative) + // Charge + if (charge != null) { - polarity = NegativePolarity; - } + // Scan polarity + var polarity = PositivePolarity; + if (scanFilter.Polarity == PolarityType.Negative) + { + polarity = NegativePolarity; + } - Writer.WriteLine($"CHARGE={charge}{polarity}"); - } + Writer.WriteLine($"CHARGE={charge}{polarity}"); + } - // Write the filter string - //Writer.WriteLine($"SCANEVENT={scanEvent.ToString()}"); + // Write the filter string + //Writer.WriteLine($"SCANEVENT={scanEvent.ToString()}"); - double[] masses; - double[] intensities; + double[] masses; + double[] intensities; - if (!ParseInput.NoPeakPicking.Contains(msLevel)) - { - // Check if the scan has a centroid stream - if (scan.HasCentroidStream) + if (!ParseInput.NoPeakPicking.Contains(msLevel)) { - masses = scan.CentroidScan.Masses; - intensities = scan.CentroidScan.Intensities; + // Check if the scan has a centroid stream + if (scan.HasCentroidStream) + { + masses = scan.CentroidScan.Masses; + intensities = scan.CentroidScan.Intensities; + } + else // Otherwise take segmented (low res) scan data + { + // If the spectrum is profile perform centroiding + var segmentedScan = scanEvent.ScanData == ScanDataType.Profile + ? Scan.ToCentroid(scan).SegmentedScan + : scan.SegmentedScan; + + masses = segmentedScan.Positions; + intensities = segmentedScan.Intensities; + } } - else // Otherwise take segmented (low res) scan data + else // Use the segmented data as is { - // If the spectrum is profile perform centroiding - var segmentedScan = scanEvent.ScanData == ScanDataType.Profile - ? Scan.ToCentroid(scan).SegmentedScan - : scan.SegmentedScan; - - masses = segmentedScan.Positions; - intensities = segmentedScan.Intensities; + masses = scan.SegmentedScan.Positions; + intensities = scan.SegmentedScan.Intensities; } - } - else // Use the segmented data as is - { - masses = scan.SegmentedScan.Positions; - intensities = scan.SegmentedScan.Intensities; - } - - if (!(masses is null) && masses.Length > 0) - { - Array.Sort(masses, intensities); - for (var i = 0; i < masses.Length; i++) + if (!(masses is null) && masses.Length > 0) { - Writer.WriteLine(String.Format("{0:f5} {1:f3}", masses[i], intensities[i])); + Array.Sort(masses, intensities); + + for (var i = 0; i < masses.Length; i++) + { + Writer.WriteLine(String.Format("{0:f5} {1:f3}", masses[i], intensities[i])); + } } - } - Writer.WriteLine("END IONS"); + Writer.WriteLine("END IONS"); - Log.Debug("Spectrum written to file -- SCAN# " + scanNumber); + Log.Debug("Spectrum written to file -- SCAN# " + scanNumber); + } } } diff --git a/Writer/MzMlSpectrumWriter.cs b/Writer/MzMlSpectrumWriter.cs index c830677..3d4a6a7 100644 --- a/Writer/MzMlSpectrumWriter.cs +++ b/Writer/MzMlSpectrumWriter.cs @@ -81,7 +81,7 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc ConfigureWriter(".mzML"); XmlSerializer serializer; - var settings = new XmlWriterSettings {Indent = true, Encoding = new UTF8Encoding()}; + var settings = new XmlWriterSettings { Indent = true, Encoding = new UTF8Encoding() }; var sha1 = SHA1.Create(); CryptoStream cryptoStream = null; if (_doIndexing) @@ -141,29 +141,32 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc // fileContent _writer.WriteStartElement("fileContent"); // MS1 - SerializeCvParam(new CVParamType - { - accession = "MS:1000579", - name = "MS1 spectrum", - cvRef = "MS", - value = "" - }); - // MSn - SerializeCvParam(new CVParamType + if (rawFile.SelectMsData()) { - accession = "MS:1000580", - name = "MSn spectrum", - cvRef = "MS", - value = "" - }); - // Ion current chromatogram - SerializeCvParam(new CVParamType - { - accession = "MS:1000810", - name = "ion current chromatogram", - cvRef = "MS", - value = "" - }); + SerializeCvParam(new CVParamType + { + accession = "MS:1000579", + name = "MS1 spectrum", + cvRef = "MS", + value = "" + }); + // MSn + SerializeCvParam(new CVParamType + { + accession = "MS:1000580", + name = "MSn spectrum", + cvRef = "MS", + value = "" + }); + // Ion current chromatogram + SerializeCvParam(new CVParamType + { + accession = "MS:1000810", + name = "ion current chromatogram", + cvRef = "MS", + value = "" + }); + } // Other detector data if (ParseInput.AllDetectors) @@ -192,6 +195,25 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc value = "" }); } + + // Pressure chromatogram + if (_rawFile.GetInstrumentCountOfType(Device.Analog) > 0) + { + SerializeCvParam(new CVParamType + { + accession = "MS:1003019", + name = "pressure chromatogram", + cvRef = "MS", + value = "" + }); + } + + // MSAnalog chromatogram + if (_rawFile.GetInstrumentCountOfType(Device.MSAnalog) > 0) + { + // TODO Write MSAnalog fileContent + // e.g. Front FID or Back FID + } } _writer.WriteEndElement(); // fileContent @@ -229,27 +251,32 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc _writer.WriteEndElement(); // sourceFileList _writer.WriteEndElement(); // fileDescription - var instrumentData = _rawFile.GetInstrumentData(); + if (_rawFile.SelectedInstrument.DeviceType != Device.None && _rawFile.SelectedInstrument.InstrumentIndex != -1) + { + var instrumentData = _rawFile.GetInstrumentData(); - // ReferenceableParamGroupList - _writer.WriteStartElement("referenceableParamGroupList"); - _writer.WriteAttributeString("count", "1"); - // ReferenceableParamGroup - _writer.WriteStartElement("referenceableParamGroup"); - _writer.WriteAttributeString("id", "commonInstrumentParams"); + // ReferenceableParamGroupList + _writer.WriteStartElement("referenceableParamGroupList"); + _writer.WriteAttributeString("count", "1"); + // ReferenceableParamGroup + _writer.WriteStartElement("referenceableParamGroup"); + _writer.WriteAttributeString("id", "commonInstrumentParams"); - var instrumentModel = OntologyMapping.getInstrumentModel(instrumentData.Name); - SerializeCvParam(instrumentModel); + var instrumentModel = OntologyMapping.getInstrumentModel(instrumentData.Name); + SerializeCvParam(instrumentModel); - SerializeCvParam(new CVParamType - { - cvRef = "MS", - accession = "MS:1000529", - name = "instrument serial number", - value = instrumentData.SerialNumber - }); - _writer.WriteEndElement(); // referenceableParamGroup - _writer.WriteEndElement(); // referenceableParamGroupList + SerializeCvParam(new CVParamType + { + cvRef = "MS", + accession = "MS:1000529", + name = "instrument serial number", + value = instrumentData.SerialNumber + }); + _writer.WriteEndElement(); // referenceableParamGroup + _writer.WriteEndElement(); // referenceableParamGroupList + + PopulateInstrumentConfigurationList(firstScanNumber, lastScanNumber, instrumentModel); + } // SoftwareList _writer.WriteStartElement("softwareList"); @@ -267,7 +294,6 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc _writer.WriteEndElement(); // software _writer.WriteEndElement(); // softwareList - PopulateInstrumentConfigurationList(firstScanNumber, lastScanNumber, instrumentModel); // DataProcessingList _writer.WriteStartElement("dataProcessingList"); @@ -324,64 +350,68 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc var index = 0; var lastScanProgress = 0; - Log.Info(String.Format("Processing {0} MS scans", +(1 + lastScanNumber - firstScanNumber))); - - for (var scanNumber = firstScanNumber; scanNumber <= lastScanNumber; scanNumber++) + if (_rawFile.SelectMsData()) { - if (ParseInput.LogFormat == LogFormat.DEFAULT) + Log.Info(String.Format("Processing {0} MS scans", +(1 + lastScanNumber - firstScanNumber))); + + for (var scanNumber = firstScanNumber; scanNumber <= lastScanNumber; scanNumber++) { - var scanProgress = (int) ((double) scanNumber / (lastScanNumber - firstScanNumber + 1) * 100); - if (scanProgress % ProgressPercentageStep == 0) + if (ParseInput.LogFormat == LogFormat.DEFAULT) { - if (scanProgress != lastScanProgress) + var scanProgress = (int)((double)scanNumber / (lastScanNumber - firstScanNumber + 1) * 100); + if (scanProgress % ProgressPercentageStep == 0) { - Console.Write("" + scanProgress + "% "); - lastScanProgress = scanProgress; + if (scanProgress != lastScanProgress) + { + Console.Write("" + scanProgress + "% "); + lastScanProgress = scanProgress; + } } } - } - SpectrumType spectrum = null; + SpectrumType spectrum = null; - try - { - spectrum = ConstructMSSpectrum(scanNumber); - } - catch (Exception ex) - { - Log.Error($"Scan #{scanNumber} cannot be processed because of the following exception: {ex.Message}\n{ex.StackTrace}"); - ParseInput.NewError(); - } + try + { + spectrum = ConstructMSSpectrum(scanNumber); + } + catch (Exception ex) + { + Log.Error($"Scan #{scanNumber} cannot be processed because of the following exception: {ex.Message}\n{ex.StackTrace}"); + ParseInput.NewError(); + } - var level = spectrum != null ? int.Parse(spectrum.cvParam.Where(p => p.accession == "MS:1000511").First().value) : 0; - - if (spectrum != null && ParseInput.MsLevel.Contains(level)) //applying MS level filter - { - spectrum.index = index.ToString(); - if (_doIndexing) + var level = spectrum != null ? int.Parse(spectrum.cvParam.Where(p => p.accession == "MS:1000511").First().value) : 0; + + if (spectrum != null && ParseInput.MsLevel.Contains(level)) //applying MS level filter { - // flush the writers before getting the position - _writer.Flush(); - Writer.Flush(); - if (spectrumOffSets.Count != 0) + spectrum.index = index.ToString(); + if (_doIndexing) { - spectrumOffSets.Add(spectrum.id, Writer.BaseStream.Position + 6 + _osOffset); - } - else - { - spectrumOffSets.Add(spectrum.id, Writer.BaseStream.Position + 7 + _osOffset); + // flush the writers before getting the position + _writer.Flush(); + Writer.Flush(); + if (spectrumOffSets.Count != 0) + { + spectrumOffSets.Add(spectrum.id, Writer.BaseStream.Position + 6 + _osOffset); + } + else + { + spectrumOffSets.Add(spectrum.id, Writer.BaseStream.Position + 7 + _osOffset); + } } - } - Serialize(serializer, spectrum); + Serialize(serializer, spectrum); - Log.Debug("Spectrum added to list of spectra -- ID " + spectrum.id); + Log.Debug("Spectrum added to list of spectra -- ID " + spectrum.id); - index++; + index++; + } } } + if (ParseInput.LogFormat == LogFormat.DEFAULT) { Console.WriteLine(); @@ -405,7 +435,7 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc if (ParseInput.LogFormat == LogFormat.DEFAULT) { var scanProgress = - (int) ((double) scanNumber / (lastScanNumber - firstScanNumber + 1) * 100); + (int)((double)scanNumber / (lastScanNumber - firstScanNumber + 1) * 100); if (scanProgress % ProgressPercentageStep == 0) { if (scanProgress != lastScanProgress) @@ -464,7 +494,7 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc _writer.WriteEndElement(); // spectrumList index = 0; - var chromatograms = ConstructChromatograms(firstScanNumber, lastScanNumber); + var chromatograms = ConstructChromatograms(); if (!chromatograms.IsNullOrEmpty()) { // ChromatogramList @@ -624,21 +654,22 @@ private string GetTotalScanNumber() var lastSelectedInstrument = _rawFile.SelectedInstrument; var numScans = 0; - _rawFile.SelectInstrument(Device.MS, 1); - - var levelFilter = _rawFile.GetFilterFromString(""); - - foreach (var level in ParseInput.MsLevel) + if (_rawFile.GetInstrumentCountOfType(Device.MS) != 0) { - levelFilter.MSOrder = (MSOrderType) level; + _rawFile.SelectInstrument(Device.MS, 1); + var levelFilter = _rawFile.GetFilterFromString(""); + + foreach (var level in ParseInput.MsLevel) + { + levelFilter.MSOrder = (MSOrderType)level; - var filteredScans = _rawFile.GetFilteredScansListByScanRange(levelFilter, - _rawFile.RunHeader.FirstSpectrum, _rawFile.RunHeader.LastSpectrum); + var filteredScans = _rawFile.GetFilteredScansListByScanRange(levelFilter, + _rawFile.RunHeader.FirstSpectrum, _rawFile.RunHeader.LastSpectrum); - numScans += filteredScans.Count; + numScans += filteredScans.Count; + } } - if (ParseInput.AllDetectors) { for (int nrI = 1; nrI < _rawFile.GetInstrumentCountOfType(Device.Pda) + 1; nrI++) @@ -649,7 +680,7 @@ private string GetTotalScanNumber() } // Return instrument to last selected one - if (lastSelectedInstrument != null) + if (lastSelectedInstrument != null && lastSelectedInstrument.DeviceType != Device.None && lastSelectedInstrument.InstrumentIndex != -1) _rawFile.SelectInstrument(lastSelectedInstrument.DeviceType, lastSelectedInstrument.InstrumentIndex); return numScans.ToString(); @@ -831,53 +862,57 @@ private void Serialize(XmlSerializer serializer, T t) /// the first scan number /// the last scan number /// a list of chromatograms - private List ConstructChromatograms(int firstScanNumber, int lastScanNumber) + private List ConstructChromatograms() { var chromatograms = new List(); // MS chromatograms // Reselect MS device - _rawFile.SelectInstrument(Device.MS, 1); - // Define the settings for getting the Base Peak chromatogram - var settings = new ChromatogramTraceSettings(TraceType.BasePeak); + if (_rawFile.GetInstrumentCountOfType(Device.MS) != 0) + { + _rawFile.SelectInstrument(Device.MS, 1); - // Get the chromatogram from the RAW file. - var data = _rawFile.GetChromatogramData(new IChromatogramSettings[] {settings}, -1, -1); + // Define the settings for getting the Base Peak chromatogram + var settings = new ChromatogramTraceSettings(TraceType.BasePeak); - // Split the data into the chromatograms - var trace = ChromatogramSignal.FromChromatogramData(data); + // Get the chromatogram from the RAW file. + var data = _rawFile.GetChromatogramData(new IChromatogramSettings[] { settings }, -1, -1); - for (var i = 0; i < trace.Length; i++) - { - if (trace[i].Length > 0) + // Split the data into the chromatograms + var trace = ChromatogramSignal.FromChromatogramData(data); + + for (var i = 0; i < trace.Length; i++) { - // CV Data for Base Peak Chromatogram - var chroType = new CVParamType + if (trace[i].Length > 0) { - accession = "MS:1000628", - name = "basepeak chromatogram", - cvRef = "MS", - value = "" - }; + // CV Data for Base Peak Chromatogram + var chroType = new CVParamType + { + accession = "MS:1000628", + name = "basepeak chromatogram", + cvRef = "MS", + value = "" + }; - var intensType = new CVParamType - { - accession = "MS:1000515", - name = "intensity array", - cvRef = "MS", - unitName = "number of counts", - value = "", - unitCvRef = "MS", - unitAccession = "MS:1000131" - }; + var intensType = new CVParamType + { + accession = "MS:1000515", + name = "intensity array", + cvRef = "MS", + unitName = "number of counts", + value = "", + unitCvRef = "MS", + unitAccession = "MS:1000131" + }; - var chromatogram = TraceToChromatogram(trace[i], "BasePeak_" + i.ToString(), chroType, intensType); + var chromatogram = TraceToChromatogram(trace[i], "BasePeak_" + i.ToString(), chroType, intensType); - chromatograms.Add(chromatogram); + chromatograms.Add(chromatogram); + } } } - // Chromatograms from other devices: UV, PDA + // Chromatograms from other devices: UV, PDA, Analog, MSAnalog if (ParseInput.AllDetectors) { for (int nrI = 1; nrI < _rawFile.GetInstrumentCountOfType(Device.Pda) + 1; nrI++) @@ -886,11 +921,11 @@ private List ConstructChromatograms(int firstScanNumber, int l var instData = _rawFile.GetInstrumentData(); - settings = new ChromatogramTraceSettings(TraceType.TotalAbsorbance); + var settings = new ChromatogramTraceSettings(TraceType.TotalAbsorbance); - data = _rawFile.GetChromatogramData(new IChromatogramSettings[] {settings}, -1, -1); + var data = _rawFile.GetChromatogramData(new IChromatogramSettings[] { settings }, -1, -1); - trace = ChromatogramSignal.FromChromatogramData(data); + var trace = ChromatogramSignal.FromChromatogramData(data); for (var i = 0; i < trace.Length; i++) { @@ -932,11 +967,11 @@ private List ConstructChromatograms(int firstScanNumber, int l { var channelName = instData.ChannelLabels[channel]; - settings = new ChromatogramTraceSettings(TraceType.StartUVChromatogramTraces + channel + 1); + var settings = new ChromatogramTraceSettings(TraceType.StartUVChromatogramTraces + channel + 1); - data = _rawFile.GetChromatogramData(new IChromatogramSettings[] {settings}, -1, -1); + var data = _rawFile.GetChromatogramData(new IChromatogramSettings[] { settings }, -1, -1); - trace = ChromatogramSignal.FromChromatogramData(data); + var trace = ChromatogramSignal.FromChromatogramData(data); for (var i = 0; i < trace.Length; i++) { @@ -981,16 +1016,16 @@ private List ConstructChromatograms(int firstScanNumber, int l if (channelName.ToLower().Contains("pressure")) { - settings = new ChromatogramTraceSettings(TraceType.StartPCA2DChromatogramTraces + channel + + var settings = new ChromatogramTraceSettings(TraceType.StartPCA2DChromatogramTraces + channel + 1); - data = _rawFile.GetChromatogramData(new IChromatogramSettings[] {settings}, -1, -1); + var data = _rawFile.GetChromatogramData(new IChromatogramSettings[] { settings }, -1, -1); - trace = ChromatogramSignal.FromChromatogramData(data); + var trace = ChromatogramSignal.FromChromatogramData(data); for (var i = 0; i < trace.Length; i++) { - // CV Data for Absorbance Chromatogram + // CV Data for Pressure Chromatogram var chroType = new CVParamType { accession = "MS:1003019", @@ -1019,6 +1054,67 @@ private List ConstructChromatograms(int firstScanNumber, int l } } } + + var channelNameIndex = 0; + for (int nrI = 1; nrI < _rawFile.GetInstrumentCountOfType(Device.MSAnalog) + 1; nrI++) + { + _rawFile.SelectInstrument(Device.MSAnalog, nrI); + + var instData = _rawFile.GetInstrumentData(); + + for (int channel = 0; channel < instData.ChannelLabels.Length; channel++) + { + var channelName = instData.ChannelLabels[channel]; + + if (channelName.IsNullOrEmpty()) + { + channelName = "Channel " + channelNameIndex++; + } + + var settings = new ChromatogramTraceSettings(TraceType.StartAnalogChromatogramTraces + channel + + 1); + + var data = _rawFile.GetChromatogramData(new IChromatogramSettings[] { settings }, -1, -1); + + var trace = ChromatogramSignal.FromChromatogramData(data); + + for (var i = 0; i < trace.Length; i++) + { + // CV Data for Chromatogram + var chroType = new CVParamType + { + name = channelName + " chromatogram", + value = "" + }; + + var intensType = new CVParamType(); + if (instData.Units.ToString().Equals("Volts")) + { + intensType = new CVParamType + { + name = channelName + " array", + unitAccession = "UO:0000218", + unitName = "volt", + unitCvRef = "UO" + }; + } + else + { + intensType = new CVParamType + { + name = channelName + " array", + value = instData.Units.ToString(), + }; + } + + var chromatogram = TraceToChromatogram(trace[i], + String.Format("MSAD#{0}_{1}_{2}", nrI, channelName.Replace(" ", "_"), i), + chroType, intensType); + + chromatograms.Add(chromatogram); + } + } + } } return chromatograms; @@ -1058,7 +1154,7 @@ private ChromatogramType TraceToChromatogram(ChromatogramSignal trace, string ch : GetZLib64BitArray(trace.Times) }; timesBinaryData.encodedLength = - (4 * Math.Ceiling((double) timesBinaryData + (4 * Math.Ceiling((double)timesBinaryData .binary.Length / 3)).ToString(CultureInfo.InvariantCulture); var timesBinaryDataCvParams = new List { @@ -1123,7 +1219,7 @@ private ChromatogramType TraceToChromatogram(ChromatogramSignal trace, string ch : GetZLib64BitArray(trace.Intensities) }; intensitiesBinaryData.encodedLength = - (4 * Math.Ceiling((double) intensitiesBinaryData + (4 * Math.Ceiling((double)intensitiesBinaryData .binary.Length / 3)).ToString(CultureInfo.InvariantCulture); var intensitiesBinaryDataCvParams = new List { @@ -1196,7 +1292,7 @@ private SpectrumType ConstructMSSpectrum(int scanNumber) var scanEvent = _rawFile.GetScanEventForScanNumber(scanNumber); var spectrum = new SpectrumType { - id = ConstructSpectrumTitle((int) Device.MS, 1, scanNumber), + id = ConstructSpectrumTitle((int)Device.MS, 1, scanNumber), defaultArrayLength = 0 }; @@ -1229,7 +1325,7 @@ private SpectrumType ConstructMSSpectrum(int scanNumber) int? charge = trailerData.AsPositiveInt("Charge State:"); double? monoisotopicMz = trailerData.AsDouble("Monoisotopic M/Z:"); double? ionInjectionTime = trailerData.AsDouble("Ion Injection Time (ms):"); - double? isolationWidth = trailerData.AsDouble("MS" + (int) scanFilter.MSOrder + " Isolation Width:"); + double? isolationWidth = trailerData.AsDouble("MS" + (int)scanFilter.MSOrder + " Isolation Width:"); double? FAIMSCV = null; if (trailerData.AsBool("FAIMS Voltage On:").GetValueOrDefault(false)) FAIMSCV = trailerData.AsDouble("FAIMS CV:"); @@ -1241,7 +1337,7 @@ private SpectrumType ConstructMSSpectrum(int scanNumber) foreach (var label in trailerData.MatchKeys(_spSentry)) { var mass = trailerData.AsDouble(label).GetValueOrDefault(0); - if (mass > 0) SPSMasses.Add((double) mass); //zero means mass does not exist + if (mass > 0) SPSMasses.Add((double)mass); //zero means mass does not exist } } @@ -1251,7 +1347,7 @@ private SpectrumType ConstructMSSpectrum(int scanNumber) foreach (var labelvalue in trailerData.MatchValues(_spSentry3)) { foreach (var mass in labelvalue.Trim() - .Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries)) + .Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { SPSMasses.Add(double.Parse(mass)); } @@ -1280,14 +1376,14 @@ private SpectrumType ConstructMSSpectrum(int scanNumber) } else if (msLevel > 1) - { + { spectrumCvParams.Add(new CVParamType - { - accession = "MS:1000580", - cvRef = "MS", - name = "MSn spectrum", - value = "" - }); + { + accession = "MS:1000580", + cvRef = "MS", + name = "MSn spectrum", + value = "" + }); // Keep track of scan number and isolation m/z for precursor reference var result = _filterStringIsolationMzPattern.Match(scanEvent.ToString()); @@ -1355,7 +1451,7 @@ private SpectrumType ConstructMSSpectrum(int scanNumber) _precursorTree[scanNumber] = new PrecursorInfo(_precursorScanNumber, 1, 0, new PrecursorType[0]); } - + } else { @@ -1430,7 +1526,7 @@ private SpectrumType ConstructMSSpectrum(int scanNumber) double[] masses; double[] intensities; - if (!ParseInput.NoPeakPicking.Contains((int) scanFilter.MSOrder)) + if (!ParseInput.NoPeakPicking.Contains((int)scanFilter.MSOrder)) { //Spectrum will be centroided spectrumCvParams.Add(new CVParamType @@ -1593,7 +1689,7 @@ private SpectrumType ConstructMSSpectrum(int scanNumber) binary = ParseInput.NoZlibCompression ? Get64BitArray(masses) : GetZLib64BitArray(masses) }; massesBinaryData.encodedLength = - (4 * Math.Ceiling((double) massesBinaryData + (4 * Math.Ceiling((double)massesBinaryData .binary.Length / 3)).ToString(CultureInfo.InvariantCulture); var massesBinaryDataCvParams = new List { @@ -1655,7 +1751,7 @@ private SpectrumType ConstructMSSpectrum(int scanNumber) : GetZLib64BitArray(intensities) }; intensitiesBinaryData.encodedLength = - (4 * Math.Ceiling((double) intensitiesBinaryData + (4 * Math.Ceiling((double)intensitiesBinaryData .binary.Length / 3)).ToString(CultureInfo.InvariantCulture); var intensitiesBinaryDataCvParams = new List { @@ -1898,7 +1994,7 @@ private SpectrumType ConstructPDASpectrum(int scanNumber, int instrumentNumber) var spectrum = new SpectrumType { - id = ConstructSpectrumTitle((int) Device.Pda, instrumentNumber, scanNumber), + id = ConstructSpectrumTitle((int)Device.Pda, instrumentNumber, scanNumber), defaultArrayLength = 0 }; @@ -2017,7 +2113,7 @@ private SpectrumType ConstructPDASpectrum(int scanNumber, int instrumentNumber) binary = ParseInput.NoZlibCompression ? Get64BitArray(positions) : GetZLib64BitArray(positions) }; positionsBinaryData.encodedLength = - (4 * Math.Ceiling((double) positionsBinaryData + (4 * Math.Ceiling((double)positionsBinaryData .binary.Length / 3)).ToString(CultureInfo.InvariantCulture); var positionsBinaryDataCvParams = new List { @@ -2078,7 +2174,7 @@ private SpectrumType ConstructPDASpectrum(int scanNumber, int instrumentNumber) : GetZLib64BitArray(intensities) }; intensitiesBinaryData.encodedLength = - (4 * Math.Ceiling((double) intensitiesBinaryData + (4 * Math.Ceiling((double)intensitiesBinaryData .binary.Length / 3)).ToString(CultureInfo.InvariantCulture); var intensitiesBinaryDataCvParams = new List { @@ -2161,16 +2257,16 @@ private PrecursorListType ConstructPrecursorList(int precursorScanNumber, IScanE spectrumRef = ConstructSpectrumTitle((int)Device.MS, 1, precursorScanNumber); reaction = scanEvent.GetReaction(reactionCount); - + precursorMz = reaction.PrecursorMass; //if isolation width was not found in the trailer, try to get one from the reaction if (isolationWidth == null) isolationWidth = reaction.IsolationWidth; - + var precursor = new PrecursorType { selectedIonList = - new SelectedIonListType {count = "1", selectedIon = new ParamGroupType[1]}, + new SelectedIonListType { count = "1", selectedIon = new ParamGroupType[1] }, spectrumRef = spectrumRef }; @@ -2380,7 +2476,7 @@ private PrecursorListType ConstructPrecursorList(int precursorScanNumber, IScanE var SPSPrecursor = new PrecursorType { selectedIonList = - new SelectedIonListType {count = "1", selectedIon = new ParamGroupType[1]}, + new SelectedIonListType { count = "1", selectedIon = new ParamGroupType[1] }, spectrumRef = spectrumRef }; @@ -2689,7 +2785,7 @@ private static byte[] Get64BitArray(ICollection array) memoryStream.Position = 0; bytes = memoryStream.ToArray(); } - } + } return (byte[])bytes; } @@ -2709,8 +2805,8 @@ private static byte[] GetZLib64BitArray(ICollection array) using (var memoryStream = new MemoryStream()) using (var outZStream = new ZOutputStream(memoryStream, zlibConst.Z_DEFAULT_COMPRESSION)) { - outZStream.Write(bytes, 0, bytes.Length); - + outZStream.Write(bytes, 0, bytes.Length); + outZStream.finish(); memoryStream.Position = 0; bytes = memoryStream.ToArray(); diff --git a/Writer/ParquetSpectrumWriter.cs b/Writer/ParquetSpectrumWriter.cs index ced94be..f2ad5c1 100644 --- a/Writer/ParquetSpectrumWriter.cs +++ b/Writer/ParquetSpectrumWriter.cs @@ -43,64 +43,68 @@ private static void WritePScans(string outputDirectory, string fileName, IRawDataPlus raw, List scans) { - var enumerator = raw.GetFilteredScanEnumerator(" "); - - foreach (var scanNumber in enumerator - ) // note in my tests serial is faster than Parallel.Foreach() (this involves disk access, so it makes sense) + if (raw.SelectMsData()) { - //trailer information is extracted via index - var trailers = raw.GetTrailerExtraValues(scanNumber); - var trailerLabels = raw.GetTrailerExtraInformation(scanNumber); - object chargeState = 0; - for (int i = 0; i < trailerLabels.Labels.Length; i++) + var enumerator = raw.GetFilteredScanEnumerator(" "); + + foreach (var scanNumber in enumerator + ) // note in my tests serial is faster than Parallel.Foreach() (this involves disk access, so it makes sense) { - if (trailerLabels.Labels[i] == "Charge State:") + //trailer information is extracted via index + var trailers = raw.GetTrailerExtraValues(scanNumber); + var trailerLabels = raw.GetTrailerExtraInformation(scanNumber); + object chargeState = 0; + for (int i = 0; i < trailerLabels.Labels.Length; i++) { - chargeState = raw.GetTrailerExtraValue(scanNumber, i); - break; + if (trailerLabels.Labels[i] == "Charge State:") + { + chargeState = raw.GetTrailerExtraValue(scanNumber, i); + break; + } } - } - var scanFilter = raw.GetFilterForScanNumber(scanNumber); - var scanStats = raw.GetScanStatsForScanNumber(scanNumber); + var scanFilter = raw.GetFilterForScanNumber(scanNumber); + var scanStats = raw.GetScanStatsForScanNumber(scanNumber); - CentroidStream centroidStream = new CentroidStream(); + CentroidStream centroidStream = new CentroidStream(); - //check for FT mass analyzer data - if (scanFilter.MassAnalyzer == MassAnalyzerType.MassAnalyzerFTMS) - { - centroidStream = raw.GetCentroidStream(scanNumber, false); - } + //check for FT mass analyzer data + if (scanFilter.MassAnalyzer == MassAnalyzerType.MassAnalyzerFTMS) + { + centroidStream = raw.GetCentroidStream(scanNumber, false); + } - //check for IT mass analyzer data - if (scanFilter.MassAnalyzer == MassAnalyzerType.MassAnalyzerITMS) - { - var scanData = raw.GetSimplifiedScan(scanNumber); - centroidStream.Masses = scanData.Masses; - centroidStream.Intensities = scanData.Intensities; - } + //check for IT mass analyzer data + if (scanFilter.MassAnalyzer == MassAnalyzerType.MassAnalyzerITMS) + { + var scanData = raw.GetSimplifiedScan(scanNumber); + centroidStream.Masses = scanData.Masses; + centroidStream.Intensities = scanData.Intensities; + } - var msOrder = raw.GetScanEventForScanNumber(scanNumber).MSOrder; + var msOrder = raw.GetScanEventForScanNumber(scanNumber).MSOrder; - if (msOrder == MSOrderType.Ms) - { - var pscan = GetPScan(scanStats, centroidStream, fileName, Convert.ToInt32(chargeState)); - scans.Add(pscan); - } + if (msOrder == MSOrderType.Ms) + { + var pscan = GetPScan(scanStats, centroidStream, fileName, Convert.ToInt32(chargeState)); + scans.Add(pscan); + } - if (msOrder == MSOrderType.Ms2) - { - var precursorMz = raw.GetScanEventForScanNumber(scanNumber).GetReaction(0).PrecursorMass; - var pscan = GetPScan(scanStats, centroidStream, fileName, precursorMz, - Convert.ToInt32(chargeState)); - scans.Add(pscan); + if (msOrder == MSOrderType.Ms2) + { + var precursorMz = raw.GetScanEventForScanNumber(scanNumber).GetReaction(0).PrecursorMass; + var pscan = GetPScan(scanStats, centroidStream, fileName, precursorMz, + Convert.ToInt32(chargeState)); + scans.Add(pscan); + } + + var t = raw.GetTrailerExtraValues(scanNumber); } - var t = raw.GetTrailerExtraValues(scanNumber); + WriteScans(outputDirectory, scans, fileName); } - - WriteScans(outputDirectory, scans, fileName); } + private static PScan GetPScan(ScanStatistics scanStats, CentroidStream centroidStream, string fileName, double? precursorMz = null, int? precursorCharge = null)