/// <summary> /// Builds a peak matcher object. /// </summary> public void BuildPeakMatcher(MultiAlignAnalysisOptions options) { var tolerances = new FeatureMatcherTolerances(); var stanleyMatcher = new STACAdapter <UMCClusterLight> { Options = { HistogramBinWidth = options.StacOptions.HistogramBinWidth, HistogramMultiplier = options.StacOptions.HistogramMultiplier, ShiftAmount = options.StacOptions.ShiftAmount, ShouldCalculateHistogramFDR = options.StacOptions.ShouldCalculateHistogramFDR, ShouldCalculateShiftFDR = options.StacOptions.ShouldCalculateShiftFDR, ShouldCalculateSLiC = options.StacOptions.ShouldCalculateSLiC, ShouldCalculateSTAC = options.StacOptions.ShouldCalculateSTAC, UseDriftTime = options.StacOptions.UseDriftTime, UseEllipsoid = options.StacOptions.UseEllipsoid, UsePriors = options.StacOptions.UsePriors } }; tolerances.DriftTimeTolerance = Convert.ToSingle(options.StacOptions.DriftTimeTolerance); tolerances.MassTolerancePPM = options.StacOptions.MassTolerancePPM; tolerances.NETTolerance = options.StacOptions.NETTolerance; tolerances.Refined = options.StacOptions.Refined; stanleyMatcher.Options.UserTolerances = tolerances; m_provider.PeakMatcher = stanleyMatcher; }
/// <summary> /// Builds a peak matcher object. /// </summary> public void BuildPeakMatcher(MultiAlignAnalysisOptions options) { var tolerances = new FeatureMatcherTolerances(); var stanleyMatcher = new STACAdapter<UMCClusterLight> { Options = { HistogramBinWidth = options.StacOptions.HistogramBinWidth, HistogramMultiplier = options.StacOptions.HistogramMultiplier, ShiftAmount = options.StacOptions.ShiftAmount, ShouldCalculateHistogramFDR = options.StacOptions.ShouldCalculateHistogramFDR, ShouldCalculateShiftFDR = options.StacOptions.ShouldCalculateShiftFDR, ShouldCalculateSLiC = options.StacOptions.ShouldCalculateSLiC, ShouldCalculateSTAC = options.StacOptions.ShouldCalculateSTAC, UseDriftTime = options.StacOptions.UseDriftTime, UseEllipsoid = options.StacOptions.UseEllipsoid, UsePriors = options.StacOptions.UsePriors } }; tolerances.DriftTimeTolerance = Convert.ToSingle(options.StacOptions.DriftTimeTolerance); tolerances.MassTolerancePPM = options.StacOptions.MassTolerancePPM; tolerances.NETTolerance = options.StacOptions.NETTolerance; tolerances.Refined = options.StacOptions.Refined; stanleyMatcher.Options.UserTolerances = tolerances; m_provider.PeakMatcher = stanleyMatcher; }
/// <summary> /// Sets the internal flag as to whether the match is within the given tolerances. /// </summary> /// <param name="tolerances">Tolerances to use for matching.</param> /// <param name="useElllipsoid">Whether to use ellipsoidal region for matching.</param> /// <returns></returns> public bool InRegion(FeatureMatcherTolerances tolerances, bool useElllipsoid) { if (m_targetFeature == new TTarget()) { throw new InvalidOperationException("Match must be populated before using functions involving the match."); } var toleranceMatrix = tolerances.AsVector(true); if (m_reducedDifferenceVector != new DenseMatrix(2, 1)) { var dimensions = m_reducedDifferenceVector.RowCount; if (useElllipsoid) { double distance = 0; for (var i = 0; i < dimensions; i++) { distance += m_reducedDifferenceVector[i, 0] * m_reducedDifferenceVector[i, 0] / toleranceMatrix[i, 0] / toleranceMatrix[i, 0]; } m_withinRefinedRegion = (distance <= 1); } else { var truthValue = true; for (var i = 0; i < dimensions; i++) { truthValue = (truthValue && Math.Abs(m_reducedDifferenceVector[i, 0]) <= toleranceMatrix[i, 0]); } m_withinRefinedRegion = truthValue; } } else { if (useElllipsoid) { double distance = 0; var massDiff = m_observedFeature.MassMonoisotopicAligned - m_targetFeature.MassMonoisotopicAligned; var netDiff = m_observedFeature.NetAligned - m_targetFeature.NetAligned; distance += massDiff * massDiff / toleranceMatrix[0, 0] / toleranceMatrix[0, 0]; distance += netDiff * netDiff / toleranceMatrix[1, 0] / toleranceMatrix[1, 0]; // TODO: Add drift time difference. m_withinRefinedRegion = (distance <= 1); } } return(m_withinRefinedRegion); }
/// <summary> /// Find a list of matches between two lists. /// </summary> /// <param name="shortObservedList">List of observed features. Possibly a subset of the entire list corresponding to a particular charge state.</param> /// <param name="shortTargetList">List of target features. Possibly a subset of the entire list corresponding to a particular charge state.</param> /// <param name="tolerances">Tolerances to be used for matching.</param> /// <param name="shiftAmount">A fixed shift amount to use for populating the shifted match list.</param> /// <returns>A list of type FeatureMatch containing matches within the defined region.</returns> public List <FeatureMatch <TObserved, TTarget> > FindMatches(List <TObserved> shortObservedList, List <TTarget> shortTargetList, FeatureMatcherTolerances tolerances, double shiftAmount) { // Create a list to hold the matches until they are returned. var matchList = new List <FeatureMatch <TObserved, TTarget> >(); // Set indices to use when iterating over the lists. var observedIndex = 0; var lowerBound = 0; // Sort both lists by mass. if (!double.IsNaN(shortObservedList[0].MassMonoisotopicAligned) && shortObservedList[0].MassMonoisotopicAligned > 0.0) { shortObservedList.Sort(FeatureLight.MassAlignedComparison); } else { shortObservedList.Sort(FeatureLight.MassComparison); } if (!double.IsNaN(shortTargetList[0].MassMonoisotopicAligned) && shortTargetList[0].MassMonoisotopicAligned > 0.0) { shortTargetList.Sort(FeatureLight.MassAlignedComparison); } else { shortTargetList.Sort(FeatureLight.MassComparison); } // Locally store the tolerances. var massTolerancePpm = tolerances.MassTolerancePPM; var netTolerance = tolerances.NETTolerance; var driftTimeTolerance = tolerances.DriftTimeTolerance; // Iterate through the list of observed features. while (observedIndex < shortObservedList.Count) { // Store the current observed feature locally. var observedFeature = shortObservedList[observedIndex]; // Flag variable that gets set to false when the observed mass is greater than the current mass tag by more than the tolerance. var continueLoop = true; // Set the target feature iterator to the current lower bound. var targetIndex = lowerBound; // Iterate through the list of target featrues or until the observed feature is too great. while (targetIndex < shortTargetList.Count && continueLoop) { // Add any shift to the mass tag. var targetFeature = shortTargetList[targetIndex]; // Check to see that the features are within the mass tolearance of one another. double massDifference; if (WithinMassTolerance(observedFeature, targetFeature, massTolerancePpm, shiftAmount, out massDifference)) { var withinTolerances = WithinNETTolerance(observedFeature, targetFeature, netTolerance); if (m_matchParameters.UseDriftTime) { withinTolerances = withinTolerances & WithinDriftTimeTolerance(observedFeature, targetFeature, driftTimeTolerance); withinTolerances = withinTolerances & (observedFeature.ChargeState == targetFeature.ChargeState); } // Create a temporary match between the two and check it against all tolerances before adding to the match list. if (withinTolerances) { var match = new FeatureMatch <TObserved, TTarget>(); match.AddFeatures(observedFeature, targetFeature, m_matchParameters.UseDriftTime, (shiftAmount > 0)); matchList.Add(match); } } else { // Increase the lower bound if the the MassTag masses are too low or set the continueLoop flag to false if they are too high. if (massDifference < massTolerancePpm) { lowerBound++; } else { continueLoop = false; } } // Increment the target index. targetIndex++; } // Increment the observed index. observedIndex++; } // Return the list of matches. return(matchList); }