public bool DiscoverPeak(List <double> mzList, List <double> intensityList, double startMz, double stopMz, out clsPeak peak, bool findFwhm = false, bool findSignalToNoise = false, bool fitPeak = false) { peak = new clsPeak(); var startIndex = PeakIndex.GetNearest(mzList, startMz, 0); var stopIndex = PeakIndex.GetNearest(mzList, stopMz, startIndex); peak.Mz = 0; peak.Intensity = 0; peak.DataIndex = -1; peak.FWHM = 0; peak.SignalToNoise = 0; double maxIntensity = 0; var found = false; for (var i = startIndex; i < stopIndex; i++) { var intensity = intensityList[i]; if (intensity > maxIntensity) { maxIntensity = intensity; peak.Mz = mzList[i]; peak.Intensity = intensity; peak.DataIndex = i; found = true; } } if (found) { if (findFwhm) { peak.FWHM = PeakStatistician.FindFwhm(mzList, intensityList, peak.DataIndex); } if (findSignalToNoise) { peak.SignalToNoise = PeakStatistician.FindSignalToNoise(peak.Intensity, intensityList, peak.DataIndex); } if (fitPeak) { peak.Mz = _peakFit.Fit(peak.DataIndex, mzList, intensityList); } } return(found); }
/// <summary> /// Gets the peak that fits the point at a given index with a Lorentzian fit. /// </summary> /// <param name="index">index of the point in the m/z vectors which is the apex of the peak.</param> /// <param name="mzs">List of raw data of m\zs.</param> /// <param name="intensities">List of raw data of intensities.</param> /// <param name="fwhm"></param> /// <returns>returns the m/z of the peak.</returns> private double LorentzianFit(List <double> mzs, List <double> intensities, int index, double fwhm) { var a = intensities[index]; var vo = mzs[index]; var e = Math.Abs((vo - mzs[index + 1]) / 100); if (index < 1) { return(mzs[index]); } if (index == mzs.Count) { return(mzs[index]); } var lstart = PeakIndex.GetNearest(mzs, vo + fwhm, index) + 1; var lstop = PeakIndex.GetNearest(mzs, vo - fwhm, index) - 1; var currentE = LorentzianLS(mzs, intensities, a, fwhm, vo, lstart, lstop); for (var i = 0; i < 50; i++) { var lastE = currentE; vo = vo + e; currentE = LorentzianLS(mzs, intensities, a, fwhm, vo, lstart, lstop); if (currentE > lastE) { break; } } vo = vo - e; currentE = LorentzianLS(mzs, intensities, a, fwhm, vo, lstart, lstop); for (var i = 0; i < 50; i++) { var lastE = currentE; vo = vo - e; currentE = LorentzianLS(mzs, intensities, a, fwhm, vo, lstart, lstop); if (currentE > lastE) { break; } } vo = vo + e; return(vo); }
public double GetSignalToNoise(List <double> mzList, List <double> intensityList, double peak) { var index = PeakIndex.GetNearest(mzList, peak, 0); return(PeakStatistician.FindSignalToNoise(intensityList[index], intensityList, index)); }
public double GetFWHM(List <double> mzList, List <double> intensityList, double peak) { var index = PeakIndex.GetNearest(mzList, peak, 0); return(PeakStatistician.FindFwhm(mzList, intensityList, index)); }
/// <summary> /// Function discovers peaks in the m/z and intensity vectors supplied within the supplied m/z window. /// </summary> /// <param name="mzList">is the pointer to List of m/z values</param> /// <param name="intensityList">is the pointer to List of intensity values</param> /// <param name="startMz">minimum m/z of the peak.</param> /// <param name="stopMz">maximum m/z of the peak.</param> /// <returns>returns the number of peaks that were found in the vectors.</returns> /// <remarks> /// The function uses <see cref="Engine.PeakProcessing.PeakStatistician.FindFwhm" />, and /// <see cref="Engine.PeakProcessing.PeakStatistician.FindSignalToNoise" /> /// to discover the full width at half maximum and signal to noise values for a peak. The signal to noise of a /// peak is tested against the threshold value before its accepted as a peak. All peaks are used during the process, /// but once generated only those which are above <see cref="_peakIntensityThreshold" /> are tested for peptidicity by /// Deconvolution.HornMassTransform /// </remarks> public int DiscoverPeaks(List <double> mzList, List <double> intensityList, double startMz, double stopMz) { if (intensityList.Count < 1) { return(0); } PeakData.Clear(); var numDataPts = intensityList.Count; double previousPeakMz = 0; double previousPeakIntensity = 0; var previousPeakIndex = -1; var startIndex = PeakIndex.GetNearestBinary(mzList, startMz, 0, numDataPts - 1); var stopIndex = PeakIndex.GetNearestBinary(mzList, stopMz, startIndex, numDataPts - 1); if (startIndex <= 0) { startIndex = 1; } if (stopIndex >= mzList.Count - 2) { stopIndex = mzList.Count - 2; } for (var index = startIndex; index <= stopIndex; index++) { double fwhm = -1; var currentIntensity = intensityList[index]; var lastIntensity = intensityList[index - 1]; var nextIntensity = intensityList[index + 1]; var currentMz = mzList[index]; if (_arePeaksCentroided) { if (currentIntensity >= _peakIntensityThreshold) { var mz = mzList[index]; var signalToNoise = currentIntensity / _peakIntensityThreshold; fwhm = 0.6; PeakData.AddPeak(new clsPeak(mz, currentIntensity, signalToNoise, PeakData.GetNumPeaks(), index, fwhm)); } } else { //three point peak picking. Check if peak is greater than both the previous and next points if (currentIntensity >= lastIntensity && currentIntensity >= nextIntensity && currentIntensity >= _peakIntensityThreshold) { //See if the peak meets the conditions. //The peak data will be found at _transformData.begin()+i+1. double signalToNoise; if (!_isDataThresholded) { signalToNoise = PeakStatistician.FindSignalToNoise(currentIntensity, intensityList, index); } else { signalToNoise = currentIntensity / _backgroundIntensity; } // Run Full-Width Half-Max algorithm to try and squeak out a higher SN if (signalToNoise < _signalToNoiseThreshold) { //double mz = mzList[index]; fwhm = PeakStatistician.FindFwhm(mzList, intensityList, index, signalToNoise); if (fwhm > 0 && fwhm < 0.5) { var ilow = PeakIndex.GetNearestBinary(mzList, currentMz - fwhm, 0, index); var ihigh = PeakIndex.GetNearestBinary(mzList, currentMz + fwhm, index, stopIndex); var lowIntensity = intensityList[ilow]; var highIntensity = intensityList[ihigh]; var sumIntensity = lowIntensity + highIntensity; if (sumIntensity > 0) { signalToNoise = 2.0 * currentIntensity / sumIntensity; } else { signalToNoise = 10; } } } // Found a peak if (signalToNoise >= _signalToNoiseThreshold) { // Find a more accurate m/z location of the peak. var fittedPeak = _peakFit.Fit(index, mzList, intensityList); if (fwhm.Equals(-1)) { fwhm = PeakStatistician.FindFwhm(mzList, intensityList, index, signalToNoise); } var incremented = false; if (fwhm > 0) { // Compare this peak to the previous peak // If within PeakMergeTolerancePPM then only keep one of the peaks //System.Console.WriteLine("{0}\t{1}\t{2}", fittedPeak, currentIntensity, signalToNoise); var addPeak = true; if (previousPeakIndex > -1) { var deltaPPM = (fittedPeak - previousPeakMz) / (previousPeakMz / 1E6); if (deltaPPM <= PeakMergeTolerancePPM) { // Compare this peak's intensity to the previous peak if (currentIntensity > previousPeakIntensity) { // Remove the most recently added peak PeakData.RemoveLastPeak(); } else { addPeak = false; } } } if (addPeak) { previousPeakMz = fittedPeak; previousPeakIntensity = currentIntensity; previousPeakIndex = PeakData.GetNumPeaks(); PeakData.AddPeak(new clsPeak(fittedPeak, currentIntensity, signalToNoise, PeakData.GetNumPeaks(), index, fwhm)); } // move beyond peaks have the same intensity. while (index < numDataPts && intensityList[index].Equals(currentIntensity)) { incremented = true; index++; } } if (index > 0 && index < numDataPts && incremented) { index--; } } } } } PeakData.MzList = mzList; PeakData.IntensityList = intensityList; return(PeakData.GetNumPeaks()); }
/// <summary> /// Finds the highest peak from the raw data lists withing the specified m/z range. /// </summary> /// <param name="startMz">minimum m\z at which to look for the peak</param> /// <param name="stopMz">maximum m\z at which to look for the peak.</param> /// <param name="peak"> instance whose mz and intensity are set to the peak that is found.</param> /// <remarks>The function only sets the mz, intensity of the peak, not the other members (SN, FWHM etc).</remarks> public void FindPeak(double startMz, double stopMz, out clsPeak peak) { peak = new clsPeak(); peak.Mz = -1; var width = (stopMz - startMz) / 2; var foundExistingPeak = GetClosestPeak(startMz + width, width, out peak); if (foundExistingPeak) { // peak already exists. Send it back. } else { // peak doesn't exist. Lets find a starting index to start looking at. // perhaps there was a peak there. var foundPeak = GetClosestPeakFromAll(startMz + width, width, out peak); var numPts = MzList.Count; if (foundPeak) { var index = peak.DataIndex; while (index > 0 && MzList[index] >= startMz) { var intensity = IntensityList[index]; var mz = MzList[index]; if (intensity > peak.Intensity && mz <= stopMz) { peak.Mz = mz; peak.Intensity = intensity; peak.DataIndex = index; } index--; } index = peak.DataIndex; while (index < numPts && MzList[index] <= stopMz) { var intensity = IntensityList[index]; if (intensity > peak.Intensity) { var mz = MzList[index]; peak.Mz = mz; peak.Intensity = intensity; peak.DataIndex = index; } index++; } if (peak.Intensity <= 0) { peak.Mz = 0; } } else { var startIndex = PeakIndex.GetNearestBinary(MzList, startMz, 0, numPts - 1); if (startIndex > numPts - 1) { startIndex = numPts - 1; } if (startIndex < 0) { startIndex = 0; } if (MzList[startIndex] > startMz) { while (startIndex > 0 && MzList[startIndex] > startMz) { startIndex--; } } else { while (startIndex < numPts && MzList[startIndex] < startMz) { startIndex++; } startIndex--; } for (var i = startIndex; i < numPts; i++) { var mz = MzList[i]; var intensity = IntensityList[i]; if (mz > stopMz) { break; } if (intensity > peak.Intensity) { peak.Mz = mz; peak.Intensity = intensity; peak.DataIndex = i; } } } } }