public void TestGetParentScan(string mzXmlFileName, int startScan, int endScan, params int[] expectedParents) { var dataFile = FindInputFile(mzXmlFileName); var reader = new MzXMLFileAccessor(); reader.OpenFile(dataFile.FullName); var i = 0; var validScanCount = 0; for (var scanNumber = startScan; scanNumber <= endScan; scanNumber++) { var validScan = reader.GetSpectrumByScanNumber(scanNumber, out var spectrumInfo); if (!validScan) { ConsoleMsgUtils.ShowWarning("Invalid scan number: {0}", scanNumber); i++; continue; } validScanCount++; if (spectrumInfo is not SpectrumInfoMzXML mzXmlSpectrum) { Assert.Fail("Input file is not a .mzXML file; cannot validate precursor scan numbers"); return; } Console.WriteLine("MS{0} scan {1,-4} has parent {2,-4}", spectrumInfo.MSLevel, scanNumber, mzXmlSpectrum.PrecursorScanNum); if (i < expectedParents.Length && expectedParents[i] != 0) { Assert.AreEqual( expectedParents[i], mzXmlSpectrum.PrecursorScanNum, "Parent scan does not match expected value: {0}", expectedParents[i]); } i++; } var percentValid = validScanCount / (double)(endScan - startScan + 1) * 100; Assert.Greater(percentValid, 90, "Over 10% of the spectra had invalid scan numbers"); }
public void TestGetCollisionEnergy(string mzXmlFileName) { // Keys in this Dictionary are filename, values are Collision Energies by scan var expectedData = new Dictionary <string, Dictionary <int, List <double> > >(); var ce30 = new List <double> { 30.00 }; var ce45 = new List <double> { 45.00 }; var ce120 = new List <double> { 120.55119 }; var ms1Scan = new List <double>(); var ms2ScanWithoutCollisionMode = new List <double>(); // Keys in this dictionary are scan number and values are collision energies var file1Data = new Dictionary <int, List <double> > { { 2250, ce45 }, { 2251, ce45 }, { 2252, ce45 }, { 2253, ms1Scan }, { 2254, ce45 }, { 2255, ce45 }, { 2256, ce45 }, { 2257, ms1Scan }, { 2258, ce45 }, { 2259, ce45 }, { 2260, ce45 } }; expectedData.Add("Shew_246a_LCQa_15Oct04_Andro_0904-2_4-20", file1Data); var file2Data = new Dictionary <int, List <double> > { { 19000, ms2ScanWithoutCollisionMode }, { 19001, ce120 }, { 19002, ce120 }, { 19003, ms1Scan }, { 19004, ce30 }, { 19005, ce30 }, { 19006, ce30 }, { 19007, ms2ScanWithoutCollisionMode }, { 19008, ce120 }, { 19009, ce120 }, { 19010, ce30 } }; expectedData.Add("HCC-38_ETciD_EThcD_07Jan16_Pippin_15-08-53", file2Data); var file3Data = new Dictionary <int, List <double> > { { 1, ms2ScanWithoutCollisionMode }, { 2, ms2ScanWithoutCollisionMode } }; expectedData.Add("MZ0210MnxEF889ETD", file3Data); var file4Data = new Dictionary <int, List <double> > { { 27799, ms1Scan }, { 27800, ce30 }, { 27801, ce30 }, { 27802, ce30 }, { 27803, ce30 }, { 27804, ce30 }, { 27805, ms1Scan }, { 27806, ce30 }, { 27807, ce30 } }; expectedData.Add("QC_Mam_16_01_125ng_2pt0-IT22_Run-A_16Oct17_Pippin_AQ_17-10-01", file4Data); var dataFile = FindInputFile(mzXmlFileName); if (!expectedData.TryGetValue(Path.GetFileNameWithoutExtension(dataFile.Name), out var collisionEnergiesThisFile)) { Assert.Fail("Dataset {0} not found in dictionary expectedData", dataFile.Name); } // Keys are scan number, values are the collision energy var collisionEnergiesActual = new Dictionary <int, float>(); // Keys are scan number, values are msLevel var msLevelsActual = new Dictionary <int, int>(); // Keys are scan number, values are the ActivationType, for example cid, etd, hcd var activationTypesActual = new Dictionary <int, string>(); var reader = new MzXMLFileAccessor(); reader.OpenFile(dataFile.FullName); foreach (var scanNumber in collisionEnergiesThisFile.Keys) { var validScan = reader.GetSpectrumByScanNumber(scanNumber, out var spectrumInfo); Assert.IsTrue(validScan, "GetSpectrumByScanNumber returned false for scan {0}", scanNumber); if (spectrumInfo is not SpectrumInfoMzXML mzXmlSpectrum) { Assert.Fail("Input file is not a .mzXML file; cannot validate collision energy"); return; } collisionEnergiesActual.Add(scanNumber, mzXmlSpectrum.CollisionEnergy); msLevelsActual.Add(scanNumber, mzXmlSpectrum.MSLevel); activationTypesActual.Add(scanNumber, mzXmlSpectrum.ActivationMethod); } Console.WriteLine("{0,-5} {1,-5} {2}", "Valid", "Scan", "Collision Energy"); foreach (var actualEnergyOneScan in (from item in collisionEnergiesActual orderby item.Key select item)) { var scanNumber = actualEnergyOneScan.Key; var expectedEnergies = collisionEnergiesThisFile[scanNumber]; var activationTypes = string.Join(", ", activationTypesActual[scanNumber]); if (Math.Abs(actualEnergyOneScan.Value) < float.Epsilon) { var msLevel = msLevelsActual[scanNumber]; if (msLevel != 1) { if (expectedEnergies.Count == 0) { var warning = string.Format( "Scan {0} has msLevel={1} and activationType={2}, but no collision energy. This isn't typically true, but can happen in .mzXML files", scanNumber, msLevel, activationTypes); Console.WriteLine(warning); continue; } var msg = string.Format( "Scan {0} has no collision energy, which should only be true for spectra with msLevel=1. This scan has msLevel={1} and activationType={2}", scanNumber, msLevel, activationTypes); Console.WriteLine(msg); Assert.Fail(msg); } else { Console.WriteLine("{0,-5} {1,-5} {2}", true, scanNumber, "MS1 scan"); } } else { var actualEnergy = actualEnergyOneScan.Value; var isValid = expectedEnergies.Any(expectedEnergy => Math.Abs(actualEnergy - expectedEnergy) < 0.00001); Console.WriteLine("{0,-5} {1,-5} {2:F2}", isValid, scanNumber, actualEnergy); Assert.IsTrue(isValid, "Unexpected collision energy {0:F2} for scan {1}", actualEnergy, scanNumber); } } }
public void TestDataIsSortedByMz(string mzXmlFileName, int scanStart, int scanEnd, int scanStep) { var dataFile = FindInputFile(mzXmlFileName); var reader = new MzXMLFileAccessor(); reader.OpenFile(dataFile.FullName); for (var iteration = 1; iteration <= 4; iteration++) { int maxNumberOfPeaks; bool centroidData; switch (iteration) { case 1: maxNumberOfPeaks = 0; centroidData = false; break; case 2: maxNumberOfPeaks = 0; centroidData = true; break; case 3: maxNumberOfPeaks = 50; centroidData = false; break; default: maxNumberOfPeaks = 50; centroidData = true; break; } if (iteration == 1) { Console.WriteLine("Scan data for {0}", dataFile.Name); Console.WriteLine( "{0,5} {1,-5} {2,-10} {3,-8} {4,-8} {5,-10} {6,-8} {7,-10} {8,-8} {9}", "Scan", "Max#", "Centroid", "MzCount", "IntCount", "FirstMz", "FirstInt", "MidMz", "MidInt", "ScanFilter"); } if (scanEnd > reader.CachedSpectraScanNumberMaximum) { scanEnd = reader.CachedSpectraScanNumberMaximum; } if (scanStep < 1) { scanStep = 1; } var statsInterval = (int)Math.Floor((scanEnd - scanStart) / (double)scanStep / 10); var scansProcessed = 0; for (var scanNumber = scanStart; scanNumber <= scanEnd; scanNumber += scanStep) { var validScan = reader.GetSpectrumByScanNumber(scanNumber, out var spectrumInfo); if (!validScan) { Assert.Fail("Invalid scan number: {0}", scanNumber); } var mzList = spectrumInfo.MzList; var intensityList = spectrumInfo.IntensityList; var unsortedMzValues = 0; for (var i = 0; i < mzList.Count - 1; i++) { if (mzList[i] > mzList[i + 1]) { unsortedMzValues++; } } Assert.AreEqual(0, unsortedMzValues, "Scan {0} has {1} m/z values not sorted properly", scanNumber, unsortedMzValues); scansProcessed++; if (scansProcessed % statsInterval == 0) { var scanInfo = GenerateThermoScanFilter(spectrumInfo); if (mzList.Count > 0) { var midIndex = (int)Math.Floor(mzList.Count / 2.0); Console.WriteLine( "{0,5} {1,-5} {2,-10} {3,-8} {4,-8} {5,-10:0.0000} {6,-8:0.0} {7,-10:0.0000} {8,-8:0.0} {9}", scanNumber, maxNumberOfPeaks, centroidData, mzList.Count, intensityList.Count, mzList[0], intensityList[0], mzList[midIndex], intensityList[midIndex], scanInfo); } else { Console.WriteLine( "{0,5} {1,-5} {2,-10} {3,-8} {4,-8} {5,-10} {6,-8} {7,-10} {8,-8} {9}", scanNumber, maxNumberOfPeaks, centroidData, mzList.Count, intensityList.Count, "n/a", "n/a", "n/a", "n/a", scanInfo); } } } } }