private ChromDataPeakList FindCoelutingPeaks(ChromDataPeak dataPeakMax, IList<ChromDataPeak> allPeaks) { CrawdadPeak peakMax = dataPeakMax.Peak; float areaMax = peakMax.Area; int centerMax = peakMax.TimeIndex; int startMax = peakMax.StartIndex; int endMax = peakMax.EndIndex; int widthMax = peakMax.Length; int deltaMax = (int)Math.Round(widthMax / 4.0, 0); var listPeaks = new ChromDataPeakList(dataPeakMax); // Allow peaks in the group to be smaller, if the max peak is the precursor. // Really this should be checking to see if the precursor data came from MS1 // scans, since this is the main case it is intended to handle, where MS1 // intensities can be quite a bit higher than MS/MS fragments. var keyMax = dataPeakMax.Data.Key; double minPrecentMax = (keyMax.Precursor != keyMax.Product ? MIN_PERCENT_OF_MAX : MIN_PERCENT_OF_MAX_PRECURSOR); foreach (var chromData in _listChromData) { if (ReferenceEquals(chromData, dataPeakMax.Data)) continue; int iPeakNearest = -1; int deltaNearest = deltaMax; // Find nearest peak in remaining set that is less than 1/4 length // from the primary peak's center for (int i = 0, len = allPeaks.Count; i < len; i++) { var peak = allPeaks[i]; if (!ReferenceEquals(peak.Data, chromData)) continue; // Exclude peaks where the apex is not inside the max peak, // or apex is at one end of the peak int timeIndex = peak.Peak.TimeIndex; int startPeak = peak.Peak.StartIndex; int endPeak = peak.Peak.EndIndex; if (startMax >= timeIndex || timeIndex >= endMax || startPeak == timeIndex || timeIndex == endPeak) continue; // or peak area is less than 1% of max peak area (or 0.1% if max is precursor) if (peak.Peak.Area < areaMax * minPrecentMax) continue; // or when FWHM is very narrow, usually a good indicator of noise if (/* peak.Peak.Fwhm < 1.2 too agressive || */ peak.Peak.Fwhm * 12 < widthMax) continue; // or where the peak does not overlap at least 50% of the max peak int intersect = Math.Min(endMax, peak.Peak.EndIndex) - Math.Max(startMax, peak.Peak.StartIndex) + 1; // +1 for inclusive end int lenPeak = peak.Peak.Length; // Allow 25% coverage, if the peak is entirely inside the max, since // sometimes Crawdad breaks smaller peaks up. int factor = (intersect == lenPeak ? 4 : 2); if (intersect * factor < widthMax) continue; int delta = Math.Abs(timeIndex - centerMax); // If apex delta and FWHM are not very close to the max peak, make further checks if (delta * 4.0 > deltaMax || Math.Abs(peak.Peak.Fwhm - peakMax.Fwhm) / peakMax.Fwhm > 0.05) { // If less than 2/3 of the peak is inside the max peak, or 1/2 if the // peak entirely contains the max peak. double dFactor = (intersect == widthMax ? 2.0 : 1.5); if (intersect * dFactor < lenPeak) continue; // or where either end is more than 2/3 of the intersect width outside // the max peak. if (intersect != lenPeak) { dFactor = 1.5; if ((startMax - peak.Peak.StartIndex) * dFactor > intersect || (peak.Peak.EndIndex - endMax) * dFactor > intersect) continue; } } if (delta <= deltaNearest) { deltaNearest = delta; iPeakNearest = i; } } if (iPeakNearest == -1) listPeaks.Add(new ChromDataPeak(chromData, null)); else { listPeaks.Add(new ChromDataPeak(chromData, allPeaks[iPeakNearest].Peak)); allPeaks.RemoveAt(iPeakNearest); } } return listPeaks; }
public void SetPeakSet(ChromDataPeakList peakSet, int index) { _listPeakSets[index] = peakSet; }
public ChromDataPeakList SetBestPeak(ChromDataPeakList peakSet, PeptideChromDataPeak bestPeptidePeak, int indexSet) { ChromDataPeakList peakSetAdd = null; int startIndex, endIndex; // TODO: Need to do something more reasonable for Deuterium elution time shifts bool matchBounds = GetLocalPeakBounds(bestPeptidePeak, out startIndex, out endIndex); if (peakSet != null) { // If the peak ranked by peptide matching is not in its proper position, // then move it there if (!ReferenceEquals(peakSet, _listPeakSets[indexSet])) { _listPeakSets.Remove(peakSet); _listPeakSets.Insert(indexSet, peakSet); } // If there is a different best peptide peak, and it should have // the same retention time charachteristics, then reset the integration // boundaries of this peak set if (matchBounds) { var peak = peakSet[0].Peak; // If this peak and the best peak for this peptide are allowed to be shifted in // relationship to each other, then make that shift be the delta between the apex // times of the two peaks. They still need to be the same width. if (!IsSameRT(bestPeptidePeak.Data)) { int deltaBounds = GetLocalIndex(bestPeptidePeak.TimeIndex) - peak.TimeIndex; startIndex = Math.Max(0, startIndex + deltaBounds); endIndex = Math.Min(Times.Length - 1, endIndex + deltaBounds); } // Reset the range of the best peak, if the chromatograms for this peak group // overlap with the best peptide peak at all. Resetting the range of the best // peak for this peak group will cause it and all other peaks in the peak group // to be reintegrated to this range if (startIndex < endIndex) { peak.ResetBoundaries(startIndex, endIndex); } // In a peak set with mutiple charge states and light-heavy pairs, it is // possible that a peak may not overlap with the best peak in its // charge group. If this is the case, and the best peak is completely // outside the bounds of the current chromatogram, then insert an // empty peak. else { var peakAdd = new ChromDataPeak(BestChromatogram, null); peakSetAdd = new ChromDataPeakList(peakAdd, _listChromData) { IsForcedIntegration = true }; } } } // If no peak was found at the peptide level for this data set, // but there is a best peak for the peptide else if (bestPeptidePeak != null && matchBounds) { // And the chromatograms for this transition group overlap with the best peptide // peak, then create a peak with the same extents as the best peak. This peak will // appear as missing, if Integrate All is not selected. ChromDataPeak peakAdd; if (startIndex < endIndex) { // CONSIDER: Not that great for peaks that are expected to be shifted in relationship // to each other, since this will force them to have the same boundaries, // but if no evidence of a peak was found, it is hard to understand what // could be done better. var chromData = BestChromatogram; peakAdd = new ChromDataPeak(chromData, chromData.CalcPeak(startIndex, endIndex)); } // Otherwise, create an empty peak else { peakAdd = new ChromDataPeak(BestChromatogram, null); } peakSetAdd = new ChromDataPeakList(peakAdd, _listChromData) {IsForcedIntegration = true}; } else { // Otherwise, insert an empty peak var peakAdd = new ChromDataPeak(BestChromatogram, null); peakSetAdd = new ChromDataPeakList(peakAdd, _listChromData) { IsForcedIntegration = true }; } if (peakSetAdd != null) { if (indexSet < _listPeakSets.Count) _listPeakSets.Insert(indexSet, peakSetAdd); else _listPeakSets.Add(peakSetAdd); peakSet = peakSetAdd; } return peakSet; }
public void RemovePeak(ChromDataPeakList peakGroup) { _listPeakSets.Remove(peakGroup); }
public void NarrowPeak(ChromDataPeakList peakSet, PeptideChromDataPeak narrowestPeptidePeak, int indexSet) { var peak = peakSet[0].Peak; if (peak != null) { int len = narrowestPeptidePeak.Length; if (narrowestPeptidePeak.IsRightBound) peak.ResetBoundaries(peak.EndIndex - len + 1, peak.EndIndex); else // if (narrowestPeptidePeak.IsLeftBound) Need to make sure they are the same length peak.ResetBoundaries(peak.StartIndex, peak.StartIndex + len - 1); } }
public int ComparePeakLists(ChromDataPeakList p1, ChromDataPeakList p2) { // Then order by PeakScore descending return Comparer<double>.Default.Compare(p2.CombinedScore, p1.CombinedScore); }