Skip to content

Commit

Permalink
Added support for negative mode deconvolution (#723)
Browse files Browse the repository at this point in the history
* Added support for negative mode deconvolution

* Changed name of ExampleNewDeconvolution to include the word Template

---------

Co-authored-by: trishorts <[email protected]>
  • Loading branch information
nbollis and trishorts authored Aug 4, 2023
1 parent c07ad54 commit 40dc604
Show file tree
Hide file tree
Showing 14 changed files with 318 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,16 @@ public override IEnumerable<IsotopicEnvelope> Deconvolute(MzSpectrum spectrumToD
1.1) //if we're past a Th spacing, we're no longer looking at the closest isotope
{
//get the lower bound charge state
int charge =
(int)Math.Floor(1 /
deltaMass); //e.g. deltaMass = 0.4 Th, charge is now 2 (but might be 3)
int charge = 0;
if (deconParams.Polarity == Polarity.Negative)
{
charge = (int)Math.Floor(-1 / deltaMass); //e.g. deltaMass = 0.4 Th, charge is now 2 (but might be 3)
}
else
{
charge = (int)Math.Floor(1 / deltaMass); //e.g. deltaMass = 0.4 Th, charge is now 2 (but might be 3)
}

if (charge >= deconParams.MinAssumedChargeState && charge <= deconParams.MaxAssumedChargeState)
{
allPossibleChargeStates.Add(charge);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@
namespace MassSpectrometry
{
[ExcludeFromCodeCoverage]
public class ExampleNewDeconvolutionAlgorithm : DeconvolutionAlgorithm
public class ExampleNewDeconvolutionAlgorithmTemplate : DeconvolutionAlgorithm
{
public ExampleNewDeconvolutionAlgorithm(DeconvolutionParameters deconParameters) : base(deconParameters)
public ExampleNewDeconvolutionAlgorithmTemplate(DeconvolutionParameters deconParameters) : base(deconParameters)
{

}

public override IEnumerable<IsotopicEnvelope> Deconvolute(MzSpectrum spectrum, MzRange range = null)
{
var deconParams = DeconvolutionParameters as ExampleNewDeconvolutionParameters ?? throw new MzLibException("Deconvolution params and algorithm do not match");
var deconParams = DeconvolutionParameters as ExampleNewDeconvolutionParametersTemplate ?? throw new MzLibException("Deconvolution params and algorithm do not match");
range ??= spectrum.Range;

throw new NotImplementedException();
Expand Down
8 changes: 4 additions & 4 deletions mzLib/MassSpectrometry/Deconvolution/Deconvoluter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace MassSpectrometry
public enum DeconvolutionType
{
ClassicDeconvolution,
AlexDeconvolution,
ExampleNewDeconvolutionTemplate,
}

/// <summary>
Expand Down Expand Up @@ -46,7 +46,7 @@ public IEnumerable<IsotopicEnvelope> Deconvolute(MsDataScan scan, MzRange rangeT
case DeconvolutionType.ClassicDeconvolution:
break;

case DeconvolutionType.AlexDeconvolution:
case DeconvolutionType.ExampleNewDeconvolutionTemplate:
break;
}

Expand All @@ -69,8 +69,8 @@ private void ConstructDeconvolutionAlgorithm(DeconvolutionParameters deconParame
DeconvolutionAlgorithm = new ClassicDeconvolutionAlgorithm(deconParameters);
break;

case DeconvolutionType.AlexDeconvolution:
DeconvolutionAlgorithm = new ExampleNewDeconvolutionAlgorithm(deconParameters);
case DeconvolutionType.ExampleNewDeconvolutionTemplate:
DeconvolutionAlgorithm = new ExampleNewDeconvolutionAlgorithmTemplate(deconParameters);
break;

default: throw new MzLibException("DeconvolutionType not yet supported");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static class DeconvoluterExtensions
/// </summary>
/// <param name="deconvoluter">performs deconvolution</param>
/// <param name="spectrum">spectrum to deconvolute</param>
/// <param name="range">mz range of returned peaks</param>
/// <param name="range">mz range of returned peaks, if null will deconvolute entire spectrum</param>
/// <returns></returns>
/// <exception cref="MzLibException"></exception>
public static IEnumerable<IsotopicEnvelope> Deconvolute(this Deconvoluter deconvoluter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ namespace MassSpectrometry
/// </summary>
public class ClassicDeconvolutionParameters : DeconvolutionParameters
{
public int MinAssumedChargeState { get; set; }
public int MaxAssumedChargeState { get; set; }
public double DeconvolutionTolerancePpm { get; set; }
public double IntensityRatioLimit { get; set; }

Expand All @@ -25,12 +23,11 @@ public class ClassicDeconvolutionParameters : DeconvolutionParameters
/// <param name="deconPpm"></param>
/// <param name="intensityRatio"></param>
/// <param name="range">Isolation range of the scan to be deconvoluted</param>
public ClassicDeconvolutionParameters(int minCharge, int maxCharge, double deconPpm, double intensityRatio) : base()
public ClassicDeconvolutionParameters(int minCharge, int maxCharge, double deconPpm, double intensityRatio, Polarity polarity = Polarity.Positive)
: base(minCharge, maxCharge, polarity)
{
IntensityRatioLimit = intensityRatio;
DeconvolutionTolerancePpm = deconPpm;
MinAssumedChargeState = minCharge;
MaxAssumedChargeState = maxCharge;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,20 @@ namespace MassSpectrometry
/// </summary>
public abstract class DeconvolutionParameters
{
public int MinAssumedChargeState { get; set; }
public int MaxAssumedChargeState { get; set; }
public Polarity Polarity { get; set; }

/// <summary>
/// Constructor should initialize all fields that are used by every deconvolution algorithm
/// </summary>
public DeconvolutionParameters()
public DeconvolutionParameters(int minCharge, int maxCharge, Polarity polarity = Polarity.Positive)
{

MinAssumedChargeState = minCharge;
MaxAssumedChargeState = maxCharge;
Polarity = polarity;
}
}
}


This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MassSpectrometry
{
[ExcludeFromCodeCoverage]
public class ExampleNewDeconvolutionParametersTemplate : DeconvolutionParameters
{
public ExampleNewDeconvolutionParametersTemplate(int minCharge, int maxCharge, Polarity polarity = Polarity.Positive)
: base(minCharge, maxCharge, polarity)
{

}
}
}
7 changes: 4 additions & 3 deletions mzLib/MassSpectrometry/MzSpectra/IsotopicEnvelope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Chemistry;

namespace MassSpectrometry
{
public class IsotopicEnvelope
public class IsotopicEnvelope : IHasMass
{
public readonly List<(double mz, double intensity)> Peaks;
public double MonoisotopicMass { get; private set; }
Expand Down Expand Up @@ -35,7 +36,7 @@ public IsotopicEnvelope(List<(double mz, double intensity)> bestListOfPeaks, dou

public double GetMostAbundantObservedIsotopicMass(List<(double mz, double intensity)> peaks, int charge)
{
return peaks.MaxBy(p => p.intensity).mz * charge;
return peaks.MaxBy(p => p.intensity).mz * Math.Abs(charge);
}

public override string ToString()
Expand All @@ -46,7 +47,7 @@ public override string ToString()
private double ScoreIsotopeEnvelope() //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(Charge, 0.06) :
TotalIntensity / Math.Pow(StDev, 0.13) * Math.Pow(Peaks.Count, 0.4) / Math.Pow(Math.Abs(Charge), 0.06) :
0;
}

Expand Down
229 changes: 229 additions & 0 deletions mzLib/Test/DataFiles/GUACUG_NegativeMode_Sliced.mzML

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions mzLib/Test/Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,9 @@
<None Update="DataFiles\BinGenerationTest.mzML">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DataFiles\GUACUG_NegativeMode_Sliced.mzML">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="FileReadingTests\ExternalFileTypes\Ms1Feature_FlashDeconvOpenMs3.0.0_ms1.feature">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
Expand Down
30 changes: 30 additions & 0 deletions mzLib/Test/TestDeconvolution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,5 +191,35 @@ public static void CheckClassicGetMostAbundantObservedIsotopicMass(string peptid
}

#endregion

[Test]
[TestCase(373.85, -5, 1874.28)] // GUAGUC -5
[TestCase(467.57, -4, 1874.28)] // GUAGUC -4
[TestCase(623.75, -3, 1874.28)] // GUAGUC -3
[TestCase(936.13, -2, 1874.28)] // GUAGUC -2
[TestCase(473.05, -4, 1896.26)] // GUAGUC +Na -H -4
[TestCase(631.07, -3, 1896.26)] // GUAGUC +Na -H -3
[TestCase(947.121, -2, 1896.26)] // GUAGUC +Na -H -2
public void TestNegativeModeClassicDeconvolution(double expectedMz, int expectedCharge, double expectedMonoMass)
{
// get scan
string filePath = Path.Combine(TestContext.CurrentContext.TestDirectory, "DataFiles",
"GUACUG_NegativeMode_Sliced.mzML");
var scan = MsDataFileReader.GetDataFile(filePath).GetAllScansList().First();
var tolerance = new PpmTolerance(20);

// set up deconvolution
DeconvolutionParameters deconParams = new ClassicDeconvolutionParameters(-10, -1, 20, 3, Polarity.Negative);
Deconvoluter deconvoluter = new(DeconvolutionType.ClassicDeconvolution, deconParams);

List<IsotopicEnvelope> deconvolutionResults = deconvoluter.Deconvolute(scan).ToList();
// ensure each expected result is found, with correct mz, charge, and monoisotopic mass
var resultsWithPeakOfInterest = deconvolutionResults.FirstOrDefault(envelope =>
envelope.Peaks.Any(peak => tolerance.Within(peak.mz, expectedMz)));
if (resultsWithPeakOfInterest is null) Assert.Fail();

Assert.That(tolerance.Within(expectedMonoMass, resultsWithPeakOfInterest.MonoisotopicMass));
Assert.That(expectedCharge, Is.EqualTo(resultsWithPeakOfInterest.Charge));
}
}
}
4 changes: 2 additions & 2 deletions mzLib/mzLib.sln
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ Global
{04615EBF-20FC-437C-9CF7-47DA6260FAE3}.Debug|x64.ActiveCfg = Debug|x64
{04615EBF-20FC-437C-9CF7-47DA6260FAE3}.Debug|x64.Build.0 = Debug|x64
{04615EBF-20FC-437C-9CF7-47DA6260FAE3}.Release|x64.ActiveCfg = Release|x64
{04615EBF-20FC-437C-9CF7-47DA6260FAE3}.TestAndRelease|x64.ActiveCfg = Release|Any CPU
{04615EBF-20FC-437C-9CF7-47DA6260FAE3}.TestAndRelease|x64.Build.0 = Release|Any CPU
{04615EBF-20FC-437C-9CF7-47DA6260FAE3}.TestAndRelease|x64.ActiveCfg = Release|x64
{04615EBF-20FC-437C-9CF7-47DA6260FAE3}.TestAndRelease|x64.Build.0 = Release|x64
{E27A5C14-0C05-466A-91CE-ABB5151A69C4}.Debug|x64.ActiveCfg = Debug|x64
{E27A5C14-0C05-466A-91CE-ABB5151A69C4}.Debug|x64.Build.0 = Debug|x64
{E27A5C14-0C05-466A-91CE-ABB5151A69C4}.Release|x64.ActiveCfg = Release|x64
Expand Down
1 change: 1 addition & 0 deletions mzLib/mzLib.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Deconvolute/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=deconvoluted/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Deconvoluter/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Monoisotopic/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Winsorize/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Winsorized/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

0 comments on commit 40dc604

Please sign in to comment.