public bool Overlap(IsoEnvelop other) { if (this.ExistedExperimentPeak.Select(p => p.Mz).Intersect(other.ExistedExperimentPeak.Select(p => p.Mz)).Count() > 0) { return(true); } return(false); }
public static IsoEnvelop MsDeconvExperimentPeak(MzSpectrumXY mzSpectrumXY, int candidateForMostIntensePeak, DeconvolutionParameter deconvolutionParameter, double noiseLevel) { IsoEnvelop bestIsotopeEnvelopeForThisPeak = null; var candidateForMostIntensePeakMz = mzSpectrumXY.XArray[candidateForMostIntensePeak]; //Find possible chargeStates. List <int> allPossibleChargeState = new List <int>(); for (int i = candidateForMostIntensePeak + 1; i < mzSpectrumXY.XArray.Length; i++) { if (mzSpectrumXY.XArray[i] - candidateForMostIntensePeakMz < 1.1) //In case charge is +1 { var chargeDouble = 1.00289 / (mzSpectrumXY.XArray[i] - candidateForMostIntensePeakMz); int charge = Convert.ToInt32(chargeDouble); if (deconvolutionParameter.DeconvolutionAcceptor.Within(candidateForMostIntensePeakMz + 1.00289 / chargeDouble, mzSpectrumXY.XArray[i]) && charge >= deconvolutionParameter.DeconvolutionMinAssumedChargeState && charge <= deconvolutionParameter.DeconvolutionMaxAssumedChargeState && !allPossibleChargeState.Contains(charge)) { allPossibleChargeState.Add(charge); } } else { break; } } foreach (var chargeState in allPossibleChargeState) { List <int> arrayOfTheoPeakIndexes; //Is not used here, is used in ChargeDecon var isoEnvelop = GetETEnvelopForPeakAtChargeState(mzSpectrumXY, candidateForMostIntensePeakMz, chargeState, deconvolutionParameter, noiseLevel, out arrayOfTheoPeakIndexes); if (MsDeconvScore(isoEnvelop) > MsDeconvScore(bestIsotopeEnvelopeForThisPeak)) { var temp = bestIsotopeEnvelopeForThisPeak; bestIsotopeEnvelopeForThisPeak = isoEnvelop; //This is to refine mis charge ones. But not working perfect. if (temp != null && bestIsotopeEnvelopeForThisPeak != null) { int cd = temp.Charge / bestIsotopeEnvelopeForThisPeak.Charge; if (temp.ExperimentIsoEnvelop.Where(p => p.Intensity != 0).Count() >= bestIsotopeEnvelopeForThisPeak.ExperimentIsoEnvelop.Where(p => p.Intensity != 0).Count() + 3 && cd > 1 && temp.Charge == bestIsotopeEnvelopeForThisPeak.Charge * cd) { bestIsotopeEnvelopeForThisPeak = temp; } } } } return(bestIsotopeEnvelopeForThisPeak); }
//MsDeconv Envelop public static double MsDeconvScore(IsoEnvelop isoEnvelop) { if (isoEnvelop == null) { return(0); } double score = 0; for (int i = 0; i < isoEnvelop.TheoIsoEnvelop.Length; i++) { score += MsDeconvScore_peak(isoEnvelop.ExperimentIsoEnvelop[i], isoEnvelop.TheoIsoEnvelop[i]); } isoEnvelop.MsDeconvScore = score; return(score); }
//Kind of similar as a S/N filter. It works for top-down, Not working for bottom-up. private static double CalIsoEnvelopNoise(MzSpectrumXY mzSpectrumXY, IsoEnvelop isoEnvelop) { double intensityInRange = 0; int minInd = isoEnvelop.TheoPeakIndex.Min(); int maxInd = isoEnvelop.TheoPeakIndex.Max(); for (int i = minInd; i <= maxInd; i++) { intensityInRange += mzSpectrumXY.YArray[i]; } //less peak and lower intensity means low ratio. double ratio = (isoEnvelop.TotalIntensity / intensityInRange) * ((double)isoEnvelop.ExperimentIsoEnvelop.Where(p => p.Intensity != 0).Count() / ((double)maxInd - (double)minInd + 1)); return(ratio); }
public static List <IsoEnvelop> MsDeconv_Deconvolute(MzSpectrumXY mzSpectrumXY, MzRange theRange, DeconvolutionParameter deconvolutionParameter) { var isolatedMassesAndCharges = new List <IsoEnvelop>(); if (mzSpectrumXY.Size == 0) { return(isolatedMassesAndCharges); } ////Deconvolution by MZ increasing order //double intensityThread = mzSpectrumXY.TotalIntensity / mzSpectrumXY.Size; for (int candidateForMostIntensePeak = 0; candidateForMostIntensePeak < mzSpectrumXY.XArray.Length - 1; candidateForMostIntensePeak++) { //if (mzSpectrumXY.YArray[candidateForMostIntensePeak] <= intensityThread) //{ // continue; //} double noiseLevel = CalNoiseLevel(); //TO THINK: Only get one isoEnvelop per best peak. It is possible this is a overlap best peak with different charge state. IsoEnvelop bestIsotopeEnvelopeForThisPeak = MsDeconvExperimentPeak(mzSpectrumXY, candidateForMostIntensePeak, deconvolutionParameter, noiseLevel); if (bestIsotopeEnvelopeForThisPeak != null) { bestIsotopeEnvelopeForThisPeak.MsDeconvSignificance = CalIsoEnvelopNoise(mzSpectrumXY, bestIsotopeEnvelopeForThisPeak); bestIsotopeEnvelopeForThisPeak.IntensityRatio = bestIsotopeEnvelopeForThisPeak.TotalIntensity / mzSpectrumXY.TotalIntensity; isolatedMassesAndCharges.Add(bestIsotopeEnvelopeForThisPeak); } } HashSet <double> seen = new HashSet <double>(); //Do we still need this List <IsoEnvelop> isoEnvelops = new List <IsoEnvelop>(); //TO DO: consider peak overlap foreach (var ok in isolatedMassesAndCharges.OrderByDescending(b => b.MsDeconvScore)) { //if (seen.Overlaps(ok.ExperimentIsoEnvelop.Select(b => b.Mz))) //{ // continue; //} int noOverlap = 0; foreach (var ah in ok.ExistedExperimentPeak.Select(b => b.Mz)) { if (!seen.Contains(ah)) { noOverlap++; } } if (noOverlap < 2) { continue; } foreach (var ah in ok.ExperimentIsoEnvelop.Select(b => b.Mz)) { seen.Add(ah); } isoEnvelops.Add(ok); } var orderedIsoEnvelops = isoEnvelops.OrderBy(p => p.ExperimentIsoEnvelop.First().Mz).ToList(); return(orderedIsoEnvelops); }
//Change the workflow for different score method. public static IsoEnvelop GetETEnvelopForPeakAtChargeState(MzSpectrumXY mzSpectrumXY, double candidateForMostIntensePeakMz, int chargeState, DeconvolutionParameter deconvolutionParameter, double noiseLevel, out List <int> arrayOfTheoPeakIndexes) { var testMostIntenseMass = candidateForMostIntensePeakMz.ToMass(chargeState); var massIndex = GetClosestIndexInArray(testMostIntenseMass, mostIntenseMasses).Value; var differenceBetweenTheorAndActual = candidateForMostIntensePeakMz.ToMass(chargeState) - mostIntenseMasses[massIndex]; var theoryIsoEnvelopLength = 0; for (int i = 0; i < allIntensities[massIndex].Length; i++) { theoryIsoEnvelopLength++; if (allIntensities[massIndex][i] / allIntensities[massIndex][0] <= 0.05 && i >= 2) { break; } } var arrayOfPeaks = new MzPeak[theoryIsoEnvelopLength]; var arrayOfTheoPeaks = new MzPeak[theoryIsoEnvelopLength]; arrayOfTheoPeakIndexes = new List <int>(); //For top-down to calculate MsDeconvSignificance for (int indexToLookAt = 0; indexToLookAt < theoryIsoEnvelopLength; indexToLookAt++) { double theorMassThatTryingToFind = allMasses[massIndex][indexToLookAt] + differenceBetweenTheorAndActual; arrayOfTheoPeaks[indexToLookAt] = new MzPeak(theorMassThatTryingToFind.ToMz(chargeState), allIntensities[massIndex][indexToLookAt]); var closestPeakToTheorMassIndex = GetClosestIndexInArray(theorMassThatTryingToFind.ToMz(chargeState), mzSpectrumXY.XArray); var closestPeakmz = mzSpectrumXY.XArray[closestPeakToTheorMassIndex.Value]; var closestPeakIntensity = mzSpectrumXY.YArray[closestPeakToTheorMassIndex.Value]; if (!deconvolutionParameter.DeconvolutionAcceptor.Within(theorMassThatTryingToFind, closestPeakmz.ToMass(chargeState)) || closestPeakIntensity < noiseLevel) { closestPeakmz = theorMassThatTryingToFind.ToMz(chargeState); closestPeakIntensity = 0; } else { //if the peak was matched arrayOfTheoPeakIndexes.Add(closestPeakToTheorMassIndex.Value); } arrayOfPeaks[indexToLookAt] = new MzPeak(closestPeakmz, closestPeakIntensity); } if (FilterEEnvelop(arrayOfPeaks)) { var scaleArrayOfTheoPeaks = ScaleTheoEnvelop(arrayOfPeaks, arrayOfTheoPeaks); //The following 3 lines are for calculating monoisotopicMass, origin from Stephan, I don't understand it, and may optimize it in the future. (Lei) //var extrapolatedMonoisotopicMass = candidateForMostIntensePeakMz.ToMass(chargeState) - diffToMonoisotopic[massIndex]; // Optimized for proteoforms!! //var lowestMass = arrayOfPeaks.Min(b => b.Mz).ToMass(chargeState); // But may actually observe this small peak //var monoisotopicMass = Math.Abs(extrapolatedMonoisotopicMass - lowestMass) < 0.5 ? lowestMass : extrapolatedMonoisotopicMass; var monoisotopicMass = candidateForMostIntensePeakMz.ToMass(chargeState) - diffToMonoisotopic[massIndex]; IsoEnvelop isoEnvelop = new IsoEnvelop(arrayOfPeaks, scaleArrayOfTheoPeaks, monoisotopicMass, chargeState, arrayOfTheoPeakIndexes); return(isoEnvelop); } return(null); }