diff --git a/src/MSDIAL5/MsdialCore/Utility/DataAccess.cs b/src/MSDIAL5/MsdialCore/Utility/DataAccess.cs index bf8cccd0d..6245a695b 100644 --- a/src/MSDIAL5/MsdialCore/Utility/DataAccess.cs +++ b/src/MSDIAL5/MsdialCore/Utility/DataAccess.cs @@ -332,11 +332,10 @@ public static List GetMs2ValuePeaks(IDataProvider provider, double int startScanID, int endScanID, IReadOnlyList pMzValues, ParameterBase param, AcquisitionType acquisitionType, double targetCE = -1, ChromXType type = ChromXType.RT, ChromXUnit unit = ChromXUnit.Min) { - var counter = 0; - var arrayLength = GetTargetArrayLength(provider, startScanID, endScanID, precursorMz, targetCE, param, acquisitionType); - var valuePeakArrayList = new List(pMzValues.Count); - valuePeakArrayList.AddRange(pMzValues.Select(_ => new ValuePeak[arrayLength])); - +var valuePeakLists = new List[pMzValues.Count]; +for (int j = 0; j < valuePeakLists.Length; j++) { + valuePeakLists[j] = new List(); +} for (int i = startScanID; i <= endScanID; i++) { var spec = provider.LoadMsSpectrumFromIndex(i); if (spec.MsLevel == 2 && spec.Precursor != null) { @@ -348,27 +347,16 @@ public static List GetMs2ValuePeaks(IDataProvider provider, double var intensities = RetrieveIntensitiesFromMzValues(pMzValues, spec.Spectrum, param.CentroidMs2Tolerance); for (int j = 0; j < pMzValues.Count; j++) { - valuePeakArrayList[j][counter] = new ValuePeak(id, chromX, pMzValues[j], intensities[j]); + valuePeakLists[j].Add(new ValuePeak(id, chromX, pMzValues[j], intensities[j])); } - counter++; - } - } - } - return valuePeakArrayList; - } - - private static int GetTargetArrayLength(IDataProvider provider, int startScanID, int endScanID, double precursorMz, double targetCE, ParameterBase param, AcquisitionType type) { - var counter = 0; - for (int i = startScanID; i <= endScanID; i++) { - var spec = provider.LoadMsSpectrumFromIndex(i); - if (spec.MsLevel == 2 && spec.Precursor != null) { - if (targetCE >= 0 && spec.CollisionEnergy >= 0 && Math.Abs(targetCE - spec.CollisionEnergy) > 1) continue; // for AIF mode - if (IsInMassWindow(precursorMz, spec, param.CentroidMs1Tolerance, type)) { - counter++; } } } - return counter; +var results = new List(valuePeakLists.Length); +for (int j = 0; j < valuePeakLists.Length; j++) { + results.Add(valuePeakLists[j].ToArray()); +} +return results; } public static double[] RetrieveIntensitiesFromMzValues( diff --git a/tests/MSDIAL5/MsdialCoreTests/Utility/DataAccessTests.cs b/tests/MSDIAL5/MsdialCoreTests/Utility/DataAccessTests.cs index f4c023aca..365a0e47f 100644 --- a/tests/MSDIAL5/MsdialCoreTests/Utility/DataAccessTests.cs +++ b/tests/MSDIAL5/MsdialCoreTests/Utility/DataAccessTests.cs @@ -1,8 +1,16 @@ using CompMs.Common.Components; using CompMs.Common.DataObj; +using CompMs.Common.Enum; +using CompMs.MsdialCore.Algorithm; using CompMs.Common.DataObj.Property; using CompMs.MsdialCore.DataObj; +using CompMs.MsdialCore.Parameter; using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; namespace CompMs.MsdialCore.Utility.Tests; @@ -118,6 +126,72 @@ public void GetAverageSpectrumTest() { } } + [TestMethod()] + public void GetMs2ValuePeaksReturnsMatchingPeaksInScanOrder() { + var provider = new StubDataProvider([ + new RawSpectrum { MsLevel = 1 }, + CreateMs2Spectrum(10, 500, 0, 3, 7), + CreateMs2Spectrum(11, 500, 2, 100, 200), + CreateMs2Spectrum(12, 500, 0, 5, 11), + new RawSpectrum { MsLevel = 2 }, + ]); + var parameter = new ParameterBase { + CentroidMs1Tolerance = 0.1f, + CentroidMs2Tolerance = 0.05f, + }; + + var actual = DataAccess.GetMs2ValuePeaks( + provider, 500, 0, 4, [100, 200], parameter, AcquisitionType.DDA, targetCE: 0); + + Assert.AreEqual(2, actual.Count); + Assert.AreEqual(2, actual[0].Length); + Assert.AreEqual(2, actual[1].Length); + CollectionAssert.AreEqual(new[] { 10, 12 }, actual[0].Select(peak => peak.Id).ToArray()); + CollectionAssert.AreEqual(new[] { 10, 12 }, actual[1].Select(peak => peak.Id).ToArray()); + Assert.AreEqual(3d, actual[0][0].Intensity); + Assert.AreEqual(5d, actual[0][1].Intensity); + Assert.AreEqual(7d, actual[1][0].Intensity); + Assert.AreEqual(11d, actual[1][1].Intensity); + } + + private static RawSpectrum CreateMs2Spectrum(int index, double precursorMz, double collisionEnergy, double firstIntensity, double secondIntensity) { + return new RawSpectrum { + Index = index, + MsLevel = 2, + CollisionEnergy = collisionEnergy, + ScanStartTime = index, + Precursor = new RawPrecursorIon { IsolationTargetMz = precursorMz }, + Spectrum = [ + new RawPeakElement { Mz = 100, Intensity = firstIntensity }, + new RawPeakElement { Mz = 150, Intensity = 0 }, + new RawPeakElement { Mz = 200, Intensity = secondIntensity }, + new RawPeakElement { Mz = 250, Intensity = 0 }, + ], + }; + } + + private sealed class StubDataProvider : IDataProvider { + private readonly ReadOnlyCollection _spectra; + + public StubDataProvider(IList spectra) { + _spectra = new ReadOnlyCollection(spectra); + } + + public ReadOnlyCollection LoadMsSpectrums() { + return _spectra; + } + + public ReadOnlyCollection LoadMs1Spectrums() => throw new System.NotImplementedException(); + + public ReadOnlyCollection LoadMsNSpectrums(int level) => throw new System.NotImplementedException(); + + public Task> LoadMsSpectrumsAsync(CancellationToken token) => throw new System.NotImplementedException(); + + public Task> LoadMs1SpectrumsAsync(CancellationToken token) => throw new System.NotImplementedException(); + + public Task> LoadMsNSpectrumsAsync(int level, CancellationToken token) => throw new System.NotImplementedException(); + } + [TestMethod()] public void ReferenceMatchedExportUsesAnnotationName() { foreach (var name in new[] { "", " ", "Unknown", "unknown feature", "null", "empty", "w/o MS2: compound", "RIKEN MS/MS" }) {