示例#1
0
            public void CalculateRank(RankParams rp)
            {
                // Rank based on filtered range, if the settings use it in picking
                bool filter = (rp.pick == TransitionLibraryPick.filter);

                if (rp.knownFragments != null)
                {
                    // Small molecule work - we only know about the fragments we're given, we can't predict others
                    foreach (IonType type in rp.types)
                    {
                        if (Transition.IsPrecursor(type))
                        {
                            if (!MatchNext(rp, type, 0, null, rp.precursorAdduct, null, 0, filter, 0, 0, 0))
                            {
                                // If matched return.  Otherwise look for other ion types.
                                if (rp.matched)
                                {
                                    rp.Clean();
                                    return;
                                }
                            }
                        }
                        else
                        {
                            for (var i = 0; i < rp.knownFragments.Count; i++)
                            {
                                var fragment = rp.knownFragments[i];
                                if (!MatchNext(rp, IonType.custom, i, null, fragment.Adduct, fragment.Name, 0, filter, 0, 0, fragment.Mz))
                                {
                                    // If matched return.  Otherwise look for other ion types.
                                    if (rp.matched)
                                    {
                                        rp.Clean();
                                        return;
                                    }
                                }
                            }
                        }
                    }
                    return;
                }

                // Look for a predicted match within the acceptable tolerance
                int len = rp.massesMatch.GetLength(1);

                foreach (IonType type in rp.types)
                {
                    if (Transition.IsPrecursor(type))
                    {
                        foreach (var losses in TransitionGroup.CalcTransitionLosses(type, 0, rp.massType, rp.potentialLosses))
                        {
                            if (!MatchNext(rp, type, len, losses, rp.precursorAdduct, null, len + 1, filter, len, len, 0))
                            {
                                // If matched return.  Otherwise look for other ion types.
                                if (rp.matched)
                                {
                                    rp.Clean();
                                    return;
                                }
                            }
                        }
                        continue;
                    }

                    foreach (var adduct in rp.adducts)
                    {
                        // Precursor charge can never be lower than product ion charge.
                        if (Math.Abs(rp.precursorAdduct.AdductCharge) < Math.Abs(adduct.AdductCharge))
                        {
                            continue;
                        }

                        int    start = 0, end = 0;
                        double startMz = 0;
                        if (filter)
                        {
                            start = rp.startFinder.FindStartFragment(rp.massesMatch, type, adduct,
                                                                     rp.precursorMz, rp.filter.PrecursorMzWindow, out startMz);
                            end = rp.endFinder.FindEndFragment(type, start, len);
                            if (Transition.IsCTerminal(type))
                            {
                                Helpers.Swap(ref start, ref end);
                            }
                        }

                        // These inner loops are performance bottlenecks, and the following
                        // code duplication proved the fastest implementation under a
                        // profiler.  Apparently .NET failed to inline an attempt to put
                        // the loop contents in a function.
                        if (Transition.IsCTerminal(type))
                        {
                            for (int i = len - 1; i >= 0; i--)
                            {
                                foreach (var losses in TransitionGroup.CalcTransitionLosses(type, i, rp.massType, rp.potentialLosses))
                                {
                                    if (!MatchNext(rp, type, i, losses, adduct, null, len, filter, end, start, startMz))
                                    {
                                        if (rp.matched)
                                        {
                                            rp.Clean();
                                            return;
                                        }
                                        i = -1; // Terminate loop on i
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            for (int i = 0; i < len; i++)
                            {
                                foreach (var losses in TransitionGroup.CalcTransitionLosses(type, i, rp.massType, rp.potentialLosses))
                                {
                                    if (!MatchNext(rp, type, i, losses, adduct, null, len, filter, end, start, startMz))
                                    {
                                        if (rp.matched)
                                        {
                                            rp.Clean();
                                            return;
                                        }
                                        i = len; // Terminate loop on i
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
示例#2
0
        private RankedMI CalculateRank(RankingState rankingState, RankedMI rankedMI)
        {
            // Rank based on filtered range, if the settings use it in picking
            bool filter = (Pick == TransitionLibraryPick.filter);

            var knownFragments = MoleculeMassesObj.MatchIonMasses.KnownFragments;

            if (knownFragments != null)
            {
                // Small molecule work - we only know about the fragments we're given, we can't predict others
                foreach (IonType type in Types)
                {
                    if (Transition.IsPrecursor(type))
                    {
                        var matchedFragmentIon = MakeMatchedFragmentIon(type, 0, PrecursorAdduct, null, out double matchMz);

                        if (!MatchNext(rankingState, matchMz, matchedFragmentIon, filter, 0, 0, 0, ref rankedMI))
                        {
                            // If matched return.  Otherwise look for other ion types.
                            if (rankingState.matched)
                            {
                                rankingState.Clean();
                                return(rankedMI);
                            }
                        }
                    }
                    else
                    {
                        for (var i = 0; i < knownFragments.Count; i++)
                        {
                            var    fragment = knownFragments[i];
                            double matchMz  = MoleculeMassesObj.PredictIonMasses.KnownFragments[i].PredictedMz;
                            if (!MatchNext(rankingState, matchMz, fragment, filter, 0, 0, fragment.PredictedMz, ref rankedMI))
                            {
                                // If matched return.  Otherwise look for other ion types.
                                if (rankingState.matched)
                                {
                                    rankingState.Clean();
                                    return(rankedMI);
                                }
                            }
                        }
                    }
                }
                return(rankedMI);
            }

            // Look for a predicted match within the acceptable tolerance
            int len = MoleculeMassesObj.MatchIonMasses.FragmentMasses.GetLength(1);

            foreach (IonType type in Types)
            {
                if (Transition.IsPrecursor(type))
                {
                    foreach (var losses in TransitionGroup.CalcTransitionLosses(type, 0, MassType, PotentialLosses))
                    {
                        var matchedFragmentIon =
                            MakeMatchedFragmentIon(type, 0, PrecursorAdduct, losses, out double matchMz);
                        if (!MatchNext(rankingState, matchMz, matchedFragmentIon, filter, len, len, 0, ref rankedMI))
                        {
                            // If matched return.  Otherwise look for other ion types.
                            if (rankingState.matched)
                            {
                                rankingState.Clean();
                                return(rankedMI);
                            }
                        }
                    }
                    continue;
                }

                foreach (var adduct in Adducts)
                {
                    // Precursor charge can never be lower than product ion charge.
                    if (Math.Abs(PrecursorAdduct.AdductCharge) < Math.Abs(adduct.AdductCharge))
                    {
                        continue;
                    }

                    int    start = 0, end = 0;
                    double startMz = 0;
                    if (filter)
                    {
                        start = TransitionSettings.Filter.FragmentRangeFirst.FindStartFragment(
                            MoleculeMassesObj.MatchIonMasses.FragmentMasses, type, adduct,
                            MoleculeMassesObj.precursorMz, TransitionSettings.Filter.PrecursorMzWindow, out startMz);
                        end = TransitionSettings.Filter.FragmentRangeLast.FindEndFragment(type, start, len);
                        if (Transition.IsCTerminal(type))
                        {
                            Helpers.Swap(ref start, ref end);
                        }
                    }

                    // These inner loops are performance bottlenecks, and the following
                    // code duplication proved the fastest implementation under a
                    // profiler.  Apparently .NET failed to inline an attempt to put
                    // the loop contents in a function.
                    if (Transition.IsCTerminal(type))
                    {
                        for (int i = len - 1; i >= 0; i--)
                        {
                            foreach (var losses in TransitionGroup.CalcTransitionLosses(type, i, MassType, PotentialLosses))
                            {
                                var matchedFragmentIon =
                                    MakeMatchedFragmentIon(type, i, adduct, losses, out double matchMz);
                                if (!MatchNext(rankingState, matchMz, matchedFragmentIon, filter, end, start, startMz, ref rankedMI))
                                {
                                    if (rankingState.matched)
                                    {
                                        rankingState.Clean();
                                        return(rankedMI);
                                    }
                                    i = -1; // Terminate loop on i
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < len; i++)
                        {
                            foreach (var losses in TransitionGroup.CalcTransitionLosses(type, i, MassType, PotentialLosses))
                            {
                                var matchedFragmentIon =
                                    MakeMatchedFragmentIon(type, i, adduct, losses, out double matchMz);
                                if (!MatchNext(rankingState, matchMz, matchedFragmentIon, filter, end, start, startMz, ref rankedMI))
                                {
                                    if (rankingState.matched)
                                    {
                                        rankingState.Clean();
                                        return(rankedMI);
                                    }
                                    i = len; // Terminate loop on i
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            return(rankedMI);
        }