예제 #1
0
        /// <summary>
        /// Compares the modifications indicated in the sequence string to the calculated masses.
        /// </summary>
        /// <param name="seq">The modified sequence.</param>
        /// <param name="calc">Calculator used to calculate the masses.</param>
        /// <param name="calcLight">
        /// Additional light calculator if necessary to isolate mass changes
        /// caused by heavy modifications alone.
        /// </param>
        /// <returns>
        /// True if the given calculators explain the modifications indicated on the sequence,
        /// false otherwise.
        /// </returns>
        private bool EqualsModifications(string seq, IPrecursorMassCalc calc, IPrecursorMassCalc calcLight)
        {
            var    modifications = Settings.PeptideSettings.Modifications;
            bool   structural    = calcLight == null;
            string aas           = FastaSequence.StripModifications(seq);

            foreach (var info in EnumerateSequenceInfos(seq, true))
            {
                int indexAA   = info.IndexAA; // ReSharper
                var aa        = aas[indexAA];
                var roundedTo = info.RoundedTo;
                // If the user has indicated the modification by name, find that modification
                // and calculate the mass.
                double massKey;
                if (info.Mass != null)
                {
                    massKey = (double)info.Mass;
                }
                else
                {
                    var       info1    = info;
                    StaticMod modMatch = null;
                    int       index;
                    if (structural &&
                        ((index = modifications.StaticModifications.IndexOf(mod => Equals(mod.Name, info1.Name)))
                         != -1))
                    {
                        modMatch = modifications.StaticModifications[index];
                    }
                    if (!structural &&
                        ((index = modifications.HeavyModifications.IndexOf(mod => Equals(mod.Name, info1.Name)))
                         != -1))
                    {
                        modMatch = modifications.HeavyModifications[index];
                    }

                    if (modMatch == null)
                    {
                        return(false);
                    }
                    roundedTo = DEFAULT_ROUNDING_DIGITS;
                    massKey   = Math.Round(GetDefaultModMass(aa, modMatch), roundedTo);
                }
                double massMod = Math.Round(calc.GetAAModMass(aas[indexAA], indexAA, aas.Length), roundedTo);
                // Subtract the mass difference of the light
                // modifications to isolate the masses of the heavy modifications.
                if (calcLight != null)
                {
                    massMod -= Math.Round(calcLight.GetAAModMass(aas[indexAA], indexAA, aas.Length), roundedTo);
                }
                if (!Equals(massKey, massMod))
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #2
0
        public IEnumerable <TransitionDocNode> GetPrecursorTransitions(SrmSettings settings,
                                                                       ExplicitMods mods,
                                                                       IPrecursorMassCalc calcFilterPre,
                                                                       IFragmentMassCalc calcPredict,
                                                                       double precursorMz,
                                                                       IsotopeDistInfo isotopeDist,
                                                                       IList <IList <ExplicitLoss> > potentialLosses,
                                                                       IDictionary <double, LibraryRankedSpectrumInfo.RankedMI> transitionRanks,
                                                                       bool libraryFilter,
                                                                       bool useFilter)
        {
            var      tranSettings = settings.TransitionSettings;
            var      fullScan     = tranSettings.FullScan;
            MassType massType     = tranSettings.Prediction.FragmentMassType;
            int      minMz        = tranSettings.Instrument.GetMinMz(precursorMz);
            int      maxMz        = tranSettings.Instrument.MaxMz;
            bool     precursorMS1 = fullScan.IsEnabledMs;

            if (IsCustomIon)
            {
                var ionMz =
                    BioMassCalc.CalculateIonMz(
                        CustomIon.GetMass(settings.TransitionSettings.Prediction.PrecursorMassType),
                        PrecursorCharge);
                if (!useFilter ||
                    !libraryFilter ||
                    IsMatched(transitionRanks,
                              ionMz, IonType.precursor,
                              PrecursorCharge, null))
                {
                    if (precursorMS1 && isotopeDist != null)
                    {
                        foreach (int i in fullScan.SelectMassIndices(isotopeDist, useFilter))
                        {
                            double precursorMS1Mass = isotopeDist.GetMassI(i);
                            ionMz = BioMassCalc.CalculateIonMz(precursorMS1Mass, PrecursorCharge);
                            if (minMz > ionMz || ionMz > maxMz)
                            {
                                continue;
                            }
                            var isotopeDistInfo = new TransitionIsotopeDistInfo(isotopeDist.GetRankI(i), isotopeDist.GetProportionI(i));
                            yield return(CreateTransitionNode(i, precursorMS1Mass, isotopeDistInfo, null, transitionRanks, CustomIon));
                        }
                    }
                    else
                    {
                        var    transition = new Transition(this, PrecursorCharge, null, CustomIon, IonType.precursor);
                        double massH      = CustomIon.GetMass(settings.TransitionSettings.Prediction.PrecursorMassType);
                        yield return(new TransitionDocNode(transition, null, massH, null, null));
                    }
                }
                yield break;
            }

            string sequence            = Peptide.Sequence;
            bool   precursorNoProducts = precursorMS1 && !fullScan.IsEnabledMsMs &&
                                         tranSettings.Filter.IonTypes.Count == 1 && tranSettings.Filter.IonTypes[0] == IonType.precursor;
            double precursorMassPredict = calcPredict.GetPrecursorFragmentMass(sequence);

            foreach (var losses in CalcTransitionLosses(IonType.precursor, 0, massType, potentialLosses))
            {
                double ionMz = SequenceMassCalc.GetMZ(Transition.CalcMass(precursorMassPredict, losses), PrecursorCharge);
                if (losses == null)
                {
                    if (precursorMS1 && isotopeDist != null)
                    {
                        foreach (int i in fullScan.SelectMassIndices(isotopeDist, useFilter))
                        {
                            double precursorMS1Mass = isotopeDist.GetMassI(i, DecoyMassShift);
                            ionMz = SequenceMassCalc.GetMZ(precursorMS1Mass, PrecursorCharge);
                            if (minMz > ionMz || ionMz > maxMz)
                            {
                                continue;
                            }
                            var isotopeDistInfo = new TransitionIsotopeDistInfo(
                                isotopeDist.GetRankI(i), isotopeDist.GetProportionI(i));
                            yield return(CreateTransitionNode(i, precursorMS1Mass, isotopeDistInfo, null, transitionRanks));
                        }
                        continue;
                    }
                }
                // If there was loss, it is possible (though not likely) that the ion m/z value
                // will now fall below the minimum measurable value for the instrument
                else if (minMz > ionMz)
                {
                    continue;
                }

                // If filtering precursors from MS1 scans, then ranking in MS/MS does not apply
                bool precursorIsProduct = !precursorMS1 || losses != null;
                // Skip product ion precursors, if the should not be included
                if (useFilter && precursorIsProduct && precursorNoProducts)
                {
                    continue;
                }
                if (!useFilter || !precursorIsProduct ||
                    !libraryFilter || IsMatched(transitionRanks, ionMz, IonType.precursor,
                                                PrecursorCharge, losses))
                {
                    yield return(CreateTransitionNode(0, precursorMassPredict, null, losses,
                                                      precursorIsProduct ? transitionRanks : null));
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Compares the modifications indicated in the sequence string to the calculated masses.
        /// </summary>
        /// <param name="seq">The modified sequence.</param>
        /// <param name="calc">Calculator used to calculate the masses.</param>
        /// <param name="calcLight">
        /// Additional light calculator if necessary to isolate mass changes
        /// caused by heavy modifications alone.
        /// </param>
        /// <returns>
        /// True if the given calculators explain the modifications indicated on the sequence, 
        /// false otherwise.
        /// </returns>
        private bool EqualsModifications(string seq, IPrecursorMassCalc calc, IPrecursorMassCalc calcLight)
        {
            var modifications = Settings.PeptideSettings.Modifications;
            bool structural = calcLight == null;
            string aas = FastaSequence.StripModifications(seq);
            foreach (var info in EnumerateSequenceInfos(seq, true))
            {
                int indexAA = info.IndexAA; // ReSharper
                var aa = aas[indexAA];
                var roundedTo = info.RoundedTo;
                // If the user has indicated the modification by name, find that modification
                // and calculate the mass.
                double massKey;
                if (info.Mass != null)
                    massKey = (double)info.Mass;
                else
                {
                    var info1 = info;
                    StaticMod modMatch = null;
                    int index;
                    if (structural &&
                        ((index = modifications.StaticModifications.IndexOf(mod => Equals(mod.Name, info1.Name)))
                        != -1))
                        modMatch = modifications.StaticModifications[index];
                    if (!structural &&
                        ((index = modifications.HeavyModifications.IndexOf(mod => Equals(mod.Name, info1.Name)))
                        != -1))
                        modMatch = modifications.HeavyModifications[index];

                    if (modMatch == null)
                        return false;
                    roundedTo = DEFAULT_ROUNDING_DIGITS;
                    massKey = Math.Round(GetDefaultModMass(aa, modMatch), roundedTo);
                }
                double massMod = Math.Round(calc.GetAAModMass(aas[indexAA], indexAA, aas.Length), roundedTo);
                // Subtract the mass difference of the light
                // modifications to isolate the masses of the heavy modifications.
                if (calcLight != null)
                    massMod -= Math.Round(calcLight.GetAAModMass(aas[indexAA], indexAA, aas.Length), roundedTo);
                if (!Equals(massKey, massMod))
                    return false;
            }
            return true;
        }
예제 #4
0
        public IEnumerable <TransitionDocNode> GetPrecursorTransitions(SrmSettings settings,
                                                                       ExplicitMods mods,
                                                                       IPrecursorMassCalc calcPredictPre,
                                                                       IFragmentMassCalc calcPredict,
                                                                       double precursorMz,
                                                                       IsotopeDistInfo isotopeDist,
                                                                       IList <IList <ExplicitLoss> > potentialLosses,
                                                                       IDictionary <double, LibraryRankedSpectrumInfo.RankedMI> transitionRanks,
                                                                       bool libraryFilter,
                                                                       bool useFilter,
                                                                       bool ensureMassesAreMeasurable)
        {
            var      tranSettings = settings.TransitionSettings;
            var      fullScan     = tranSettings.FullScan;
            int      minMz        = tranSettings.Instrument.GetMinMz(precursorMz);
            int      maxMz        = tranSettings.Instrument.MaxMz;
            bool     precursorMS1 = fullScan.IsEnabledMs;
            MassType massType     = tranSettings.Prediction.FragmentMassType;
            MassType massTypeIon  = precursorMS1 ? tranSettings.Prediction.PrecursorMassType : massType;

            var  sequence            = Peptide.Target;
            var  ionTypes            = IsProteomic ? tranSettings.Filter.PeptideIonTypes : tranSettings.Filter.SmallMoleculeIonTypes;
            bool precursorNoProducts = precursorMS1 && !fullScan.IsEnabledMsMs &&
                                       ionTypes.Count == 1 && ionTypes[0] == IonType.precursor;
            var precursorMassPredict = precursorMS1
                ? calcPredictPre.GetPrecursorMass(sequence)
                : calcPredict.GetPrecursorFragmentMass(sequence);

            foreach (var losses in CalcTransitionLosses(IonType.precursor, 0, massType, potentialLosses))
            {
                Adduct productAdduct;
                if (losses == null)
                {
                    productAdduct = PrecursorAdduct;
                }
                else
                {
                    productAdduct = losses.GetProductAdduct(PrecursorAdduct);
                    if (productAdduct == null)
                    {
                        continue;
                    }
                }

                double ionMz = IsProteomic ?
                               SequenceMassCalc.GetMZ(Transition.CalcMass(precursorMassPredict, losses), PrecursorAdduct) :
                               PrecursorAdduct.MzFromNeutralMass(CustomMolecule.GetMass(massTypeIon), massTypeIon);

                if (losses == null)
                {
                    if (precursorMS1 && isotopeDist != null && ensureMassesAreMeasurable)
                    {
                        foreach (int i in fullScan.SelectMassIndices(isotopeDist, useFilter))
                        {
                            var precursorMS1Mass = isotopeDist.GetMassI(i, DecoyMassShift);
                            ionMz = SequenceMassCalc.GetMZ(precursorMS1Mass, PrecursorAdduct);
                            if (minMz > ionMz || ionMz > maxMz)
                            {
                                continue;
                            }
                            var isotopeDistInfo = new TransitionIsotopeDistInfo(
                                isotopeDist.GetRankI(i), isotopeDist.GetProportionI(i));
                            yield return(CreateTransitionNode(i, precursorMS1Mass, isotopeDistInfo, null, transitionRanks, productAdduct));
                        }
                        continue;
                    }
                }
                // If there was loss, it is possible (though not likely) that the ion m/z value
                // will now fall below the minimum measurable value for the instrument
                else if (ensureMassesAreMeasurable && minMz > ionMz)
                {
                    continue;
                }

                // If filtering precursors from MS1 scans, then ranking in MS/MS does not apply
                bool precursorIsProduct = !precursorMS1 || losses != null;
                // Skip product ion precursors, if the should not be included
                if (useFilter && precursorIsProduct && precursorNoProducts)
                {
                    continue;
                }
                if (!useFilter || !precursorIsProduct ||
                    !libraryFilter || IsMatched(transitionRanks, ionMz, IonType.precursor,
                                                PrecursorAdduct, losses))
                {
                    yield return(CreateTransitionNode(0, precursorMassPredict, null, losses,
                                                      precursorIsProduct ? transitionRanks : null, productAdduct));
                }
            }
        }