Beispiel #1
0
        private static bool TryInsertPeakAlignment(IList <PeakAlignment> alignList, PeakAlignment alignment)
        {
            var reference = alignment.ReferencePeak;
            var other     = alignment.AlignedPeak;

            if (Math.Min(reference.PercentArea, other.PercentArea) < ALIGN_AREA_MIN || reference.Abundances.Dot(other.Abundances) < ALIGN_DOT_MIN)
            {
                return(false);
            }

            PeakAlignment prev, next;
            var           insertPos = GetSurroundingAlignments(alignList, reference, out prev, out next);

            if ((prev != null && other.RetentionTime < prev.AlignedPeak.RetentionTime) ||
                (next != null && other.RetentionTime > next.AlignedPeak.RetentionTime))
            {
                return(false);
            }

            alignList.Insert(insertPos, alignment);
            return(true);
        }
Beispiel #2
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 #3
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 #4
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 #5
0
        private static bool TryInsertPeakAlignment(IList<PeakAlignment> alignList, PeakAlignment alignment)
        {
            var reference = alignment.ReferencePeak;
            var other = alignment.AlignedPeak;

            if (Math.Min(reference.PercentArea, other.PercentArea) < ALIGN_AREA_MIN || reference.Abundances.Dot(other.Abundances) < ALIGN_DOT_MIN)
                return false;

            PeakAlignment prev, next;
            var insertPos = GetSurroundingAlignments(alignList, reference, out prev, out next);
            if ((prev != null && other.RetentionTime < prev.AlignedPeak.RetentionTime) ||
                (next != null && other.RetentionTime > next.AlignedPeak.RetentionTime))
            {
                return false;
            }

            alignList.Insert(insertPos, alignment);
            return true;
        }
Beispiel #6
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 #7
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 #8
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
        }