예제 #1
0
        /// <summary>
        /// Returns a 'peak-to-the-left' of the monoisotopic peak if: 1) it exists and 2) it is above the user provided relative intensity
        /// </summary>
        /// <param name="monoPeak"></param>
        /// <param name="chargeState"></param>
        /// <param name="peakList"></param>
        /// <param name="minRelIntensityForFlag"></param>
        /// <returns></returns>
        public MSPeak LookforPeakToTheLeftOfMonoPeak(MSPeak monoPeak, int chargeState, List <Peak> peakList, double minRelIntensityForFlag)
        {
            double mzTol = monoPeak.Width;

            var targetMZ = monoPeak.XValue - (1.003 / (double)chargeState);


            var foundLeftOfMonoPeaks = PeakUtilities.GetPeaksWithinTolerance(peakList, targetMZ, mzTol);

            //if found a peak to the left, will return that peak. If

            if (foundLeftOfMonoPeaks.Count == 0)
            {
                return(null);
            }


            var peakToTheLeft = foundLeftOfMonoPeaks.OrderByDescending(p => p.Height).First() as MSPeak;

            if (peakToTheLeft == null)
            {
                return(null);
            }


            if (peakToTheLeft.Height > monoPeak.Height * MinRatioToGiveFlag)
            {
                return(peakToTheLeft);
            }

            return(null);
        }
예제 #2
0
        private List <Peak> FilterPeaksBasedOnBasePeakList(List <Peak> basePeaklist, List <Peak> inputPeakList)
        {
            var trimmedPeakList = new List <Peak>();

            foreach (var peak in basePeaklist)
            {
                var mzTolerance = _toleranceInPPM * peak.XValue / 1e6;
                var foundPeaks  = PeakUtilities.GetPeaksWithinTolerance(inputPeakList, peak.XValue,
                                                                        mzTolerance);

                if (foundPeaks.Count == 1)
                {
                    trimmedPeakList.Add(foundPeaks.First());
                }
                else if (foundPeaks.Count > 1)
                {
                    trimmedPeakList.Add(foundPeaks.OrderByDescending(p => p.Height).First());
                }
            }

            //if we can't find any observed peaks, we won't trim anything. Just return the original list
            if (!trimmedPeakList.Any())
            {
                return(basePeaklist);
            }
            return(trimmedPeakList);
        }
예제 #3
0
        public void FindPeaksWithinTolerance_highMZRangeTest()
        {
            List <IPeak> peakList = TestUtilities.GeneratePeakList(new ScanSet(6005));

            List <IPeak> filteredList = PeakUtilities.GetPeaksWithinTolerance(peakList, 1500, 100);

            Assert.AreEqual(809, peakList.Count);

            TestUtilities.DisplayPeaks(filteredList);

            Assert.AreEqual(115, filteredList.Count);
        }
예제 #4
0
        private void GetIsotopicProfilePeaks(List <Peak> peakList, int chargeState, double monoMass, ref IsotopicProfile inputProfile)
        {
            double toleranceInPPM = 20;
            var    tff            = new BasicTFF(toleranceInPPM);

            var theorProfile = new IsotopicProfile();

            theorProfile.MonoIsotopicMass = monoMass;
            theorProfile.ChargeState      = chargeState;
            theorProfile.MonoPeakMZ       = monoMass / chargeState + Globals.PROTON_MASS;

            //a hack to guess how many peaks to include in the theor isotopic profile
            int numPeaksToIncludeInProfile = (int)Math.Round(Math.Max(3, 3 + (monoMass - 1000) / 1000));

            double monoPeakMZ = monoMass / chargeState + Globals.PROTON_MASS;

            for (int i = 0; i < numPeaksToIncludeInProfile; i++)
            {
                var peak = new MSPeak();
                peak.XValue = monoPeakMZ + i * Globals.MASS_DIFF_BETWEEN_ISOTOPICPEAKS / chargeState;

                if (i == 0)
                {
                    peak.Height = 1;
                }
                else
                {
                    peak.Height = 0;
                }


                theorProfile.Peaklist.Add(peak);
            }

            var foundIso = tff.FindMSFeature(peakList, theorProfile);

            if (foundIso == null)
            {
                var monoPeak = PeakUtilities.GetPeaksWithinTolerance(peakList, monoPeakMZ, toleranceInPPM).OrderByDescending(p => p.Height).FirstOrDefault();


                if (monoPeak != null)
                {
                    inputProfile.Peaklist.Add((MSPeak)monoPeak);
                }
            }
            else
            {
                inputProfile.Peaklist = new List <MSPeak>(foundIso.Peaklist);
            }
        }
예제 #5
0
        /// <summary>
        /// Calculates mass error based on the theoretical most intense peak.
        /// </summary>
        /// <returns> This returns the mass error between a theoretical and observed peak.  Nota bene the is MASS, not m/z
        /// If no peak is detected, we return the mass error 999999.  This should be interpreted as a null value.</returns>
        protected double TheorMostIntensePeakMassError(IsotopicProfile theoreticalIso, IsotopicProfile observedIso, int chargeState)
        {
            var theoreticalMostIntensePeak = theoreticalIso.getMostIntensePeak();

            //find peak in obs data
            var mzTolerance = WorkflowParameters.MSToleranceInPPM * theoreticalMostIntensePeak.XValue / 1e6;
            var foundPeaks  = PeakUtilities.GetPeaksWithinTolerance(new List <Peak>(observedIso.Peaklist), theoreticalMostIntensePeak.XValue, mzTolerance);

            if (foundPeaks.Count == 0)
            {
                return(999999);
            }

            var obsXValue = foundPeaks.OrderByDescending(p => p.Height).First().XValue; //order the peaks and take the first (most intense) one.

            return((theoreticalMostIntensePeak.XValue * chargeState) - (obsXValue * chargeState));
        }
예제 #6
0
        private List <Peak> ApplySmartTrimming(List <Peak> theorPeakList, List <Peak> massSpectrumPeakList)
        {
            var trimmedPeakList = new List <Peak>();

            foreach (var peak in theorPeakList)
            {
                var mzTolerance = _toleranceInPPM * peak.XValue / 1e6;
                var foundPeaks  = PeakUtilities.GetPeaksWithinTolerance(massSpectrumPeakList, peak.XValue,
                                                                        mzTolerance);
                if (foundPeaks.Any())
                {
                    trimmedPeakList.Add(peak);
                }
            }

            //if we can't find any observed peaks, we won't trim anything. Just return the original list
            if (!trimmedPeakList.Any())
            {
                return(theorPeakList);
            }
            return(trimmedPeakList);
        }
예제 #7
0
        public double GetFit(
            List <Peak> theorPeakList,
            List <Peak> observedPeakList,
            double minIntensityForScore,
            double toleranceInPPM,
            int numPeaksToTheLeftForScoring,
            out int ionCountUsed)
        {
            Utilities.IqLogger.IqLogger.LogTrace("Min Intensity For Scoring: " + minIntensityForScore);
            Utilities.IqLogger.IqLogger.LogTrace("PPM Tolerance: " + toleranceInPPM);

            ionCountUsed = 0;
            var theorIntensitiesUsedInCalc    = new List <double>();
            var observedIntensitiesUsedInCalc = new List <double>();

            //first gather all the intensities from theor and obs peaks

            var maxTheorIntensity = double.MinValue;

            foreach (var peak in theorPeakList)
            {
                if (peak.Height > maxTheorIntensity)
                {
                    maxTheorIntensity = peak.Height;
                }
            }

            for (var index = 0; index < theorPeakList.Count; index++)
            {
                var peak = theorPeakList[index];

                var overrideMinIntensityCutoff = index < numPeaksToTheLeftForScoring;

                if (peak.Height > minIntensityForScore || overrideMinIntensityCutoff)
                {
                    theorIntensitiesUsedInCalc.Add(peak.Height);

                    Utilities.IqLogger.IqLogger.LogTrace("Theoretical Peak Selected!	Peak Height: "+ peak.Height + " Peak X-Value: " + peak.XValue);

                    //find peak in obs data
                    var mzTolerance = toleranceInPPM * peak.XValue / 1e6;
                    var foundPeaks  = PeakUtilities.GetPeaksWithinTolerance(observedPeakList, peak.XValue, mzTolerance);

                    double obsIntensity;
                    if (foundPeaks.Count == 0)
                    {
                        Utilities.IqLogger.IqLogger.LogTrace("No Observed Peaks Found Within Tolerance");
                        obsIntensity = 0;
                    }
                    else if (foundPeaks.Count == 1)
                    {
                        obsIntensity = foundPeaks.First().Height;
                        Utilities.IqLogger.IqLogger.LogTrace("Observed Peak Selected!	Peak Height: "+ foundPeaks[0].Height + " Peak X-Value " + foundPeaks[0].XValue);
                    }
                    else
                    {
                        obsIntensity = foundPeaks.OrderByDescending(p => p.Height).First().Height;
                        Utilities.IqLogger.IqLogger.LogTrace("Observed Peak Selected!	Peak Height: "+ foundPeaks[0].Height + " Peak X-Value " + foundPeaks[0].XValue);
                    }

                    observedIntensitiesUsedInCalc.Add(obsIntensity);
                }
                else
                {
                    Utilities.IqLogger.IqLogger.LogTrace("Theoretical Peak Not Selected!	Peak Height: "+ peak.Height + " Peak X-Value: " + peak.XValue);
                }
            }

            //the minIntensityForScore is too high and no theor peaks qualified. This is bad. But we don't
            //want to throw errors here
            if (theorIntensitiesUsedInCalc.Count == 0)
            {
                Utilities.IqLogger.IqLogger.LogTrace("No peaks meet minIntensityForScore.");
                return(1.0);
            }

            var maxObs = observedIntensitiesUsedInCalc.Max();

            if (Math.Abs(maxObs) < float.Epsilon)
            {
                maxObs = double.PositiveInfinity;
            }
            Utilities.IqLogger.IqLogger.LogTrace("Max Observed Intensity: " + maxObs);

            var normalizedObs = observedIntensitiesUsedInCalc.Select(p => p / maxObs).ToList();

            var maxTheor        = theorIntensitiesUsedInCalc.Max();
            var normalizedTheor = theorIntensitiesUsedInCalc.Select(p => p / maxTheor).ToList();

            Utilities.IqLogger.IqLogger.LogTrace("Max Theoretical Intensity: " + maxTheor);

            //foreach (var val in normalizedObs)
            //{
            //    Console.WriteLine(val);
            //}

            //Console.WriteLine();
            //foreach (var val in normalizedTheor)
            //{
            //    Console.WriteLine(val);
            //}

            double sumSquareOfDiffs = 0;
            double sumSquareOfTheor = 0;

            for (var i = 0; i < normalizedTheor.Count; i++)
            {
                var diff = normalizedObs[i] - normalizedTheor[i];

                sumSquareOfDiffs += (diff * diff);
                sumSquareOfTheor += (normalizedTheor[i] * normalizedTheor[i]);

                Utilities.IqLogger.IqLogger.LogTrace("Normalized Observed: " + normalizedObs[i]);
                Utilities.IqLogger.IqLogger.LogTrace("Normalized Theoretical: " + normalizedTheor[i]);
                Utilities.IqLogger.IqLogger.LogTrace("Iterator: " + i + " Sum of Squares Differences: " + sumSquareOfDiffs + " Sum of Squares Theoretical: " + sumSquareOfTheor);
            }

            ionCountUsed = normalizedTheor.Count;

            var fitScore = sumSquareOfDiffs / sumSquareOfTheor;

            if (double.IsNaN(fitScore) || fitScore > 1)
            {
                fitScore = 1;
            }
            else
            {
                // Future possibility (considered in January 2014):
                // Normalize the fit score by the number of theoretical ions
                // fitScore /= ionCountUsed;
            }

            Utilities.IqLogger.IqLogger.LogTrace("Fit Score: " + fitScore);
            return(fitScore);
        }
예제 #8
0
        public virtual IsotopicProfile FindMSFeature(List <Peak> peakList, IsotopicProfile theorFeature)
        {
            Check.Require(theorFeature != null, "Theoretical feature hasn't been defined.");
            if (theorFeature == null)
            {
                return(null);
            }

            Check.Require(theorFeature.Peaklist != null && theorFeature.Peaklist.Count > 0, "Theoretical feature hasn't been defined.");

            var outFeature = new IsotopicProfile
            {
                ChargeState = theorFeature.ChargeState
            };

            var indexOfMaxTheorPeak = theorFeature.GetIndexOfMostIntensePeak();

            var toleranceInMZ = theorFeature.getMonoPeak().XValue *ToleranceInPPM / 1e6;

            var    foundMatchingMaxPeak = false;
            double massDefect           = 0; // this is the m/z diff between the max peak of theor feature and the max peak of the experimental feature

            var failedResult = false;

            for (var i = indexOfMaxTheorPeak; i >= 0; i--)
            {
                //find experimental peak(s) within range
                var peaksWithinTol = PeakUtilities.GetPeaksWithinTolerance(peakList, theorFeature.Peaklist[i].XValue, toleranceInMZ);

                if (i == indexOfMaxTheorPeak)
                {
                    foundMatchingMaxPeak = peaksWithinTol.Count > 0;
                }

                if (!foundMatchingMaxPeak)   // can't even find the observed peak that matches the most intense theor peak.
                {
                    failedResult = true;
                    break;
                }

                if (peaksWithinTol.Count == 0)
                {
                    if (NeedMonoIsotopicPeak)
                    {
                        //here, we are looking to the left of most intense theor peak.  If we have the prerequisite of finding the monoIsotopic peak and fail here, we'll return a failed result
                        failedResult = true;
                    }
                    break;  // stop looking to the left of the most intense peak.
                }

                if (peaksWithinTol.Count == 1)
                {
                    if (outFeature.Peaklist.Count == 0)
                    {
                        outFeature.Peaklist.Add((MSPeak)peaksWithinTol[0]);
                    }
                    else
                    {
                        outFeature.Peaklist.Insert(0, (MSPeak)peaksWithinTol[0]);
                    }
                }
                else    // when we have several peaks within tolerance, we'll need to decide what to do
                {
                    MSPeak bestPeak;
                    if (i == indexOfMaxTheorPeak)   //when matching to most intense peak, we will use the most intense peak
                    {
                        bestPeak = (MSPeak)findMostIntensePeak(peaksWithinTol);
                    }
                    else
                    {
                        bestPeak = (MSPeak)findClosestToXValue(peaksWithinTol, theorFeature.Peaklist[i].XValue - massDefect);
                    }

                    if (outFeature.Peaklist.Count == 0)
                    {
                        outFeature.Peaklist.Add(bestPeak);
                    }
                    else
                    {
                        outFeature.Peaklist.Insert(0, bestPeak);
                    }
                }

                if (i == indexOfMaxTheorPeak)   //when matching to most intense peak, we will get the mass defect using the most intense peak
                {
                    massDefect = theorFeature.Peaklist[i].XValue - outFeature.Peaklist[0].XValue;
                }
            }

            //------------------------- look right -------------------------------------------
            for (var i = indexOfMaxTheorPeak + 1; i < theorFeature.Peaklist.Count; i++)     //start one peak to the right of the max intense theor peak
            {
                var peaksWithinTol = PeakUtilities.GetPeaksWithinTolerance(peakList, theorFeature.Peaklist[i].XValue, toleranceInMZ);
                if (peaksWithinTol.Count == 0)
                {
                    if (i == indexOfMaxTheorPeak + 1)  // first peak to the right of the max peak.  We need this one or we declare it to be a failure (= null)
                    {
                        failedResult = true;
                    }
                    break;    // finished.  Exit loop.
                }

                if (peaksWithinTol.Count == 1)
                {
                    outFeature.Peaklist.Add((MSPeak)peaksWithinTol[0]); //here, we tack peaks onto the profile
                }
                else                                                    //two or more peaks are within tolerance. Need to get the best one, which is based on the distance from the
                {
                    outFeature.Peaklist.Add((MSPeak)findClosestToXValue(peaksWithinTol, theorFeature.Peaklist[i].XValue - massDefect));
                }
            }

            //for higher mass peptides, we will return the profile if there is 2 or more peaks, regardless if none are found to the right of the most abundant
            if (indexOfMaxTheorPeak > 0 && outFeature.Peaklist.Count > 1)
            {
                failedResult = false;
            }

            if (failedResult)
            {
                return(null);   // return a null Isotopic profile, indicating a failed result
            }

            addMassInfoToIsotopicProfile(theorFeature, outFeature);
            return(outFeature);
        }
        public static int GetChargeState(XYData rawData, List <Peak> peakList, MSPeak peak)
        {
            //look in rawData to the left (-0.1) and right (+1.1) of peak
            var minus = 0.1;
            var plus  = 1.1;

            double fwhm = peak.Width;

            var leftIndex  = MathUtils.GetClosest(rawData.Xvalues, peak.XValue - fwhm - minus);
            var rightIndex = MathUtils.GetClosest(rawData.Xvalues, peak.XValue + fwhm + plus);

            var filteredXYData = getFilteredXYData(rawData, leftIndex, rightIndex);
            var minMZ          = filteredXYData.Xvalues[0];
            var maxMZ          = filteredXYData.Xvalues[filteredXYData.Xvalues.Length - 1];

            double sumOfDiffsBetweenValues = 0;
            double pointCounter            = 0;

            for (var i = 0; i < filteredXYData.Xvalues.Length - 1; i++)
            {
                var y1 = filteredXYData.Yvalues[i];
                var y2 = filteredXYData.Yvalues[i + 1];

                if (y1 > 0 && y2 > 0)
                {
                    var x1 = filteredXYData.Xvalues[i];
                    var x2 = filteredXYData.Xvalues[i + 1];

                    sumOfDiffsBetweenValues += (x2 - x1);
                    pointCounter++;
                }
            }

            int numL;

            if (pointCounter > 5)
            {
                var averageDiffBetweenPoints = sumOfDiffsBetweenValues / pointCounter;

                numL = (int)Math.Ceiling((maxMZ - minMZ) / averageDiffBetweenPoints);

                numL = (int)(numL + numL * 0.1);
                //numL = 445;
            }
            else
            {
                var numPoints = rightIndex - leftIndex + 1;

                var desiredNumPoints = 256;

                var pointMultiplier = (int)Math.Ceiling(desiredNumPoints / (double)numPoints);

                if (numPoints < 5)
                {
                    return(-1);
                }

                if (numPoints < desiredNumPoints)
                {
                    pointMultiplier = Math.Max(5, pointMultiplier);
                    numL            = pointMultiplier * numPoints;
                }
                else
                {
                    numL = numPoints;
                }
            }

            //Console.WriteLine("Number of points in interpolated data= " + numL);

            var interpolationFunction = new alglib.spline1d.spline1dinterpolant();

            var sw = new System.Diagnostics.Stopwatch();

            sw.Start();

            alglib.spline1d.spline1dbuildcubic(
                filteredXYData.Xvalues, filteredXYData.Yvalues, filteredXYData.Xvalues.Length,
                1, +1, 1, -1, interpolationFunction);

            sw.Stop();
            //Console.WriteLine("spline time = " + sw.ElapsedMilliseconds);

            // DisplayXYVals(filteredXYData);

            var evenlySpacedXYData = new XYData
            {
                Xvalues = new double[numL],
                Yvalues = new double[numL]
            };

            for (var i = 0; i < numL; i++)
            {
                var xVal = (minMZ + ((maxMZ - minMZ) * i) / numL);
                var yVal = alglib.spline1d.spline1dcalc(interpolationFunction, xVal);

                evenlySpacedXYData.Xvalues[i] = xVal;
                evenlySpacedXYData.Yvalues[i] = yVal;
            }

            //Console.WriteLine();
            //DisplayXYVals(evenlySpacedXYData);

            var autoCorrScores = ACss(evenlySpacedXYData.Yvalues);

            //var tempXYData = new XYData
            //{
            //    Xvalues = autoCorrScores,
            //    Yvalues = autoCorrScores
            //};

            // DisplayXYVals(tempXYData);

            var startingIndex = 0;

            while (startingIndex < numL - 1 && autoCorrScores[startingIndex] > autoCorrScores[startingIndex + 1])
            {
                startingIndex++;
            }

            double bestAutoCorrScore = -1;
            var    bestChargeState   = -1;

            GetHighestChargeStatePeak(minMZ, maxMZ, startingIndex, autoCorrScores, MaxCharge, ref bestAutoCorrScore, ref bestChargeState);

            if (bestChargeState == -1)
            {
                return(-1);
            }

            var returnChargeStateVal = -1;

            var chargeStateList = new List <int>();

            GenerateChargeStateData(minMZ, maxMZ, startingIndex, autoCorrScores, MaxCharge, bestAutoCorrScore, chargeStateList);

            for (var i = 0; i < chargeStateList.Count; i++)
            {
                var tempChargeState = chargeStateList[i];
                var skip            = false;
                for (var j = 0; j < i; j++)
                {
                    if (chargeStateList[j] == tempChargeState)
                    {
                        skip = true;
                        break;
                    }
                }

                if (skip)
                {
                    continue;
                }

                if (tempChargeState > 0)
                {
                    var anotherPeak = peak.XValue + (1.003d / tempChargeState);

                    var foundPeak = PeakUtilities.GetPeaksWithinTolerance(peakList, anotherPeak, peak.Width).Count > 0;
                    if (foundPeak)
                    {
                        returnChargeStateVal = tempChargeState;
                        if (peak.XValue * tempChargeState < 3000)
                        {
                            break;
                        }

                        return(tempChargeState);
                    }
                }
            }

            return(returnChargeStateVal);

            //StringBuilder sb = new StringBuilder();
            //foreach (var item in chargeStatesAndScores)
            //{
            //    sb.Append(item.Key + "\t" + item.Value + "\n");

            //}
            //Console.WriteLine(sb.ToString());

            //StringBuilder sb = new StringBuilder();
            //foreach (var item in autoCorrScores)
            //{
            //    sb.Append(item);
            //    sb.Append(Environment.NewLine);

            //}
            //Console.WriteLine(sb.ToString());

            //then extract AutoCorrelation scores (ACss)

            //determine highest charge state peak (?)
        }
예제 #10
0
        public void AppendO16O18PeakInfo(List <Peak> peakList, List <IsosResult> resultList)
        {
            //iterate over each ms feature
            foreach (var isosResult in resultList)
            {
                if (!(isosResult is O16O18IsosResult msFeature))
                {
                    continue;
                }

                if (msFeature.IsotopicProfile == null)
                {
                    continue;
                }

                var monoMZ = msFeature.IsotopicProfile.GetMZ();

                var mzMinusDaltons   = monoMZ - (MASS_UNIT_BETWEEN_ISO * 4 / msFeature.IsotopicProfile.ChargeState);
                var mzPlusDaltons    = monoMZ + (MASS_UNIT_BETWEEN_ISO * 4 / msFeature.IsotopicProfile.ChargeState);
                var mzPlusTwoDaltons = monoMZ + (MASS_UNIT_BETWEEN_ISO * 2 / msFeature.IsotopicProfile.ChargeState);

                double toleranceInPPM = 50;

                var toleranceInMZ = toleranceInPPM * monoMZ / 1e6;

                var minusPeaksWithinTol          = PeakUtilities.GetPeaksWithinTolerance(peakList, mzMinusDaltons, toleranceInMZ);
                var plusPeaksWithinTol           = PeakUtilities.GetPeaksWithinTolerance(peakList, mzPlusDaltons, toleranceInMZ);
                var twoDaltonsPlusPeaksWithinTol = PeakUtilities.GetPeaksWithinTolerance(peakList, mzPlusTwoDaltons, toleranceInMZ);

                var fourDaltonsMinusPeak = GetBestPeak(minusPeaksWithinTol, mzMinusDaltons);
                var fourDaltonsPlusPeak  = GetBestPeak(plusPeaksWithinTol, mzPlusDaltons);

                var twoDaltonsPlusPeak = GetBestPeak(twoDaltonsPlusPeaksWithinTol, mzPlusTwoDaltons);

                if (fourDaltonsMinusPeak != null)
                {
                    msFeature.MonoMinus4Abundance = fourDaltonsMinusPeak.Height;
                }
                else
                {
                    msFeature.MonoMinus4Abundance = 0;
                }

                if (fourDaltonsPlusPeak != null)
                {
                    msFeature.MonoPlus4Abundance = fourDaltonsPlusPeak.Height;
                }
                else
                {
                    msFeature.MonoPlus4Abundance = 0;
                }

                if (twoDaltonsPlusPeak != null)
                {
                    msFeature.MonoPlus2Abundance = twoDaltonsPlusPeak.Height;
                }
                else
                {
                    msFeature.MonoPlus2Abundance = 0;
                }
            }
        }