diff --git a/mzLib/MassSpectrometry/Deconvolution/Algorithms/ClassicDeconvolutionAlgorithm.cs b/mzLib/MassSpectrometry/Deconvolution/Algorithms/ClassicDeconvolutionAlgorithm.cs
index 4a919a7e5..8f7bb320b 100644
--- a/mzLib/MassSpectrometry/Deconvolution/Algorithms/ClassicDeconvolutionAlgorithm.cs
+++ b/mzLib/MassSpectrometry/Deconvolution/Algorithms/ClassicDeconvolutionAlgorithm.cs
@@ -1,20 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Chemistry;
-using Easy.Common.Extensions;
using MathNet.Numerics.Statistics;
using MzLibUtil;
namespace MassSpectrometry
{
- public class ClassicDeconvolutionAlgorithm : DeconvolutionAlgorithm
+ internal class ClassicDeconvolutionAlgorithm : DeconvolutionAlgorithm
{
private MzSpectrum spectrum;
- public ClassicDeconvolutionAlgorithm(DeconvolutionParameters deconParameters) : base(deconParameters)
+ internal ClassicDeconvolutionAlgorithm(DeconvolutionParameters deconParameters) : base(deconParameters)
{
}
@@ -25,7 +22,7 @@ public ClassicDeconvolutionAlgorithm(DeconvolutionParameters deconParameters) :
/// spectrum to deconvolute
/// Range of peaks to deconvolute
///
- public override IEnumerable Deconvolute(MzSpectrum spectrumToDeconvolute, MzRange range)
+ internal override IEnumerable Deconvolute(MzSpectrum spectrumToDeconvolute, MzRange range)
{
var deconParams = DeconvolutionParameters as ClassicDeconvolutionParameters ?? throw new MzLibException("Deconvolution params and algorithm do not match");
spectrum = spectrumToDeconvolute;
@@ -205,7 +202,7 @@ private IsotopicEnvelope FindIsotopicEnvelope(int massIndex, double candidateFor
}
}
- return new IsotopicEnvelope(listOfObservedPeaks, monoisotopicMass, chargeState, totalIntensity, Statistics.StandardDeviation(listOfRatios), massIndex);
+ return new IsotopicEnvelope(listOfObservedPeaks, monoisotopicMass, chargeState, totalIntensity, listOfRatios.StandardDeviation());
}
private int ObserveAdjacentChargeStates(IsotopicEnvelope originalEnvelope, double mostIntensePeakMz, int massIndex, double deconvolutionTolerancePpm, double intensityRatioLimit, double minChargeToLookFor, double maxChargeToLookFor, List monoisotopicMassPredictions)
diff --git a/mzLib/MassSpectrometry/Deconvolution/Algorithms/DeconvolutionAlgorithm.cs b/mzLib/MassSpectrometry/Deconvolution/Algorithms/DeconvolutionAlgorithm.cs
index e8a052e39..1bb6bf523 100644
--- a/mzLib/MassSpectrometry/Deconvolution/Algorithms/DeconvolutionAlgorithm.cs
+++ b/mzLib/MassSpectrometry/Deconvolution/Algorithms/DeconvolutionAlgorithm.cs
@@ -8,6 +8,9 @@
namespace MassSpectrometry
{
+ ///
+ /// Parent class defining minimum requirement to be used
+ ///
public abstract class DeconvolutionAlgorithm
{
// For ClassicDeconv. If not used elsewhere, move to that class
@@ -79,6 +82,6 @@ protected DeconvolutionAlgorithm(DeconvolutionParameters deconParameters)
/// spectrum to be deconvoluted
/// Range of peaks to deconvolute
///
- public abstract IEnumerable Deconvolute(MzSpectrum spectrum, MzRange range);
+ internal abstract IEnumerable Deconvolute(MzSpectrum spectrum, MzRange range);
}
}
diff --git a/mzLib/MassSpectrometry/Deconvolution/Algorithms/ExampleNewDeconvolutionAlgorithmTemplate.cs b/mzLib/MassSpectrometry/Deconvolution/Algorithms/ExampleNewDeconvolutionAlgorithmTemplate.cs
index 18957d8d0..c70c10b63 100644
--- a/mzLib/MassSpectrometry/Deconvolution/Algorithms/ExampleNewDeconvolutionAlgorithmTemplate.cs
+++ b/mzLib/MassSpectrometry/Deconvolution/Algorithms/ExampleNewDeconvolutionAlgorithmTemplate.cs
@@ -1,22 +1,19 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using MzLibUtil;
namespace MassSpectrometry
{
[ExcludeFromCodeCoverage]
- public class ExampleNewDeconvolutionAlgorithmTemplate : DeconvolutionAlgorithm
+ internal class ExampleNewDeconvolutionAlgorithmTemplate : DeconvolutionAlgorithm
{
- public ExampleNewDeconvolutionAlgorithmTemplate(DeconvolutionParameters deconParameters) : base(deconParameters)
+ internal ExampleNewDeconvolutionAlgorithmTemplate(DeconvolutionParameters deconParameters) : base(deconParameters)
{
}
- public override IEnumerable Deconvolute(MzSpectrum spectrum, MzRange range = null)
+ internal override IEnumerable Deconvolute(MzSpectrum spectrum, MzRange range = null)
{
var deconParams = DeconvolutionParameters as ExampleNewDeconvolutionParametersTemplate ?? throw new MzLibException("Deconvolution params and algorithm do not match");
range ??= spectrum.Range;
diff --git a/mzLib/MassSpectrometry/Deconvolution/Deconvoluter.cs b/mzLib/MassSpectrometry/Deconvolution/Deconvoluter.cs
index d419561f2..773422862 100644
--- a/mzLib/MassSpectrometry/Deconvolution/Deconvoluter.cs
+++ b/mzLib/MassSpectrometry/Deconvolution/Deconvoluter.cs
@@ -1,10 +1,5 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Easy.Common.Extensions;
-using Easy.Common.Interfaces;
+using System.Collections.Generic;
+using Chemistry;
using MzLibUtil;
namespace MassSpectrometry
@@ -30,27 +25,11 @@ public static class Deconvoluter
public static IEnumerable Deconvolute(MsDataScan scan,
DeconvolutionParameters deconvolutionParameters, MzRange rangeToGetPeaksFrom = null)
{
- rangeToGetPeaksFrom ??= scan.MassSpectrum.Range;
+ // set any specific deconvolution parameters found only in the MsDataScan
- // set deconvolution algorithm and any specific deconvolution parameters found in the MsDataScan
- DeconvolutionAlgorithm deconAlgorithm;
- switch (deconvolutionParameters.DeconvolutionType)
- {
- case DeconvolutionType.ClassicDeconvolution:
- deconAlgorithm = new ClassicDeconvolutionAlgorithm(deconvolutionParameters);
- break;
-
- case DeconvolutionType.ExampleNewDeconvolutionTemplate:
- deconAlgorithm = new ExampleNewDeconvolutionAlgorithmTemplate(deconvolutionParameters);
- break;
-
- default: throw new MzLibException("DeconvolutionType not yet supported");
- }
-
- return deconAlgorithm.Deconvolute(scan.MassSpectrum, rangeToGetPeaksFrom);
+ foreach (var isotopicEnvelope in Deconvolute(scan.MassSpectrum, deconvolutionParameters, rangeToGetPeaksFrom))
+ yield return isotopicEnvelope;
}
-
-
///
/// Static deconvolution of an MzSpectrum that does not require Deconvoluter construction
@@ -79,7 +58,22 @@ public static IEnumerable Deconvolute(MzSpectrum spectrum,
default: throw new MzLibException("DeconvolutionType not yet supported");
}
- return deconAlgorithm.Deconvolute(spectrum, rangeToGetPeaksFrom);
+ // Short circuit deconvolution if it is called on a neutral mass spectrum
+ if (spectrum is NeutralMassSpectrum newt)
+ {
+ for (int i = 0; i < newt.XArray.Length; i++)
+ {
+ // skip this peak if it's outside the range of interest (e.g. if we're only interested in deconvoluting a small m/z range)
+ if (!rangeToGetPeaksFrom.Contains(newt.XArray[i].ToMz(newt.Charges[i])))
+ continue;
+ yield return new IsotopicEnvelope(newt.XArray[i], newt.YArray[i], newt.Charges[i]);
+ }
+ }
+ else
+ {
+ foreach (var isotopicEnvelope in deconAlgorithm.Deconvolute(spectrum, rangeToGetPeaksFrom))
+ yield return isotopicEnvelope;
+ }
}
}
}
diff --git a/mzLib/MassSpectrometry/MassSpectrometry.csproj b/mzLib/MassSpectrometry/MassSpectrometry.csproj
index 6af63b9e4..9d8e74edc 100644
--- a/mzLib/MassSpectrometry/MassSpectrometry.csproj
+++ b/mzLib/MassSpectrometry/MassSpectrometry.csproj
@@ -20,4 +20,8 @@
+
+
+
+
diff --git a/mzLib/MassSpectrometry/MsDataFile.cs b/mzLib/MassSpectrometry/MsDataFile.cs
index 7242f2cf7..3e88fcfef 100644
--- a/mzLib/MassSpectrometry/MsDataFile.cs
+++ b/mzLib/MassSpectrometry/MsDataFile.cs
@@ -23,9 +23,6 @@
namespace MassSpectrometry
{
- // TODO: Define scope of class
- // Class scope is to provide to the data loaded from the DataFile.
-
///
/// A class for interacting with data collected from a Mass Spectrometer, and stored in a file
///
diff --git a/mzLib/MassSpectrometry/MzSpectra/IsotopicEnvelope.cs b/mzLib/MassSpectrometry/MzSpectra/IsotopicEnvelope.cs
index 7e42426b1..3b2ab3d1b 100644
--- a/mzLib/MassSpectrometry/MzSpectra/IsotopicEnvelope.cs
+++ b/mzLib/MassSpectrometry/MzSpectra/IsotopicEnvelope.cs
@@ -14,29 +14,36 @@ public class IsotopicEnvelope : IHasMass
///
/// Mass of most abundant observed isotopic peak, not accounting for addition or subtraction or protons due to ESI charge state induction
///
- public double MostAbundantObservedIsotopicMass { get; private set; }
+ internal double MostAbundantObservedIsotopicMass { get; private set; }
public readonly int Charge;
public readonly double TotalIntensity;
- public readonly double StDev;
- public readonly int MassIndex;
public double Score { get; private set; }
- public IsotopicEnvelope(List<(double mz, double intensity)> bestListOfPeaks, double bestMonoisotopicMass, int bestChargeState, double bestTotalIntensity, double bestStDev, int bestMassIndex)
+ ///
+ /// Used for an isotopic envelope that mzLib deconvoluted (e.g., from a mass spectrum)
+ ///
+ public IsotopicEnvelope(List<(double mz, double intensity)> bestListOfPeaks, double bestMonoisotopicMass, int bestChargeState, double bestTotalIntensity, double bestStDev)
{
Peaks = bestListOfPeaks;
MonoisotopicMass = bestMonoisotopicMass;
- MostAbundantObservedIsotopicMass = GetMostAbundantObservedIsotopicMass(bestListOfPeaks, bestChargeState);
+ MostAbundantObservedIsotopicMass = bestListOfPeaks.MaxBy(p => p.intensity).mz * Math.Abs(bestChargeState);
Charge = bestChargeState;
TotalIntensity = bestTotalIntensity;
- StDev = bestStDev;
- MassIndex = bestMassIndex;
- Score = ScoreIsotopeEnvelope();
+ Score = ScoreIsotopeEnvelope(bestStDev);
}
- public double GetMostAbundantObservedIsotopicMass(List<(double mz, double intensity)> peaks, int charge)
+ ///
+ /// Used for a neutral mass read in from a deconvoluted file
+ /// Assumes the mass is correct: score is max value
+ ///
+ public IsotopicEnvelope(double monoisotopicMass, double intensity, int charge)
{
- return peaks.MaxBy(p => p.intensity).mz * Math.Abs(charge);
+ MonoisotopicMass = monoisotopicMass;
+ Charge = charge;
+ TotalIntensity = intensity;
+ Score = double.MaxValue;
+ Peaks = [(monoisotopicMass.ToMz(charge), intensity)];
}
public override string ToString()
@@ -44,10 +51,10 @@ public override string ToString()
return Charge + "\t" + Peaks[0].mz.ToString("G8") + "\t" + Peaks.Count + "\t" + TotalIntensity;
}
- private double ScoreIsotopeEnvelope() //likely created by Stefan Solntsev using peptide data
+ private double ScoreIsotopeEnvelope(double stDev) //likely created by Stefan Solntsev using peptide data
{
return Peaks.Count >= 2 ?
- TotalIntensity / Math.Pow(StDev, 0.13) * Math.Pow(Peaks.Count, 0.4) / Math.Pow(Math.Abs(Charge), 0.06) :
+ TotalIntensity / Math.Pow(stDev, 0.13) * Math.Pow(Peaks.Count, 0.4) / Math.Pow(Math.Abs(Charge), 0.06) :
0;
}
@@ -60,6 +67,5 @@ public void SetMedianMonoisotopicMass(List monoisotopicMassPredictions)
{
MonoisotopicMass = monoisotopicMassPredictions.Median();
}
-
}
}
\ No newline at end of file
diff --git a/mzLib/MassSpectrometry/MzSpectra/MzSpectrum.cs b/mzLib/MassSpectrometry/MzSpectra/MzSpectrum.cs
index 2e9fcc7a4..88a97d1ac 100644
--- a/mzLib/MassSpectrometry/MzSpectra/MzSpectrum.cs
+++ b/mzLib/MassSpectrometry/MzSpectra/MzSpectrum.cs
@@ -22,10 +22,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
-using System.Diagnostics;
using System.IO;
using System.Linq;
-using System.Text.Json;
namespace MassSpectrometry
{
@@ -126,7 +124,7 @@ public MzRange Range
}
}
- public double? FirstX
+ public virtual double? FirstX
{
get
{
@@ -138,7 +136,7 @@ public double? FirstX
}
}
- public double? LastX
+ public virtual double? LastX
{
get
{
@@ -373,7 +371,7 @@ public IsotopicEnvelope FindIsotopicEnvelope(int massIndex, double candidateForM
}
}
- return new IsotopicEnvelope(listOfObservedPeaks, monoisotopicMass, chargeState, totalIntensity, Statistics.StandardDeviation(listOfRatios), massIndex);
+ return new IsotopicEnvelope(listOfObservedPeaks, monoisotopicMass, chargeState, totalIntensity, listOfRatios.StandardDeviation());
}
[Obsolete("Deconvolution Has been moved to the Deconvoluter Object")]
@@ -796,7 +794,12 @@ private MzPeak GetPeak(int index)
return peakList[index];
}
- private MzPeak GeneratePeak(int index)
+ ///
+ /// The source of all peaks which populate the peakList
+ ///
+ ///
+ ///
+ protected virtual MzPeak GeneratePeak(int index)
{
return new MzPeak(XArray[index], YArray[index]);
}
diff --git a/mzLib/MassSpectrometry/MzSpectra/NeutralMassSpectrum.cs b/mzLib/MassSpectrometry/MzSpectra/NeutralMassSpectrum.cs
new file mode 100644
index 000000000..dcb5d7d2b
--- /dev/null
+++ b/mzLib/MassSpectrometry/MzSpectra/NeutralMassSpectrum.cs
@@ -0,0 +1,65 @@
+using System;
+using Chemistry;
+
+namespace MassSpectrometry
+{
+ public class NeutralMassSpectrum : MzSpectrum
+ {
+ public int[] Charges { get; init; }
+ public NeutralMassSpectrum(double[,] monoisotopicMassesIntensities, int[] charges) : base(monoisotopicMassesIntensities)
+ {
+ if (monoisotopicMassesIntensities.GetLength(0) != charges.Length)
+ throw new ArgumentException("The lengths of monoisotopicMasses, intensities, and charges must be the same.");
+
+ Charges = charges;
+
+ double minMz = double.MaxValue;
+ double maxMz = double.MinValue;
+ for (int i = 0; i < monoisotopicMassesIntensities.GetLength(0); i++)
+ {
+ var mz = monoisotopicMassesIntensities[i,0].ToMz(charges[i]);
+ if (mz < minMz)
+ minMz = mz;
+ if (mz > maxMz)
+ maxMz = mz;
+ }
+
+ FirstX = minMz;
+ LastX = maxMz;
+ }
+
+ public NeutralMassSpectrum(double[] monoisotopicMasses, double[] intensities, int[] charges, bool shouldCopy)
+ : base(monoisotopicMasses, intensities, shouldCopy)
+ {
+ if (monoisotopicMasses.GetLength(0) != intensities.Length || monoisotopicMasses.Length != charges.Length)
+ throw new ArgumentException("The lengths of monoisotopicMasses, intensities, and charges must be the same.");
+
+ Charges = charges;
+
+ double minMz = double.MaxValue;
+ double maxMz = double.MinValue;
+ for (int i = 0; i < monoisotopicMasses.Length; i++)
+ {
+ var mz = monoisotopicMasses[i].ToMz(charges[i]);
+ if (mz < minMz)
+ minMz = mz;
+ if (mz > maxMz)
+ maxMz = mz;
+ }
+
+ FirstX = minMz;
+ LastX = maxMz;
+ }
+
+ public override double? FirstX { get; } // in m/z
+ public override double? LastX { get; } // in m/z
+
+ ///
+ /// Converts to a charged spectrum
+ ///
+ protected override MzPeak GeneratePeak(int index)
+ {
+ return new MzPeak(XArray[index].ToMz(Charges[index]), YArray[index]);
+ }
+ }
+}
diff --git a/mzLib/Test/TestDeconvolution.cs b/mzLib/Test/TestDeconvolution.cs
index 8f6cbb9ee..7ee3f59a2 100644
--- a/mzLib/Test/TestDeconvolution.cs
+++ b/mzLib/Test/TestDeconvolution.cs
@@ -26,15 +26,18 @@ public sealed class TestDeconvolution
#region Old Deconvolution
[Test]
- [TestCase(586.2143122, 24, 41983672, 586.2)]//This is a lesser abundant charge state envelope at the low mz end
- [TestCase(740.372202090153, 19, 108419280, 740.37)]//This is the most abundant charge state envelope
- [TestCase(1081.385183, 13, 35454636, 1081.385)]//This is a lesser abundant charge state envelope at the high mz end
- public void TestDeconvolutionProteoformMultiChargeState(double selectedIonMz, int selectedIonChargeStateGuess, double selectedIonIntensity, double isolationMz)
+ [TestCase(586.2143122, 24, 41983672, 586.2)] //This is a lesser abundant charge state envelope at the low mz end
+ [TestCase(740.372202090153, 19, 108419280, 740.37)] //This is the most abundant charge state envelope
+ [TestCase(1081.385183, 13, 35454636,
+ 1081.385)] //This is a lesser abundant charge state envelope at the high mz end
+ public void TestDeconvolutionProteoformMultiChargeState(double selectedIonMz, int selectedIonChargeStateGuess,
+ double selectedIonIntensity, double isolationMz)
{
MsDataScan[] Scans = new MsDataScan[1];
//txt file, not mgf, because it's an MS1. Most intense proteoform has mass of ~14037.9 Da
- string Ms1SpectrumPath = Path.Combine(TestContext.CurrentContext.TestDirectory, @"DataFiles\14kDaProteoformMzIntensityMs1.txt");
+ string Ms1SpectrumPath = Path.Combine(TestContext.CurrentContext.TestDirectory,
+ @"DataFiles\14kDaProteoformMzIntensityMs1.txt");
string[] spectrumLines = File.ReadAllLines(Ms1SpectrumPath);
@@ -51,7 +54,9 @@ public void TestDeconvolutionProteoformMultiChargeState(double selectedIonMz, in
MzSpectrum spectrum = new MzSpectrum(ms1mzs, ms1intensities, false);
- Scans[0] = new MsDataScan(spectrum, 1, 1, false, Polarity.Positive, 1.0, new MzRange(495, 1617), "first spectrum", MZAnalyzerType.Unknown, spectrum.SumOfAllY, null, null, null, selectedIonMz, selectedIonChargeStateGuess, selectedIonIntensity, isolationMz, 4);
+ Scans[0] = new MsDataScan(spectrum, 1, 1, false, Polarity.Positive, 1.0, new MzRange(495, 1617),
+ "first spectrum", MZAnalyzerType.Unknown, spectrum.SumOfAllY, null, null, null, selectedIonMz,
+ selectedIonChargeStateGuess, selectedIonIntensity, isolationMz, 4);
var myMsDataFile = new FakeMsDataFile(Scans);
@@ -68,21 +73,24 @@ public void TestDeconvolutionProteoformMultiChargeState(double selectedIonMz, in
[Test]
[TestCase("APSGGKK", "12-18-17_frac7_calib_ms1_663_665.mzML", 2)]
- [TestCase("PKRKAEGDAKGDKAKVKDEPQRRSARLSAKPAPPKPEPKPKKAPAKKGEKVPKGKKGKADAGKEGNNPAENGDAKTDQAQKAEGAGDAK", "FXN11_tr1_032017-calib_ms1_scans716_718.mzML", 8)]
- [TestCase("PKRKVSSAEGAAKEEPKRRSARLSAKPPAKVEAKPKKAAAKDKSSDKKVQTKGKRGAKGKQAEVANQETKEDLPAENGETKTEESPASDEAGEKEAKSD", "FXN11_tr1_032017-calib_ms1_scans781_783.mzML", 16)]
+ [TestCase("PKRKAEGDAKGDKAKVKDEPQRRSARLSAKPAPPKPEPKPKKAPAKKGEKVPKGKKGKADAGKEGNNPAENGDAKTDQAQKAEGAGDAK",
+ "FXN11_tr1_032017-calib_ms1_scans716_718.mzML", 8)]
+ [TestCase("PKRKVSSAEGAAKEEPKRRSARLSAKPPAKVEAKPKKAAAKDKSSDKKVQTKGKRGAKGKQAEVANQETKEDLPAENGETKTEESPASDEAGEKEAKSD",
+ "FXN11_tr1_032017-calib_ms1_scans781_783.mzML", 16)]
public static void CheckGetMostAbundantObservedIsotopicMass(string peptide, string file, int charge)
{
Protein test1 = new Protein(peptide, "Accession");
DigestionParams d = new DigestionParams();
- PeptideWithSetModifications pw = new PeptideWithSetModifications(test1, d, 1, test1.Length, CleavageSpecificity.None, "", 0, new Dictionary(), 0);
+ PeptideWithSetModifications pw = new PeptideWithSetModifications(test1, d, 1, test1.Length,
+ CleavageSpecificity.None, "", 0, new Dictionary(), 0);
double m = pw.MostAbundantMonoisotopicMass.ToMz(charge);
string singleScan = Path.Combine(TestContext.CurrentContext.TestDirectory, "DataFiles", file);
- var reader = MsDataFileReader.GetDataFile(singleScan);
+ var reader = MsDataFileReader.GetDataFile(singleScan);
reader.LoadAllStaticData();
List singlescan = reader.GetAllScansList();
-
+
MzSpectrum singlespec = singlescan[0].MassSpectrum;
MzRange singleRange = new MzRange(singlespec.XArray.Min(), singlespec.XArray.Max());
int minAssumedChargeState = 1;
@@ -91,13 +99,16 @@ public static void CheckGetMostAbundantObservedIsotopicMass(string peptide, stri
double intensityRatioLimit = 3;
//check assigned correctly
- List lie2 = singlespec.Deconvolute(singleRange, minAssumedChargeState, maxAssumedChargeState, deconvolutionTolerancePpm, intensityRatioLimit).ToList();
+ List lie2 = singlespec.Deconvolute(singleRange, minAssumedChargeState,
+ maxAssumedChargeState, deconvolutionTolerancePpm, intensityRatioLimit).ToList();
List lie2_charge = lie2.Where(p => p.Charge == charge).ToList();
Assert.That(lie2_charge[0].MostAbundantObservedIsotopicMass / charge, Is.EqualTo(m).Within(0.1));
//check that if already assigned, skips assignment and just recalls same value
- List lie3 = singlespec.Deconvolute(singleRange, minAssumedChargeState, maxAssumedChargeState, deconvolutionTolerancePpm, intensityRatioLimit).ToList();
- Assert.AreEqual(lie2.Select(p => p.MostAbundantObservedIsotopicMass), lie3.Select(p => p.MostAbundantObservedIsotopicMass));
+ List lie3 = singlespec.Deconvolute(singleRange, minAssumedChargeState,
+ maxAssumedChargeState, deconvolutionTolerancePpm, intensityRatioLimit).ToList();
+ Assert.AreEqual(lie2.Select(p => p.MostAbundantObservedIsotopicMass),
+ lie3.Select(p => p.MostAbundantObservedIsotopicMass));
}
#endregion
@@ -105,15 +116,18 @@ public static void CheckGetMostAbundantObservedIsotopicMass(string peptide, stri
#region Classic Deconvolution
[Test]
- [TestCase(586.2143122, 24, 41983672, 586.2)]//This is a lesser abundant charge state envelope at the low mz end
- [TestCase(740.372202090153, 19, 108419280, 740.37)]//This is the most abundant charge state envelope
- [TestCase(1081.385183, 13, 35454636, 1081.385)]//This is a lesser abundant charge state envelope at the high mz end
- public void TestClassicDeconvolutionProteoformMultiChargeState(double selectedIonMz, int selectedIonChargeStateGuess, double selectedIonIntensity, double isolationMz)
+ [TestCase(586.2143122, 24, 41983672, 586.2)] //This is a lesser abundant charge state envelope at the low mz end
+ [TestCase(740.372202090153, 19, 108419280, 740.37)] //This is the most abundant charge state envelope
+ [TestCase(1081.385183, 13, 35454636,
+ 1081.385)] //This is a lesser abundant charge state envelope at the high mz end
+ public void TestClassicDeconvolutionProteoformMultiChargeState(double selectedIonMz,
+ int selectedIonChargeStateGuess, double selectedIonIntensity, double isolationMz)
{
MsDataScan[] Scans = new MsDataScan[1];
//txt file, not mgf, because it's an MS1. Most intense proteoform has mass of ~14037.9 Da
- string Ms1SpectrumPath = Path.Combine(TestContext.CurrentContext.TestDirectory, @"DataFiles\14kDaProteoformMzIntensityMs1.txt");
+ string Ms1SpectrumPath = Path.Combine(TestContext.CurrentContext.TestDirectory,
+ @"DataFiles\14kDaProteoformMzIntensityMs1.txt");
string[] spectrumLines = File.ReadAllLines(Ms1SpectrumPath);
@@ -130,7 +144,9 @@ public void TestClassicDeconvolutionProteoformMultiChargeState(double selectedIo
MzSpectrum spectrum = new MzSpectrum(ms1mzs, ms1intensities, false);
- Scans[0] = new MsDataScan(spectrum, 1, 1, false, Polarity.Positive, 1.0, new MzRange(495, 1617), "first spectrum", MZAnalyzerType.Unknown, spectrum.SumOfAllY, null, null, null, selectedIonMz, selectedIonChargeStateGuess, selectedIonIntensity, isolationMz, 4);
+ Scans[0] = new MsDataScan(spectrum, 1, 1, false, Polarity.Positive, 1.0, new MzRange(495, 1617),
+ "first spectrum", MZAnalyzerType.Unknown, spectrum.SumOfAllY, null, null, null, selectedIonMz,
+ selectedIonChargeStateGuess, selectedIonIntensity, isolationMz, 4);
var myMsDataFile = new FakeMsDataFile(Scans);
@@ -141,7 +157,8 @@ public void TestClassicDeconvolutionProteoformMultiChargeState(double selectedIo
DeconvolutionParameters deconParameters = new ClassicDeconvolutionParameters(1, 60, 4, 3);
List isolatedMasses = scan.GetIsolatedMassesAndCharges(scan, deconParameters).ToList();
- List isolatedMasses2 = scan.GetIsolatedMassesAndCharges(scan.MassSpectrum, deconParameters).ToList();
+ List isolatedMasses2 =
+ scan.GetIsolatedMassesAndCharges(scan.MassSpectrum, deconParameters).ToList();
List monoIsotopicMasses = isolatedMasses.Select(m => m.MonoisotopicMass).ToList();
List monoIsotopicMasses2 = isolatedMasses2.Select(m => m.MonoisotopicMass).ToList();
@@ -154,13 +171,16 @@ public void TestClassicDeconvolutionProteoformMultiChargeState(double selectedIo
[Test]
[TestCase("APSGGKK", "12-18-17_frac7_calib_ms1_663_665.mzML", 2)]
- [TestCase("PKRKAEGDAKGDKAKVKDEPQRRSARLSAKPAPPKPEPKPKKAPAKKGEKVPKGKKGKADAGKEGNNPAENGDAKTDQAQKAEGAGDAK", "FXN11_tr1_032017-calib_ms1_scans716_718.mzML", 8)]
- [TestCase("PKRKVSSAEGAAKEEPKRRSARLSAKPPAKVEAKPKKAAAKDKSSDKKVQTKGKRGAKGKQAEVANQETKEDLPAENGETKTEESPASDEAGEKEAKSD", "FXN11_tr1_032017-calib_ms1_scans781_783.mzML", 16)]
+ [TestCase("PKRKAEGDAKGDKAKVKDEPQRRSARLSAKPAPPKPEPKPKKAPAKKGEKVPKGKKGKADAGKEGNNPAENGDAKTDQAQKAEGAGDAK",
+ "FXN11_tr1_032017-calib_ms1_scans716_718.mzML", 8)]
+ [TestCase("PKRKVSSAEGAAKEEPKRRSARLSAKPPAKVEAKPKKAAAKDKSSDKKVQTKGKRGAKGKQAEVANQETKEDLPAENGETKTEESPASDEAGEKEAKSD",
+ "FXN11_tr1_032017-calib_ms1_scans781_783.mzML", 16)]
public static void CheckClassicGetMostAbundantObservedIsotopicMass(string peptide, string file, int charge)
{
Protein test1 = new Protein(peptide, "Accession");
DigestionParams d = new DigestionParams();
- PeptideWithSetModifications pw = new PeptideWithSetModifications(test1, d, 1, test1.Length, CleavageSpecificity.None, "", 0, new Dictionary(), 0);
+ PeptideWithSetModifications pw = new PeptideWithSetModifications(test1, d, 1, test1.Length,
+ CleavageSpecificity.None, "", 0, new Dictionary(), 0);
double m = pw.MostAbundantMonoisotopicMass.ToMz(charge);
string singleScan = Path.Combine(TestContext.CurrentContext.TestDirectory, "DataFiles", file);
@@ -176,7 +196,8 @@ public static void CheckClassicGetMostAbundantObservedIsotopicMass(string peptid
double intensityRatioLimit = 3;
DeconvolutionParameters deconParameters =
- new ClassicDeconvolutionParameters(minAssumedChargeState, maxAssumedChargeState, deconvolutionTolerancePpm,
+ new ClassicDeconvolutionParameters(minAssumedChargeState, maxAssumedChargeState,
+ deconvolutionTolerancePpm,
intensityRatioLimit);
//check assigned correctly
@@ -187,7 +208,8 @@ public static void CheckClassicGetMostAbundantObservedIsotopicMass(string peptid
//check that if already assigned, skips assignment and just recalls same value
List lie3 = Deconvoluter.Deconvolute(singlespec, deconParameters, singleRange).ToList();
- Assert.AreEqual(lie2.Select(p => p.MostAbundantObservedIsotopicMass), lie3.Select(p => p.MostAbundantObservedIsotopicMass));
+ Assert.AreEqual(lie2.Select(p => p.MostAbundantObservedIsotopicMass),
+ lie3.Select(p => p.MostAbundantObservedIsotopicMass));
}
#endregion
@@ -225,21 +247,22 @@ public void TestNegativeModeClassicDeconvolution(double expectedMz, int expected
public static void TestExampleNewDeconvolutionInDeconvoluter()
{
DeconvolutionParameters deconParams = new ExampleNewDeconvolutionParametersTemplate(1, 60);
- var dataFile = MsDataFileReader.GetDataFile(Path.Combine(TestContext.CurrentContext.TestDirectory, "DataFiles", "GUACUG_NegativeMode_Sliced.mzML"));
+ var dataFile = MsDataFileReader.GetDataFile(Path.Combine(TestContext.CurrentContext.TestDirectory,
+ "DataFiles", "GUACUG_NegativeMode_Sliced.mzML"));
dataFile.InitiateDynamicConnection();
var scan = dataFile.GetOneBasedScanFromDynamicConnection(726);
var spectrum = scan.MassSpectrum;
dataFile.CloseDynamicConnection();
// test switch statements in Deconvoluter
- Assert.Throws(() => Deconvoluter.Deconvolute(spectrum, deconParams));
- Assert.Throws(() => Deconvoluter.Deconvolute(scan, deconParams));
+ NUnit.Framework.Assert.Throws(() => _ = Deconvoluter.Deconvolute(spectrum, deconParams).ToList());
+ NUnit.Framework.Assert.Throws(() => _ =Deconvoluter.Deconvolute(scan, deconParams).ToList());
// test default exceptions in deconvoluter
var badEnumValue = (DeconvolutionType)Int32.MaxValue;
deconParams.GetType().GetProperty("DeconvolutionType")!.SetValue(deconParams, badEnumValue);
- Assert.Throws(() => Deconvoluter.Deconvolute(spectrum, deconParams));
- Assert.Throws(() => Deconvoluter.Deconvolute(scan, deconParams));
+ NUnit.Framework.Assert.Throws(() => _ = Deconvoluter.Deconvolute(spectrum, deconParams).ToList());
+ NUnit.Framework.Assert.Throws(() => _ = Deconvoluter.Deconvolute(scan, deconParams).ToList());
}
@@ -247,14 +270,15 @@ public static void TestExampleNewDeconvolutionInDeconvoluter()
public static void Test_MsDataScan_GetIsolatedMassesAndCharges()
{
// get scan
- string filePath = Path.Combine(TestContext.CurrentContext.TestDirectory, "DataFiles", "GUACUG_NegativeMode_Sliced.mzML");
+ string filePath = Path.Combine(TestContext.CurrentContext.TestDirectory, "DataFiles",
+ "GUACUG_NegativeMode_Sliced.mzML");
var dataFile = MsDataFileReader.GetDataFile(filePath);
var precursorScan = dataFile.GetOneBasedScan(1);
var fragmentationScan = dataFile.GetOneBasedScan(2);
// set up deconvolution
DeconvolutionParameters deconParams = new ClassicDeconvolutionParameters(-10, -1, 20, 3, Polarity.Negative);
-
+
// get isolated masses and charges on an MS1 scan. This means the isolation window is null.
var ms1Result = precursorScan.GetIsolatedMassesAndCharges(precursorScan.MassSpectrum, deconParams).ToList();
Assert.That(ms1Result.Count, Is.EqualTo(0));
@@ -262,10 +286,132 @@ public static void Test_MsDataScan_GetIsolatedMassesAndCharges()
Assert.That(ms1Result.Count, Is.EqualTo(0));
// get isolated masses and charges on an MS2 scan. This should work correctly
- var ms2Result = fragmentationScan.GetIsolatedMassesAndCharges(precursorScan.MassSpectrum, deconParams).ToList();
+ var ms2Result = fragmentationScan.GetIsolatedMassesAndCharges(precursorScan.MassSpectrum, deconParams)
+ .ToList();
Assert.That(ms2Result.Count, Is.EqualTo(1));
ms2Result = fragmentationScan.GetIsolatedMassesAndCharges(precursorScan, deconParams).ToList();
Assert.That(ms2Result.Count, Is.EqualTo(1));
}
+
+ [Test]
+ public void NeutralMassSpectrum_Deconvolute_AllInRange()
+ {
+ // Arrange
+ var xArray = new[] { 260.774188159546, 391.660998843979 };
+ var yArray = new[] { 1000.0, 1.0 };
+ var charges = new[] { 1, 1 };
+ var spectrum = new NeutralMassSpectrum(xArray, yArray, charges, false);
+ var deconvolutionParameters = new ClassicDeconvolutionParameters(1, 60, 20, 2);
+ var rangeToGetPeaksFrom = new MzRange(260.0, 400.0);
+
+ // Act
+ var result = Deconvoluter.Deconvolute(spectrum, deconvolutionParameters, rangeToGetPeaksFrom).ToList();
+
+ // Assert
+ Assert.IsNotNull(result);
+ Assert.IsInstanceOf>(result);
+ Assert.AreEqual(2, result.Count());
+
+ for (int i = 0; i < result.Count(); i++)
+ {
+ Assert.That(result[i].MonoisotopicMass, Is.EqualTo(xArray[i]));
+ Assert.That(result[i].TotalIntensity, Is.EqualTo(yArray[i]));
+ Assert.That(result[i].Peaks.Count, Is.EqualTo(1));
+ Assert.That(result[i].Peaks.First().mz, Is.EqualTo(xArray[i].ToMz(charges[i])));
+ Assert.That(result[i].Peaks.First().intensity, Is.EqualTo(yArray[i]));
+ Assert.That(result[i].Charge, Is.EqualTo(charges[i]));
+ }
+ }
+
+
+ [Test]
+ public void NeutralMassSpectrum_Deconvolute_AllInRange_Charged()
+ {
+ // Arrange
+ var xArray = new[] { 260.774188159546, 391.660998843979 };
+ var yArray = new[] { 1000.0, 1.0 };
+ var charges = new[] { 3, 3 };
+ var spectrum = new NeutralMassSpectrum(xArray, yArray, charges, false);
+ var deconvolutionParameters = new ClassicDeconvolutionParameters(1, 60, 20, 2);
+ var rangeToGetPeaksFrom = new MzRange(00, 200.0);
+
+ // Act
+ var result = Deconvoluter.Deconvolute(spectrum, deconvolutionParameters, rangeToGetPeaksFrom).ToList();
+
+ // Assert
+ Assert.IsNotNull(result);
+ Assert.IsInstanceOf>(result);
+ Assert.AreEqual(2, result.Count());
+
+ for (int i = 0; i < result.Count(); i++)
+ {
+ Assert.That(result[i].MonoisotopicMass, Is.EqualTo(xArray[i]));
+ Assert.That(result[i].TotalIntensity, Is.EqualTo(yArray[i]));
+ Assert.That(result[i].Peaks.Count, Is.EqualTo(1));
+ Assert.That(result[i].Peaks.First().mz, Is.EqualTo(xArray[i].ToMz(charges[i])));
+ Assert.That(result[i].Peaks.First().intensity, Is.EqualTo(yArray[i]));
+ Assert.That(result[i].Charge, Is.EqualTo(charges[i]));
+ }
+ }
+
+ [Test]
+ public void NeutralMassSpectrum_Deconvolute_SomeInRange()
+ {
+ // Arrange
+ var xArray = new[] { 260.774188159546, 391.660998843979 };
+ var yArray = new[] { 1000.0, 1.0 };
+ var charges = new[] { 1, 1 };
+ var spectrum = new NeutralMassSpectrum(xArray, yArray, charges, false);
+ var deconvolutionParameters = new ClassicDeconvolutionParameters(1, 60, 20, 2);
+ var rangeToGetPeaksFrom = new MzRange(260.0, 300.0);
+
+ // Act
+ var result = Deconvoluter.Deconvolute(spectrum, deconvolutionParameters, rangeToGetPeaksFrom).ToList();
+
+ // Assert
+ Assert.IsNotNull(result);
+ Assert.IsInstanceOf>(result);
+ Assert.AreEqual(1, result.Count());
+
+ for (int i = 0; i < result.Count(); i++)
+ {
+ Assert.That(result[i].MonoisotopicMass, Is.EqualTo(xArray[i]));
+ Assert.That(result[i].TotalIntensity, Is.EqualTo(yArray[i]));
+ Assert.That(result[i].Peaks.Count, Is.EqualTo(1));
+ Assert.That(result[i].Peaks.First().mz, Is.EqualTo(xArray[i].ToMz(charges[i])));
+ Assert.That(result[i].Peaks.First().intensity, Is.EqualTo(yArray[i]));
+ Assert.That(result[i].Charge, Is.EqualTo(charges[i]));
+ }
+ }
+
+ [Test]
+ public void NeutralMassSpectrum_Deconvolute_SomeInRange_Charged()
+ {
+ // Arrange
+ var xArray = new[] { 260.774188159546, 391.660998843979 };
+ var yArray = new[] { 1000.0, 1.0 };
+ var charges = new[] { 1, 20 };
+ var spectrum = new NeutralMassSpectrum(xArray, yArray, charges, false);
+ var deconvolutionParameters = new ClassicDeconvolutionParameters(1, 60, 20, 2);
+ var rangeToGetPeaksFrom = new MzRange(260.0, 300.0);
+
+ // Act
+ var result = Deconvoluter.Deconvolute(spectrum, deconvolutionParameters, rangeToGetPeaksFrom).ToList();
+
+ // Assert
+ Assert.IsNotNull(result);
+ Assert.IsInstanceOf>(result);
+ Assert.AreEqual(1, result.Count());
+
+ for (int i = 0; i < result.Count(); i++)
+ {
+ Assert.That(result[i].MonoisotopicMass, Is.EqualTo(xArray[i]));
+ Assert.That(result[i].TotalIntensity, Is.EqualTo(yArray[i]));
+ Assert.That(result[i].Peaks.Count, Is.EqualTo(1));
+ Assert.That(result[i].Peaks.First().mz, Is.EqualTo(xArray[i].ToMz(charges[i])));
+ Assert.That(result[i].Peaks.First().intensity, Is.EqualTo(yArray[i]));
+ Assert.That(result[i].Charge, Is.EqualTo(charges[i]));
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/mzLib/Test/TestSpectra.cs b/mzLib/Test/TestSpectra.cs
index e33d9adb1..fec83ba8b 100644
--- a/mzLib/Test/TestSpectra.cs
+++ b/mzLib/Test/TestSpectra.cs
@@ -22,6 +22,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Chemistry;
using Assert = NUnit.Framework.Legacy.ClassicAssert;
using Stopwatch = System.Diagnostics.Stopwatch;
@@ -342,5 +343,111 @@ public void TestEqualsAndHashCode()
Assert.That(!_mzSpectrumA.Equals(2));
Assert.That(!_mzSpectrumA.Equals((object)2));
}
+
+
+ [Test]
+ public void NeutralMassSpectrum_Constructor_ValidArguments_InitializesProperties()
+ {
+ double[] monoisotopicMasses = { 100.0, 200.0, 300.0 };
+ double[] intensities = { 0.5, 0.8, 1.0 };
+ int[] charges = { 1, 2, 3 };
+
+ var spectrum = new NeutralMassSpectrum(monoisotopicMasses, intensities, charges, true);
+
+ Assert.That(monoisotopicMasses.Length, Is.EqualTo(spectrum.XArray.Length));
+ Assert.That(intensities.Length, Is.EqualTo(spectrum.YArray.Length));
+ Assert.That(charges.Length, Is.EqualTo(spectrum.Charges.Length));
+ }
+
+ [Test]
+ public void NeutralMassSpectrum_Constructor_InvalidArguments_ThrowsArgumentException()
+ {
+ double[] monoisotopicMasses = { 100.0, 200.0, 300.0 };
+ double[] intensities = { 0.5, 0.8 };
+ int[] charges = { 1, 2, 3 };
+ bool shouldCopy = true;
+
+ Assert.Throws(() => new NeutralMassSpectrum(monoisotopicMasses, intensities, charges, shouldCopy));
+ }
+
+ [Test]
+ public void NeutralMassSpectrum_MzPeak()
+ {
+ double[] monoisotopicMasses = { 100.0, 200.0, 300.0 };
+ double[] intensities = { 0.5, 0.8, 1.0 };
+ int[] charges = { 1, 2, 3 };
+ var spectrum = new NeutralMassSpectrum(monoisotopicMasses, intensities, charges, true);
+
+
+ var peak = spectrum.Extract(50, 210).ToArray();
+ Assert.That(peak.Length, Is.EqualTo(2));
+
+ for (int i = 0; i < peak.Length; i++)
+ {
+ double mono = monoisotopicMasses[i];
+ int charge = charges[i];
+ double intensity = intensities[i];
+ double mz = mono.ToMz(charge);
+
+ Assert.That(peak[i].Mz, Is.EqualTo(mz));
+ Assert.That(peak[i].Intensity, Is.EqualTo(intensity));
+ }
+ }
+
+ [Test]
+ public void NeutralMassSpectrum_MzRange()
+ {
+ double[] monoisotopicMasses = { 100.0, 200.0, 300.0 };
+ double[] intensities = { 0.5, 0.8, 1.0 };
+ int[] charges = { 1, 2, 3 };
+ var spectrum = new NeutralMassSpectrum(monoisotopicMasses, intensities, charges, true);
+
+
+ var peak = spectrum.Extract(50, 2100).ToArray();
+ Assert.That(peak.Length, Is.EqualTo(3));
+ var minPeak = peak.MinBy(p => p.Mz);
+ var maxPeak = peak.MaxBy(p => p.Mz);
+
+ Assert.That(minPeak.Mz, Is.EqualTo(spectrum.Range.Minimum));
+ Assert.That(minPeak.Mz, Is.EqualTo(spectrum.FirstX));
+ Assert.That(maxPeak.Mz, Is.EqualTo(spectrum.Range.Maximum));
+ Assert.That(maxPeak.Mz, Is.EqualTo(spectrum.LastX));
+
+ for (int i = 0; i < peak.Length; i++)
+ {
+ double mono = monoisotopicMasses[i];
+ int charge = charges[i];
+ double intensity = intensities[i];
+ double mz = mono.ToMz(charge);
+
+ Assert.That(peak[i].Mz, Is.EqualTo(mz));
+ Assert.That(peak[i].Intensity, Is.EqualTo(intensity));
+ }
+ }
+
+ [Test]
+ public void NeutralMassSpectrum_Constructor_ValidArguments_InitializesCharges()
+ {
+ // Arrange
+ double[,] monoisotopicMassesIntensities = new double[,] { { 100.0, 200.0 }, { 300.0, 400.0 } };
+ int[] charges = new int[] { 1, 2 };
+
+ // Act
+ var spectrum = new NeutralMassSpectrum(monoisotopicMassesIntensities, charges);
+
+ // Assert
+ Assert.AreEqual(charges, spectrum.Charges);
+ }
+
+ [Test]
+ public void NeutralMassSpectrum_Constructor2_InvalidArguments_ThrowsArgumentException()
+ {
+ // Arrange
+ double[,] monoisotopicMassesIntensities = new double[,] { { 100.0, 200.0 }, { 300.0, 400.0 } };
+ int[] charges = new int[] { 1, 2, 3 };
+
+ // Act & Assert
+ Assert.Throws(() => new NeutralMassSpectrum(monoisotopicMassesIntensities, charges));
+ }
}
}
\ No newline at end of file