/// <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); }
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)); } } }
/// <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; }
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)); } } }