Ejemplo n.º 1
0
        /// <summary>
        /// Generates candidate matches between alignee features and baseline features.
        /// It does so by finding all alignee-baseline feature pairs that match within a provided
        /// mass tolerance window.
        /// This method matches in mass only.
        /// </summary>
        /// <param name="aligneeFeatures"></param>
        /// <param name="baselineFeatures"></param>
        /// <param name="separationTypes">Separation types to include in matching.</param>
        public void GenerateCandidateMatches(List <UMCLight> aligneeFeatures, List <UMCLight> baselineFeatures, IEnumerable <FeatureLight.SeparationTypes> separationTypes = null)
        {
            // Sort features by mass
            var massComparer = new UMCLight.UmcMassComparer();

            aligneeFeatures.Sort(massComparer);
            baselineFeatures.Sort(massComparer);

            // Go through each MassTimeFeature and see if the next baseline MassTimeFeature matches it
            var baselineFeatureIndex = 0;

            var featureMatches = new List <LcmsWarpFeatureMatch>();

            foreach (var aligneeFeature in aligneeFeatures)
            {
                // Convert tolerance from ppm to Dalton
                var massToleranceDa = aligneeFeature.MassMonoisotopic * this.options.MassTolerance / 1000000;

                // Backtrack baselineFeatureIndex while the baseline feature's mass is greater than the candidate feature's mass minus massToleranceDa
                while (baselineFeatureIndex == baselineFeatures.Count || baselineFeatureIndex >= 0 &&
                       (baselineFeatures[baselineFeatureIndex].MassMonoisotopic > aligneeFeature.MassMonoisotopic - massToleranceDa))
                {
                    baselineFeatureIndex--;
                }
                baselineFeatureIndex++;

                // Add candidate matches
                while (baselineFeatureIndex < baselineFeatures.Count &&
                       (baselineFeatures[baselineFeatureIndex].MassMonoisotopic <
                        (aligneeFeature.MassMonoisotopic + massToleranceDa)))
                {
                    var baselineFeature = baselineFeatures[baselineFeatureIndex];
                    if (baselineFeature.MassMonoisotopic >
                        (aligneeFeature.MassMonoisotopic - massToleranceDa))
                    {   // Feature is within mass tolerance, add the match.
                        var matchToAdd = new LcmsWarpFeatureMatch
                        {
                            AligneeFeature  = aligneeFeature,
                            BaselineFeature = baselineFeature,
                            Net             = aligneeFeature.Net,
                            BaselineNet     = baselineFeature.Net
                        };

                        featureMatches.Add(matchToAdd);
                    }
                    baselineFeatureIndex++;
                }
            }

            // Filter out ambiguous matches
            featureMatches = this.RemovePromiscuousMatches(featureMatches);

            this.Matches = featureMatches;
        }
Ejemplo n.º 2
0
        public List <LcmsWarpFeatureMatch> CalculateAlignmentMatches(List <UMCLight> aligneeFeatures, List <UMCLight> baselineFeatures, double netStdDev, double massStdDev)
        {
            // Sort features by mass
            var massComparer = new UMCLight.UmcMassComparer();

            aligneeFeatures.Sort(massComparer);
            baselineFeatures.Sort(massComparer);

            var baselineFeatureIndex = 0;

            var featureMatches = new List <LcmsWarpFeatureMatch>();

            var minMatchScore = -0.5 * (this.options.MassTolerance * this.options.MassTolerance) / (massStdDev * massStdDev);

            minMatchScore -= 0.5 * (this.options.NetTolerance * this.options.NetTolerance) / (netStdDev * netStdDev);

            foreach (var aligneeFeature in aligneeFeatures)
            {
                // Convert tolerance from ppm to Dalton
                var massTolerance = aligneeFeature.MassMonoisotopic * this.options.MassTolerance / 1000000;

                while (baselineFeatureIndex == baselineFeatures.Count || baselineFeatureIndex >= 0 &&
                       baselineFeatures[baselineFeatureIndex].MassMonoisotopic >
                       aligneeFeature.MassMonoisotopic - massTolerance)
                {
                    baselineFeatureIndex--;
                }
                baselineFeatureIndex++;

                LcmsWarpFeatureMatch bestMatchFeature = null;
                var bestMatchScore = minMatchScore;
                while (baselineFeatureIndex < baselineFeatures.Count &&
                       baselineFeatures[baselineFeatureIndex].MassMonoisotopic <
                       aligneeFeature.MassMonoisotopic + massTolerance)
                {
                    var baselineFeature = baselineFeatures[baselineFeatureIndex];
                    if (baselineFeature.MassMonoisotopic >
                        aligneeFeature.MassMonoisotopic - massTolerance)
                    {
                        // Calculate the mass and net errors
                        // Compute as observedValue - expectedValue
                        var netDiff     = aligneeFeature.NetAligned - baselineFeature.Net;
                        var driftDiff   = aligneeFeature.DriftTime - baselineFeature.DriftTime;
                        var massDiff    = aligneeFeature.MassMonoisotopic - baselineFeature.MassMonoisotopic;
                        var massDiffPpm = massDiff * 1000000.0 / baselineFeature.MassMonoisotopic;

                        var massDiffOriginal    = aligneeFeature.MassMonoisotopicOriginal - baselineFeature.MassMonoisotopic;
                        var originalMassDiffPpm = massDiffOriginal * 1000000.0 / baselineFeature.MassMonoisotopic;

                        // Calculate the match score.
                        var matchScore = -0.5 * (netDiff * netDiff) / (netStdDev * netStdDev);
                        matchScore -= 0.5 * (massDiffPpm * massDiffPpm) / (massStdDev * massStdDev);

                        // If the match score is greater than the best match score, update the holding item.
                        if (matchScore > bestMatchScore)
                        {
                            bestMatchScore   = matchScore;
                            bestMatchFeature = new LcmsWarpFeatureMatch
                            {
                                AligneeFeature       = aligneeFeature,
                                BaselineFeature      = baselineFeature,
                                BaselineFeatureIndex = baselineFeatureIndex,
                                Net                  = aligneeFeature.Net,
                                NetError             = netDiff,
                                MassError            = massDiff,
                                PpmMassError         = massDiffPpm,
                                PpmMassErrorOriginal = originalMassDiffPpm,
                                DriftError           = driftDiff,
                                BaselineNet          = baselineFeatures[baselineFeatureIndex].Net
                            };
                        }
                    }
                    baselineFeatureIndex++;
                }

                // If we found a match, add it to the list of matches.
                if (bestMatchFeature != null)
                {
                    featureMatches.Add(bestMatchFeature);
                }
            }

            return(featureMatches);
        }