Esempio n. 1
0
        private bool MatchNext(RankingState rankingState, double ionMz, MatchedFragmentIon match, bool filter, int end, int start, double startMz, ref RankedMI rankedMI)
        {
            // Unless trying to match everything, stop looking outside the instrument range
            if (!rankingState.matchAll && !HasLosses && ionMz > MaxMz)
            {
                return(false);
            }
            // Check filter properties, if appropriate
            if ((rankingState.matchAll || ionMz >= MinMz) && Math.Abs(ionMz - rankedMI.ObservedMz) < Libraries.IonMatchTolerance)
            {
                // Make sure each m/z value is only used for the most intense peak
                // that is within the tolerance range.
                if (rankingState.IsSeen(ionMz))
                {
                    return(true); // Keep looking
                }
                rankingState.Seen(ionMz);

                // If this m/z already matched a different ion, just remember the second ion.
                if (rankedMI.MatchedIons != null)
                {
                    // If first type was excluded from causing a ranking, but second does, then make it the first
                    // Otherwise, this can cause very mysterious failures to rank transitions that appear in the
                    // document.
                    if (rankedMI.Rank == 0 && ApplyRanking(rankingState, ionMz, match, filter, start, end, startMz, ref rankedMI))
                    {
                        rankedMI = rankedMI.ChangeMatchedIons(rankedMI.MatchedIons.Prepend(match));
                    }
                    else
                    {
                        rankedMI = rankedMI.ChangeMatchedIons(rankedMI.MatchedIons.Append(match));
                    }
                    if (rankedMI.MatchedIons.Count < MAX_MATCH)
                    {
                        return(true);
                    }

                    rankingState.matched = true;
                    return(false);
                }

                double predictedMz = match.PredictedMz;
                // Avoid using the same predicted m/z on two different peaks
                if (predictedMz == ionMz || !rankingState.IsSeen(predictedMz))
                {
                    rankingState.Seen(predictedMz);

                    ApplyRanking(rankingState, ionMz, match, filter, start, end, startMz, ref rankedMI);
                    rankedMI             = rankedMI.ChangeMatchedIons(ImmutableList.Singleton(match));
                    rankingState.matched = !rankingState.matchAll;
                    return(rankingState.matchAll);
                }
            }
            // Stop looking once the mass has been passed, unless there are losses to consider
            if (HasLosses)
            {
                return(true);
            }
            return(ionMz <= rankedMI.ObservedMz);
        }
Esempio n. 2
0
        private bool ApplyRanking(RankingState rankingState, double ionMz, MatchedFragmentIon match, bool filter, int start, int end, double startMz, ref RankedMI rankedMI)
        {
            // Avoid ranking precursor ions without losses, if the precursor isotopes will
            // not be taken from product ions
            if (!ExcludePrecursorIsotopes || match.IonType != IonType.precursor || match.Losses != null)
            {
                int offset = OrdinalToOffset(match.IonType, match.Ordinal);
                var type   = match.IonType;
                if (filter)
                {
                    if (TargetInfoObj.LookupMods == null || !TargetInfoObj.LookupMods.HasCrosslinks)
                    {
                        if (!TransitionSettings.Accept(Sequence, MoleculeMassesObj.precursorMz, type, offset, ionMz, start,
                                                       end, startMz))
                        {
                            return(false);
                        }
                    }
                }
                if (rankingState.matchAll)
                {
                    if (MinMz > ionMz || ionMz > MaxMz)
                    {
                        return(false);
                    }

                    if (!RankTypes.Contains(type))
                    {
                        return(false);
                    }

                    if (RankLimit.HasValue && rankingState.Ranked >= RankLimit)
                    {
                        return(false);
                    }

                    if (type != IonType.precursor)
                    {
                        // CONSIDER(bspratt) we may eventually want adduct-level control for small molecules, not just abs charge
                        if (!RankCharges.Contains(Math.Abs(match.Charge.AdductCharge)))
                        {
                            return(false);
                        }
                    }
                }

                rankedMI = rankedMI.ChangeRank(rankingState.RankNext());
                return(true);
            }

            return(false);
        }
Esempio n. 3
0
        private MoleculeMasses GetCrosslinkMasses(SrmSettings settings)
        {
            var predictDocNode = MakeTransitionGroupWithAllPossibleChildren(settings, TargetInfoObj.TransitionGroupDocNode.LabelType);
            TransitionGroupDocNode matchDocNode;

            if (Equals(TargetInfoObj.TransitionGroupDocNode.LabelType, TargetInfoObj.SpectrumLabelType))
            {
                matchDocNode = predictDocNode;
            }
            else
            {
                matchDocNode = MakeTransitionGroupWithAllPossibleChildren(settings, TargetInfoObj.SpectrumLabelType);
            }

            var matchTransitions = matchDocNode.Transitions.ToDictionary(child => child.Key(matchDocNode));


            var predictFragments = new List <MatchedFragmentIon>();
            var matchFragments   = new List <MatchedFragmentIon>();

            foreach (var predictedTransition in predictDocNode.Transitions)
            {
                var key = predictedTransition.Key(null);
                TransitionDocNode matchTransition;
                if (!matchTransitions.TryGetValue(key, out matchTransition))
                {
                    continue;
                }

                var    complexFragmentIonName = predictedTransition.ComplexFragmentIon.GetName();
                var    ionType      = DecideIonType(complexFragmentIonName);
                string fragmentName = predictedTransition.ComplexFragmentIon.GetFragmentIonName();
                var    predictedIon = new MatchedFragmentIon(ionType, predictFragments.Count + 1,
                                                             predictedTransition.Transition.Adduct, fragmentName, predictedTransition.Losses,
                                                             predictedTransition.Mz)
                                      .ChangeComplexFragmentIonName(complexFragmentIonName);
                predictFragments.Add(predictedIon);
                matchFragments.Add(predictedIon.ChangePredictedMz(matchTransition.Mz));
            }

            var matchMasses = new IonMasses(
                SequenceMassCalc.GetMH(matchDocNode.PrecursorMz, matchDocNode.PrecursorAdduct,
                                       MassType.MonoisotopicMassH), IonTable <TypedMass> .EMPTY)
                              .ChangeKnownFragments(matchFragments);
            var predictMasses = new IonMasses(
                SequenceMassCalc.GetMH(predictDocNode.PrecursorMz, predictDocNode.PrecursorAdduct,
                                       MassType.MonoisotopicMassH), IonTable <TypedMass> .EMPTY)
                                .ChangeKnownFragments(predictFragments);

            return(new MoleculeMasses(predictDocNode.PrecursorMz, matchMasses).ChangePredictIonMasses(predictMasses));
        }
Esempio n. 4
0
            private bool MatchNext(RankParams rp, IonType type, int offset, TransitionLosses losses, Adduct adduct, string fragmentName, int len, bool filter, int end, int start, double startMz)
            {
                bool isFragment = !Transition.IsPrecursor(type);
                var  ionMass    = isFragment ? rp.massesMatch[type, offset] : rp.massPreMatch;

                if (losses != null)
                {
                    ionMass -= losses.Mass;
                }
                double ionMz = SequenceMassCalc.GetMZ(ionMass, adduct);

                // Unless trying to match everything, stop looking outside the instrument range
                if (!rp.matchAll && !rp.HasLosses && ionMz > rp.maxMz)
                {
                    return(false);
                }
                // Check filter properties, if apropriate
                if ((rp.matchAll || ionMz >= rp.minMz) && Math.Abs(ionMz - ObservedMz) < rp.tolerance)
                {
                    // Make sure each m/z value is only used for the most intense peak
                    // that is within the tolerance range.
                    if (rp.IsSeen(ionMz))
                    {
                        return(true); // Keep looking
                    }
                    rp.Seen(ionMz);

                    int ordinal = Transition.OffsetToOrdinal(type, offset, len + 1);
                    // If this m/z aready matched a different ion, just remember the second ion.
                    var predictedMass = isFragment ? rp.massesPredict[type, offset] : rp.massPrePredict;
                    if (losses != null)
                    {
                        predictedMass -= losses.Mass;
                    }
                    double predictedMz = SequenceMassCalc.GetMZ(predictedMass, adduct);
                    if (MatchedIons != null)
                    {
                        // If first type was excluded from causing a ranking, but second does, then make it the first
                        // Otherwise, this can cause very mysterious failures to rank transitions that appear in the
                        // document.
                        var match = new MatchedFragmentIon(type, ordinal, adduct, fragmentName, losses, predictedMz);
                        if (Rank == 0 && ApplyRanking(rp, type, offset, losses, adduct, filter, start, end, startMz, ionMz))
                        {
                            MatchedIons.Insert(0, match);
                        }
                        else
                        {
                            MatchedIons.Add(match);
                        }
                        if (MatchedIons.Count < RankParams.MAX_MATCH)
                        {
                            return(true);
                        }

                        rp.matched = true;
                        return(false);
                    }

                    // Avoid using the same predicted m/z on two different peaks
                    if (predictedMz == ionMz || !rp.IsSeen(predictedMz))
                    {
                        rp.Seen(predictedMz);

                        ApplyRanking(rp, type, offset, losses, adduct, filter, start, end, startMz, ionMz);

                        MatchedIons = new List <MatchedFragmentIon> {
                            new MatchedFragmentIon(type, ordinal, adduct, fragmentName, losses, predictedMz)
                        };
                        rp.matched = !rp.matchAll;
                        return(rp.matchAll);
                    }
                }
                // Stop looking once the mass has been passed, unless there are losses to consider
                if (rp.HasLosses)
                {
                    return(true);
                }
                return(ionMz <= ObservedMz);
            }