/// <summary> /// Adds a peak to the processing list. /// </summary> /// <param name="pk">is the peak that we want to add to our processing list.</param> /// <remarks> /// The processing list is really the set of /// peaks that are unprocessed and the way these are tracked, are by puttting these indices in the processing maps /// <see cref="_peakIntensityToIndexDict" /> and <see cref="_peakMzToIndexDict" /> /// </remarks> public void AddPeakToProcessingList(clsPeak pk) { // The assumption is that this peak already exists in the List. // The peak was removed from the processing list, so we're going to add it in. // The map for all peaks is unaffected so we won't add to it. // Also the intensity is set to 0 when deletion happens. So lets copy // the peak back into our peak vector. var peakIndex = pk.PeakIndex; var mz = pk.Mz; var intensity = (int)pk.Intensity; PeakTops[peakIndex] = new clsPeak(pk); _peakMzToIndexDict.Add(mz, peakIndex); //mmap_pk_intensity_index.insert(std.pair<int,int> (intensity, peak_index)); if (_peakIntensityToIndexDict.ContainsKey(intensity)) { _peakIntensityToIndexDict[intensity].Add(peakIndex); } else { _peakIntensityToIndexDict.Add(intensity, new List <int> { peakIndex }); } }
public bool GetPeakFromAllOriginalIntensity(double startMz, double stopMz, out clsPeak peak, double excludeMass) { peak = new clsPeak(); peak.Intensity = -10; var found = false; foreach (var item in _allPeakMzToIndexDict.Where(x => x.Key >= startMz)) { var peakIndex = item.Value; var mzVal = item.Key; if (mzVal.Equals(excludeMass)) { continue; } if (mzVal > stopMz) { return(found); } var dataIndex = PeakTops[peakIndex].DataIndex; if (IntensityList[dataIndex] >= peak.Intensity && mzVal >= startMz) { //double thisMz = PeakTops[peakIndex].Mz; peak = new clsPeak(PeakTops[peakIndex]); found = true; } } return(found); }
/// <summary> /// Get the most intense unprocessed peak in the given m/z range and remove it from the processing list. /// </summary> /// <param name="startMz">minimum m/z of the peak.</param> /// <param name="stopMz">maximum m/z of the peak.</param> /// <param name="peak">is assigned the most intense peak with m/z between the startMz and stopMz.</param> /// <returns>returns true if a peak was found and false if none was found.</returns> /// <remarks> /// The peak that is returned by this function is removed from the processing list. This is essentially the /// function that is called repeatedly in the deconvolution process which deisotopes peaks in order of decreasing /// intensity. /// </remarks> public bool GetNextPeak(double startMz, double stopMz, out clsPeak peak) { peak = new clsPeak(); peak.Mz = -1; peak.Intensity = -1; var found = false; foreach (var indexList in _peakIntensityToIndexDict) { foreach (var peakIndex in indexList.Value) { var mz = PeakTops[peakIndex].Mz; if (mz > startMz && mz <= stopMz) { peak = new clsPeak(PeakTops[peakIndex]); found = true; break; } } if (found) { break; } } if (found) { RemovePeak(peak); } return(found); }
public double GetClosestPeakMzFast(double peakMz, ref clsPeak selectedPeak) { var min_score = 1.00727638; clsPeak thisPeak; double score; selectedPeak.Mz = 0.0; try { var high = PeakData.PeakTops.Count; var low = 0; var mid = (low + high) / 2; var peakFound = false; while (low <= high && !peakFound) { mid = (low + high) / 2; thisPeak = new clsPeak(PeakData.PeakTops[mid]); score = (peakMz - thisPeak.Mz) * (peakMz - thisPeak.Mz); if (score <= min_score) { //we've found a peak that gives a score lower than what we expect. //Instead of redividing, maybe we proceed sequentially from here on //and stop when we get a score that's higher than our current score selectedPeak = thisPeak; min_score = score; peakFound = true; //keep going lower till the score improves, there is no point in going //to the right while (score <= min_score && (mid - 1) >= 0) { thisPeak = new clsPeak(PeakData.PeakTops[mid - 1]); score = (peakMz - thisPeak.Mz) * (peakMz - thisPeak.Mz); if (score < min_score) { selectedPeak = thisPeak; min_score = score; mid -= 1; peakFound = true; } else { break; } } } else if (score > min_score) { high = mid - 1; } } } catch (Exception) { } return(selectedPeak.Mz); }
public Peak(clsPeak pk) { FWHM = pk.FWHM; Intensity = pk.Intensity; Mz = pk.Mz; SignalToNoise = pk.SignalToNoise; DataIndex = pk.DataIndex; PeakIndex = pk.PeakIndex; }
/// <summary> /// Finds the highest peak from the raw data vectors withing the specified m/z range (reduced from original FindPeak /// </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 FindPeakAbsolute(double startMz, double stopMz, out clsPeak peak) { // Anoop : modified from original FindPEak so as to return peaks only // and not shoulders, eliminates all the +ve Da DelM regions peak = new clsPeak(); peak.Mz = -1; peak.Intensity = 0; 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; } } } }
/// <summary> /// Gets the peak in <see cref="PeakTops" /> whose m/z is exactly equal to mz. /// </summary> /// <param name="mz">m/z of the peak we are looking for.</param> /// <param name="peak">the peak whose m/z equals input parameter.</param> /// <returns>true is the peak was found; false otherwise</returns> public bool GetPeak(double mz, out clsPeak peak) { peak = new clsPeak(); if (_peakMzToIndexDict.ContainsKey(mz)) { var peakIndex = _peakMzToIndexDict[mz]; peak = new clsPeak(PeakTops[peakIndex]); return(true); } return(false); }
/// <summary> /// Removes the peak from the unprocessed list. /// </summary> /// <param name="peak">is the peak we want to remove from the unprocessed peaks.</param> /// <remarks> /// In order to remove the peak from the processing "list", we clear the indices of the peak from the unprocessed /// maps <see cref="_peakMzToIndexDict" /> and <see cref="_peakIntensityToIndexDict" /> /// </remarks> public void RemovePeak(clsPeak peak) { if (peak == null) { return; } var found = false; if (_peakIntensityToIndexDict.ContainsKey((int)peak.Intensity)) { var indexList = _peakIntensityToIndexDict[(int)peak.Intensity]; found = indexList.Remove(peak.PeakIndex); if (indexList.Count == 0) { _peakIntensityToIndexDict.Remove((int)peak.Intensity); } } if (!found) { return; } found = false; if (_peakMzToIndexDict.ContainsKey(peak.Mz)) { if (_peakMzToIndexDict[peak.Mz] == peak.PeakIndex) { _peakMzToIndexDict.Remove(peak.Mz); found = true; } } else { var items = _peakMzToIndexDict.Where(x => x.Value == peak.PeakIndex).ToList(); foreach (var item in items) { if (peak.Mz.Equals(item.Key)) { _peakMzToIndexDict.Remove(item.Key); found = true; } } } if (!found) { // so how did this happen ? return; } PeakTops[peak.PeakIndex].Intensity = -1; }
/// <summary> /// calculates the fit score between the theoretical distribution stored and the observed data. Normalizes the observed /// intensity by specified intensity. /// </summary> /// <param name="peakData"> variable which stores the data itself</param> /// <param name="chargeState"> charge state at which we want to compute the peak.</param> /// <param name="peak"> peak for which we want to compute the fit function.</param> /// <param name="mzDelta">specifies the mass delta between theoretical and observed m/z with the best fit so far.</param> /// <param name="minIntensityForScore">minimum intensity for score</param> /// <param name="pointsUsed">number of points used</param> /// <param name="debug">debug output flag</param> public override double FitScore(PeakData peakData, int chargeState, clsPeak peak, double mzDelta, double minIntensityForScore, out int pointsUsed, bool debug = false) { pointsUsed = 0; var numPoints = TheoreticalDistMzs.Count; if (numPoints < 3) { return(1); } if (peak.Intensity <= 0) { return(1); } var maxObservedIntensity = peak.Intensity; if (maxObservedIntensity <= 0) { Console.Error.WriteLine("Peak intensity was <=0 during FitScore. mz = " + peak.Mz + " , intensity = " + peak.Intensity); Environment.Exit(1); } double fit = 0; double sum = 0; for (var pointNum = 0; pointNum < numPoints; pointNum++) { var mz = TheoreticalDistMzs[pointNum] + mzDelta; var theoreticalIntensity = (float)TheoreticalDistIntensities[pointNum]; if (theoreticalIntensity >= minIntensityForScore) { // observed intensities have to be normalized so that the maximum intensity is 100, // like that for theoretical intensities. var observedIntensity = 100 * GetPointIntensity(mz, peakData.MzList, peakData.IntensityList) / maxObservedIntensity; var intensityDiff = observedIntensity - theoreticalIntensity; fit += intensityDiff * intensityDiff; sum += theoreticalIntensity * theoreticalIntensity; pointsUsed++; } } return(fit / (sum + 0.001)); }
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 information for points, required for calculations. /// </summary> /// <param name="peak"> /// The peak found. /// </param> /// <param name="originalList"> /// The original list given to the peak finder. /// </param> /// <param name="smoothedIntensityValues"> /// The smoothed intensity values output by the peak finder. /// </param> /// <param name="precisionUsed"> /// The precision used. /// </param> /// <param name="leftSidePoints"> /// The list to store the left side points. /// </param> /// <param name="rightSidePoints"> /// The list to store the right side points. /// </param> /// <returns> /// The <see> /// <cref>List</cref> /// </see> /// . /// </returns> private static List <PointInformation> ExtractPointInformation( clsPeak peak, IReadOnlyList <KeyValuePair <int, double> > originalList, IReadOnlyList <double> smoothedIntensityValues, int precisionUsed, out List <KeyValuePair <int, double> > leftSidePoints, out List <KeyValuePair <int, double> > rightSidePoints) { var allPoints = new List <PointInformation>(); // build left side leftSidePoints = new List <KeyValuePair <int, double> >(); for (var l = peak.LeftEdge; l < peak.LocationIndex && l < originalList.Count; l++) { leftSidePoints.Add(originalList[l]); allPoints.Add( new PointInformation { Location = (double)originalList[l].Key / precisionUsed, Intensity = originalList[l].Value, SmoothedIntensity = smoothedIntensityValues[l] }); } // build right side rightSidePoints = new List <KeyValuePair <int, double> >(); for (var r = peak.LocationIndex; r < peak.RightEdge && r < originalList.Count; r++) { rightSidePoints.Add(originalList[r]); allPoints.Add( new PointInformation { Location = (double)originalList[r].Key / precisionUsed, Intensity = originalList[r].Value, SmoothedIntensity = smoothedIntensityValues[r] }); } return(allPoints); }
/// <summary> /// Get the most intense unprocessed peak in the given m/z range. /// </summary> /// <param name="startMz">minimum m/z of the peak.</param> /// <param name="stopMz">maximum m/z of the peak.</param> /// <param name="peak">is assigned the most intense Peak with m/z between the startMz and stopMz.</param> /// <returns>returns true if a peak was found and false if none was found.</returns> public bool GetPeak(double startMz, double stopMz, out clsPeak peak) { peak = new clsPeak(); peak.Intensity = -10; var found = false; foreach (var item in _peakMzToIndexDict.Where(x => x.Key >= startMz)) { var peakIndex = item.Value; var mzVal = item.Key; if (mzVal > stopMz) { return(found); } if (PeakTops[peakIndex].Intensity > peak.Intensity && mzVal >= startMz) { peak = new clsPeak(PeakTops[peakIndex]); found = true; } } return(found); }
/// <summary> /// Gets the closest to peakMz among the peak list mzList /// </summary> /// <param name="peakMz"></param> /// <param name="peak"></param> /// <returns></returns> public double GetClosestPeakMz(double peakMz, out clsPeak peak) { //This should be changed to be a binary search, especially for DeconToolsV2 if it's using the same code //I am assuming that the peak list is sorted by mz? //looks through the peak list and finds the closest peak to peakMz var minScore = 1.00727638; //enough for one charge away peak = new clsPeak(); peak.Mz = 0.0; try { var numberPeaks = PeakData.PeakTops.Count; for (var peakCount = 0; peakCount < numberPeaks; peakCount++) { var thisPeak = PeakData.PeakTops[peakCount]; var score = Math.Pow(peakMz - thisPeak.Mz, 2); if (score < minScore) { minScore = score; peak = new clsPeak(thisPeak); } } } catch (Exception) { peak.Mz = 0.0; peak.Intensity = 0.0; #if DEBUG throw; #endif } return(peak.Mz); }
/// <summary> /// calculates the fit score between the theoretical distribution stored and the observed data. Normalizes the observed /// intensity by specified intensity. /// </summary> /// <param name="peakData"> variable which stores the data itself</param> /// <param name="chargeState"> charge state at which we want to compute the peak.</param> /// <param name="peak"> peak for which we want to compute the fit function.</param> /// <param name="mzDelta">specifies the mass delta between theoretical and observed m/z with the best fit so far.</param> /// <param name="minIntensityForScore">minimum intensity for score</param> /// <param name="pointsUsed">number of points used</param> /// <param name="debug">debug output flag</param> public override double FitScore(PeakData peakData, int chargeState, clsPeak peak, double mzDelta, double minIntensityForScore, out int pointsUsed, bool debug = false) { pointsUsed = 0; var numPoints = TheoreticalDistMzs.Count; if (numPoints < 3) { return(1); } double fit = 0; double sum = 0; for (var pointNum = 0; pointNum < numPoints; pointNum++) { var mz = TheoreticalDistMzs[pointNum] + mzDelta; var theoreticalIntensity = TheoreticalDistIntensities[pointNum]; if (theoreticalIntensity >= minIntensityForScore) { // observed intensities have to be normalized so that the maximum intensity is 100, // like that for theoretical intensities. var observedIntensity = 100 * GetPointIntensity(mz, peakData.MzList, peakData.IntensityList) / peak.Intensity; var intensityDiff = observedIntensity - theoreticalIntensity; var intensitySum = observedIntensity + theoreticalIntensity; fit += intensityDiff * intensityDiff / intensitySum; sum += theoreticalIntensity * observedIntensity; pointsUsed++; } } return(fit / (sum + 0.001)); }
/// <summary> /// Gets the peak (whether or not it is processed) whose m/z is closest to supplied mz in the m/z range (mz - width to /// mz + width). /// </summary> /// <param name="mz">the center m\z around which we want to look for a Peak.</param> /// <param name="width">the width of the m\z window in which we want to look for the peak.</param> /// <param name="peak">is the peak closest to m/z.</param> /// <returns>returns true if a peak was found in the window (mz - width to mz + width) and false if not found.</returns> /// <remarks>The returned peak can have an intensity of 0 because it was already processed and removed.</remarks> public bool GetClosestPeakFromAll(double mz, double width, out clsPeak peak) { peak = new clsPeak(); var found = false; var startMz = mz - width; var stopMz = mz + width; foreach (var item in _allPeakMzToIndexDict.Where(x => x.Key >= startMz)) { var peakIndex = item.Value; var mzVal = item.Key; if (mzVal > stopMz) { return(found); } if (mzVal >= startMz && Math.Abs(mzVal - mz) < Math.Abs(peak.Mz - mz)) { peak = new clsPeak(PeakTops[peakIndex]); found = true; } } return(found); }
/// <summary> /// Gets the most intense peak(whether or not it is processed) in the m/z range (mz - width to mz + width). The /// intensity returned is the intensity in the original raw data in <see cref="IntensityList" /> /// </summary> /// <param name="startMz">minimum m/z of the Peak.</param> /// <param name="stopMz">maximum m/z of the Peak.</param> /// <param name="peak">is set to the peak that was found.</param> /// <returns>returns true if a peak was found in the window (mz - width to mz + width) and false if not found.</returns> /// <remarks>The returned peak has the intensity in the original raw data in <see cref="IntensityList" />.</remarks> public bool GetPeakFromAllOriginalIntensity(double startMz, double stopMz, out clsPeak peak) { peak = new clsPeak(); peak.Intensity = -10; var found = false; foreach (var item in _allPeakMzToIndexDict.Where(x => x.Key <= stopMz).Reverse()) { var peakIndex = item.Value; var mzVal = item.Key; if (mzVal < startMz) { return(found); } if (PeakTops[peakIndex].Intensity > peak.Intensity && mzVal >= startMz && mzVal <= stopMz) { //double thisMz = PeakTops[peakIndex].Mz; peak = new clsPeak(PeakTops[peakIndex]); found = true; } } return(found); }
/// <summary> /// calculates the fit score between the theoretical distribution stored and the observed data. Normalizes the observed /// intensity by specified intensity. /// </summary> /// <param name="peakData"> variable which stores the data itself</param> /// <param name="chargeState"> charge state at which we want to compute the peak.</param> /// <param name="peak"> peak for which we want to compute the fit function.</param> /// <param name="mzDelta">specifies the mass delta between theoretical and observed m/z with the best fit so far.</param> /// <param name="minIntensityForScore">minimum intensity for score</param> /// <param name="pointsUsed">number of points used</param> /// <param name="debug">debug output flag</param> public override double FitScore(PeakData peakData, int chargeState, clsPeak peak, double mzDelta, double minIntensityForScore, out int pointsUsed, bool debug = false) { pointsUsed = 0; var numPoints = TheoreticalDistMzs.Count; if (numPoints < 3) { return(1); } double fit = 0; double sum = 0; double lastYVal = 0; double diff = 0; for (var pointNum = 0; pointNum < numPoints; pointNum++) { var mz = TheoreticalDistMzs[pointNum] + mzDelta; var theoreticalIntensity = TheoreticalDistIntensities[pointNum]; // observed intensities have to be normalized so that the maximum intensity is 100, if (theoreticalIntensity >= minIntensityForScore && diff >= 0 && theoreticalIntensity < lastYVal) { var found = false; clsPeak foundPeak; // remember you might be searching for the current peak (which has already been // taken out of the list of peaks. So first check it. if (Math.Abs(peak.Mz - mz) < 2 * peak.FWHM) { found = true; foundPeak = peak; } else { peakData.FindPeak(mz - peak.FWHM, mz + peak.FWHM, out foundPeak); if (foundPeak.Mz > 0) { found = true; } } if (found) { var observedIntensity = 100 * foundPeak.Intensity / peak.Intensity; var intensityDiff = observedIntensity - theoreticalIntensity; var intensityAvg = (observedIntensity + theoreticalIntensity) / 2; fit += intensityDiff * intensityDiff; sum += intensityAvg * intensityAvg; } else { fit += theoreticalIntensity * theoreticalIntensity; sum += theoreticalIntensity * theoreticalIntensity; } pointsUsed++; } diff = theoreticalIntensity - lastYVal; lastYVal = theoreticalIntensity; } return(fit / (sum + 0.001)); }
public virtual bool FindTransform(PeakData peakData, ref clsPeak peak, out clsHornTransformResults record, double backgroundIntensity = 0) { record = new clsHornTransformResults(); if (peak.SignalToNoise < TransformParameters.MinS2N || peak.FWHM.Equals(0)) { return(false); } //var resolution = peak.Mz / peak.FWHM; var chargeState = AutoCorrelationChargeDetermination.GetChargeState(peak, peakData, DebugFlag); if (chargeState == -1 && TransformParameters.CheckAllPatternsAgainstCharge1) { chargeState = 1; } if (DebugFlag) { Console.Error.WriteLine("Deisotoping :" + peak.Mz); Console.Error.WriteLine("Charge = " + chargeState); } if (chargeState == -1) { return(false); } if ((peak.Mz + TransformParameters.CCMass) * chargeState > TransformParameters.MaxMW) { return(false); } if (TransformParameters.O16O18Media) { if (peak.FWHM < 1.0 / chargeState) { // move back by 4 Da and see if there is a peak. var minMz = peak.Mz - 4.0 / chargeState - peak.FWHM; var maxMz = peak.Mz - 4.0 / chargeState + peak.FWHM; clsPeak o16Peak; var found = peakData.GetPeak(minMz, maxMz, out o16Peak); if (found && !o16Peak.Mz.Equals(peak.Mz)) { // put back the current into the to be processed list of peaks. peakData.AddPeakToProcessingList(peak); // reset peak to the right peak so that the calling function may // know that the peak might have changed in the O16/O18 business peak = o16Peak; peakData.RemovePeak(peak); return(FindTransform(peakData, ref peak, out record, backgroundIntensity)); } } } var peakCharge1 = new clsPeak(peak); // Until now, we have been using constant theoretical delete intensity threshold.. // instead, from now, we should use one that is proportional to intensity, for more intense peaks. // However this will not solve all problems. If thrashing occurs, then the peak intensity will // change when the function returns and we may not delete far enough. //double deleteThreshold = backgroundIntensity / peak.Intensity * 100; //if (backgroundIntensity ==0 || deleteThreshold > _deleteIntensityThreshold) // deleteThreshold = _deleteIntensityThreshold; var deleteThreshold = TransformParameters.DeleteIntensityThreshold; int fitCountBasis; var bestFit = TransformParameters.IsotopeFitScorer.GetFitScore(peakData, chargeState, ref peak, out record, deleteThreshold, TransformParameters.MinIntensityForScore, TransformParameters.LeftFitStringencyFactor, TransformParameters.RightFitStringencyFactor, out fitCountBasis, DebugFlag); // When deleting an isotopic profile, this value is set to the first m/z to perform deletion at. double zeroingStartMz; // When deleting an isotopic profile, this value is set to the last m/z to perform deletion at. double zeroingStopMz; TransformParameters.IsotopeFitScorer.GetZeroingMassRange(out zeroingStartMz, out zeroingStopMz, record.DeltaMz, deleteThreshold, DebugFlag); //bestFit = _isotopeFitter.GetFitScore(peakData, chargeState, peak, record, _deleteIntensityThreshold, _minTheoreticalIntensityForScore, DebugFlag); //_isotopeFitter.GetZeroingMassRange(_zeroingStartMz, _zeroingStopMz, record.DeltaMz, _deleteIntensityThreshold, DebugFlag); if (TransformParameters.CheckAllPatternsAgainstCharge1 && chargeState != 1) { clsHornTransformResults recordCharge1; int fitCountBasisCharge1; var bestFitCharge1 = TransformParameters.IsotopeFitScorer.GetFitScore(peakData, 1, ref peakCharge1, out recordCharge1, deleteThreshold, TransformParameters.MinIntensityForScore, TransformParameters.LeftFitStringencyFactor, TransformParameters.RightFitStringencyFactor, out fitCountBasisCharge1, DebugFlag); //double bestFitCharge1 = _isotopeFitter.GetFitScore(peakData, 1, peakCharge1, recordCharge1, _deleteIntensityThreshold, _minTheoreticalIntensityForScore, DebugFlag); //_isotopeFitter.GetZeroingMassRange(_zeroingStartMz, _zeroingStopMz, record.DeltaMz, _deleteIntensityThreshold, DebugFlag); double startMz1 = 0; double stopMz1 = 0; TransformParameters.IsotopeFitScorer.GetZeroingMassRange(out startMz1, out stopMz1, record.DeltaMz, deleteThreshold, DebugFlag); if (bestFit > TransformParameters.MaxFit && bestFitCharge1 < TransformParameters.MaxFit) { bestFit = bestFitCharge1; fitCountBasis = fitCountBasisCharge1; peak = peakCharge1; record = new clsHornTransformResults(recordCharge1); zeroingStartMz = startMz1; zeroingStopMz = stopMz1; chargeState = 1; } } if (bestFit > TransformParameters.MaxFit) // check if fit is good enough { return(false); } if (DebugFlag) { Console.Error.WriteLine("\tBack with fit = " + record.Fit); } // Applications using this DLL should use Abundance instead of AbundanceInt record.Abundance = peak.Intensity; record.ChargeState = chargeState; clsPeak monoPeak; var monoMz = record.MonoMw / record.ChargeState + TransformParameters.CCMass; // used when _reportO18Plus2Da is true. clsPeak m3Peak; var monoPlus2Mz = record.MonoMw / record.ChargeState + 2.0 / record.ChargeState + TransformParameters.CCMass; peakData.FindPeak(monoMz - peak.FWHM, monoMz + peak.FWHM, out monoPeak); peakData.FindPeak(monoPlus2Mz - peak.FWHM, monoPlus2Mz + peak.FWHM, out m3Peak); record.MonoIntensity = (int)monoPeak.Intensity; record.MonoPlus2Intensity = (int)m3Peak.Intensity; record.SignalToNoise = peak.SignalToNoise; record.FWHM = peak.FWHM; record.PeakIndex = peak.PeakIndex; SetIsotopeDistributionToZero(peakData, peak, zeroingStartMz, zeroingStopMz, record.MonoMw, chargeState, true, record, DebugFlag); if (DebugFlag) { Console.Error.WriteLine("Performed deisotoping of " + peak.Mz); } return(true); }
/// <summary> /// Convert the MS feature from MASIC to standard feature from watershed. /// </summary> /// <param name="peak"> /// The peak. /// </param> /// <returns> /// The <see cref="StandardImsPeak"/>. /// </returns> private static StandardImsPeak NormalizeMASICFeature(clsPeak peak) { // Write it. // FeatureBlob watershedFeature = new FeatureBlob(0); // watershedFeature.PointList = new List<Point>(); // // Talor MASIC's sometimes asymetirc peak into watershed flavored peak. // // watershedFeature.PointList blablabla throw new NotImplementedException(); }
/// <summary> /// Calculates peak information. /// </summary> /// <param name="peak"> /// The peak to calculate. /// </param> /// <param name="originalList"> /// The original list given to the peak finder. /// </param> /// <param name="smoothedIntensityValues"> /// The smoothed intensity values from the peak finder. /// </param> /// <param name="precisionUsed"> /// The precision used when passing data to the peak finder so it can handle numbers with doubles. /// </param> /// <returns> /// The <see cref="PeakInformation"/>. /// </returns> private static PeakInformation CalculatePeakInformation( clsPeak peak, List <KeyValuePair <int, double> > originalList, IReadOnlyList <double> smoothedIntensityValues, int precisionUsed) { const double Tolerance = 0.01; var centerPoint = originalList.ElementAt(peak.LocationIndex); var offsetCenter = centerPoint.Key; // + firstpoint.Key; var intensity = centerPoint.Value; var smoothedPeakIntensity = smoothedIntensityValues[peak.LocationIndex]; var realCenter = (double)offsetCenter / precisionUsed; var halfmax = smoothedPeakIntensity / 2.0; var currPoint = new KeyValuePair <int, double>(0, 0); var currPointIndex = 0; List <KeyValuePair <int, double> > leftSidePoints; List <KeyValuePair <int, double> > rightSidePoints; var allPoints = ExtractPointInformation( peak, originalList, smoothedIntensityValues, precisionUsed, out leftSidePoints, out rightSidePoints); // find the left side half max var leftMidpoint = FindMidPoint( originalList, smoothedIntensityValues, leftSidePoints, ref currPoint, halfmax, Tolerance, ref currPointIndex, Side.LeftSide); // find the right side of the half max var rightMidPoint = FindMidPoint( originalList, smoothedIntensityValues, rightSidePoints, ref currPoint, halfmax, Tolerance, ref currPointIndex, Side.RightSide); var correctedRightMidPoint = rightMidPoint / precisionUsed; var correctedLeftMidPoint = leftMidpoint / precisionUsed; var fullWidthHalfMax = correctedRightMidPoint - correctedLeftMidPoint; var resolution = realCenter / fullWidthHalfMax; var temp = new PeakInformation { AreaUnderThePeak = peak.Area, FullWidthHalfMax = fullWidthHalfMax, Intensity = intensity, LeftMidpoint = correctedLeftMidPoint, PeakCenter = realCenter, RightMidpoint = correctedRightMidPoint, ResolvingPower = resolution, SmoothedIntensity = smoothedPeakIntensity, TotalDataPointSet = allPoints }; return(temp); }
/// <summary> /// Adds a peak to <see cref="PeakTops" /> /// </summary> /// <param name="peak">is the peak that we want to add to <see cref="PeakTops" />.</param> public void AddPeak(clsPeak peak) { PeakTops.Add(new clsPeak(peak)); }
/// <summary> /// Gets the charge state (determined by AutoCorrelation algorithm) for a peak in some data. /// </summary> /// <param name="peak">is the peak whose charge we want to detect.</param> /// <param name="peakData">is the PeakData object containing raw data, peaks, etc which are used in the process.</param> /// <returns>Returns the charge of the feature.</returns> public static int GetChargeState(clsPeak peak, PeakData peakData, bool debug) { var minus = 0.1; var plus = 1.1; // right direction to look var startIndex = PeakIndex.GetNearest(peakData.MzList, peak.Mz - peak.FWHM - minus, peak.DataIndex); var stopIndex = PeakIndex.GetNearest(peakData.MzList, peak.Mz + peak.FWHM + plus, peak.DataIndex); var numPts = stopIndex - startIndex; var numL = numPts; if (numPts < 5) { return(-1); } if (numPts < 256) { numL = 10 * numPts; } // variable to help us perform spline interpolation. // count is stopIndex - startIndex + 1 because we need to include the values at stopIndex as well // NOTE: This output is different from what the DeconEngineV2 code outputs; there are notes in that code // wondering if there was a bug in the previous implementation imported from VB, of starting at startIndex + 1. // That code performed interpolation on the range from startIndex + 1 to stopIndex, inclusive, and minMz set to PeakData.MzList[startIndex + 1]. // This code can produce output that more closely matches the DeconEngineV2 output by using // "startIndex, stopIndex - startIndex + 2" as the parameters to "GetRange()", and setting minMz to PeakData.MzList[startIndex + 1]. // Since using startIndex and stopIndex directly produces output that mostly differs on fit score by a small amount, // we are changing this code to use them. var interpolator = CubicSpline.InterpolateNaturalSorted( peakData.MzList.GetRange(startIndex, stopIndex - startIndex + 1).ToArray(), peakData.IntensityList.GetRange(startIndex, stopIndex - startIndex + 1).ToArray()); var minMz = peakData.MzList[startIndex]; var maxMz = peakData.MzList[stopIndex]; // List to store the interpolated intensities of the region on which we performed the cubic spline interpolation. var iv = new List <double>(numL); for (var i = 0; i < numL; i++) { var xVal = minMz + (maxMz - minMz) * i / numL; var fVal = interpolator.Interpolate(xVal); iv.Add(fVal); } if (debug) { Console.Error.WriteLine("mz,intensity"); for (var i = 0; i < numL; i++) { var xVal = minMz + (maxMz - minMz) * i / numL; Console.Error.WriteLine(xVal + "," + iv[i]); } } // List to store the autocorrelation values at the points in the region. var autocorrelationScores = ACss(iv); if (debug) { Console.Error.WriteLine("AutoCorrelation values"); for (var i = 0; i < autocorrelationScores.Count; i++) { var score = autocorrelationScores[i]; Console.Error.WriteLine((maxMz - minMz) * i / numL + "," + score); } } var minN = 0; while (minN < numL - 1 && autocorrelationScores[minN] > autocorrelationScores[minN + 1]) { minN++; } // Determine the highest CS peak double bestAcScore; int bestChargeState; var success = HighestChargeStatePeak(minMz, maxMz, minN, autocorrelationScores, MaxCharge, out bestAcScore, out bestChargeState); if (!success) { return(-1); // Didn't find anything } // List to temporarily store charge list. These charges are calculated at peak values of autocorrelation. // Now go back through the CS peaks and make a list of all CS that are at least 10% of the highest var charges = GenerateChargeStates(minMz, maxMz, minN, autocorrelationScores, MaxCharge, bestAcScore); // Get the final CS value to be returned var returnChargeStateVal = -1; var fwhm = peak.FWHM; // Store a copy of the FWHM to avoid modifying the actual value if (fwhm > 0.1) { fwhm = 0.1; } for (var i = 0; i < charges.Count; i++) { // no point retesting previous charge. var tempChargeState = charges[i]; var skip = false; for (var j = 0; j < i; j++) { if (charges[j] == tempChargeState) { skip = true; break; } } if (skip) { continue; } if (tempChargeState > 0) { var peakA = peak.Mz + 1.0 / tempChargeState; var found = true; clsPeak isoPeak; found = peakData.GetPeakFromAllOriginalIntensity(peakA - fwhm, peakA + fwhm, out isoPeak); if (found) { returnChargeStateVal = tempChargeState; if (isoPeak.Mz * tempChargeState < 3000) { break; } // if the mass is greater than 3000, lets make sure that multiple isotopes exist. peakA = peak.Mz - 1.03 / tempChargeState; found = peakData.GetPeakFromAllOriginalIntensity(peakA - fwhm, peakA + fwhm, out isoPeak); if (found) { return(tempChargeState); } } else { peakA = peak.Mz - 1.0 / tempChargeState; found = peakData.GetPeakFromAllOriginalIntensity(peakA - fwhm, peakA + fwhm, out isoPeak); if (found && isoPeak.Mz * tempChargeState < 3000) { return(tempChargeState); } } } } return(returnChargeStateVal); }
public void GetFeaturesForSpectra(List <double> mzs, List <double> intensities, clsPeak parentPeak, int msNscan) { double xscore2, xscore3, xscore_ratio, bscore2, bscore3, pk1_prob, pk2_prob, pk3_prob, pk4_prob, fscore2, fscore3, xscore2_CO, xscore3_CO, xscore2_H2O, xscore3_H2O, xscore2_NH3, xscore3_NH3; var numPeaks = mzs.Count; var noLoss = 0d; var parentMz = parentPeak.Mz; //Get input spectra InitVectors(); for (var i = 0; i < numPeaks; i++) { _intensities.Add(intensities[i]); _mzs.Add(mzs[i]); } //Start with feature detection CalculatePeakProbabilities(parentMz, out pk1_prob, out pk2_prob, out pk3_prob, out pk4_prob); GetFisherScores(out fscore2, out fscore3); NormalizeSpectra(); GetXScores(parentMz, out xscore2, out xscore3, noLoss); if (!xscore2.Equals(0)) { xscore_ratio = xscore3 / xscore2; } else { xscore_ratio = 0; } GetBScores(parentMz, out bscore2, out bscore3); GetXScores(parentMz, out xscore2_CO, out xscore3_CO, MassCO); GetXScores(parentMz, out xscore2_H2O, out xscore3_H2O, MassH2O); GetXScores(parentMz, out xscore2_NH3, out xscore3_NH3, MassNH3); ReadValues(msNscan, parentMz, xscore2, xscore3, xscore_ratio, bscore2, bscore3, pk1_prob, pk2_prob, pk3_prob, pk4_prob, fscore2, fscore3, xscore2_CO, xscore3_CO, xscore2_H2O, xscore3_H2O, xscore2_NH3, xscore3_NH3); }
private void SetIsotopeDistributionToZero(PeakData peakData, clsPeak peak, double zeroingStartMz, double zeroingStopMz, double monoMw, int chargeState, bool clearSpectrum, clsHornTransformResults record, bool debug = false) { var peakIndices = new List <int>(); peakIndices.Add(peak.PeakIndex); var mzDelta = record.DeltaMz; if (debug) { Console.Error.WriteLine("Clearing peak data for " + peak.Mz + " Delta = " + mzDelta); Console.Error.WriteLine("Zeroing range = " + zeroingStartMz + " to " + zeroingStopMz); } double maxMz = 0; if (TransformParameters.O16O18Media) { maxMz = (monoMw + 3.5) / chargeState + TransformParameters.CCMass; } var numUnprocessedPeaks = peakData.GetNumUnprocessedPeaks(); if (numUnprocessedPeaks == 0) { record.IsotopePeakIndices.Add(peak.PeakIndex); return; } if (clearSpectrum) { if (debug) { Console.Error.WriteLine("Deleting main peak :" + peak.Mz); } SetPeakToZero(peak.DataIndex, ref peakData.IntensityList, ref peakData.MzList, debug); } peakData.RemovePeaks(peak.Mz - peak.FWHM, peak.Mz + peak.FWHM, debug); if (1 / (peak.FWHM * chargeState) < 3) // gord: ?? { record.IsotopePeakIndices.Add(peak.PeakIndex); peakData.RemovePeaks(zeroingStartMz, zeroingStopMz, debug); return; } // Delete isotopes of mzs higher than mz of starting isotope for (var peakMz = peak.Mz + 1.003 / chargeState; (!TransformParameters.O16O18Media || peakMz <= maxMz) && peakMz <= zeroingStopMz + 2 * peak.FWHM; peakMz += 1.003 / chargeState) { if (debug) { Console.Error.WriteLine("\tFinding next peak top from " + (peakMz - 2 * peak.FWHM) + " to " + (peakMz + 2 * peak.FWHM) + " pk = " + peakMz + " FWHM = " + peak.FWHM); } clsPeak nextPeak; peakData.GetPeakFromAll(peakMz - 2 * peak.FWHM, peakMz + 2 * peak.FWHM, out nextPeak); if (nextPeak.Mz.Equals(0)) { if (debug) { Console.Error.WriteLine("\t\tNo peak found."); } break; } if (debug) { Console.Error.WriteLine("\t\tFound peak to delete =" + nextPeak.Mz); } // Before assuming that the next peak is indeed an isotope, we must check for the height of this // isotope. If the height is greater than expected by a factor of 3, lets not delete it. peakIndices.Add(nextPeak.PeakIndex); SetPeakToZero(nextPeak.DataIndex, ref peakData.IntensityList, ref peakData.MzList, debug); peakData.RemovePeaks(nextPeak.Mz - peak.FWHM, nextPeak.Mz + peak.FWHM, debug); peakMz = nextPeak.Mz; } // Delete isotopes of mzs lower than mz of starting isotope // TODO: Use the delta m/z to make sure to remove 1- peaks from the unprocessed list, but not from the list of peaks? for (var peakMz = peak.Mz - 1.003 / chargeState; peakMz > zeroingStartMz - 2 * peak.FWHM; peakMz -= 1.003 / chargeState) { if (debug) { Console.Error.WriteLine("\tFinding previous peak top from " + (peakMz - 2 * peak.FWHM) + " to " + (peakMz + 2 * peak.FWHM) + " pk = " + peakMz + " FWHM = " + peak.FWHM); } clsPeak nextPeak; peakData.GetPeakFromAll(peakMz - 2 * peak.FWHM, peakMz + 2 * peak.FWHM, out nextPeak); if (nextPeak.Mz.Equals(0)) { if (debug) { Console.Error.WriteLine("\t\tNo peak found."); } break; } if (debug) { Console.Error.WriteLine("\t\tFound peak to delete =" + nextPeak.Mz); } peakIndices.Add(nextPeak.PeakIndex); SetPeakToZero(nextPeak.DataIndex, ref peakData.IntensityList, ref peakData.MzList, debug); peakData.RemovePeaks(nextPeak.Mz - peak.FWHM, nextPeak.Mz + peak.FWHM, debug); peakMz = nextPeak.Mz; } if (debug) { Console.Error.WriteLine("Done Clearing peak data for " + peak.Mz); } peakIndices.Sort(); // now insert into array. var numPeaksObserved = peakIndices.Count; var numIsotopesObserved = 0; var lastIsotopeNumObserved = int.MinValue; for (var i = 0; i < numPeaksObserved; i++) { var currentIndex = peakIndices[i]; var currentPeak = new clsPeak(peakData.PeakTops[currentIndex]); var isotopeNum = (int)(Math.Abs((currentPeak.Mz - peak.Mz) * chargeState / 1.003) + 0.5); if (currentPeak.Mz < peak.Mz) { isotopeNum = -1 * isotopeNum; } if (isotopeNum > lastIsotopeNumObserved) { lastIsotopeNumObserved = isotopeNum; numIsotopesObserved++; if (numIsotopesObserved > MaxIsotopes) { break; } record.IsotopePeakIndices.Add(peakIndices[i]); } else { record.IsotopePeakIndices[numIsotopesObserved - 1] = peakIndices[i]; } } if (debug) { Console.Error.WriteLine("Copied " + record.NumIsotopesObserved + " isotope peak indices into record "); } }
public bool IdentifyIfChargeOne(List <double> mzs, List <double> intensities, clsPeak parentPeak, int parentScan) { var numPeaks = mzs.Count; var parentMz = parentPeak.Mz; double temp1, temp2, temp3, temp4; //Get input spectra InitVectors(); for (var i = 0; i < numPeaks; i++) { _intensities.Add(intensities[i]); _mzs.Add(mzs[i]); } CalculatePeakProbabilities(parentMz, out temp1, out temp2, out temp3, out temp4); // If all frag peaks lie in first bin [0 - parent_Mz] if (_peakDistribution[0] > 0.9 * numPeaks) { return(true); } else { return(false); } }
/// <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; } } } } }