-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IsoDec Deconvolution Algorithm #791
base: master
Are you sure you want to change the base?
Changes from 15 commits
3d7ebd1
ddd03b5
6720fc5
73df199
50b8d9d
b626f41
7c5132e
fc0f4bb
097b4bd
ba54e46
678dbc3
64d4a4b
6ef4447
1a0bd54
963826b
bc1b6a9
a8bba37
455f3c0
0dd9e52
09cefc7
72d8202
4277814
6c124c5
f049ee4
3c560ee
93e4161
b97a23d
492f7e0
fc32cd2
2e4a772
8ff5883
302a07a
e45fb3f
cf8b6a3
9aa30a8
7cd2639
3db9ab4
788aa81
4bacc61
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Numerics; | ||
using System.Runtime.InteropServices; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using MassSpectrometry.MzSpectra; | ||
using MzLibUtil; | ||
using MathNet.Numerics.Statistics; | ||
using System.Reflection.Metadata.Ecma335; | ||
|
||
namespace MassSpectrometry | ||
{ | ||
public class IsoDecAlgorithm(DeconvolutionParameters deconParameters) | ||
: DeconvolutionAlgorithm(deconParameters) | ||
Check warning on line 17 in mzLib/MassSpectrometry/Deconvolution/Algorithms/IsoDecAlgorithm.cs GitHub Actions / build
Check warning on line 17 in mzLib/MassSpectrometry/Deconvolution/Algorithms/IsoDecAlgorithm.cs GitHub Actions / build
|
||
{ | ||
private static string _phaseModelPath; | ||
static IsoDecAlgorithm() | ||
{ | ||
_phaseModelPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Deconvolution", "Algorithms", "IsoDecResources", "phase_model.bin"); | ||
} | ||
|
||
[StructLayout(LayoutKind.Sequential, Pack =1)] | ||
public struct MatchedPeak | ||
{ | ||
public float mz; | ||
public int z; | ||
public float monoiso; | ||
public float peakmass; | ||
public float avgmass; | ||
public float area; | ||
public float peakint; | ||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] | ||
public float[] matchedindsiso; | ||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] | ||
public float[] matchedindsexp; | ||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] | ||
public float[] isomz; | ||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] | ||
public float[] isodist; | ||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] | ||
public float[] isomass; | ||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] | ||
public float[] monoisos; | ||
int startindex; | ||
int endindex; | ||
public float startmz; | ||
public float endmz; | ||
public float score; | ||
public int realisolength; | ||
} | ||
|
||
public struct IsoSettings | ||
{ | ||
public int phaseres; // Precision of encoding matrix | ||
public int verbose; // Verbose output | ||
public int peakwindow; // Peak Detection Window | ||
public float peakthresh; // Peak Detection Threshold | ||
public int minpeaks; // Minimum Peaks for an allowed peak | ||
public float css_thresh; // Minimum cosine similarity score for isotope distribution | ||
public float matchtol; // Match Tolerance for peak detection in ppm | ||
public int maxshift; // Maximum shift allowed for isotope distribution | ||
[MarshalAs(UnmanagedType.ByValArray, SizeConst =2)] | ||
public float[] mzwindow; // MZ Window for isotope distribution | ||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] | ||
public float[] plusoneintwindow; // Plus One Intensity range. Will be used for charge state 1 | ||
public int knockdown_rounds; // Number of knockdown rounds | ||
public float min_score_diff; // Minimum score difference for isotope distribution to allow missed monoisotopic peaks | ||
public float minareacovered; // Minimum area covered by isotope distribution. Use in or with css_thresh | ||
public int isolength; // Isotope Distribution Length | ||
public double mass_diff_c; // Mass difference between isotopes | ||
public float adductmass; // Adduct Mass | ||
public int minusoneaszero; // Use set the -1 isotope as 0 to help force better alignments | ||
public float isotopethreshold; // Threshold for isotope distribution. Will remove relative intensities below this. | ||
public float datathreshold; // Threshold for data. Will remove relative intensities below this relative to max intensity in each cluster | ||
public float zscore_threshold; //Ratio above which a secondary charge state prediction will be returned. | ||
} | ||
|
||
|
||
|
||
[DllImport("Deconvolution/Algorithms/IsoDecResources/isodeclib.dll", CallingConvention = CallingConvention.Cdecl)] | ||
public static extern int process_spectrum(double[] mz, float[] intensity, int len, string modelpath, IntPtr matchedpeaks, IsoSettings settings); | ||
|
||
public override IEnumerable<IsotopicEnvelope> Deconvolute(MzSpectrum spectrum, MzRange range) | ||
{ | ||
var firstIndex = spectrum.GetClosestPeakIndex(range.Minimum); | ||
var lastIndex = spectrum.GetClosestPeakIndex(range.Maximum); | ||
|
||
var mzs = spectrum.XArray[firstIndex..lastIndex] | ||
.Select(p => p) | ||
.ToArray(); | ||
var intensities = spectrum.YArray[firstIndex..lastIndex] | ||
.Select(p => (float)p) | ||
.ToArray(); | ||
|
||
IntPtr matchedPeaksPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MatchedPeak)) * intensities.Length); | ||
IsoSettings settings = DeconParametersToIsoSettings(deconParameters); | ||
int result = process_spectrum(mzs, intensities, intensities.Length, _phaseModelPath , matchedPeaksPtr, settings); | ||
if(result > 0) | ||
{ | ||
MatchedPeak[] matchedpeaks = new MatchedPeak[result]; | ||
for(int i = 0;i<result;i++) | ||
{ | ||
matchedpeaks[i] = Marshal.PtrToStructure<MatchedPeak>(matchedPeaksPtr + i * Marshal.SizeOf(typeof(MatchedPeak))); | ||
} | ||
return ConvertToIsotopicEnvelopes(matchedpeaks, spectrum); | ||
} | ||
|
||
else return new List<IsotopicEnvelope>(); | ||
} | ||
|
||
private List<IsotopicEnvelope> ConvertToIsotopicEnvelopes(MatchedPeak[] matchedpeaks, MzSpectrum spectrum) | ||
{ | ||
List<IsotopicEnvelope> result = new List<IsotopicEnvelope>(); | ||
foreach(MatchedPeak peak in matchedpeaks) | ||
{ | ||
List<(double,double)> peaks = new List<(double,double)> (); | ||
List<double> listofratios = new List<double>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. better variable name |
||
for (int i = 0; i < peak.realisolength; i++) | ||
{ | ||
|
||
List<int> indicesWithinTolerance = spectrum.GetPeakIndicesWithinTolerance(peak.isomz[i], new PpmTolerance(5)); | ||
double maxIntensity = 0; | ||
int maxIndex = -1; | ||
foreach (int index in indicesWithinTolerance) | ||
{ | ||
if (spectrum.YArray[index] > maxIntensity) { maxIntensity = spectrum.YArray[index]; maxIndex = index; } | ||
} | ||
if (maxIndex >= 0) | ||
{ | ||
listofratios.Add(peak.isodist[i] / spectrum.YArray[maxIndex]); | ||
peaks.Add((spectrum.XArray[maxIndex], spectrum.YArray[maxIndex])); | ||
} | ||
else | ||
{ | ||
listofratios.Add(0); | ||
peaks.Add((peak.isomz[i], 0)); | ||
} | ||
|
||
} | ||
//One of the features of our algorithm is that it reports multiple possible monoisotopics if they score highly enough. | ||
//This should do away with having to allow missed monoisotopics randomly. | ||
foreach (float monoiso in peak.monoisos) | ||
{ | ||
if(monoiso > 0) { result.Add(new IsotopicEnvelope(peaks, (double)monoiso, peak.z, peak.peakint, Statistics.StandardDeviation(listofratios), 0)); } | ||
|
||
} | ||
} | ||
return result; | ||
} | ||
|
||
public IsoSettings DeconParametersToIsoSettings(DeconvolutionParameters parameters) | ||
{ | ||
IsoSettings result = new IsoSettings(); | ||
result.phaseres = 8; | ||
result.verbose = 1; | ||
result.peakwindow = 80; | ||
result.peakthresh = (float)0.0001; | ||
result.minpeaks = 3; | ||
result.css_thresh = (float)0.7; | ||
result.matchtol = 5; | ||
result.maxshift = 3; | ||
result.mzwindow = [(float)-1.05, (float)2.05]; | ||
result.plusoneintwindow = [(float)0.1, (float)0.6]; | ||
result.knockdown_rounds = 5; | ||
result.min_score_diff = (float)0.1; | ||
result.minareacovered = (float)0.15; | ||
result.isolength = 64; | ||
result.mass_diff_c = 1.0033; | ||
//If polarity is positive, adduct is a proton, if negative, it's the loss of a proton. | ||
if(parameters.Polarity == Polarity.Positive) { result.adductmass = (float)1.007276467; } | ||
else { result.adductmass = (float)-1.007276467; } | ||
result.minusoneaszero = 1; | ||
result.isotopethreshold = (float)0.01; | ||
result.datathreshold = (float)0.05; | ||
result.zscore_threshold = (float)0.95; | ||
return result; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace MassSpectrometry | ||
{ | ||
public enum DeconvolutionType | ||
{ | ||
ClassicDeconvolution, | ||
ExampleNewDeconvolutionTemplate, | ||
IsoDecDeconvolution, | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace MassSpectrometry | ||
{ | ||
public class IsoDecDeconvolutionParameters(Polarity polarity = Polarity.Positive) | ||
: DeconvolutionParameters(1, 100, polarity) | ||
{ | ||
public override DeconvolutionType DeconvolutionType { get; protected set; } = DeconvolutionType.IsoDecDeconvolution; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be good to use our standard variable names for these features.