/// <summary> /// The find optimum hypothesis. /// </summary> /// <param name="observations"> /// The observations. /// </param> /// <param name="driftTubeLength"> /// The drift Tube Length. /// </param> /// <param name="massTarget"> /// The mass Target. /// </param> /// <param name="parameters"> /// The parameters. /// </param> /// <returns> /// The <see cref="AssociationHypothesis"/>. /// </returns> /// <exception cref="NotImplementedException"> /// </exception> public AssociationHypothesis FindOptimumHypothesis(IEnumerable<ObservedPeak> observations, double driftTubeLength, IImsTarget massTarget, CrossSectionSearchParameters parameters, int numberOfVoltageGroups) { observations = observations.ToList(); ObservationTransitionGraph<IonTransition> transitionGraph = new ObservationTransitionGraph<IonTransition>(observations, (a, b) => new IonTransition(a, b)); // Visualize the graph. // transitionGraph.PlotGraph(); // Find all the possible combinotorial tracks // IList<IsomerTrack> candidateTracks = this.FindAllReasonableTracks(transitionGraph, driftTubeLength, massTarget, parameters).ToList(); // Find the top N tracks using K shorestest path algorithm IEnumerable<IEnumerable<IonTransition>> kShorestPaths = transitionGraph.PeakGraph.RankedShortestPathHoffmanPavley(t => 0 - Math.Log(t.TransitionProbability), transitionGraph.SourceVertex, transitionGraph.SinkVertex, this.maxTracks); IEnumerable<IsomerTrack> candidateTracks = MinCostFlowIonTracker.ToTracks(kShorestPaths, parameters, numberOfVoltageGroups, parameters.RegressionSelection); // filter paths TrackFilter filter = new TrackFilter(); Predicate<IsomerTrack> trackPredicate = track => filter.IsTrackPossible(track, massTarget, parameters); List<IsomerTrack> filteredTracks = candidateTracks.ToList().FindAll(trackPredicate); // Select the top N tracks to proceed to next step. var hypotheses = this.FindAllHypothesis(filteredTracks, observations).ToArray(); // Find the combination of tracks that produces the highest posterior probablity. IOrderedEnumerable<AssociationHypothesis> sortedAssociationHypotheses = hypotheses.OrderByDescending(h => h.ProbabilityOfHypothesisGivenData); return sortedAssociationHypotheses.FirstOrDefault(); }
/// <summary> /// Binary increment the selected peaks /// </summary> /// <param name="groups"> /// The groups. /// </param> /// <param name="selectedPeaks"> /// The selected peaks. /// </param> /// <param name="onIndex"> /// The on index. /// </param> /// <param name="graph"> /// The base peak map. /// </param> /// <param name="minFitPoints"> /// The min Fit Points. /// </param> /// <returns> /// The <see cref="bool"/>. /// </returns> /// If incrementing overflows occurs/ all combinations were gone through. /// <exception cref="Exception"> /// </exception> private bool IncrementCombination(VoltageGroup[] groups, ref ObservedPeak[] selectedPeaks, int onIndex, ObservationTransitionGraph<IonTransition> graph) { int peakIndex; if (groups.Length != selectedPeaks.Length) { throw new ArgumentException("Votlage group does not match selected peaks"); } int length = selectedPeaks.Length; // Base case if (onIndex >= length) { return true; } ObservedPeak incrementPeak = selectedPeaks[onIndex]; VoltageGroup group = groups[onIndex]; IList<ObservedPeak> candidates = graph.FindPeaksInVoltageGroup(group).ToList(); // Empty peak if (incrementPeak == null) { peakIndex = -1; } else { peakIndex = candidates.IndexOf(incrementPeak); if (peakIndex < 0) { throw new Exception("The combination to be incremented is not in the base peak map space."); } } if (peakIndex + 1 >= candidates.Count) { if (selectedPeaks[onIndex] != null) { this.trackPointsCounter--; } selectedPeaks[onIndex] = null; return this.IncrementCombination(groups, ref selectedPeaks, onIndex + 1, graph); } else { if (peakIndex + 1 == 0) { this.trackPointsCounter++; } selectedPeaks[onIndex] = candidates[peakIndex + 1]; return false; } }
/// <summary> /// The increment combination. /// </summary> /// <param name="groups"> /// The groups. /// </param> /// <param name="selectedPeaks"> /// The selected peaks. /// </param> /// <param name="basePeakMap"> /// The base peak map. /// </param> /// <param name="minFitPoints"> /// The min Fit Points. /// </param> /// <returns> /// If the increment overflows the "counter"<see cref="bool"/>. /// </returns> private bool IncrementCombination(VoltageGroup[] groups, ref ObservedPeak[] selectedPeaks, ObservationTransitionGraph<IonTransition> graph, int minFitPoints) { bool overflow = false; // So-called do while loop overflow = this.IncrementCombination(groups, ref selectedPeaks, 0, graph); while (!overflow && this.trackPointsCounter < minFitPoints) { overflow = this.IncrementCombination(groups, ref selectedPeaks, 0, graph); } return overflow; }