示例#1
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="peaks"></param>
        /// <param name="scanNum"></param>
        public DeconvolutedSpectrum(ICollection <DeconvolutedPeak> peaks, int scanNum) : base(scanNum)
        {
            var dPeaks = new DeconvolutedPeak[peaks.Count];

            peaks.CopyTo(dPeaks, 0);
            Peaks = dPeaks;
        }
示例#2
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="originalSpec"></param>
        /// <param name="peaks"></param>
        public DeconvolutedSpectrum(Spectrum originalSpec, DeconvolutedPeak[] peaks)
            : base(originalSpec.ScanNum)
        {
            MsLevel         = originalSpec.MsLevel;
            NativeId        = originalSpec.NativeId;
            ElutionTime     = originalSpec.ElutionTime;
            TotalIonCurrent = originalSpec.TotalIonCurrent;

            var ms2Spec = originalSpec as ProductSpectrum;

            if (ms2Spec == null)
            {
                ActivationMethod = ActivationMethod.Unknown;
            }
            else
            {
                ActivationMethod = ms2Spec.ActivationMethod;
                IsolationWindow  = new IsolationWindow(ms2Spec.IsolationWindow.IsolationWindowTargetMz, ms2Spec.IsolationWindow.IsolationWindowLowerOffset, ms2Spec.IsolationWindow.IsolationWindowUpperOffset, ms2Spec.IsolationWindow.MonoisotopicMz, ms2Spec.IsolationWindow.Charge);
            }

            var dPeaks = new DeconvolutedPeak[peaks.Length];

            peaks.CopyTo(dPeaks, 0);
            Peaks = dPeaks;
        }
 private void UpdateDeconvPeak(int binNum, DeconvolutedPeak newPeak)
 {
     if (newPeak == null) return;
     DeconvolutedPeak existingPeak;
     if (_massBinToPeakMap.TryGetValue(binNum, out existingPeak))
     {
         if (existingPeak.Intensity < newPeak.Intensity) _massBinToPeakMap[binNum] = newPeak;
     }
     else
     {
         _massBinToPeakMap[binNum] = newPeak;
     }
 }
示例#4
0
        /// <summary>
        /// Find the praks that match the provided composition
        /// </summary>
        /// <param name="fragmentComposition"></param>
        /// <param name="corrThreshold"></param>
        /// <param name="distThreshold"></param>
        /// <returns></returns>
        protected IEnumerable <DeconvolutedPeak> FindMatchedPeaks(Composition fragmentComposition,
                                                                  double corrThreshold, double distThreshold)
        {
            var mostAbundantIsotopeIndex = fragmentComposition.GetMostAbundantIsotopeZeroBasedIndex();
            var fragmentIonMass          = fragmentComposition.Mass;

            //var matchedPeak = new MatchedFragmentPeak();
            //var deconvPeak = new DeconvolutedPeak()
            if (fragmentIonMass < Ms2Spectrum.Peaks.First().Mz)
            {
                yield break;
            }

            var prevObservedCharge     = 0;
            var fragmentIonMostAbuMass = fragmentIonMass + Constants.C13MinusC12 * mostAbundantIsotopeIndex;
            var chargeRange            = GetMinMaxChargeRange(fragmentIonMostAbuMass);

            for (var charge = chargeRange.Min; charge <= chargeRange.Max; charge++)
            {
                var ion = new Ion(fragmentComposition, charge);

                var observedPeaks = Ms2Spectrum.GetAllIsotopePeaks(ion, Tolerance, RelativeIsotopeIntensityThreshold);
                if (observedPeaks == null)
                {
                    if (prevObservedCharge > 0 && charge - prevObservedCharge > 1)
                    {
                        yield break;
                    }
                    continue;
                }

                var distCorr = GetDistCorr(ion, observedPeaks);
                if (distCorr.Item2 < corrThreshold && distCorr.Item1 > distThreshold)
                {
                    if (prevObservedCharge > 0 && charge - prevObservedCharge > 1)
                    {
                        yield break;
                    }
                    continue;
                }
                var matchedPeak = new DeconvolutedPeak(fragmentIonMass, observedPeaks[mostAbundantIsotopeIndex].Intensity, charge, distCorr.Item2, distCorr.Item1, observedPeaks);
                prevObservedCharge = charge;

                yield return(matchedPeak);
            }
        }
示例#5
0
        /// <summary>
        /// Store the peaks in the Peaks, assuring that each peak is an instance of DeconvolutedPeak
        /// </summary>
        /// <param name="peaks"></param>
        private void StorePeaks(IReadOnlyList <DeconvolutedPeak> peaks)
        {
            var dPeaks = new DeconvolutedPeak[peaks.Count];

            for (var i = 0; i < peaks.Count; i++)
            {
                dPeaks[i] = peaks[i];
            }

            // Store the deconvoluted peaks in Peaks
            // ReSharper disable once CoVariantArrayConversion
            Peaks = new DeconvolutedPeak[dPeaks.Length];

            for (var i = 0; i < dPeaks.Length; i++)
            {
                Peaks[i] = dPeaks[i];
            }
        }
示例#6
0
        public DeconvolutedSpectrum(Spectrum originalSpec, DeconvolutedPeak[] peaks)
            : base(originalSpec.ScanNum)
        {
            Peaks = new DeconvolutedPeak[peaks.Length];
            peaks.CopyTo(Peaks, 0);
            MsLevel = originalSpec.MsLevel;

            var ms2Spec = originalSpec as ProductSpectrum;

            if (ms2Spec == null)
            {
                ActivationMethod = ActivationMethod.Unknown;
            }
            else
            {
                ActivationMethod = ms2Spec.ActivationMethod;
            }
            MsLevel = originalSpec.MsLevel;
        }
示例#7
0
        public DeconvolutedSpectrum(Spectrum originalSpec, DeconvolutedPeak[] peaks)
            : base(originalSpec.ScanNum)
        {
            Peaks = new DeconvolutedPeak[peaks.Length];
            peaks.CopyTo(Peaks, 0);
            MsLevel = originalSpec.MsLevel;

            var ms2Spec = originalSpec as ProductSpectrum;

            if (ms2Spec == null)
            {
                ActivationMethod = ActivationMethod.Unknown;
            }
            else
            {
                ActivationMethod = ms2Spec.ActivationMethod;
            }
            MsLevel = originalSpec.MsLevel;
        }
示例#8
0
        /// <summary>
        /// Find a neutral monoisotopic peak corrsponding to a single compound/
        /// </summary>
        /// <param name="composition">The compound to look for.</param>
        /// <param name="tolerance">The peak tolerance to use.</param>
        /// <returns>The neutral monoisotopic peak.</returns>
        public DeconvolutedPeak FindPeak(Composition.Composition composition, Tolerance tolerance)
        {
            double           mass             = composition.Mass;
            DeconvolutedPeak deconvolutedPeak = null;
            double           maxIntensity     = 0.0;

            for (int charge = this.minCharge; charge <= this.maxCharge; charge++)
            {
                var ion          = new Ion(composition, charge);
                var isotopePeaks = this.spectrum.GetAllIsotopePeaks(ion, tolerance);
                var intensity    = isotopePeaks.Max(peak => peak.Intensity);
                var corrCos      = this.GetCorrCos(ion, isotopePeaks);
                if (intensity > maxIntensity)
                {
                    deconvolutedPeak = new DeconvolutedPeak(mass, intensity, charge, corrCos.Item1, corrCos.Item2, isotopePeaks);
                }
            }

            return(deconvolutedPeak);
        }
示例#9
0
        protected IEnumerable<DeconvolutedPeak> FindMatchedPeaks(Composition.Composition fragmentComposition,
                   double corrThreshold, double distThreshold)
        {
            var mostAbundantIsotopeIndex = fragmentComposition.GetMostAbundantIsotopeZeroBasedIndex();
            var fragmentIonMass = fragmentComposition.Mass;

            //var matchedPeak = new MatchedFragmentPeak();
            //var deconvPeak = new DeconvolutedPeak()
            if (fragmentIonMass < Ms2Spectrum.Peaks.First().Mz) yield break;

            var prevObservedCharge = 0;
            var fragmentIonMostAbuMass = fragmentIonMass + Constants.C13MinusC12 * mostAbundantIsotopeIndex;
            var chargeRange = GetMinMaxChargeRange(fragmentIonMostAbuMass);

            for (var charge = chargeRange.Min; charge <= chargeRange.Max; charge++)
            {
                var ion = new Ion(fragmentComposition, charge);

                var observedPeaks = Ms2Spectrum.GetAllIsotopePeaks(ion, Tolerance, RelativeIsotopeIntensityThreshold);
                if (observedPeaks == null)
                {
                    if (prevObservedCharge > 0 && charge - prevObservedCharge > 1) yield break;
                    continue;
                }

                var distCorr = GetDistCorr(ion, observedPeaks);
                if (distCorr.Item2 < corrThreshold && distCorr.Item1 > distThreshold)
                {
                    if (prevObservedCharge > 0 && charge - prevObservedCharge > 1) yield break;
                    continue;
                }
                var matchedPeak = new DeconvolutedPeak(fragmentIonMass, observedPeaks[mostAbundantIsotopeIndex].Intensity, charge, distCorr.Item2, distCorr.Item1, observedPeaks);
                prevObservedCharge = charge;

                yield return matchedPeak;
            }
        }
示例#10
0
 public double GetNodeScoreWithoutMassError(ActivationMethod activationMethod, bool isPrefix, DeconvolutedPeak matchedPeak, double refIntensity)
 {
     return GetNodeScoreWithoutMassError(activationMethod, isPrefix, matchedPeak.Mass, matchedPeak.Charge, matchedPeak.Corr, matchedPeak.Dist, matchedPeak.Intensity / refIntensity);
 }
示例#11
0
 public double GetNodeScore(ActivationMethod activationMethod, bool isPrefix, double fragmentIonMass, DeconvolutedPeak matchedPeak, double refIntensity)
 {
     var massErrorPpm = 1e6 * ((matchedPeak.Mass - fragmentIonMass) / fragmentIonMass);
     return GetNodeScore(activationMethod, isPrefix, fragmentIonMass, matchedPeak.Charge, matchedPeak.Corr, matchedPeak.Dist, matchedPeak.Intensity / refIntensity, massErrorPpm);   
 }
示例#12
0
        // Select the best peak within +/- filteringWindowSize
        public static List<DeconvolutedPeak> GetDeconvolutedPeaks(
            Peak[] peaks, int minCharge, int maxCharge, 
            int isotopeOffsetTolerance, double filteringWindowSize,
            Tolerance tolerance, double corrScoreThreshold)
        {

            var monoIsotopePeakList = new List<DeconvolutedPeak>();
            for (var peakIndex = 0; peakIndex < peaks.Length; peakIndex++)
            {
                var peak = peaks[peakIndex];

                // Check whether peak has the maximum intensity within the window
                var isBest = true;

                var prevIndex = peakIndex - 1;
                while (prevIndex >= 0)
                {
                    var prevPeak = peaks[prevIndex];
                    if ((peak.Mz - prevPeak.Mz) > filteringWindowSize) break;
                    if (prevPeak.Intensity > peak.Intensity)
                    {
                        isBest = false;
                        break;
                    }
                    prevIndex--;
                }

                if (!isBest) continue;

                var nextIndex = peakIndex + 1;
                while (nextIndex < peaks.Length)
                {
                    var nextPeak = peaks[nextIndex];
                    if ((nextPeak.Mz - peak.Mz) > filteringWindowSize) break;
                    if (nextPeak.Intensity > peak.Intensity)
                    {
                        isBest = false;
                        break;
                    }
                    nextIndex++;
                }

                if (!isBest) continue;

                // peak has the maximum intensity, window = [prevIndex+1,nextIndex-1]

                var window = new Peak[nextIndex - prevIndex - 1];
                Array.Copy(peaks, prevIndex + 1, window, 0, window.Length);
                var windowSpectrum = new Spectrum(window, 1);
                var peakMz = peak.Mz;

                for (var charge = maxCharge; charge >= minCharge; charge--)
                {
                    var mass = peak.Mz * charge;
                    var mostAbundantIsotopeIndex = Averagine.GetIsotopomerEnvelope(mass).MostAbundantIsotopeIndex;

                    for (var isotopeIndex = mostAbundantIsotopeIndex - isotopeOffsetTolerance; isotopeIndex <= mostAbundantIsotopeIndex + isotopeOffsetTolerance; isotopeIndex++)
                    {
                        var monoIsotopeMass = Ion.GetMonoIsotopicMass(peakMz, charge, isotopeIndex);
                        var isotopomerEnvelope = Averagine.GetIsotopomerEnvelope(monoIsotopeMass);
                        var observedPeaks = windowSpectrum.GetAllIsotopePeaks(monoIsotopeMass, charge, isotopomerEnvelope, tolerance, 0.1);
                        if (observedPeaks == null) continue;

                        var envelop = isotopomerEnvelope.Envolope;
                        var observedIntensities = new double[observedPeaks.Length];

                        for (var i = 0; i < observedPeaks.Length; i++)
                        {
                            var observedPeak = observedPeaks[i];
                            observedIntensities[i] = observedPeak != null ? (float)observedPeak.Intensity : 0.0;
                        }

                        var sim = FitScoreCalculator.GetDistanceAndCorrelation(envelop, observedIntensities);
                        var bcDist = sim.Item1;
                        var corr = sim.Item2;

                        if (corr < corrScoreThreshold && bcDist > 0.03) continue;

                        // monoIsotopeMass is valid
                        var deconvPeak = new DeconvolutedPeak(monoIsotopeMass, observedIntensities[mostAbundantIsotopeIndex], charge, corr, bcDist, observedPeaks);
                        monoIsotopePeakList.Add(deconvPeak);
                    }
                }
            }

            monoIsotopePeakList.Sort();
            return monoIsotopePeakList;
        }
示例#13
0
        /// <summary>
        /// Get the deconvoluted peaks, selecting the best peak within +/- filteringWindowSize
        /// </summary>
        /// <param name="scanNum">Scan number (included in any exceptions that are caught)</param>
        /// <param name="peaks"></param>
        /// <param name="minCharge"></param>
        /// <param name="maxCharge"></param>
        /// <param name="isotopeOffsetTolerance"></param>
        /// <param name="filteringWindowSize"></param>
        /// <param name="tolerance"></param>
        /// <param name="corrScoreThreshold"></param>
        /// <returns></returns>
        public static List <DeconvolutedPeak> GetDeconvolutedPeaks(
            int scanNum, Peak[] peaks,
            int minCharge, int maxCharge,
            int isotopeOffsetTolerance, double filteringWindowSize,
            Tolerance tolerance, double corrScoreThreshold)
        {
            try
            {
                var monoIsotopePeakList = new List <DeconvolutedPeak>();
                for (var peakIndex = 0; peakIndex < peaks.Length; peakIndex++)
                {
                    var peak = peaks[peakIndex];

                    // Check whether peak has the maximum intensity within the window
                    var isBest = true;

                    var prevIndex = peakIndex - 1;
                    while (prevIndex >= 0)
                    {
                        var prevPeak = peaks[prevIndex];
                        if ((peak.Mz - prevPeak.Mz) > filteringWindowSize)
                        {
                            break;
                        }
                        if (prevPeak.Intensity > peak.Intensity)
                        {
                            isBest = false;
                            break;
                        }
                        prevIndex--;
                    }

                    if (!isBest)
                    {
                        continue;
                    }

                    var nextIndex = peakIndex + 1;
                    while (nextIndex < peaks.Length)
                    {
                        var nextPeak = peaks[nextIndex];
                        if ((nextPeak.Mz - peak.Mz) > filteringWindowSize)
                        {
                            break;
                        }
                        if (nextPeak.Intensity > peak.Intensity)
                        {
                            isBest = false;
                            break;
                        }
                        nextIndex++;
                    }

                    if (!isBest)
                    {
                        continue;
                    }

                    // peak has the maximum intensity, window = [prevIndex+1,nextIndex-1]

                    var window = new Peak[nextIndex - prevIndex - 1];
                    Array.Copy(peaks, prevIndex + 1, window, 0, window.Length);
                    var windowSpectrum = new Spectrum(window, 1);
                    var peakMz         = peak.Mz;

                    //var bestScore = 0.0;
                    //DeconvolutedPeak bestPeak = null;

                    for (var charge = maxCharge; charge >= minCharge; charge--)
                    {
                        var mass = (peak.Mz * charge) - charge * Constants.Proton;
                        //var isotopomerEnvelope = Averagine.GetIsotopomerEnvelope(mass);
                        //var mostAbundantIsotopeIndex = isotopomerEnvelope.MostAbundantIsotopeIndex;
                        var mostAbundantIsotopeIndex = Averagine.GetIsotopomerEnvelope(mass).MostAbundantIsotopeIndex;

                        for (var isotopeIndex = mostAbundantIsotopeIndex - isotopeOffsetTolerance; isotopeIndex <= mostAbundantIsotopeIndex + isotopeOffsetTolerance; isotopeIndex++)
                        {
                            var monoIsotopeMass    = Ion.GetMonoIsotopicMass(peakMz, charge, isotopeIndex);
                            var isotopomerEnvelope = Averagine.GetIsotopomerEnvelope(monoIsotopeMass);
                            var observedPeaks      = windowSpectrum.GetAllIsotopePeaks(monoIsotopeMass, charge, isotopomerEnvelope, tolerance, 0.1);
                            if (observedPeaks == null)
                            {
                                continue;
                            }

                            var envelop             = isotopomerEnvelope.Envelope;
                            var observedIntensities = new double[observedPeaks.Length];

                            for (var i = 0; i < observedPeaks.Length; i++)
                            {
                                var observedPeak = observedPeaks[i];
                                observedIntensities[i] = observedPeak != null ? (float)observedPeak.Intensity : 0.0;
                            }

                            var sim    = FitScoreCalculator.GetDistanceAndCorrelation(envelop, observedIntensities);
                            var bcDist = sim.Item1;
                            var corr   = sim.Item2;
                            //var score = corr / (bcDist * ((double)Math.Abs(isotopeIndex - mostAbundantIsotopeIndex) / envelop.Length));

                            if (corr < corrScoreThreshold && bcDist > 0.03)
                            {
                                continue;
                            }

                            // monoIsotopeMass is valid
                            //if (score >= bestScore)
                            //{
                            //    bestScore = score;
                            //    bestPeak = new DeconvolutedPeak(monoIsotopeMass, observedIntensities[mostAbundantIsotopeIndex], charge, corr, bcDist, observedPeaks);
                            //}
                            var deconvPeak = new DeconvolutedPeak(monoIsotopeMass, observedIntensities[mostAbundantIsotopeIndex], charge, corr, bcDist, observedPeaks);
                            monoIsotopePeakList.Add(deconvPeak);
                        }
                    }

                    //if (bestPeak != null)
                    //{
                    //    monoIsotopePeakList.Add(bestPeak);
                    //}
                }

                monoIsotopePeakList.Sort();
                return(monoIsotopePeakList);
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Error getting deconvoluted peaks for scan {0} in GetDeconvolutedPeaks: {1}", scanNum, ex.Message), ex);
            }
        }
示例#14
0
        /// <summary>
        /// Get the deconvoluted peaks that correspond to the provided peak list
        /// </summary>
        /// <param name="peaks"></param>
        /// <param name="minCharge"></param>
        /// <param name="maxCharge"></param>
        /// <param name="isotopeOffsetTolerance"></param>
        /// <param name="tolerance"></param>
        /// <param name="corrScoreThreshold"></param>
        /// <returns></returns>
        public static List <DeconvolutedPeak> GetDeconvolutedPeaks_new(
            Peak[] peaks,
            int minCharge,
            int maxCharge,
            int isotopeOffsetTolerance,
            Tolerance tolerance,
            double corrScoreThreshold)
        {
            var spectrum            = new Spectrum(peaks, 0);
            var monoIsotopePeakList = new List <DeconvolutedPeak>();

            var sortedPeaks = peaks.OrderByDescending(peak => peak.Intensity).ToArray();
            var peakUsed    = new bool[peaks.Length];

            foreach (var peak in sortedPeaks)
            {
                var peakIndex = Array.BinarySearch(peaks, peak);
                if (peakUsed[peakIndex])
                {
                    continue;
                }

                var bestScore = 0.0;
                DeconvolutedPeak    bestPeak          = null;
                Tuple <Peak, int>[] bestObservedPeaks = null;

                for (var charge = minCharge; charge <= maxCharge; charge++)
                {
                    var mass = peak.Mz * charge - (charge * Constants.Proton);
                    if (mass > MaxMass)
                    {
                        continue;
                    }

                    var isotopomerEnvelope       = Averagine.GetIsotopomerEnvelope(mass);
                    var mostAbundantIsotopeIndex = isotopomerEnvelope.MostAbundantIsotopeIndex;
                    var offsetTolerance          = isotopeOffsetTolerance;
                    if (isotopeOffsetTolerance < 0)
                    {
                        offsetTolerance = isotopomerEnvelope.Envelope.Length;
                    }

                    for (var isotopeIndex = mostAbundantIsotopeIndex - offsetTolerance;
                         isotopeIndex <= mostAbundantIsotopeIndex + offsetTolerance;
                         isotopeIndex++)
                    {
                        var monoIsotopeMass = Ion.GetMonoIsotopicMass(peak.Mz, charge, isotopeIndex);

                        var observedPeaks = GetAllIsotopePeaks(spectrum, monoIsotopeMass, charge, isotopomerEnvelope, tolerance, 0.1);
                        if (observedPeaks == null)
                        {
                            continue;
                        }

                        var envelop             = isotopomerEnvelope.Envelope;
                        var observedIntensities = new double[observedPeaks.Length];

                        var observedPeakCount = 0;
                        for (var i = 0; i < observedPeaks.Length; i++)
                        {
                            var observedPeak = observedPeaks[i];
                            if (observedPeak != null && peakUsed[observedPeak.Item2])
                            {
                                observedPeak     = null;
                                observedPeaks[i] = null;
                            }

                            observedPeakCount     += observedPeak != null ? 1 : 0;
                            observedIntensities[i] = observedPeak != null ? (float)observedPeak.Item1.Intensity : 0.0;
                        }

                        var sim            = FitScoreCalculator.GetDistanceAndCorrelation(envelop, observedIntensities);
                        var bcDist         = sim.Item1;
                        var corr           = sim.Item2;
                        var foundPeakRatio = observedPeakCount / ((double)envelop.Length);

                        var interferenceScore = 10.0;

                        var filteredObserved = observedPeaks.Where(p => p != null).ToArray();
                        if (filteredObserved.Length >= 2)
                        {
                            var allPeaks =
                                spectrum.Peaks.Where(p => p.Mz >= filteredObserved[0].Item1.Mz && p.Mz <= filteredObserved[filteredObserved.Length - 1].Item1.Mz).ToArray();
                            interferenceScore = CalculateInterferenceScore(allPeaks, filteredObserved);
                        }

                        bcDist = Math.Max(bcDist, double.Epsilon);

                        if (corr < corrScoreThreshold && bcDist > 0.1)
                        {
                            continue;
                        }

                        var score = (foundPeakRatio * corr) / (bcDist * (Math.Abs(mostAbundantIsotopeIndex - isotopeIndex) + 1) * interferenceScore);

                        //if (corr < corrScoreThreshold) continue;

                        // monoIsotopeMass is valid
                        if (score >= bestScore)
                        {
                            bestScore         = score;
                            bestPeak          = new DeconvolutedPeak(monoIsotopeMass, observedIntensities[mostAbundantIsotopeIndex], charge, corr, bcDist, observedPeaks.Where(p => p != null).Select(p => p.Item1).ToArray());
                            bestObservedPeaks = observedPeaks;
                        }
                    }
                }

                if (bestPeak != null)
                {
                    monoIsotopePeakList.Add(bestPeak);
                    foreach (var p in bestObservedPeaks)
                    {
                        if (p != null)
                        {
                            bestPeak.ObservedPeakIndices.Add(p.Item2);
                            peakUsed[p.Item2] = true;
                        }
                    }
                }
            }

            monoIsotopePeakList.Sort();
            return(monoIsotopePeakList);
        }
示例#15
0
        // Select the best peak within +/- filteringWindowSize
        public static List <DeconvolutedPeak> GetDeconvolutedPeaks(
            Peak[] peaks, int minCharge, int maxCharge,
            int isotopeOffsetTolerance, double filteringWindowSize,
            Tolerance tolerance, double corrScoreThreshold)
        {
            var monoIsotopePeakList = new List <DeconvolutedPeak>();

            for (var peakIndex = 0; peakIndex < peaks.Length; peakIndex++)
            {
                var peak = peaks[peakIndex];

                // Check whether peak has the maximum intensity within the window
                var isBest = true;

                var prevIndex = peakIndex - 1;
                while (prevIndex >= 0)
                {
                    var prevPeak = peaks[prevIndex];
                    if ((peak.Mz - prevPeak.Mz) > filteringWindowSize)
                    {
                        break;
                    }
                    if (prevPeak.Intensity > peak.Intensity)
                    {
                        isBest = false;
                        break;
                    }
                    prevIndex--;
                }

                if (!isBest)
                {
                    continue;
                }

                var nextIndex = peakIndex + 1;
                while (nextIndex < peaks.Length)
                {
                    var nextPeak = peaks[nextIndex];
                    if ((nextPeak.Mz - peak.Mz) > filteringWindowSize)
                    {
                        break;
                    }
                    if (nextPeak.Intensity > peak.Intensity)
                    {
                        isBest = false;
                        break;
                    }
                    nextIndex++;
                }

                if (!isBest)
                {
                    continue;
                }

                // peak has the maximum intensity, window = [prevIndex+1,nextIndex-1]

                var window = new Peak[nextIndex - prevIndex - 1];
                Array.Copy(peaks, prevIndex + 1, window, 0, window.Length);
                var windowSpectrum = new Spectrum(window, 1);
                var peakMz         = peak.Mz;

                for (var charge = maxCharge; charge >= minCharge; charge--)
                {
                    var mass = peak.Mz * charge;
                    var mostAbundantIsotopeIndex = Averagine.GetIsotopomerEnvelope(mass).MostAbundantIsotopeIndex;

                    for (var isotopeIndex = mostAbundantIsotopeIndex - isotopeOffsetTolerance; isotopeIndex <= mostAbundantIsotopeIndex + isotopeOffsetTolerance; isotopeIndex++)
                    {
                        var monoIsotopeMass    = Ion.GetMonoIsotopicMass(peakMz, charge, isotopeIndex);
                        var isotopomerEnvelope = Averagine.GetIsotopomerEnvelope(monoIsotopeMass);
                        var observedPeaks      = windowSpectrum.GetAllIsotopePeaks(monoIsotopeMass, charge, isotopomerEnvelope, tolerance, 0.1);
                        if (observedPeaks == null)
                        {
                            continue;
                        }

                        var envelop             = isotopomerEnvelope.Envolope;
                        var observedIntensities = new double[observedPeaks.Length];

                        for (var i = 0; i < observedPeaks.Length; i++)
                        {
                            var observedPeak = observedPeaks[i];
                            observedIntensities[i] = observedPeak != null ? (float)observedPeak.Intensity : 0.0;
                        }

                        var sim    = FitScoreCalculator.GetDistanceAndCorrelation(envelop, observedIntensities);
                        var bcDist = sim.Item1;
                        var corr   = sim.Item2;

                        if (corr < corrScoreThreshold && bcDist > 0.03)
                        {
                            continue;
                        }

                        // monoIsotopeMass is valid
                        var deconvPeak = new DeconvolutedPeak(monoIsotopeMass, observedIntensities[mostAbundantIsotopeIndex], charge, corr, bcDist, observedPeaks);
                        monoIsotopePeakList.Add(deconvPeak);
                    }
                }
            }

            monoIsotopePeakList.Sort();
            return(monoIsotopePeakList);
        }
 private double GetMatchedIonPeakScore(bool isPrefixIon, DeconvolutedPeak peak)
 {
     var param = (isPrefixIon) ? ScoreParam.Prefix : ScoreParam.Suffix;
     var score = param.Count;
     score += param.Intensity * Math.Min(peak.Intensity / ReferencePeakIntensity, 1.0d);
     score += param.Corr * peak.Corr;
     score += param.Dist * peak.Dist;
     return score;
 }