Beispiel #1
0
        private static int GetSurroundingAlignments(IList <PeakAlignment> alignList, PeakMatchData target, out PeakAlignment prev, out PeakAlignment next)
        {
            prev = next = null;
            if (!alignList.Any())
            {
                return(0);
            }

            var insertPos = alignList.Select(align => align.ReferencePeak).ToList().BinarySearch(target, RT_COMPARER);

            if (insertPos < 0)
            {
                insertPos = ~insertPos;
            }

            if (insertPos == 0)
            {
                next = alignList.First();
            }
            else if (insertPos != alignList.Count)
            {
                prev = alignList[insertPos - 1];
                next = alignList[insertPos];
            }
            else
            {
                prev = alignList.Last();
            }
            return(insertPos);
        }
Beispiel #2
0
        private static PeakMatch MakePeakMatchBetween(float scale, PeakMatchData referenceTarget, PeakAlignment prev, PeakAlignment next)
        {
            if (prev == null && next == null)
            {
                return(null);
            }

            float startTime, endTime;
            var   range = scale * (referenceTarget.EndTime - referenceTarget.StartTime);

            if (prev != null && next != null)
            {
                startTime = prev.AlignedPeak.RetentionTime + scale * (referenceTarget.StartTime - prev.ReferencePeak.RetentionTime);
                endTime   = next.AlignedPeak.RetentionTime - scale * (next.ReferencePeak.RetentionTime - referenceTarget.EndTime);
            }
            else if (next != null)
            {
                endTime   = next.AlignedPeak.StartTime - scale * (next.ReferencePeak.StartTime - referenceTarget.EndTime);
                startTime = endTime - range;
            }
            else
            {
                startTime = prev.AlignedPeak.EndTime + scale * (referenceTarget.StartTime - prev.ReferencePeak.EndTime);
                endTime   = startTime + range;
            }
            return(new PeakMatch(startTime + (referenceTarget.ShiftLeft * range), endTime + (referenceTarget.ShiftRight * range)));
        }
Beispiel #3
0
            public double GetMatchScore(PeakMatchData other)
            {
                var timeMin = Math.Min(MinTime, other.MinTime);
                var timeMax = Math.Max(MaxTime, other.MaxTime);

                return(SCORE_DOT_WEIGHT * Abundances.Dot(other.Abundances) +
                       SCORE_RT_WEIGHT * (1 - Math.Abs((RetentionTime - timeMin) - (other.RetentionTime - timeMin)) / (timeMax - timeMin)) +
                       SCORE_AREA_WEIGHT * (1 - Math.Abs(PercentArea - other.PercentArea)));
            }
Beispiel #4
0
 public PeakAlignment(PeakMatchData referencePeak, PeakMatchData alignedPeak)
 {
     ReferencePeak = referencePeak;
     AlignedPeak   = alignedPeak;
 }
Beispiel #5
0
        private static void GetReferenceData(SrmDocument doc, PeptideDocNode nodePep, TransitionGroupDocNode nodeTranGroup, int resultsIndex, ChromFileInfoId resultsFile,
                                             out PeakMatchData referenceTarget, out PeakMatchData[] referenceMatchData, out DateTime?runTime)
        {
            referenceTarget    = null;
            referenceMatchData = new PeakMatchData[0];
            runTime            = null;

            var referenceMatchDataList = new List <PeakMatchData>();

            var mzMatchTolerance = (float)doc.Settings.TransitionSettings.Instrument.MzMatchTolerance;

            if (!nodeTranGroup.HasResults || resultsIndex < 0 || resultsIndex >= nodeTranGroup.Results.Count)
            {
                return;
            }

            var tranGroupChromInfo = nodeTranGroup.GetChromInfo(resultsIndex, resultsFile);

            if (tranGroupChromInfo == null)
            {
                return;
            }

            var chromSet = doc.Settings.MeasuredResults.Chromatograms[resultsIndex];

            if (!doc.Settings.MeasuredResults.TryLoadChromatogram(chromSet, nodePep, nodeTranGroup, mzMatchTolerance, true, out var chromGroupInfos))
            {
                return;
            }

            var chromGroupInfo = chromGroupInfos.FirstOrDefault(info => Equals(chromSet.GetFileInfo(tranGroupChromInfo.FileId).FilePath, info.FilePath));

            if (chromGroupInfo == null || chromGroupInfo.NumPeaks == 0 || !chromGroupInfo.TimeIntensitiesGroup.HasAnyPoints)
            {
                return;
            }

            runTime = chromGroupInfo.RunStartTime;

            if (!tranGroupChromInfo.RetentionTime.HasValue || !tranGroupChromInfo.StartRetentionTime.HasValue || !tranGroupChromInfo.EndRetentionTime.HasValue)
            {
                return;
            }

            int peakIndex = -1;

            foreach (var transition in chromGroupInfo.TransitionPointSets)
            {
                peakIndex = transition.IndexOfPeak(tranGroupChromInfo.RetentionTime.Value);
                if (peakIndex != -1)
                {
                    break;
                }
            }

            // Get time information
            float timeMin = chromGroupInfo.TimeIntensitiesGroup.MinTime;
            float timeMax = chromGroupInfo.TimeIntensitiesGroup.MaxTime;

            float totalArea = chromGroupInfo.TransitionPointSets.Sum(chromInfo => chromInfo.Peaks.Sum(peak => peak.Area));

            for (int i = 0; i < chromGroupInfo.NumPeaks; i++)
            {
                referenceMatchDataList.Add(new PeakMatchData(nodeTranGroup, chromGroupInfo, mzMatchTolerance, i, totalArea, chromSet.OptimizationFunction));
            }

            // Get ion abundance information
            var abundances = new IonAbundances();

            foreach (var nodeTran in nodeTranGroup.Transitions)
            {
                var chromInfoCached = chromGroupInfo.GetTransitionInfo(nodeTran, mzMatchTolerance, chromSet.OptimizationFunction);
                if (chromInfoCached == null)
                {
                    continue;
                }

                var tranChromInfo = nodeTran.Results[resultsIndex].First(r => r.FileIndex == tranGroupChromInfo.FileIndex);

                float area;
                if (peakIndex != -1)
                {
                    // A peak exists here
                    var cachedPeak = chromInfoCached.GetPeak(peakIndex);
                    area = cachedPeak.Area;

                    if (cachedPeak.RetentionTime.Equals(tranGroupChromInfo.RetentionTime.Value))
                    {
                        var range = cachedPeak.EndTime - cachedPeak.StartTime;
                        referenceMatchDataList[peakIndex].ShiftLeft  = (tranChromInfo.StartRetentionTime - cachedPeak.StartTime) / range;
                        referenceMatchDataList[peakIndex].ShiftRight = (tranChromInfo.EndRetentionTime - cachedPeak.EndTime) / range;
                    }
                }
                else
                {
                    area = tranChromInfo.Area;
                }
                abundances.Add(nodeTran, area);
            }

            referenceTarget = peakIndex != -1
                ? referenceMatchDataList[peakIndex]
                : new PeakMatchData(abundances, abundances.Sum() / totalArea, tranGroupChromInfo.RetentionTime.Value,
                                    tranGroupChromInfo.StartRetentionTime.Value, tranGroupChromInfo.EndRetentionTime.Value, timeMin, timeMax);

            referenceMatchData = referenceMatchDataList.ToArray();
        }
Beispiel #6
0
 public double GetMatchScore(PeakMatchData other)
 {
     var timeMin = Math.Min(MinTime, other.MinTime);
     var timeMax = Math.Max(MaxTime, other.MaxTime);
     return SCORE_DOT_WEIGHT * Abundances.Dot(other.Abundances) +
            SCORE_RT_WEIGHT * (1 - Math.Abs((RetentionTime - timeMin) - (other.RetentionTime - timeMin)) / (timeMax - timeMin)) +
            SCORE_AREA_WEIGHT * (1 - Math.Abs(PercentArea - other.PercentArea));
 }
Beispiel #7
0
        private static PeakMatch GetPeakMatch(SrmDocument doc, ChromatogramSet chromSet, IPathContainer fileInfo, TransitionGroupDocNode nodeTranGroup,
                                              PeakMatchData referenceTarget, IEnumerable <PeakMatchData> referenceMatchData)
        {
            if (referenceTarget == null)
            {
                return(new PeakMatch(0, 0));
            }

            var mzMatchTolerance = (float)doc.Settings.TransitionSettings.Instrument.MzMatchTolerance;

            ChromatogramGroupInfo[] loadInfos;
            if (!nodeTranGroup.HasResults || !doc.Settings.MeasuredResults.TryLoadChromatogram(chromSet, null, nodeTranGroup, mzMatchTolerance, true, out loadInfos))
            {
                return(null);
            }

            var chromGroupInfo = loadInfos.FirstOrDefault(info => Equals(info.FilePath, fileInfo.FilePath));

            if (chromGroupInfo == null || chromGroupInfo.NumPeaks == 0 || !chromGroupInfo.TimeIntensitiesGroup.HasAnyPoints)
            {
                return(null);
            }

            var    matchData = new List <PeakMatchData>();
            double totalArea = chromGroupInfo.TransitionPointSets.Sum(chromInfo => chromInfo.Peaks.Sum(peak => peak.Area));

            for (int i = 0; i < chromGroupInfo.NumPeaks; i++)
            {
                matchData.Add(new PeakMatchData(nodeTranGroup, chromGroupInfo, mzMatchTolerance, i, totalArea, chromSet.OptimizationFunction));
            }

            // TODO: Try to improve this. Align peaks in area descending order until peaks do not match
            var  alignments       = new List <PeakAlignment>();
            bool referenceAligned = false;

            using (var referenceIter = referenceMatchData.OrderByDescending(d => d.PercentArea).GetEnumerator())
                using (var curIter = matchData.OrderByDescending(d => d.PercentArea).GetEnumerator())
                {
                    while (referenceIter.MoveNext() && curIter.MoveNext())
                    {
                        var alignAttempt = new PeakAlignment(referenceIter.Current, curIter.Current);
                        if (!TryInsertPeakAlignment(alignments, alignAttempt))
                        {
                            break;
                        }

                        if (referenceTarget == alignAttempt.ReferencePeak)
                        {
                            // Reference target aligned
                            referenceAligned = true;
                            matchData        = new List <PeakMatchData> {
                                alignAttempt.AlignedPeak
                            };
                            break;
                        }
                    }
                }

            PeakMatch manualMatch = null;

            if (!referenceAligned)
            {
                PeakAlignment prev, next;
                GetSurroundingAlignments(alignments, referenceTarget, out prev, out next);
                if (prev != null || next != null)
                {
                    // At least one alignment occurred
                    var chromGroupMinTime = chromGroupInfo.TimeIntensitiesGroup.MinTime;
                    var chromGroupMaxTime = chromGroupInfo.TimeIntensitiesGroup.MaxTime;

                    float scale = (chromGroupMaxTime - chromGroupMinTime) / (referenceTarget.MaxTime - referenceTarget.MinTime);
                    manualMatch = MakePeakMatchBetween(scale, referenceTarget, prev, next);
                    if (chromGroupMinTime >= manualMatch.EndTime || manualMatch.StartTime >= chromGroupMaxTime)
                    {
                        manualMatch = null;
                    }

                    float curMinTime = prev == null ? chromGroupMinTime : prev.AlignedPeak.RetentionTime;
                    float curMaxTime = next == null ? chromGroupMaxTime : next.AlignedPeak.RetentionTime;

                    matchData = matchData.Where(d => curMinTime < d.RetentionTime && d.RetentionTime < curMaxTime).ToList();
                }
            }

            PeakMatchData bestMatch = null;
            double        bestScore = double.MinValue;

            foreach (var other in matchData)
            {
                var score = referenceTarget.GetMatchScore(other);
                if (bestMatch == null || score > bestScore)
                {
                    bestScore = score;
                    bestMatch = other;
                }
            }

            // If no matching peak with high enough score was found, but there is a matching
            // peak or some peak with a low score.
            if (bestMatch == null || (!referenceAligned && bestScore < INTEGRATE_SCORE_THRESHOLD && manualMatch != null))
            {
                return(manualMatch);
            }

            if (referenceTarget.ShiftLeft == 0 && referenceTarget.ShiftRight == 0)
            {
                return(new PeakMatch(bestMatch.RetentionTime));
            }

            var range     = bestMatch.EndTime - bestMatch.StartTime;
            var startTime = bestMatch.StartTime + (referenceTarget.ShiftLeft * range);
            var endTime   = bestMatch.EndTime + (referenceTarget.ShiftRight * range);

            return(startTime <= bestMatch.RetentionTime && bestMatch.RetentionTime <= endTime
                ? new PeakMatch(startTime, endTime)
                : new PeakMatch(bestMatch.RetentionTime)); // If the shifted boundaries exclude the peak itself, don't change the boundaries
        }
Beispiel #8
0
 public PeakAlignment(PeakMatchData referencePeak, PeakMatchData alignedPeak)
 {
     ReferencePeak = referencePeak;
     AlignedPeak = alignedPeak;
 }
Beispiel #9
0
        private static PeakMatch MakePeakMatchBetween(float scale, PeakMatchData referenceTarget, PeakAlignment prev, PeakAlignment next)
        {
            if (prev == null && next == null)
                return null;

            float startTime, endTime;
            var range = scale * (referenceTarget.EndTime - referenceTarget.StartTime);
            if (prev != null && next != null)
            {
                startTime = prev.AlignedPeak.RetentionTime + scale*(referenceTarget.StartTime - prev.ReferencePeak.RetentionTime);
                endTime = next.AlignedPeak.RetentionTime - scale*(next.ReferencePeak.RetentionTime - referenceTarget.EndTime);
            }
            else if (next != null)
            {
                endTime = next.AlignedPeak.StartTime - scale*(next.ReferencePeak.StartTime - referenceTarget.EndTime);
                startTime = endTime - range;
            }
            else
            {
                startTime = prev.AlignedPeak.EndTime + scale*(referenceTarget.StartTime - prev.ReferencePeak.EndTime);
                endTime = startTime + range;
            }
            return new PeakMatch(startTime + (referenceTarget.ShiftLeft*range), endTime + (referenceTarget.ShiftRight*range));
        }
Beispiel #10
0
        private static int GetSurroundingAlignments(IList<PeakAlignment> alignList, PeakMatchData target, out PeakAlignment prev, out PeakAlignment next)
        {
            prev = next = null;
            if (!alignList.Any())
                return 0;

            var insertPos = alignList.Select(align => align.ReferencePeak).ToList().BinarySearch(target, RT_COMPARER);
            if (insertPos < 0)
                insertPos = ~insertPos;

            if (insertPos == 0)
            {
                next = alignList.First();
            }
            else if (insertPos != alignList.Count)
            {
                prev = alignList[insertPos - 1];
                next = alignList[insertPos];
            }
            else
            {
                prev = alignList.Last();
            }
            return insertPos;
        }
Beispiel #11
0
        private static void GetReferenceData(SrmDocument doc, PeptideDocNode nodePep, TransitionGroupDocNode nodeTranGroup, int resultsIndex, int? resultsFile,
            out PeakMatchData referenceTarget, out PeakMatchData[] referenceMatchData, out DateTime? runTime)
        {
            referenceTarget = null;
            referenceMatchData = new PeakMatchData[0];
            runTime = null;

            var referenceMatchDataList = new List<PeakMatchData>();

            var mzMatchTolerance = (float) doc.Settings.TransitionSettings.Instrument.MzMatchTolerance;

            if (!nodeTranGroup.HasResults || resultsIndex < 0 || resultsIndex >= nodeTranGroup.Results.Count)
                return;

            var tranGroupChromInfo = nodeTranGroup.Results[resultsIndex][resultsFile ?? 0];
            if (tranGroupChromInfo == null)
                return;

            var chromSet = doc.Settings.MeasuredResults.Chromatograms[resultsIndex];
            ChromatogramGroupInfo[] chromGroupInfos;
            if (!doc.Settings.MeasuredResults.TryLoadChromatogram(chromSet, nodePep, nodeTranGroup, mzMatchTolerance, true, out chromGroupInfos))
                return;

            var chromGroupInfo = chromGroupInfos.FirstOrDefault(info => Equals(chromSet.GetFileInfo(tranGroupChromInfo.FileId).FilePath, info.FilePath));
            if (chromGroupInfo == null || chromGroupInfo.NumPeaks == 0 || !chromGroupInfo.Times.Any())
                return;

            runTime = chromGroupInfo.RunStartTime;

            if (!tranGroupChromInfo.RetentionTime.HasValue || !tranGroupChromInfo.StartRetentionTime.HasValue || !tranGroupChromInfo.EndRetentionTime.HasValue)
                return;

            int peakIndex = -1;
            foreach (var transition in chromGroupInfo.TransitionPointSets)
            {
                peakIndex = transition.IndexOfPeak(tranGroupChromInfo.RetentionTime.Value);
                if (peakIndex != -1)
                    break;
            }

            // Get time information
            float timeMin = chromGroupInfo.Times.First();
            float timeMax = chromGroupInfo.Times.Last();

            float totalArea = chromGroupInfo.TransitionPointSets.Sum(chromInfo => chromInfo.Peaks.Sum(peak => peak.Area));
            for (int i = 0; i < chromGroupInfo.NumPeaks; i++)
                referenceMatchDataList.Add(new PeakMatchData(nodeTranGroup, chromGroupInfo, mzMatchTolerance, i, totalArea));

            // Get ion abundance information
            var abundances = new IonAbundances();
            foreach (var nodeTran in nodeTranGroup.Transitions)
            {
                var chromInfoCached = chromGroupInfo.GetTransitionInfo((float) nodeTran.Mz, mzMatchTolerance);
                if (chromInfoCached == null)
                    continue;

                var tranChromInfo = nodeTran.Results[resultsIndex].First(r => r.FileIndex == tranGroupChromInfo.FileIndex);

                float area;
                if (peakIndex != -1)
                {
                    // A peak exists here
                    var cachedPeak = chromInfoCached.GetPeak(peakIndex);
                    area = cachedPeak.Area;

                    if (cachedPeak.RetentionTime.Equals(tranGroupChromInfo.RetentionTime.Value))
                    {
                        var range = cachedPeak.EndTime - cachedPeak.StartTime;
                        referenceMatchDataList[peakIndex].ShiftLeft = (tranChromInfo.StartRetentionTime - cachedPeak.StartTime)/range;
                        referenceMatchDataList[peakIndex].ShiftRight = (tranChromInfo.EndRetentionTime - cachedPeak.EndTime)/range;
                    }
                }
                else
                {
                    area = tranChromInfo.Area;
                }
                abundances.Add(nodeTran, area);
            }

            referenceTarget = peakIndex != -1
                ? referenceMatchDataList[peakIndex]
                : new PeakMatchData(abundances, abundances.Sum()/totalArea, tranGroupChromInfo.RetentionTime.Value,
                    tranGroupChromInfo.StartRetentionTime.Value, tranGroupChromInfo.EndRetentionTime.Value, timeMin, timeMax);

            referenceMatchData = referenceMatchDataList.ToArray();
        }
Beispiel #12
0
        private static PeakMatch GetPeakMatch(SrmDocument doc, ChromatogramSet chromSet, IPathContainer fileInfo, TransitionGroupDocNode nodeTranGroup,
            PeakMatchData referenceTarget, IEnumerable<PeakMatchData> referenceMatchData)
        {
            if (referenceTarget == null)
                return new PeakMatch(0, 0);

            var mzMatchTolerance = (float) doc.Settings.TransitionSettings.Instrument.MzMatchTolerance;

            ChromatogramGroupInfo[] loadInfos;
            if (!nodeTranGroup.HasResults || !doc.Settings.MeasuredResults.TryLoadChromatogram(chromSet, null, nodeTranGroup, mzMatchTolerance, true, out loadInfos))
                return null;

            var chromGroupInfo = loadInfos.FirstOrDefault(info => Equals(info.FilePath, fileInfo.FilePath));
            if (chromGroupInfo == null || chromGroupInfo.NumPeaks == 0 || !chromGroupInfo.Times.Any())
                return null;

            var matchData = new List<PeakMatchData>();
            double totalArea = chromGroupInfo.TransitionPointSets.Sum(chromInfo => chromInfo.Peaks.Sum(peak => peak.Area));
            for (int i = 0; i < chromGroupInfo.NumPeaks; i++)
                matchData.Add(new PeakMatchData(nodeTranGroup, chromGroupInfo, mzMatchTolerance, i, totalArea));

            // TODO: Try to improve this. Align peaks in area descending order until peaks do not match
            var alignments = new List<PeakAlignment>();
            bool referenceAligned = false;
            var referenceIter = referenceMatchData.OrderByDescending(d => d.PercentArea).GetEnumerator();
            var curIter = matchData.OrderByDescending(d => d.PercentArea).GetEnumerator();
            while (referenceIter.MoveNext() && curIter.MoveNext())
            {
                var alignAttempt = new PeakAlignment(referenceIter.Current, curIter.Current);
                if (!TryInsertPeakAlignment(alignments, alignAttempt))
                    break;

                if (referenceTarget == alignAttempt.ReferencePeak)
                {
                    // Reference target aligned
                    referenceAligned = true;
                    matchData = new List<PeakMatchData> {alignAttempt.AlignedPeak};
                    break;
                }
            }

            PeakMatch manualMatch = null;

            if (!referenceAligned)
            {
                PeakAlignment prev, next;
                GetSurroundingAlignments(alignments, referenceTarget, out prev, out next);
                if (prev != null || next != null)
                {
                    // At least one alignment occurred
                    var chromGroupMinTime = chromGroupInfo.Times.First();
                    var chromGroupMaxTime = chromGroupInfo.Times.Last();

                    float scale = (chromGroupMaxTime - chromGroupMinTime)/(referenceTarget.MaxTime - referenceTarget.MinTime);
                    manualMatch = MakePeakMatchBetween(scale, referenceTarget, prev, next);
                    if (chromGroupMinTime >= manualMatch.EndTime || manualMatch.StartTime >= chromGroupMaxTime)
                        manualMatch = null;

                    float curMinTime = prev == null ? chromGroupMinTime : prev.AlignedPeak.RetentionTime;
                    float curMaxTime = next == null ? chromGroupMaxTime : next.AlignedPeak.RetentionTime;

                    matchData = matchData.Where(d => curMinTime < d.RetentionTime && d.RetentionTime < curMaxTime).ToList();
                }
            }

            PeakMatchData bestMatch = null;
            double bestScore = double.MinValue;
            foreach (var other in matchData)
            {
                var score = referenceTarget.GetMatchScore(other);
                if (bestMatch == null || score > bestScore)
                {
                    bestScore = score;
                    bestMatch = other;
                }
            }

            // If no matching peak with high enough score was found, but there is a matching
            // peak or some peak with a low score.
            if (bestMatch == null || (!referenceAligned && bestScore < INTEGRATE_SCORE_THRESHOLD && manualMatch != null))
                return manualMatch;

            if (referenceTarget.ShiftLeft == 0 && referenceTarget.ShiftRight == 0)
                return new PeakMatch(bestMatch.RetentionTime);

            var range = bestMatch.EndTime - bestMatch.StartTime;
            var startTime = bestMatch.StartTime + (referenceTarget.ShiftLeft*range);
            var endTime = bestMatch.EndTime + (referenceTarget.ShiftRight*range);
            return startTime <= bestMatch.RetentionTime && bestMatch.RetentionTime <= endTime
                ? new PeakMatch(startTime, endTime)
                : new PeakMatch(bestMatch.RetentionTime); // If the shifted boundaries exclude the peak itself, don't change the boundaries
        }