diff --git a/MainClass.cs b/MainClass.cs
index 7ece9cf..fa505ec 100644
--- a/MainClass.cs
+++ b/MainClass.cs
@@ -20,7 +20,7 @@ public static class MainClass
private static readonly ILog Log =
LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
- public const string Version = "1.4.2";
+ public const string Version = "1.4.3";
public static void Main(string[] args)
{
// Set Invariant culture as default for all further processing
diff --git a/README.md b/README.md
index 704908d..e4d08dd 100644
--- a/README.md
+++ b/README.md
@@ -192,7 +192,8 @@ Provide one of the following filters:
* M/Z start and end
* sequence and tolerance (tolerance unit optional, defaults to `ppm`)
-optionally one can define starting and ending retention times and thermo filter string (defaults to `ms`)
+optionally one can define starting and ending retention times, provide filter string (defaults to `ms`, i.e. only MS1 scans), and a comment (free text) field; any valid filter string is supported,
+however only basic validation is performed, see [issue #158](https://github.com/compomics/ThermoRawFileParser/issues/158) for details. Comment can contain any text and will be preserved in the output.
An example input JSON file:
@@ -219,7 +220,17 @@ An example input JSON file:
{
"sequence":"TRANNEL",
"tolerance":10
+ },
+ {
+ "mz":1014.5099732499732,
+ "rt_start":14.0600881872,
+ "rt_end":14.4167198290667,
+ "tolerance":5,
+ "tolerance_unit":"ppm",
+ "comment":"Only ion trap scans"
+ "scan_filter":"ITMS"
}
+ }
]
```
diff --git a/RawFileParser.cs b/RawFileParser.cs
old mode 100644
new mode 100755
index 8ac667d..48b476a
--- a/RawFileParser.cs
+++ b/RawFileParser.cs
@@ -136,18 +136,23 @@ 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);
+ var firstScanNumber = -1;
+ var lastScanNumber = -1;
- rawFile.IncludeReferenceAndExceptionData = !parseInput.ExData;
+ if (rawFile.GetInstrumentCountOfType(Device.MS) != 0)
+ {
+ rawFile.SelectInstrument(Device.MS, 1);
+ rawFile.IncludeReferenceAndExceptionData = !parseInput.ExData;
- // Get the first and last scan from the RAW file
- var firstScanNumber = rawFile.RunHeaderEx.FirstSpectrum;
- var lastScanNumber = rawFile.RunHeaderEx.LastSpectrum;
+ // Get the first and last scan from the RAW file
+ firstScanNumber = rawFile.RunHeaderEx.FirstSpectrum;
+ lastScanNumber = rawFile.RunHeaderEx.LastSpectrum;
- // Check for empty file
- if (lastScanNumber < 1)
- {
- throw new RawFileParserException("Empty RAW file, no output will be produced");
+ // Check for empty file
+ if (lastScanNumber < 1)
+ {
+ throw new RawFileParserException("Empty RAW file, no output will be produced");
+ }
}
if (parseInput.MetadataFormat != MetadataFormat.NONE)
diff --git a/ThermoRawFileParser.csproj b/ThermoRawFileParser.csproj
index 536b601..115f686 100644
--- a/ThermoRawFileParser.csproj
+++ b/ThermoRawFileParser.csproj
@@ -176,11 +176,11 @@
-
- packages\ThermoFisher.CommonCore.Data.5.0.0.88\lib\ThermoFisher.CommonCore.Data.dll
+
+ packages\ThermoFisher.CommonCore.Data.5.0.0.93\lib\netstandard2.0\ThermoFisher.CommonCore.Data.dll
-
- packages\ThermoFisher.CommonCore.RawFileReader.5.0.0.88\lib\ThermoFisher.CommonCore.RawFileReader.dll
+
+ packages\ThermoFisher.CommonCore.RawFileReader.5.0.0.93\lib\netstandard2.0\ThermoFisher.CommonCore.RawFileReader.dll
packages\zlib.net.1.0.4.0\lib\zlib.net.dll
@@ -199,6 +199,7 @@
+
diff --git a/ThermoRawFileParserTest/OntologyMappingTests.cs b/ThermoRawFileParserTest/OntologyMappingTests.cs
index d4f7f3f..69f0c31 100644
--- a/ThermoRawFileParserTest/OntologyMappingTests.cs
+++ b/ThermoRawFileParserTest/OntologyMappingTests.cs
@@ -12,13 +12,13 @@ public class OntologyMappingTests
public void TestGetInstrumentModel()
{
// exact match
- var match = OntologyMapping.getInstrumentModel("LTQ Orbitrap");
+ var match = OntologyMapping.GetInstrumentModel("LTQ Orbitrap");
Assert.AreEqual("MS:1000449", match.accession);
// partial match, should return the longest partial match
- var partialMatch = OntologyMapping.getInstrumentModel("LTQ Orbitrap XXL");
+ var partialMatch = OntologyMapping.GetInstrumentModel("LTQ Orbitrap XXL");
Assert.AreEqual("MS:1000449", partialMatch.accession);
// no match, should return the generic thermo instrument
- var noMatch = OntologyMapping.getInstrumentModel("non existing model");
+ var noMatch = OntologyMapping.GetInstrumentModel("non existing model");
Assert.AreEqual("MS:1000483", noMatch.accession);
}
}
diff --git a/ThermoRawFileParserTest/ThermoRawFileParserTest.csproj b/ThermoRawFileParserTest/ThermoRawFileParserTest.csproj
index 9cf254a..eb86bb9 100644
--- a/ThermoRawFileParserTest/ThermoRawFileParserTest.csproj
+++ b/ThermoRawFileParserTest/ThermoRawFileParserTest.csproj
@@ -155,15 +155,15 @@
..\packages\mzLib.1.0.450\lib\net471\ThermoFisher.CommonCore.BackgroundSubtraction.dll
True
-
- ..\packages\ThermoFisher.CommonCore.Data.5.0.0.88\lib\ThermoFisher.CommonCore.Data.dll
+
+ ..\packages\ThermoFisher.CommonCore.Data.5.0.0.93\lib\netstandard2.0\ThermoFisher.CommonCore.Data.dll
..\packages\mzLib.1.0.450\lib\net471\ThermoFisher.CommonCore.MassPrecisionEstimator.dll
True
-
- ..\packages\ThermoFisher.CommonCore.RawFileReader.5.0.0.88\lib\ThermoFisher.CommonCore.RawFileReader.dll
+
+ ..\packages\ThermoFisher.CommonCore.RawFileReader.5.0.0.93\lib\netstandard2.0\ThermoFisher.CommonCore.RawFileReader.dll
..\packages\mzLib.1.0.450\lib\net471\ThermoRawFileReader.dll
diff --git a/ThermoRawFileParserTest/app.config b/ThermoRawFileParserTest/app.config
index 3ee23db..60d020d 100644
--- a/ThermoRawFileParserTest/app.config
+++ b/ThermoRawFileParserTest/app.config
@@ -12,7 +12,7 @@
-
+
@@ -28,7 +28,7 @@
-
+
diff --git a/ThermoRawFileParserTest/packages.config b/ThermoRawFileParserTest/packages.config
index b89c239..ec8a33e 100644
--- a/ThermoRawFileParserTest/packages.config
+++ b/ThermoRawFileParserTest/packages.config
@@ -19,7 +19,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/Util/CVHelpers.cs b/Util/CVHelpers.cs
new file mode 100644
index 0000000..cf7c617
--- /dev/null
+++ b/Util/CVHelpers.cs
@@ -0,0 +1,21 @@
+using ThermoRawFileParser.Writer.MzML;
+
+namespace ThermoRawFileParser.Util
+{
+ public static class CVHelpers
+ {
+ public static CVParamType Copy (this CVParamType old)
+ {
+ return new CVParamType
+ {
+ accession = old.accession,
+ name = old.name,
+ cvRef = old.cvRef,
+ unitAccession = old.unitAccession,
+ unitCvRef = old.unitCvRef,
+ unitName = old.unitName,
+ value = old.value
+ };
+ }
+ }
+}
diff --git a/Writer/MetadataWriter.cs b/Writer/MetadataWriter.cs
index e7554ce..663ec13 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()))
+ {
+ msTypes[scanFilter.MSOrder.ToString()] += 1;
+ }
+ 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)
+ {
+ Log.Warn("No reaction found for scan " + scanNumber);
+ _parseInput.NewWarn();
+ }
+
+ // trailer extra data list
+ try
{
- if (int.Parse(trailerData.Values[i]) > maxCharge)
- maxCharge = int.Parse(trailerData.Values[i]);
+ var trailerData = new ScanTrailer(rawFile.GetTrailerExtraInformation(scanNumber));
+ int? charge = trailerData.AsPositiveInt("Charge State:");
- if (int.Parse(trailerData.Values[i]) < minCharge)
- minCharge = int.Parse(trailerData.Values[i]);
+ if (charge.HasValue && charge.Value > maxCharge)
+ maxCharge = charge.Value;
+
+ if (charge.HasValue && charge.Value < minCharge)
+ minCharge = charge.Value;
+ }
+ catch (Exception ex)
+ {
+ Log.WarnFormat("Cannot load trailer infromation for scan {0} due to following exception\n{1}", scanNumber, ex.Message);
+ _parseInput.NewWarn();
}
}
}
}
}
-
+
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,19 +161,23 @@ 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)
@@ -208,21 +209,31 @@ private void WriteJsonMetada(IRawDataPlus rawFile, int firstScanNumber, int last
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);
+ // Get the start and end time from the RAW file
+
+ if (rawFile.SelectMsData())
+ {
+ var runHeaderEx = rawFile.RunHeaderEx;
+ var startTime = runHeaderEx.StartTime;
+ var endTime = runHeaderEx.EndTime;
+ metadata.addScanSetting(new CVTerm("MS:1000016", "MS", "scan start time",
+ startTime.ToString(CultureInfo.InvariantCulture)));
+ metadata.addScanSetting(new CVTerm("", "", "expected runtime",
+ runHeaderEx.ExpectedRunTime.ToString(CultureInfo.InvariantCulture)));
+ metadata.addScanSetting(new CVTerm("MS:1000011", "MS", "mass resolution",
+ 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",
+ runHeaderEx.SpectraCount.ToString()));
+ metadata.addScanSetting(new CVTerm("PRIDE:0000484", "PRIDE", "Retention time range",
+ startTime + ":" + endTime));
+ metadata.addScanSetting(new CVTerm("PRIDE:0000485", "PRIDE", "Mz range",
+ runHeaderEx.LowMass + ":" + runHeaderEx.HighMass));
+ metadata.addScanSetting(fragmentationTypes);
+ metadata.addScanSetting(new CVTerm("PRIDE:0000479", "PRIDE", "MS scan range",
+ firstScanNumber + ":" + lastScanNumber));
+ }
// Sample Data
if (!rawFile.SampleInformation.SampleName.IsNullOrEmpty())
@@ -280,6 +291,43 @@ private void WriteJsonMetada(IRawDataPlus rawFile, int firstScanNumber, int last
rawFile.SampleInformation.DilutionFactor.ToString(CultureInfo.InvariantCulture)));
}
+ if (!rawFile.SampleInformation.InstrumentMethodFile.IsNullOrEmpty())
+ {
+ metadata.addSampleProperty(new CVTerm("AFR:0002045", "AFO", "device acquisition method", rawFile.SampleInformation.InstrumentMethodFile));
+ }
+
+ if (rawFile.SampleInformation.IstdAmount != 0)
+ {
+ metadata.addSampleProperty(new CVTerm("", "", "internal standard amount", rawFile.SampleInformation.IstdAmount.ToString()));
+ }
+
+ if (!rawFile.SampleInformation.CalibrationLevel.IsNullOrEmpty())
+ {
+ metadata.addSampleProperty(new CVTerm("AFR:0001849", "AFO", "calibration level", rawFile.SampleInformation.CalibrationLevel));
+ }
+
+ if (!rawFile.SampleInformation.ProcessingMethodFile.IsNullOrEmpty())
+ {
+ metadata.addSampleProperty(new CVTerm("AFR:0002175", "AFO", "data processing method", rawFile.SampleInformation.ProcessingMethodFile));
+ }
+
+ if (rawFile.SampleInformation.SampleWeight != 0)
+ {
+ metadata.addSampleProperty(new CVTerm("AFR:0001982", "AFO", "sample weight", rawFile.SampleInformation.SampleWeight.ToString()));
+ }
+
+ string[] userLabels = rawFile.UserLabel;
+ string[] userTexts = rawFile.SampleInformation.UserText;
+ if (!userLabels.IsNullOrEmpty() && !userTexts.IsNullOrEmpty())
+ {
+ for (int i = 0; i < userLabels.Length; i++)
+ {
+ if (i < userTexts.Length && !userTexts[i].IsNullOrEmpty())
+ {
+ metadata.addSampleProperty(new CVTerm("", "", userLabels[i], userTexts[i]));
+ }
+ }
+ }
// Write the meta data to file
var json = JsonConvert.SerializeObject(metadata);
@@ -296,10 +344,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,20 +358,23 @@ 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)
@@ -342,8 +389,8 @@ private void WriteTextMetadata(IRawDataPlus rawFile, int firstScanNumber, int la
output.AddRange(new List
{
- "MS min charge=" + minCharge.ToString(CultureInfo.InvariantCulture),
- "MS max charge=" + maxCharge.ToString(CultureInfo.InvariantCulture),
+ $"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)}",
@@ -352,20 +399,26 @@ private void WriteTextMetadata(IRawDataPlus rawFile, int firstScanNumber, int la
);
// 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))
- }
- );
-
+ if (rawFile.SelectMsData())
+ {
+ // 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)}",
+ $"Expected runtime={rawFile.RunHeaderEx.ExpectedRunTime.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");
@@ -415,6 +468,44 @@ private void WriteTextMetadata(IRawDataPlus rawFile, int firstScanNumber, int la
output.Add("Sample dilution factor=" + rawFile.SampleInformation.DilutionFactor);
}
+ if (rawFile.SampleInformation.IstdAmount != 0)
+ {
+ output.Add("Internal standard amount=" + rawFile.SampleInformation.IstdAmount);
+ }
+
+ if (!rawFile.SampleInformation.CalibrationLevel.IsNullOrEmpty())
+ {
+ output.Add("Calibration level=" + rawFile.SampleInformation.CalibrationLevel);
+ }
+
+ if (!rawFile.SampleInformation.InstrumentMethodFile.IsNullOrEmpty())
+ {
+ output.Add("Device acquisition method=" + rawFile.SampleInformation.InstrumentMethodFile);
+ }
+
+ if (rawFile.SampleInformation.SampleWeight != 0)
+ {
+ output.Add("Sample weight=" + rawFile.SampleInformation.SampleWeight);
+ }
+
+ if (!rawFile.SampleInformation.ProcessingMethodFile.IsNullOrEmpty())
+ {
+ output.Add("Data processing method=" + rawFile.SampleInformation.ProcessingMethodFile);
+ }
+
+ string[] userLabels = rawFile.UserLabel;
+ string[] userTexts = rawFile.SampleInformation.UserText;
+ if (!userLabels.IsNullOrEmpty() && !userTexts.IsNullOrEmpty())
+ {
+ for (int i = 0; i < userLabels.Length; i++)
+ {
+ if (i < userTexts.Length && !userTexts[i].IsNullOrEmpty())
+ {
+ output.Add(userLabels[i] + "=" + userTexts[i]);
+ }
+ }
+ }
+
// Write the meta data to file
File.WriteAllLines(_metadataFileName, output.ToArray());
}
diff --git a/Writer/MgfSpectrumWriter.cs b/Writer/MgfSpectrumWriter.cs
index c347944..0c86189 100644
--- a/Writer/MgfSpectrumWriter.cs
+++ b/Writer/MgfSpectrumWriter.cs
@@ -38,9 +38,15 @@ public MgfSpectrumWriter(ParseInput parseInput) : base(parseInput)
///
public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastScanNumber)
{
+ if (!rawFile.HasMsData)
+ {
+ throw new RawFileParserException("No MS data in RAW file, no output will be produced");
+ }
+
ConfigureWriter(".mgf");
using (Writer)
{
+
Log.Info("Processing " + (lastScanNumber - firstScanNumber + 1) + " scans");
var lastScanProgress = 0;
@@ -48,7 +54,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);
+ var scanProgress = (int)((double)scanNumber / (lastScanNumber - firstScanNumber + 1) * 100);
if (scanProgress % ProgressPercentageStep == 0)
{
if (scanProgress != lastScanProgress)
@@ -160,12 +166,12 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
Writer.WriteLine("BEGIN IONS");
if (!ParseInput.MgfPrecursor)
{
- Writer.WriteLine($"TITLE={ConstructSpectrumTitle((int) Device.MS, 1, scanNumber)}");
+ Writer.WriteLine($"TITLE={ConstructSpectrumTitle((int)Device.MS, 1, scanNumber)}");
}
else
{
Writer.WriteLine(
- $"TITLE={ConstructSpectrumTitle((int) Device.MS, 1, scanNumber)} [PRECURSOR={precursorReference}]");
+ $"TITLE={ConstructSpectrumTitle((int)Device.MS, 1, scanNumber)} [PRECURSOR={precursorReference}]");
}
Writer.WriteLine($"SCANS={scanNumber}");
@@ -250,6 +256,7 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
{
Console.WriteLine();
}
+
}
}
}
diff --git a/Writer/MzMlSpectrumWriter.cs b/Writer/MzMlSpectrumWriter.cs
index c830677..411f2dc 100644
--- a/Writer/MzMlSpectrumWriter.cs
+++ b/Writer/MzMlSpectrumWriter.cs
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Diagnostics.Eventing.Reader;
using System.Globalization;
using System.IO;
using System.IO.Compression;
@@ -16,7 +18,6 @@
using ThermoFisher.CommonCore.Data.Business;
using ThermoFisher.CommonCore.Data.FilterEnums;
using ThermoFisher.CommonCore.Data.Interfaces;
-using ThermoRawFileParser.Util;
using ThermoRawFileParser.Writer.MzML;
using zlib;
@@ -68,6 +69,8 @@ public MzMlSpectrumWriter(ParseInput parseInput) : base(parseInput)
_mzMlNamespace.Add(string.Empty, "http://psi.hupo.org/ms/mzml");
_doIndexing = ParseInput.OutputFormat == OutputFormat.IndexMzML;
_osOffset = Environment.NewLine == "\n" ? 0 : 1;
+ _precursorScanNumbers[""] = -1;
+ _precursorTree[-1] = new PrecursorInfo();
}
///
@@ -140,30 +143,35 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
_writer.WriteStartElement("fileDescription");
// fileContent
_writer.WriteStartElement("fileContent");
- // MS1
- 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
+
+ //accumulating different types of file content
+ HashSet content = new HashSet();
+
+ if (_rawFile.HasMsData)
{
- accession = "MS:1000810",
- name = "ion current chromatogram",
- cvRef = "MS",
- value = ""
- });
+ var nMS1 = rawFile.GetFilteredScanEnumerator("ms").Count();
+ var nMS = rawFile.RunHeaderEx.SpectraCount;
+ // MS1
+ if(ParseInput.MsLevel.Contains(1) && nMS1 > 0)
+ content.Add(new CVParamType
+ {
+ accession = "MS:1000579",
+ name = "MS1 spectrum",
+ cvRef = "MS",
+ value = ""
+ });
+ // MSn
+ if(ParseInput.MsLevel.Any(n => n > 1) && nMS > nMS1)
+ content.Add(new CVParamType
+ {
+ accession = "MS:1000580",
+ name = "MSn spectrum",
+ cvRef = "MS",
+ value = ""
+ });
+ // Ion current chromatogram
+ content.Add(OntologyMapping.GetChromatogramType("current"));
+ }
// Other detector data
if (ParseInput.AllDetectors)
@@ -171,7 +179,7 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
// PDA spectrum
if (_rawFile.GetInstrumentCountOfType(Device.Pda) > 0)
{
- SerializeCvParam(new CVParamType
+ content.Add(new CVParamType
{
accession = "MS:1000806",
name = "absorption spectrum",
@@ -184,14 +192,39 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
if (_rawFile.GetInstrumentCountOfType(Device.Pda) > 0 ||
_rawFile.GetInstrumentCountOfType(Device.UV) > 0)
{
- SerializeCvParam(new CVParamType
+ content.Add(OntologyMapping.GetChromatogramType("absorption"));
+ }
+ //non-standard chromatograms pressure, flow, FID, etc
+ foreach (var deviceType in new Device[2] { Device.Analog, Device.MSAnalog })
+ {
+ for (int nrI = 1; nrI < _rawFile.GetInstrumentCountOfType(deviceType) + 1; nrI++)
{
- accession = "MS:1000812",
- name = "absorption chromatogram",
- cvRef = "MS",
- value = ""
- });
+ _rawFile.SelectInstrument(deviceType, nrI);
+
+ var instData = _rawFile.GetInstrumentData();
+
+ for (int channel = 0; channel < instData.ChannelLabels.Length; channel++)
+ {
+ var channelName = instData.ChannelLabels[channel];
+ if (channelName.ToLower().Contains("pressure"))
+ content.Add(OntologyMapping.GetChromatogramType("pressure"));
+ else if (channelName.ToLower().Contains("flow"))
+ content.Add(OntologyMapping.GetChromatogramType("flow"));
+
+ else if (channelName.ToLower().Contains("fid"))
+ content.Add(OntologyMapping.GetChromatogramType("current"));
+ else
+ content.Add(OntologyMapping.GetChromatogramType("unknown"));
+ }
+ }
}
+ _rawFile.SelectMsData();
+ }
+
+ //write content
+ foreach (var item in content)
+ {
+ SerializeCvParam(item);
}
_writer.WriteEndElement(); // fileContent
@@ -229,27 +262,33 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
_writer.WriteEndElement(); // sourceFileList
_writer.WriteEndElement(); // fileDescription
- var instrumentData = _rawFile.GetInstrumentData();
+ //default instrument model
+ var instrumentModel = new CVParamType();
- // ReferenceableParamGroupList
- _writer.WriteStartElement("referenceableParamGroupList");
- _writer.WriteAttributeString("count", "1");
- // ReferenceableParamGroup
- _writer.WriteStartElement("referenceableParamGroup");
- _writer.WriteAttributeString("id", "commonInstrumentParams");
+ if (_rawFile.HasMsData)
+ {
+ var instrumentData = _rawFile.GetInstrumentData();
- var instrumentModel = OntologyMapping.getInstrumentModel(instrumentData.Name);
- SerializeCvParam(instrumentModel);
+ // ReferenceableParamGroupList
+ _writer.WriteStartElement("referenceableParamGroupList");
+ _writer.WriteAttributeString("count", "1");
+ // ReferenceableParamGroup
+ _writer.WriteStartElement("referenceableParamGroup");
+ _writer.WriteAttributeString("id", "commonInstrumentParams");
- SerializeCvParam(new CVParamType
- {
- cvRef = "MS",
- accession = "MS:1000529",
- name = "instrument serial number",
- value = instrumentData.SerialNumber
- });
- _writer.WriteEndElement(); // referenceableParamGroup
- _writer.WriteEndElement(); // referenceableParamGroupList
+ instrumentModel = OntologyMapping.GetInstrumentModel(instrumentData.Model);
+ SerializeCvParam(instrumentModel);
+
+ SerializeCvParam(new CVParamType
+ {
+ cvRef = "MS",
+ accession = "MS:1000529",
+ name = "instrument serial number",
+ value = instrumentData.SerialNumber
+ });
+ _writer.WriteEndElement(); // referenceableParamGroup
+ _writer.WriteEndElement(); // referenceableParamGroupList
+ }
// SoftwareList
_writer.WriteStartElement("softwareList");
@@ -267,7 +306,20 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
_writer.WriteEndElement(); // software
_writer.WriteEndElement(); // softwareList
- PopulateInstrumentConfigurationList(firstScanNumber, lastScanNumber, instrumentModel);
+ Log.Debug("Populating instrument configurations");
+ if (_rawFile.HasMsData)
+ {
+ PopulateInstrumentConfigurationList(firstScanNumber, lastScanNumber, instrumentModel);
+ }
+ else
+ {
+ _writer.WriteStartElement("instrumentConfigurationList");
+ _writer.WriteAttributeString("count", "1");
+ _writer.WriteStartElement("instrumentConfiguration");
+ _writer.WriteAttributeString("id", "IC1");
+ _writer.WriteEndElement(); // instrumentConfiguration
+ _writer.WriteEndElement(); // instrumentConfigurationList
+ }
// DataProcessingList
_writer.WriteStartElement("dataProcessingList");
@@ -287,7 +339,7 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
value = ""
});
_writer.WriteEndElement(); // processingMethod
- if (ParseInput.NoPeakPicking.Count < ParseInput.AllLevels.Count)
+ if (_rawFile.HasMsData && ParseInput.NoPeakPicking.Count < ParseInput.AllLevels.Count)
{
_writer.WriteStartElement("processingMethod");
_writer.WriteAttributeString("order", "1");
@@ -307,78 +359,83 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
// Run
_writer.WriteStartElement("run");
- //TODO: validate id against NCName
- _writer.WriteAttributeString("id", ParseInput.RawFileNameWithoutExtension);
+ _writer.WriteAttributeString("id", GetNCName(ParseInput.RawFileNameWithoutExtension));
_writer.WriteAttributeString("defaultInstrumentConfigurationRef", "IC1");
_writer.WriteAttributeString("startTimeStamp",
XmlConvert.ToString(_rawFile.CreationDate, XmlDateTimeSerializationMode.Utc));
_writer.WriteAttributeString("defaultSourceFileRef", SourceFileId);
+
+ //indices
+ int index = 0;
+ int lastScanProgress;
+
// SpectrumList
_writer.WriteStartElement("spectrumList");
_writer.WriteAttributeString("count", GetTotalScanNumber());
_writer.WriteAttributeString("defaultDataProcessingRef", "ThermoRawFileParserProcessing");
- serializer = _factory.CreateSerializer(typeof(SpectrumType));
+ if (_rawFile.HasMsData)
+ {
+ serializer = _factory.CreateSerializer(typeof(SpectrumType));
- // MS Spectra
- var index = 0;
- var lastScanProgress = 0;
+ // MS Spectra
+ index = 0;
+ lastScanProgress = 0;
- Log.Info(String.Format("Processing {0} MS scans", +(1 + lastScanNumber - firstScanNumber)));
+ Log.Info(String.Format("Processing {0} MS scans", +(1 + lastScanNumber - firstScanNumber)));
- for (var scanNumber = firstScanNumber; scanNumber <= lastScanNumber; scanNumber++)
- {
- if (ParseInput.LogFormat == LogFormat.DEFAULT)
+ 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);
-
- index++;
+ index++;
+ }
}
}
@@ -500,7 +557,9 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
_writer.WriteEndElement(); // chromatogramList
}
- _writer.WriteEndElement(); // run
+ _writer.Flush();
+ _writer.WriteEndElement(); // run
+ _writer.Flush();
_writer.WriteEndElement(); // mzML
if (_doIndexing)
@@ -512,22 +571,26 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
// IndexList
_writer.WriteStartElement("indexList");
- var indexCount = chromatograms.IsNullOrEmpty() ? 1 : 2;
+ var indexCount = ((spectrumOffSets.Count > 0) ? 1 : 0) + (chromatograms.IsNullOrEmpty() ? 0 : 1);
_writer.WriteAttributeString("count", indexCount.ToString());
// Index
- _writer.WriteStartElement("index");
- _writer.WriteAttributeString("name", "spectrum");
- var spectrumOffsetEnumerator = spectrumOffSets.GetEnumerator();
- while (spectrumOffsetEnumerator.MoveNext())
- {
- // Offset
- _writer.WriteStartElement("offset");
- _writer.WriteAttributeString("idRef", spectrumOffsetEnumerator.Key.ToString());
- _writer.WriteString(spectrumOffsetEnumerator.Value.ToString());
- _writer.WriteEndElement(); // offset
- }
+
+ if (spectrumOffSets.Count > 0)
+ {
+ _writer.WriteStartElement("index");
+ _writer.WriteAttributeString("name", "spectrum");
+ var spectrumOffsetEnumerator = spectrumOffSets.GetEnumerator();
+ while (spectrumOffsetEnumerator.MoveNext())
+ {
+ // Offset
+ _writer.WriteStartElement("offset");
+ _writer.WriteAttributeString("idRef", spectrumOffsetEnumerator.Key.ToString());
+ _writer.WriteString(spectrumOffsetEnumerator.Value.ToString());
+ _writer.WriteEndElement(); // offset
+ }
- _writer.WriteEndElement(); // index
+ _writer.WriteEndElement(); // index
+ }
if (!chromatograms.IsNullOrEmpty())
{
@@ -587,8 +650,16 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
if (_doIndexing)
{
- cryptoStream.Flush();
- cryptoStream.Close();
+ try
+ {
+ cryptoStream.Flush();
+ cryptoStream.Close();
+ }
+ catch (System.ObjectDisposedException e)
+ {
+ // Cannot access a closed file. CryptoStream was already closed when closing _writer
+ Log.Warn($"Warning: {e.Message}");
+ }
}
}
@@ -618,27 +689,41 @@ public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastSc
}
}
+ private string GetNCName(string filename)
+ {
+ string result = Regex.Replace(filename, @"[^\d\w\.\-]+", "_");
+
+ if (Regex.IsMatch(result, @"^\d"))
+ {
+ result = $"_{result}";
+ }
+
+ return result;
+ }
+
private string GetTotalScanNumber()
{
// Save the last selected instrument
var lastSelectedInstrument = _rawFile.SelectedInstrument;
var numScans = 0;
- _rawFile.SelectInstrument(Device.MS, 1);
+ if (_rawFile.HasMsData)
+ {
+ _rawFile.SelectInstrument(Device.MS, 1);
- var levelFilter = _rawFile.GetFilterFromString("");
+ var levelFilter = _rawFile.GetFilterFromString("");
- foreach (var level in ParseInput.MsLevel)
- {
- levelFilter.MSOrder = (MSOrderType) level;
+ 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 +734,7 @@ private string GetTotalScanNumber()
}
// Return instrument to last selected one
- if (lastSelectedInstrument != null)
+ if (lastSelectedInstrument.InstrumentIndex >= 1)
_rawFile.SelectInstrument(lastSelectedInstrument.DeviceType, lastSelectedInstrument.InstrumentIndex);
return numScans.ToString();
@@ -664,11 +749,8 @@ private string GetTotalScanNumber()
private void PopulateInstrumentConfigurationList(int firstScanNumber, int lastScanNumber,
CVParamType instrumentModel)
{
- // Go over the first scans until an MS2 scan is encountered
- // to collect all mass analyzer and ionization types
- var encounteredMs2 = false;
- var scanNumber = firstScanNumber;
- do
+ // Go over scan filters to collect all mass analyzer and ionization types
+ for (int scanNumber = firstScanNumber; scanNumber <= lastScanNumber; scanNumber++)
{
// Get the scan filter for this scan number
try
@@ -705,10 +787,6 @@ private void PopulateInstrumentConfigurationList(int firstScanNumber, int lastSc
_massAnalyzers.Add(scanFilter.MassAnalyzer, "IC" + (_massAnalyzers.Count + 1));
}
- if (scanFilter.MSOrder == MSOrderType.Ms2)
- {
- encounteredMs2 = true;
- }
}
catch (Exception)
{
@@ -724,8 +802,7 @@ private void PopulateInstrumentConfigurationList(int firstScanNumber, int lastSc
}
}
- scanNumber++;
- } while (!encounteredMs2 && scanNumber <= lastScanNumber);
+ }
// Add a default analyzer if none were found
if (_massAnalyzers.Count == 0)
@@ -835,45 +912,53 @@ private List ConstructChromatograms(int firstScanNumber, int l
{
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);
+ //common variables
+ ChromatogramTraceSettings settings;
+ IChromatogramData data;
+ ChromatogramSignal[] trace;
- // Get the chromatogram from the RAW file.
- var data = _rawFile.GetChromatogramData(new IChromatogramSettings[] {settings}, -1, -1);
+ if (_rawFile.HasMsData)
+ {
+ // MS chromatograms
+ // Reselect MS device
+ _rawFile.SelectInstrument(Device.MS, 1);
+ // Define the settings for getting the Base Peak chromatogram
+ settings = new ChromatogramTraceSettings(TraceType.BasePeak);
- // Split the data into the chromatograms
- var trace = ChromatogramSignal.FromChromatogramData(data);
+ // Get the chromatogram from the RAW file.
+ 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
+ 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);
+ }
}
}
@@ -895,24 +980,9 @@ private List ConstructChromatograms(int firstScanNumber, int l
for (var i = 0; i < trace.Length; i++)
{
// CV Data for Total Absorbance Chromatogram
- var chroType = new CVParamType
- {
- accession = "MS:1000812",
- name = "absorption chromatogram",
- cvRef = "MS",
- value = ""
- };
-
- var intensType = new CVParamType
- {
- accession = "MS:1000515",
- name = "intensity array",
- cvRef = "MS",
- unitName = "absorbance unit",
- value = instData.Units.ToString(),
- unitCvRef = "UO",
- unitAccession = "UO:0000269"
- };
+ var chroType = OntologyMapping.GetChromatogramType("absorption");
+ var intensType = OntologyMapping.GetDataArrayType("absorption");
+ intensType.value = instData.Units.ToString();
var chromatogram = TraceToChromatogram(trace[i],
String.Format("PDA#{0}_TotalAbsorbance_{1}", nrI, i),
@@ -941,25 +1011,10 @@ private List ConstructChromatograms(int firstScanNumber, int l
for (var i = 0; i < trace.Length; i++)
{
// CV Data for Absorbance Chromatogram
- var chroType = new CVParamType
- {
- accession = "MS:1000812",
- name = "absorption chromatogram",
- cvRef = "MS",
- value = ""
- };
-
- var intensType = new CVParamType
- {
- accession = "MS:1000515",
- name = "intensity array",
- cvRef = "MS",
- unitName = "absorbance unit",
- value = instData.Units.ToString(),
- unitCvRef = "UO",
- unitAccession = "UO:0000269"
- };
-
+ var chroType = OntologyMapping.GetChromatogramType("absorption");
+ var intensType = OntologyMapping.GetDataArrayType("absorption");
+ intensType.value = instData.Units.ToString();
+
var chromatogram = TraceToChromatogram(trace[i],
String.Format("UV#{0}_{1}_{2}", nrI, channelName, i),
chroType, intensType);
@@ -969,49 +1024,53 @@ private List ConstructChromatograms(int firstScanNumber, int l
}
}
- for (int nrI = 1; nrI < _rawFile.GetInstrumentCountOfType(Device.Analog) + 1; nrI++)
+ //Chromatograms from (MS)Analog devices: Pressure, FID, etc
+ foreach (var deviceType in new Device[2] { Device.Analog, Device.MSAnalog })
{
- _rawFile.SelectInstrument(Device.Analog, nrI);
-
- var instData = _rawFile.GetInstrumentData();
-
- for (int channel = 0; channel < instData.ChannelLabels.Length; channel++)
+ var channelNameIndex = 0;
+ for (int nrI = 1; nrI < _rawFile.GetInstrumentCountOfType(deviceType) + 1; nrI++)
{
- var channelName = instData.ChannelLabels[channel];
+ _rawFile.SelectInstrument(deviceType, nrI);
- if (channelName.ToLower().Contains("pressure"))
- {
- settings = new ChromatogramTraceSettings(TraceType.StartPCA2DChromatogramTraces + channel +
- 1);
+ var instData = _rawFile.GetInstrumentData();
- data = _rawFile.GetChromatogramData(new IChromatogramSettings[] {settings}, -1, -1);
+ for (int channel = 0; channel < instData.ChannelLabels.Length; channel++)
+ {
+ var channelName = instData.ChannelLabels[channel];
+ if (channelName.IsNullOrEmpty())
+ {
+ channelName = $"Channel{channelNameIndex++}";
+ }
+ settings = new ChromatogramTraceSettings(TraceType.StartAnalogChromatogramTraces + channel + 1);
+ data = _rawFile.GetChromatogramData(new IChromatogramSettings[] { settings }, -1, -1);
trace = ChromatogramSignal.FromChromatogramData(data);
for (var i = 0; i < trace.Length; i++)
{
- // CV Data for Absorbance Chromatogram
- var chroType = new CVParamType
+ //Default data type
+ var chroType = OntologyMapping.GetChromatogramType("unknown");
+ var intensType = OntologyMapping.GetDataArrayType("unknown");
+
+ if (channelName.ToLower().Contains("pressure"))
{
- accession = "MS:1003019",
- name = "pressure chromatogram",
- cvRef = "MS",
- value = ""
- };
-
- var intensType = new CVParamType
+ chroType = OntologyMapping.GetChromatogramType("pressure");
+ intensType = OntologyMapping.GetDataArrayType("pressure");
+ }
+ else if (channelName.ToLower().Contains("flow"))
{
- accession = "MS:1000821",
- name = "pressure array",
- cvRef = "MS",
- unitName = "pressure unit",
- value = "",
- unitCvRef = "UO",
- unitAccession = "UO:0000109"
- };
+ chroType = OntologyMapping.GetChromatogramType("flow");
+ intensType = OntologyMapping.GetDataArrayType("flow");
+ }
+ else if (channelName.ToLower().Contains("fid"))
+ {
+ //FID is ion current type
+ chroType = OntologyMapping.GetChromatogramType("current");
+ intensType = OntologyMapping.GetDataArrayType("intensity");
+ }
var chromatogram = TraceToChromatogram(trace[i],
- String.Format("AD#{0}_{1}_{2}", nrI, channelName, i),
+ String.Format("{0}#{1}_{2}_{3}", deviceType.ToString(), nrI, channelName.Replace(" ", "_"), i),
chroType, intensType);
chromatograms.Add(chromatogram);
@@ -1019,6 +1078,7 @@ private List ConstructChromatograms(int firstScanNumber, int l
}
}
}
+
}
return chromatograms;
@@ -1062,16 +1122,7 @@ private ChromatogramType TraceToChromatogram(ChromatogramSignal trace, string ch
.binary.Length / 3)).ToString(CultureInfo.InvariantCulture);
var timesBinaryDataCvParams = new List
{
- new CVParamType
- {
- accession = "MS:1000595",
- name = "time array",
- cvRef = "MS",
- unitName = "minute",
- value = "",
- unitCvRef = "UO",
- unitAccession = "UO:0000031"
- },
+ OntologyMapping.GetDataArrayType("time"),
new CVParamType
{
accession = "MS:1000523", name = "64-bit float", cvRef = "MS", value = ""
@@ -1312,61 +1363,52 @@ private SpectrumType ConstructMSSpectrum(int scanNumber)
_precursorScanNumber = GetParentFromScanString(result.Groups[1].Value);
}
- if (_precursorScanNumber > 0)
+ //finding precursor scan failed
+ if (_precursorScanNumber == -2)
{
+ Log.Warn($"Cannot find precursor scan for scan# {scanNumber}");
+ _precursorTree[-2] = new PrecursorInfo(0, msLevel, FindLastReaction(scanEvent, msLevel), new PrecursorType[0]);
+ }
- try
+ try
+ {
+ try //since there is no direct way to get the number of reactions available, it is necessary to try and fail
+ {
+ scanEvent.GetReaction(_precursorTree[_precursorScanNumber].ReactionCount);
+ }
+ catch (ArgumentOutOfRangeException ex)
{
- try //since there is no direct way to get the number of reactions available, it is necessary to try and fail
+ Log.Debug($"Using Tribrid decision tree fix for scan# {scanNumber}");
+ //Is it a decision tree scheduled scan on tribrid?
+ if (msLevel == _precursorTree[_precursorScanNumber].MSLevel)
{
- scanEvent.GetReaction(_precursorTree[_precursorScanNumber].ReactionCount);
+ _precursorScanNumber = GetParentFromScanString(result.Groups[1].Value);
}
- catch (ArgumentOutOfRangeException ex)
+ else
{
- Log.Debug($"Using Tribrid decision tree fix for scan# {scanNumber}");
- //Is it a decision tree scheduled scan on tribrid?
- if (msLevel == _precursorTree[_precursorScanNumber].MSLevel)
- {
- _precursorScanNumber = GetParentFromScanString(result.Groups[1].Value);
- }
- else
- {
- throw new RawFileParserException(
- $"Tribrid decision tree fix failed - cannot get reaction# {_precursorTree[_precursorScanNumber].ReactionCount} from {scanEvent.ToString()}",
- ex);
- }
+ throw new RawFileParserException(
+ $"Tribrid decision tree fix failed - cannot get reaction# {_precursorTree[_precursorScanNumber].ReactionCount} from {scanEvent.ToString()}",
+ ex);
}
-
- // Construct and set the precursor list element of the spectrum
- spectrum.precursorList =
- ConstructPrecursorList(_precursorScanNumber, scanEvent, charge, monoisotopicMz, isolationWidth,
- SPSMasses, out var reactionCount);
-
- //save precursor information for later reference
- _precursorTree[scanNumber] = new PrecursorInfo(_precursorScanNumber, msLevel, reactionCount, spectrum.precursorList.precursor);
}
- catch (Exception e)
- {
- var extra = (e.InnerException is null) ? "" : $"\n{e.InnerException.StackTrace}";
- 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}");
- ParseInput.NewWarn();
+ // Construct and set the precursor list element of the spectrum
+ spectrum.precursorList =
+ ConstructPrecursorList(_precursorScanNumber, scanEvent, charge, monoisotopicMz, isolationWidth,
+ SPSMasses, out var reactionCount);
- _precursorTree[scanNumber] = new PrecursorInfo(_precursorScanNumber, 1, 0, new PrecursorType[0]);
-
- }
-
+ //save precursor information for later reference
+ _precursorTree[scanNumber] = new PrecursorInfo(_precursorScanNumber, msLevel, reactionCount, spectrum.precursorList.precursor);
}
- else
+ catch (Exception e)
{
- spectrum.precursorList = new PrecursorListType
- {
- count = "0",
- precursor = new PrecursorType[0]
- };
+ var extra = (e.InnerException is null) ? "" : $"\n{e.InnerException.StackTrace}";
+
+ 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}");
+ ParseInput.NewWarn();
+
+ _precursorTree[scanNumber] = new PrecursorInfo(_precursorScanNumber, 1, 0, new PrecursorType[0]);
- Log.Error($"Failed finding precursor for {scanNumber}");
- ParseInput.NewError();
}
}
else
@@ -1891,6 +1933,45 @@ private SpectrumType ConstructMSSpectrum(int scanNumber)
return spectrum;
}
+ private int FindLastReaction(IScanEvent scanEvent, int msLevel)
+ {
+ int lastReactionIndex = msLevel - 2;
+
+ //iteratively trying find the last available index for reaction
+ while(true)
+ {
+ try
+ {
+ scanEvent.GetReaction(lastReactionIndex + 1);
+ }
+ catch (ArgumentOutOfRangeException)
+ {
+ //stop trying
+ break;
+ }
+
+ lastReactionIndex++;
+ }
+
+ //supplemental activation flag is on -> one of the levels (not necissirily the last one) used supplemental activation
+ //check last two activations
+ if (scanEvent.SupplementalActivation == TriState.On)
+ {
+ var lastActivation = scanEvent.GetReaction(lastReactionIndex).ActivationType;
+ var beforeLastActivation = scanEvent.GetReaction(lastReactionIndex - 1).ActivationType;
+
+ if ((beforeLastActivation == ActivationType.ElectronTransferDissociation || beforeLastActivation == ActivationType.ElectronCaptureDissociation) &&
+ (lastActivation == ActivationType.CollisionInducedDissociation || lastActivation == ActivationType.HigherEnergyCollisionalDissociation))
+ return lastReactionIndex - 1; //ETD or ECD followed by HCD or CID -> supplemental activation in the last level (move the last reaction one step back)
+ else
+ return lastReactionIndex;
+ }
+ else //just use the last one
+ {
+ return lastReactionIndex;
+ }
+ }
+
private SpectrumType ConstructPDASpectrum(int scanNumber, int instrumentNumber)
{
// Get each scan from the RAW file
@@ -2153,20 +2234,25 @@ private PrecursorListType ConstructPrecursorList(int precursorScanNumber, IScanE
// Get precursors from earlier levels
var prevPrecursors = _precursorTree[precursorScanNumber];
- var spectrumRef = "";
+ string spectrumRef = null;
int msLevel = (int)scanEvent.MSOrder;
IReaction reaction = null;
var precursorMz = 0.0;
reactionCount = prevPrecursors.ReactionCount;
- 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;
-
+ if (isolationWidth < 0) isolationWidth = null;
+
+ precursorMz = reaction.PrecursorMass;
+
+ if (precursorScanNumber > 0)
+ {
+ spectrumRef = ConstructSpectrumTitle((int)Device.MS, 1, precursorScanNumber);
+ }
+
var precursor = new PrecursorType
{
selectedIonList =
@@ -2203,7 +2289,7 @@ private PrecursorListType ConstructPrecursorList(int precursorScanNumber, IScanE
});
}
- if (selectedIonMz > ZeroDelta)
+ if (selectedIonMz > ZeroDelta && precursorScanNumber > 0)
{
var selectedIonIntensity = CalculatePrecursorPeakIntensity(_rawFile, precursorScanNumber, reaction.PrecursorMass, isolationWidth,
ParseInput.NoPeakPicking.Contains(msLevel - 1));
@@ -2384,6 +2470,51 @@ private PrecursorListType ConstructPrecursorList(int precursorScanNumber, IScanE
spectrumRef = spectrumRef
};
+ //Isolation window for SPS masses is the same as for the first precursor
+ SPSPrecursor.isolationWindow =
+ new ParamGroupType
+ {
+ cvParam = new CVParamType[3]
+ };
+
+ SPSPrecursor.isolationWindow.cvParam[0] =
+ new CVParamType
+ {
+ accession = "MS:1000827",
+ name = "isolation window target m/z",
+ value = SPSMasses[n].ToString(CultureInfo.InvariantCulture),
+ cvRef = "MS",
+ unitCvRef = "MS",
+ unitAccession = "MS:1000040",
+ unitName = "m/z"
+ };
+ if (isolationWidth != null)
+ {
+ var offset = isolationWidth.Value / 2 + reaction.IsolationWidthOffset;
+ SPSPrecursor.isolationWindow.cvParam[1] =
+ new CVParamType
+ {
+ accession = "MS:1000828",
+ name = "isolation window lower offset",
+ value = (isolationWidth.Value - offset).ToString(CultureInfo.InvariantCulture),
+ cvRef = "MS",
+ unitCvRef = "MS",
+ unitAccession = "MS:1000040",
+ unitName = "m/z"
+ };
+ SPSPrecursor.isolationWindow.cvParam[2] =
+ new CVParamType
+ {
+ accession = "MS:1000829",
+ name = "isolation window upper offset",
+ value = offset.ToString(CultureInfo.InvariantCulture),
+ cvRef = "MS",
+ unitCvRef = "MS",
+ unitAccession = "MS:1000040",
+ unitName = "m/z"
+ };
+ }
+
// Selected ion MZ only
SPSPrecursor.selectedIonList.selectedIon[0] =
new ParamGroupType
@@ -2426,8 +2557,7 @@ private PrecursorListType ConstructPrecursorList(int precursorScanNumber, IScanE
private int GetParentFromScanString(string scanString)
{
- var result = _filterStringIsolationMzPattern.Match(scanString);
- var parts = Regex.Split(result.Groups[1].Value, " ");
+ var parts = Regex.Split(scanString, " ");
//find the position of the first (from the end) precursor with a different mass
//to account for possible supplementary activations written in the filter
@@ -2445,7 +2575,7 @@ private int GetParentFromScanString(string scanString)
return _precursorScanNumbers[parentFilter];
}
- return -1; //unsuccessful parsing
+ return -2; //unsuccessful parsing
}
///
diff --git a/Writer/OntologyMapping.cs b/Writer/OntologyMapping.cs
index 35f78d2..bece09f 100644
--- a/Writer/OntologyMapping.cs
+++ b/Writer/OntologyMapping.cs
@@ -3,6 +3,7 @@
using ThermoFisher.CommonCore.Data;
using ThermoFisher.CommonCore.Data.FilterEnums;
using ThermoRawFileParser.Writer.MzML;
+using ThermoRawFileParser.Util;
namespace ThermoRawFileParser.Writer
{
@@ -68,6 +69,15 @@ public static class OntologyMapping
value = ""
}
},
+ {
+ MassAnalyzerType.MassAnalyzerASTMS, new CVParamType
+ {
+ accession = "MS:1003379",
+ name = "asymmetric track lossless time-of-flight analyzer",
+ cvRef = "MS",
+ value = ""
+ }
+ },
{
MassAnalyzerType.Any, new CVParamType
{
@@ -543,6 +553,15 @@ public static class OntologyMapping
value = ""
}
},
+ {
+ "ORBITRAP ASCEND", new CVParamType
+ {
+ accession = "MS:1003356",
+ name = "Orbitrap Ascend",
+ cvRef = "MS",
+ value = ""
+ }
+ },
{
"ORBITRAP EXPLORIS 120", new CVParamType
{
@@ -570,6 +589,15 @@ public static class OntologyMapping
value = ""
}
},
+ {
+ "ORBITRAP ASTRAL", new CVParamType
+ {
+ accession = "MS:1003378",
+ name = "Orbitrap Astral",
+ cvRef = "MS",
+ value = ""
+ }
+ },
{
"EXACTIVE", new CVParamType
{
@@ -658,7 +686,7 @@ public static class OntologyMapping
///
/// the instrument name
/// the instrument CV param
- public static CVParamType getInstrumentModel(string instrumentName)
+ public static CVParamType GetInstrumentModel(string instrumentName)
{
CVParamType instrumentModel;
instrumentName = instrumentName.ToUpper();
@@ -730,6 +758,8 @@ public static List GetDetectors(string instrumentAccession)
case "MS:1002732":
// ORBITRAP ECLIPSE
case "MS:1003029":
+ // ORBITRAP ASCEND
+ case "MS:1003356":
// ORBITRAP ID-X
case "MS:1003112":
detectors = new List
@@ -768,6 +798,8 @@ public static List GetDetectors(string instrumentAccession)
case "MS:1003094":
// ORBITRAP EXPLORIS 480
case "MS:1003028":
+ // ORBITRAP ASTRAL
+ case "MS:1003378":
detectors = new List
{
new CVParamType
@@ -820,5 +852,208 @@ public static List GetDetectors(string instrumentAccession)
return detectors;
}
+
+ private static readonly Dictionary chromatogramTypes =
+ new Dictionary
+ {
+ {
+ "basepeak", new CVParamType
+ {
+ accession = "MS:1000628",
+ name = "basepeak chromatogram",
+ cvRef = "MS",
+ value = ""
+ }
+ },
+
+ {
+ "tic", new CVParamType
+ {
+ accession = "MS:1000235",
+ name = "total ion current chromatogram",
+ cvRef = "MS",
+ value = ""
+ }
+ },
+
+ {
+ "current", new CVParamType
+ {
+ accession = "MS:1000810",
+ name = "ion current chromatogram",
+ cvRef = "MS",
+ value = ""
+ }
+ },
+
+ {
+ "radiation", new CVParamType
+ {
+ accession = "MS:1000811",
+ name = "electromagnetic radiation chromatogram",
+ cvRef = "MS",
+ value = ""
+ }
+ },
+
+ {
+ "absorption", new CVParamType
+ {
+ accession = "MS:1000812",
+ name = "absorption chromatogram",
+ cvRef = "MS",
+ value = ""
+ }
+ },
+
+ {
+ "emission", new CVParamType
+ {
+ accession = "MS:1000813",
+ name = "emission chromatogram",
+ cvRef = "MS",
+ value = ""
+ }
+ },
+
+ {
+ "pressure", new CVParamType
+ {
+ accession = "MS:1003019",
+ name = "pressure chromatogram",
+ cvRef = "MS",
+ value = ""
+ }
+ },
+
+ {
+ "flow", new CVParamType
+ {
+ accession = "MS:1003020",
+ name = "flow rate chromatogram",
+ cvRef = "MS",
+ value = ""
+ }
+ },
+
+ {
+ "unknown", new CVParamType
+ {
+ accession = "MS:1000626",
+ name = "chromatogram type",
+ cvRef = "MS",
+ value = ""
+ }
+ },
+ };
+
+ public static CVParamType GetChromatogramType(string key)
+ {
+ return CVHelpers.Copy(chromatogramTypes[key]);
+ }
+
+ private static readonly Dictionary dataArrayTypes =
+ new Dictionary
+ {
+ {
+ "mz", new CVParamType
+ {
+ accession = "MS:1000514",
+ name = "m/z array",
+ cvRef = "MS",
+ value = ""
+ }
+ },
+
+ {
+ "intensity", new CVParamType
+ {
+ accession = "MS:1000515",
+ name = "intensity array",
+ cvRef = "MS",
+ value = ""
+ }
+ },
+
+ {
+ "absorption", new CVParamType
+ {
+ accession = "MS:1000515",
+ name = "intensity array",
+ cvRef = "MS",
+ value = "",
+ unitName = "absorbance unit",
+ unitCvRef = "UO",
+ unitAccession = "UO:0000269"
+ }
+ },
+
+ {
+ "time", new CVParamType
+ {
+ accession = "MS:1000595",
+ name = "time array",
+ cvRef = "MS",
+ value = "",
+ unitName = "minute",
+ unitCvRef = "UO",
+ unitAccession = "UO:0000031"
+ }
+ },
+
+ {
+ "wavelength", new CVParamType
+ {
+ accession = "MS:1000617",
+ name = "wavelength array",
+ cvRef = "MS",
+ value = ""
+ }
+ },
+
+ {
+ "flow", new CVParamType
+ {
+ accession = "MS:1000820",
+ name = "flow rate array",
+ cvRef = "MS",
+ value = "",
+ unitName = "volumetric flow rate unit",
+ unitCvRef = "UO",
+ unitAccession = "UO:0000270 "
+ }
+ },
+
+ {
+ "pressure", new CVParamType
+ {
+ accession = "MS:1000821",
+ name = "pressure array",
+ cvRef = "MS",
+ value = "",
+ unitName = "pressure unit",
+ unitCvRef = "UO",
+ unitAccession = "UO:0000109"
+ }
+ },
+
+ {
+ "unknown", new CVParamType
+ {
+ accession = "MS:1000786",
+ name = "non-standard data array",
+ cvRef = "MS",
+ value = "",
+ unitName = "unit",
+ unitCvRef = "UO",
+ unitAccession = "UO:0000000"
+ }
+ }
+ };
+
+ public static CVParamType GetDataArrayType(string key)
+ {
+ return CVHelpers.Copy(dataArrayTypes[key]);
+ }
}
}
\ No newline at end of file
diff --git a/Writer/ParquetSpectrumWriter.cs b/Writer/ParquetSpectrumWriter.cs
index ced94be..6ea4071 100644
--- a/Writer/ParquetSpectrumWriter.cs
+++ b/Writer/ParquetSpectrumWriter.cs
@@ -35,8 +35,15 @@ public ParquetSpectrumWriter(ParseInput parseInput) : base(parseInput)
public override void Write(IRawDataPlus rawFile, int firstScanNumber, int lastScanNumber)
{
_rawFile = rawFile;
- List pScans = new List();
- WritePScans(ParseInput.OutputDirectory, rawFile.FileName, rawFile, pScans);
+ if (rawFile.HasMsData)
+ {
+ List pScans = new List();
+ WritePScans(ParseInput.OutputDirectory, rawFile.FileName, rawFile, pScans);
+ }
+ else
+ {
+ throw new RawFileParserException("No MS data in RAW file, no output will be produced");
+ }
}
private static void WritePScans(string outputDirectory, string fileName,
diff --git a/Writer/PrecursorInfo.cs b/Writer/PrecursorInfo.cs
index 2189369..535f9ee 100644
--- a/Writer/PrecursorInfo.cs
+++ b/Writer/PrecursorInfo.cs
@@ -5,7 +5,7 @@
///
public class PrecursorInfo
{
- //for future use
+ //Current MSLevel
public int MSLevel { get; }
//precursor scan number, 0 - means not a precursor
diff --git a/packages.config b/packages.config
index 010dc8f..2bfb52b 100644
--- a/packages.config
+++ b/packages.config
@@ -27,7 +27,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/packages/ThermoFisher.CommonCore.Data.5.0.0.88/ThermoFisher.CommonCore.Data.5.0.0.88.nupkg b/packages/ThermoFisher.CommonCore.Data.5.0.0.88/ThermoFisher.CommonCore.Data.5.0.0.88.nupkg
deleted file mode 100644
index e7660e5..0000000
Binary files a/packages/ThermoFisher.CommonCore.Data.5.0.0.88/ThermoFisher.CommonCore.Data.5.0.0.88.nupkg and /dev/null differ
diff --git a/packages/ThermoFisher.CommonCore.Data.5.0.0.88/lib/ThermoFisher.CommonCore.Data.dll b/packages/ThermoFisher.CommonCore.Data.5.0.0.88/lib/ThermoFisher.CommonCore.Data.dll
deleted file mode 100644
index 1ed8566..0000000
Binary files a/packages/ThermoFisher.CommonCore.Data.5.0.0.88/lib/ThermoFisher.CommonCore.Data.dll and /dev/null differ
diff --git a/packages/ThermoFisher.CommonCore.Data.5.0.0.93/ThermoFisher.CommonCore.Data.5.0.0.93.nupkg b/packages/ThermoFisher.CommonCore.Data.5.0.0.93/ThermoFisher.CommonCore.Data.5.0.0.93.nupkg
new file mode 100644
index 0000000..48aa0e8
Binary files /dev/null and b/packages/ThermoFisher.CommonCore.Data.5.0.0.93/ThermoFisher.CommonCore.Data.5.0.0.93.nupkg differ
diff --git a/packages/ThermoFisher.CommonCore.Data.5.0.0.93/lib/netstandard2.0/ThermoFisher.CommonCore.Data.dll b/packages/ThermoFisher.CommonCore.Data.5.0.0.93/lib/netstandard2.0/ThermoFisher.CommonCore.Data.dll
new file mode 100644
index 0000000..c21eee4
Binary files /dev/null and b/packages/ThermoFisher.CommonCore.Data.5.0.0.93/lib/netstandard2.0/ThermoFisher.CommonCore.Data.dll differ
diff --git a/packages/ThermoFisher.CommonCore.Data.5.0.0.88/lib/ThermoFisher.CommonCore.Data.xml b/packages/ThermoFisher.CommonCore.Data.5.0.0.93/lib/netstandard2.0/ThermoFisher.CommonCore.Data.xml
similarity index 99%
rename from packages/ThermoFisher.CommonCore.Data.5.0.0.88/lib/ThermoFisher.CommonCore.Data.xml
rename to packages/ThermoFisher.CommonCore.Data.5.0.0.93/lib/netstandard2.0/ThermoFisher.CommonCore.Data.xml
index a83161d..ff68fe1 100644
--- a/packages/ThermoFisher.CommonCore.Data.5.0.0.88/lib/ThermoFisher.CommonCore.Data.xml
+++ b/packages/ThermoFisher.CommonCore.Data.5.0.0.93/lib/netstandard2.0/ThermoFisher.CommonCore.Data.xml
@@ -11287,7 +11287,7 @@
- The subtract profile segments.
+ subtract profile data, with segmented scans
The identical flag.
@@ -18228,9 +18228,10 @@
Match any type
-
+
- MultiReflection Time of Flight
+ Asymmetric Track Lossless (ASTRAL)
+ AS T
diff --git a/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.88/ThermoFisher.CommonCore.RawFileReader.5.0.0.88.nupkg b/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.88/ThermoFisher.CommonCore.RawFileReader.5.0.0.88.nupkg
deleted file mode 100644
index c36275c..0000000
Binary files a/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.88/ThermoFisher.CommonCore.RawFileReader.5.0.0.88.nupkg and /dev/null differ
diff --git a/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.88/lib/ThermoFisher.CommonCore.RawFileReader.dll b/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.88/lib/ThermoFisher.CommonCore.RawFileReader.dll
deleted file mode 100644
index f84548a..0000000
Binary files a/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.88/lib/ThermoFisher.CommonCore.RawFileReader.dll and /dev/null differ
diff --git a/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.93/ThermoFisher.CommonCore.RawFileReader.5.0.0.93.nupkg b/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.93/ThermoFisher.CommonCore.RawFileReader.5.0.0.93.nupkg
new file mode 100644
index 0000000..f9f427c
Binary files /dev/null and b/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.93/ThermoFisher.CommonCore.RawFileReader.5.0.0.93.nupkg differ
diff --git a/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.93/lib/netstandard2.0/ThermoFisher.CommonCore.RawFileReader.dll b/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.93/lib/netstandard2.0/ThermoFisher.CommonCore.RawFileReader.dll
new file mode 100644
index 0000000..841bd0d
Binary files /dev/null and b/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.93/lib/netstandard2.0/ThermoFisher.CommonCore.RawFileReader.dll differ
diff --git a/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.88/lib/ThermoFisher.CommonCore.RawFileReader.xml b/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.93/lib/netstandard2.0/ThermoFisher.CommonCore.RawFileReader.xml
similarity index 97%
rename from packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.88/lib/ThermoFisher.CommonCore.RawFileReader.xml
rename to packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.93/lib/netstandard2.0/ThermoFisher.CommonCore.RawFileReader.xml
index 4089a49..138f0dd 100644
--- a/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.88/lib/ThermoFisher.CommonCore.RawFileReader.xml
+++ b/packages/ThermoFisher.CommonCore.RawFileReader.5.0.0.93/lib/netstandard2.0/ThermoFisher.CommonCore.RawFileReader.xml
@@ -1136,7 +1136,7 @@
Data for a particular device, from an instrument method.
-
+
Opens a stream on created storage
@@ -1144,7 +1144,7 @@
The stream within the device
Access to the requested stream
-
+
get stream names.
@@ -1167,7 +1167,7 @@
Other streams (private to the instrument) may also be created.
-
+
Open the streams for the device, and retrieve the text description.
@@ -1199,14 +1199,6 @@
Gets the error message.
-
-
- Get the list of storage names, of a particular storage type
-
- Storage to open
- Type of storage
- The names of the storages
-
The file header errors.
@@ -2769,9 +2761,10 @@
Any analyzer.
-
+
- MultiReflection Time of Flight
+ Asymmetric Track Lossless (ASTRAL)
+ AS T
@@ -9251,11 +9244,6 @@
Contains factories to read various Xcalibur data system files.
-
-
- The native methods, pulled from OLE 32 DLL.
-
-
The stream seek.
@@ -9372,214 +9360,6 @@
therefore the method reduces time and resources used in an allocation and free operation.
-
-
- IOleStorage interface.
-
-
-
-
- create OLE stream.
-
-
- The stream name.
-
-
- The storage mode.
-
-
- The reserved 1.
-
-
- The reserved 2.
-
-
- The .
-
-
-
-
- open a stream.
-
-
- The stream name.
-
-
- The reserved 1.
-
-
- The mode.
-
-
- The reserved 2.
-
-
- The .
-
-
-
-
- create a storage.
-
-
- The name.
-
-
- The mode.
-
-
- The reserved 1.
-
-
- The reserved 2.
-
-
- The .
-
-
-
-
- Opens an existing storage object with the specified name according to
- the specified access mode. The name must not exceed 31 characters
- in length (not including the string terminator).
- The 000 through 01f characters, serving as the
- first character of the stream/storage name, are reserved for use by OLE.
- This is a compound file restriction, not a structured storage restriction.
-
-
- A pointer to a wide character null-terminated Unicode string that
- contains the name of the storage object to open.
- The 000 through 01f characters, serving as the first character
- of the stream/storage name, are reserved for use by OLE.
- This is a compound file restriction, not a structured storage restriction.
- It is ignored if pstgPriority is non-NULL.
-
-
- Priority Must be NULL. A non-NULL value will return STG_E_INVALIDPARAMETER.
-
-
- Specifies the access mode to use when opening the storage object. For descriptions of the possible values, see STGM Constants. Other modes you choose must at least specify STGM_SHARE_EXCLUSIVE when calling this method.
-
-
- Exclude Must be NULL. A non-NULL value will return STG_E_INVALIDPARAMETER.
-
-
- Reserved for future use; must be zero.
-
-
- The .
-
-
-
-
- The CopyTo method copies the entire contents of an open storage object to another storage object.
-
- The number of elements in the array pointed to by rgiidExclude.
- If rgiidExclude is NULL, then ciidExclude is ignored.
- An array of interface identifiers (IIDs) that either the caller
- knows about and does not want copied or that the storage object does not support,
- but whose state the caller will later explicitly copy. The array can include IStorage,
- indicating that only stream objects are to be copied, and IStream, indicating that only storage
- objects are to be copied. An array length of zero indicates that only the state exposed by the IStorage
- object is to be copied; all other interfaces on the object are to be ignored.
- Passing NULL indicates that all interfaces on the object are to be copied.
- A string name block (refer to SNB) that specifies a block of storage
- or stream objects that are not to be copied to the destination. These elements are not created at the destination.
- If IID_IStorage is in the rgiidExclude array, this parameter is ignored. This parameter may be NULL.
- A pointer to the open storage object into which this storage object is to be copied.
- The destination storage object can be a different implementation of the IStorage interface from the source storage object.
- Thus, IStorage::CopyTo can use only publicly available methods of the destination storage object.
- If pstgDest is open in transacted mode, it can be reverted by calling its IStorage::Revert method.
-
-
-
- The MoveElementTo method copies or moves a sub-storage or stream from this
- storage object to another storage object.
-
- Pointer to a wide character null-terminated Unicode string that contains the name of the element
- in this storage object to be moved or copied.
- IStorage pointer to the destination storage object.
- Pointer to a wide character null-terminated unicode string that contains the new name for the element in its new storage object.
- Specifies whether the operation should be a move (STGMOVE_MOVE) or a copy (STGMOVE_COPY). See the STGMOVE enumeration.
-
-
-
- The Commit method ensures that any changes made to a storage object open
- in transacted mode are reflected in the parent storage.
- For non-root storage objects in direct mode,
- this method has no effect. For a root storage, it reflects the changes
- in the actual device; for example, a file on disk. For a root storage object opened
- in direct mode, always call the IStorage::Commit method prior to Release.
- IStorage::Commit flushes all memory buffers to the disk for a root storage
- in direct mode and will return an error code upon failure. Although Release
- also flushes memory buffers to disk, it has no capacity to return any error
- codes upon failure. Therefore, calling
- Release without first calling Commit causes indeterminate results.
-
- Controls how the changes are committed to the storage object.
- See the STGC enumeration for a definition of these values.
-
-
-
- The Revert method discards all changes that have been made to the storage object since the last commit operation.
-
-
-
-
- The method retrieves a pointer to an enumerator
- object that can be used to enumerate the storage
- and stream objects contained within this storage object.
-
- Reserved 1 is Reserved for future use; must be zero.
- Reserved for future use; must be NULL.
- Reserved for future use; must be zero.
- Pointer to IEnumSTATSTG* pointer variable
- that receives the interface pointer to the new enumerator object.
-
-
-
- The DestroyElement method removes the specified storage or stream from this storage object.
-
- A pointer to a wide character null-terminated Unicode string that contains
- the name of the storage or stream to be removed.
-
-
-
- The RenameElement method renames the specified sub-storage or stream in this storage object.
-
- Pointer to a wide character null-terminated Unicode string that contains the name of the sub-storage or stream to be changed.
- Pointer to a wide character null-terminated Unicode string that contains the new name for the specified sub-storage or stream.
-
-
-
- The SetElementTimes method sets the modification, access, and creation times of the specified storage element, if the underlying file system supports this method.
-
- The name of the storage object element whose times are to be modified. If NULL, the time is set on the root storage rather than one of its elements.
- Either the new creation time for the element or NULL if the creation time is not to be modified.
- Either the new access time for the element or NULL if the access time is not to be modified.
- Either the new modification time for the element or NULL if the modification time is not to be modified.
-
-
-
- The SetClass method assigns the specified class identifier (CLSID) to this storage object.
-
- The CLSID that is to be associated with the storage object.
-
-
-
- stores up to 32 bits of state information in this storage object. This method is reserved for future use.
-
- Specifies the new values of the bits to set. No legal values are defined for these bits; they are all reserved for future use and must not be used by applications.
- A binary mask indicating which bits in grfStateBits are significant in this call.
-
-
-
- The Stat method retrieves the STATSTG structure for this open storage object.
-
- On return, pointer to a STATSTG structure where this method places information about the open storage object. This parameter is NULL if an error occurs.
- Specifies that some of the members in the STATSTG structure are not returned, thus saving a memory allocation operation.
- Values are taken from the STATFLAG enumeration.
-
The LOCKTYPE enumeration values indicate the type of locking requested
@@ -9631,149 +9411,6 @@
Indicates that the storage element is a stream object.
-
-
- Replacement for UCOMIOleStream (and ComTypes.IOleStream) interface.
- for Read() and Write().
-
-
-
-
- Reads a specified number of bytes from the stream object into memory starting at the current seek pointer.
-
- A pointer to the buffer which the stream data is read into.
- The number of bytes of data to read from the stream object.
- [out] Returns the actual number of bytes read from the stream object.
-
-
-
- writes a specified number of bytes into the stream object starting at the current seek pointer.
-
- A pointer to the buffer that contains the data that is to be written to the stream.
- A valid pointer must be provided for this parameter even when cb
is zero.
- The number of bytes of data to attempt to write into the stream. This value can be zero.
- [out] Returns the actual number of bytes written to the stream object.
-
-
-
- changes the seek pointer to a new location.
- The new location is relative to either the beginning of the stream,
- the end of the stream, or the current seek pointer.
-
- The displacement to be added to the location
- indicated by the origin parameter. If dwOrigin is STREAM_SEEK_SET,
- this is interpreted as an unsigned value rather than a signed value.
- The origin for the displacement specified in dlibMove.
- The origin can be the beginning of the file (STREAM_SEEK_SET),
- the current seek pointer (STREAM_SEEK_CUR), or the end of the file (STREAM_SEEK_END).
- For more information about values, see the STREAM_SEEK enumeration.
- the value of the new seek pointer from the beginning of the stream.
-
-
-
- changes the size of the stream object.
-
- Specifies the new size, in bytes, of the stream.
-
-
-
- The CopyTo method copies a specified number of bytes
- from the current seek pointer in the stream to the current seek pointer in another stream.
-
- A pointer to the destination stream. The stream pointed to by pstm
- can be a new stream or a clone of the source stream.
- The number of bytes to copy from the source stream.
- A pointer to the location where this method writes the actual
- number of bytes read from the source. You can set this pointer to NULL.
- In this case, this method does not provide the actual number of bytes read.
- the actual number of bytes written to the destination.
-
-
-
- ensures that any changes made to a stream object open in transacted mode are reflected in the parent storage
- . If the stream object is open in direct mode, IStream::Commit has
- no effect other than flushing all memory buffers to the next-level storage object.
- The COM compound file implementation of streams does not support opening streams in transacted mode.
-
- Controls how the changes for the stream object are committed.
- See the STGC enumeration for a definition of these values.
-
-
-
- discards all changes that have been made to a transacted stream since the last IStream::Commit call. On streams open in
- direct mode and streams using the COM compound file implementation of IStream::Revert, this method has no effect.
-
-
-
-
- restricts access to a specified range of bytes in the stream.
- Supporting this functionality is optional since some file systems do not provide it.
-
- Integer that specifies the byte offset for the beginning of the range.
- Integer that specifies the length of the range, in bytes, to be restricted.
- Specifies the restrictions being requested on accessing the range.
-
-
-
- removes the access restriction on a range of bytes previously restricted with IStream::LockRegion.
-
- Specifies the byte offset for the beginning of the range.
- Specifies, in bytes, the length of the range to be restricted.
- Specifies the access restrictions previously placed on the range.
-
-
-
- retrieves the STATSTG structure for this stream.
-
- Pointer to a STATSTG structure where this method places information about this stream object.
- Specifies that this method does not return some of the members in the STATSTG structure,
- thus saving a memory allocation operation. Values are taken from the STATFLAG enumeration.
-
-
-
- creates a new stream object with its own seek pointer that references the same bytes as the original stream.
-
- pointer to the new stream object.
-
-
-
- IEnumSTATSTG interface.
-
-
-
-
- retrieves a specified number of STATSTG structures,
- that follow in the enumeration sequence. If there are fewer than the requested
- number of STATSTG structures that remain in the enumeration sequence,
- it retrieves the remaining STATSTG structures.
-
- The number of STATSTG structures requested.
- An array of STATSTG structures returned.
- The number of STATSTG structures retrieved in the rgelt parameter.
- S_OK on success
-
-
-
- skips a specified number of STATSTG structures in the enumeration sequence.
-
- The number of STATSTG structures to skip.
-
-
-
- resets the enumeration sequence to the beginning of the STATSTG structure array.
-
-
-
-
- creates a new enumerator that contains the same enumeration state as the current
- STATSTG structure enumerator. Using this method, a client
- can record a particular point in the enumeration
- sequence and then return to that point at a later time.
- The new enumerator supports the same IEnumSTATSTG interface.
-
- A pointer to the variable that receives the IEnumSTATSTG interface pointer.
- If the method is unsuccessful, the value of the ppenum parameter is undefined.
-
The storage mode.
@@ -11946,16 +11583,6 @@
Name of the file.
store the mapped disk file information.
-
-
- create memory mapped file security token.
- This is a slow method (needs to access user's permissions)
- but can be static, as the user's permission doesn't change.
-
-
- The .
-
-
Opens the exist memory mapped file.
@@ -12922,7 +12549,7 @@
For additional read/write examples see version in "foundation Apps" project.
-
+
Initializes a new instance of the class.
@@ -13267,7 +12894,7 @@
Any errors that occur during calculation
True if successful
-
+
Updates the file header checksum.
@@ -27977,13 +27604,6 @@
An array of internal structures size
-
-
- Show mutex security.
-
- The mutex security.
- The errors.
-
The try reopen mutex.
@@ -28029,7 +27649,7 @@
The .
-
+
Saves the audit trailer to IOleStream.
@@ -29141,7 +28761,7 @@
The .
-
+
Calculates the instrument method file checksum. It's duplicating exactly the Xcalibur checksum for compound doc file.
@@ -29938,7 +29558,7 @@
Gets the file header for the instrument method file
-
+
Creates a device method storage.
@@ -29947,7 +29567,7 @@
Stores the error information if error occurs.
Device method storage.
-
+
Saves the audit trail.
@@ -29956,7 +29576,7 @@
Stores the error information if error occurs.
True if audit trail is saved successfully; otherwise false.
-
+
Saves the file header to stream.
@@ -29966,7 +29586,7 @@
Stores the error information if error occurs.
True if file header saved successfully; otherwise false.
-
+
Saves the device method to stream.
@@ -29975,7 +29595,7 @@
Stores the error information if error occurs.
True if the device method saved successfully; otherwise false.
-
+
Saves the device method streams, i.e. "Text", "Data, etc.
If the stream value is NULL, it will save an empty stream.
@@ -30029,49 +29649,7 @@
Provides common methods to deal with IOleStorage and IOleStream.
-
-
- Opens an existing compound document file (instrument method file).
-
- Name of the file.
- Specifies the access mode to use when opening the compound document file.
- The root storage object.
-
-
-
- Creates the compound document file (instrument method file) with a specified file name.
-
- Name of the file.
- The root storage object (IOleStorage).
-
-
-
- Creates a storage (Device method).
-
- The storage.
- Name of the device storage.
- IOleStorage object (Device method).
-
-
-
- Opens an existing storage (Device method).
-
- The storage.
- Name of the storage.
- Specifies the access mode to use when opening the storage object.
- Device storage.
-
-
-
- Saves the device stream data to the compound storage.
-
- The method.
- The storage (either the root storage or device method).
- Name of the stream data.
- Stores the last error information.
- True if data saved successfully; otherwise false.
-
-
+
Reads the device stream data from the storage.
@@ -30081,21 +29659,17 @@
Returns the error information if error occurs.
True if data saved successfully; otherwise false.
-
+
- Writes the integer 4-byte value to stream.
-
- The data stream.
- The value.
-
-
-
- Writes the bytes to the stream.
+ Saves the device stream data to the compound storage.
- The data stream.
- The value in byte array.
+ The method.
+ The storage (either the root storage or device method).
+ Name of the stream data.
+ Stores the last error information.
+ True if data saved successfully; otherwise false.
-
+
Saves the file header to the IOleStream.
@@ -30104,23 +29678,11 @@
Stores the error information if error occurs.
True if the file header saved successfully; otherwise false.
-
+
- Releases the specified storage.
-
- The storage.
-
-
-
- Releases the specified stream.
-
- The stream.
-
-
-
- Releases the specified enumerator for STATSTG structures.
+ Creates the compound document file (instrument method file) with a specified file name.
- The enumerator.
+ The root storage object (IOleStorage).
@@ -30909,16 +30471,6 @@
true on success
-
-
- Finalizes the raw file security.
- Begin create a temporary file to get its FileSecurity object instead of the one from the raw file.
- Add an access rule to remove the WellKnownSidType.WorldSid into this FileSecurity object.
- Apply the modified ACL to the raw file.
-
- Name of the raw file.
- The errors.
-
mark acquisition complete.