private TransitionDocNode CreateTransitionNode(IonType type, int cleavageOffset, int charge, double massH, TransitionLosses losses, IDictionary <double, LibraryRankedSpectrumInfo.RankedMI> transitionRanks, CustomIon customIon = null) { Transition transition = new Transition(this, type, cleavageOffset, 0, charge, null, customIon); var info = TransitionDocNode.GetLibInfo(transition, Transition.CalcMass(massH, losses), transitionRanks); return(new TransitionDocNode(transition, losses, massH, null, info)); }
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)); } } }
private TransitionDocNode CreateTransitionNode(int massIndex, double precursorMassH, TransitionIsotopeDistInfo isotopeDistInfo, TransitionLosses losses, IDictionary <double, LibraryRankedSpectrumInfo.RankedMI> transitionRanks, CustomIon customIon = null) { Transition transition = new Transition(this, massIndex, customIon); var info = isotopeDistInfo == null?TransitionDocNode.GetLibInfo(transition, Transition.CalcMass(precursorMassH, losses), transitionRanks) : null; return(new TransitionDocNode(transition, losses, precursorMassH, isotopeDistInfo, info)); }
public IEnumerable <TransitionDocNode> GetTransitions(SrmSettings settings, TransitionGroupDocNode groupDocNode, ExplicitMods mods, double precursorMz, IsotopeDistInfo isotopeDist, SpectrumHeaderInfo libInfo, IDictionary <double, LibraryRankedSpectrumInfo.RankedMI> transitionRanks, bool useFilter) { Assume.IsTrue(ReferenceEquals(groupDocNode.TransitionGroup, this)); // Get necessary mass calculators and masses var calcFilterPre = settings.GetPrecursorCalc(IsotopeLabelType.light, mods); var calcFilter = settings.GetFragmentCalc(IsotopeLabelType.light, mods); var calcPredict = settings.GetFragmentCalc(LabelType, mods); string sequence = Peptide.Sequence; // Save the true precursor m/z for TranstionSettings.Accept() now that all isotope types are // checked. This is more correct than just using the light precursor m/z for precursor window // exclusion. double precursorMzAccept = precursorMz; if (!ReferenceEquals(calcFilter, calcPredict)) { // Get the normal precursor m/z for filtering, so that light and heavy ion picks will match. precursorMz = IsCustomIon ? BioMassCalc.CalculateIonMz(calcFilterPre.GetPrecursorMass(groupDocNode.CustomIon), groupDocNode.TransitionGroup.PrecursorCharge) : SequenceMassCalc.GetMZ(calcFilterPre.GetPrecursorMass(sequence), groupDocNode.TransitionGroup.PrecursorCharge); } if (!IsAvoidMismatchedIsotopeTransitions) { precursorMzAccept = precursorMz; } var tranSettings = settings.TransitionSettings; var filter = tranSettings.Filter; var charges = filter.ProductCharges; var startFinder = filter.FragmentRangeFirst; var endFinder = filter.FragmentRangeLast; double precursorMzWindow = filter.PrecursorMzWindow; var types = filter.IonTypes; MassType massType = tranSettings.Prediction.FragmentMassType; int minMz = tranSettings.Instrument.GetMinMz(precursorMzAccept); int maxMz = tranSettings.Instrument.MaxMz; var pepMods = settings.PeptideSettings.Modifications; var potentialLosses = CalcPotentialLosses(sequence, pepMods, mods, massType); // A start m/z will need to be calculated if the start fragment // finder uses m/z and their are losses to consider. If the filter // is set to only consider fragments with m/z greater than the // precursor, the code below needs to also prevent loss fragments // from being under that m/z. double startMz = 0; // Get library settings var pick = tranSettings.Libraries.Pick; if (!useFilter) { pick = TransitionLibraryPick.all; var listAll = Transition.ALL_CHARGES.ToList(); listAll.AddRange(charges.Where(c => !Transition.ALL_CHARGES.Contains(c))); listAll.Sort(); charges = listAll.ToArray(); types = Transition.ALL_TYPES; } // If there are no libraries or no library information, then // picking cannot use library information else if (!settings.PeptideSettings.Libraries.HasLibraries || libInfo == null) { pick = TransitionLibraryPick.none; } // If filtering without library picking if (potentialLosses != null) { if (pick == TransitionLibraryPick.none) { // Only include loss combinations where all losses are included always potentialLosses = potentialLosses.Where(losses => losses.All(loss => loss.TransitionLoss.Loss.Inclusion == LossInclusion.Always)).ToArray(); } else if (useFilter) { // Exclude all losses which should never be included by default potentialLosses = potentialLosses.Where(losses => losses.All(loss => loss.TransitionLoss.Loss.Inclusion != LossInclusion.Never)).ToArray(); } if (!potentialLosses.Any()) { potentialLosses = null; } } // Return precursor ions if (!useFilter || types.Contains(IonType.precursor)) { bool libraryFilter = (pick == TransitionLibraryPick.all || pick == TransitionLibraryPick.filter); foreach (var nodeTran in GetPrecursorTransitions(settings, mods, calcFilterPre, calcPredict, precursorMz, isotopeDist, potentialLosses, transitionRanks, libraryFilter, useFilter)) { if (minMz <= nodeTran.Mz && nodeTran.Mz <= maxMz) { yield return(nodeTran); } } } // Return special ions from settings, if this is a peptide if (!IsCustomIon) { // This is a peptide, but it may have custom transitions (reporter ions), check those foreach (var measuredIon in tranSettings.Filter.MeasuredIons.Where(m => m.IsCustom)) { if (useFilter && measuredIon.IsOptional) { continue; } var tran = new Transition(this, measuredIon.Charge, null, measuredIon.CustomIon); double mass = settings.GetFragmentMass(IsotopeLabelType.light, null, tran, null); var nodeTran = new TransitionDocNode(tran, null, mass, null, null); if (minMz <= nodeTran.Mz && nodeTran.Mz <= maxMz) { yield return(nodeTran); } } } // For small molecules we can't generate new nodes, so just mz filter those we have foreach (var nodeTran in groupDocNode.Transitions.Where(tran => tran.Transition.IsNonPrecursorNonReporterCustomIon())) { if (minMz <= nodeTran.Mz && nodeTran.Mz <= maxMz) { yield return(nodeTran); } } if (sequence == null) // Completely custom { yield break; } // If picking relies on library information if (useFilter && pick != TransitionLibraryPick.none) { // If it is not yet loaded, or nothing got ranked, return an empty enumeration if (!settings.PeptideSettings.Libraries.IsLoaded || (transitionRanks != null && transitionRanks.Count == 0)) { yield break; } } double[,] massesPredict = calcPredict.GetFragmentIonMasses(sequence); int len = massesPredict.GetLength(1); if (len == 0) { yield break; } double[,] massesFilter = massesPredict; if (!ReferenceEquals(calcFilter, calcPredict)) { // Get the normal m/z values for filtering, so that light and heavy // ion picks will match. massesFilter = calcFilter.GetFragmentIonMasses(sequence); } // Get types other than this to make sure matches are possible for all types var listOtherTypes = new List <Tuple <TransitionGroupDocNode, IFragmentMassCalc> >(); foreach (var labelType in settings.PeptideSettings.Modifications.GetModificationTypes()) { if (Equals(labelType, LabelType)) { continue; } var calc = settings.GetFragmentCalc(labelType, mods); if (calc == null) { continue; } var tranGroupOther = new TransitionGroup(Peptide, PrecursorCharge, labelType, false, DecoyMassShift); var nodeGroupOther = new TransitionGroupDocNode(tranGroupOther, Annotations.EMPTY, settings, mods, libInfo, ExplicitTransitionGroupValues.EMPTY, null, new TransitionDocNode[0], false); listOtherTypes.Add(new Tuple <TransitionGroupDocNode, IFragmentMassCalc>(nodeGroupOther, calc)); } // Loop over potential product ions picking transitions foreach (IonType type in types) { // Precursor type is handled above. if (type == IonType.precursor) { continue; } foreach (int charge in charges) { // Precursor charge can never be lower than product ion charge. if (Math.Abs(PrecursorCharge) < Math.Abs(charge)) { continue; } int start = 0, end = 0; if (pick != TransitionLibraryPick.all) { start = startFinder.FindStartFragment(massesFilter, type, charge, precursorMz, precursorMzWindow, out startMz); end = endFinder.FindEndFragment(type, start, len); if (Transition.IsCTerminal(type)) { Helpers.Swap(ref start, ref end); } } for (int i = 0; i < len; i++) { // Get the predicted m/z that would be used in the transition double massH = massesPredict[(int)type, i]; foreach (var losses in CalcTransitionLosses(type, i, massType, potentialLosses)) { double ionMz = SequenceMassCalc.GetMZ(Transition.CalcMass(massH, losses), charge); // Make sure the fragment m/z value falls within the valid instrument range. // CONSIDER: This means that a heavy transition might excede the instrument // range where a light one is accepted, leading to a disparity // between heavy and light transtions picked. if (minMz > ionMz || ionMz > maxMz) { continue; } TransitionDocNode nodeTranReturn = null; bool accept = true; if (pick == TransitionLibraryPick.all || pick == TransitionLibraryPick.all_plus) { if (!useFilter) { nodeTranReturn = CreateTransitionNode(type, i, charge, massH, losses, transitionRanks); accept = false; } else { if (IsMatched(transitionRanks, ionMz, type, charge, losses)) { nodeTranReturn = CreateTransitionNode(type, i, charge, massH, losses, transitionRanks); accept = false; } // If allowing library or filter, check the filter to decide whether to accept else if (pick == TransitionLibraryPick.all_plus && tranSettings.Accept(sequence, precursorMzAccept, type, i, ionMz, start, end, startMz)) { nodeTranReturn = CreateTransitionNode(type, i, charge, massH, losses, transitionRanks); } } } else if (tranSettings.Accept(sequence, precursorMzAccept, type, i, ionMz, start, end, startMz)) { if (pick == TransitionLibraryPick.none) { nodeTranReturn = CreateTransitionNode(type, i, charge, massH, losses, transitionRanks); } else { if (IsMatched(transitionRanks, ionMz, type, charge, losses)) { nodeTranReturn = CreateTransitionNode(type, i, charge, massH, losses, transitionRanks); } } } if (nodeTranReturn != null) { if (IsAvoidMismatchedIsotopeTransitions && !OtherLabelTypesAllowed(settings, minMz, maxMz, start, end, startMz, accept, groupDocNode, nodeTranReturn, listOtherTypes)) { continue; } Assume.IsTrue(minMz <= nodeTranReturn.Mz && nodeTranReturn.Mz <= maxMz); yield return(nodeTranReturn); } } } } } }
private TransitionDocNode CreateTransitionNode(int massIndex, TypedMass precursorMassH, TransitionIsotopeDistInfo isotopeDistInfo, TransitionLosses losses, IDictionary <double, LibraryRankedSpectrumInfo.RankedMI> transitionRanks, CustomMolecule customMolecule = null) { Transition transition = new Transition(this, massIndex, customMolecule); var quantInfo = TransitionDocNode.TransitionQuantInfo.GetLibTransitionQuantInfo(transition, losses, Transition.CalcMass(precursorMassH, losses), transitionRanks).ChangeIsotopeDistInfo(isotopeDistInfo); return(new TransitionDocNode(transition, losses, precursorMassH, quantInfo)); }
private TransitionDocNode CreateTransitionNode(IonType type, int cleavageOffset, Adduct charge, TypedMass massH, TransitionLosses losses, IDictionary <double, LibraryRankedSpectrumInfo.RankedMI> transitionRanks, CustomMolecule customMolecule = null) { Transition transition = new Transition(this, type, cleavageOffset, 0, charge, null, customMolecule); var info = TransitionDocNode.TransitionQuantInfo.GetLibTransitionQuantInfo(transition, losses, Transition.CalcMass(massH, losses), transitionRanks); return(new TransitionDocNode(transition, losses, massH, info, ExplicitTransitionValues.EMPTY)); }
private TransitionDocNode CreateTransitionNode(int massIndex, TypedMass precursorMassH, TransitionIsotopeDistInfo isotopeDistInfo, TransitionLosses losses, IDictionary <double, LibraryRankedSpectrumInfo.RankedMI> transitionRanks, Adduct productAdduct, CustomMolecule customMolecule = null) { Transition transition = new Transition(this, massIndex, productAdduct, customMolecule); var quantInfo = TransitionDocNode.TransitionQuantInfo.GetLibTransitionQuantInfo(transition, losses, Transition.CalcMass(precursorMassH, losses), transitionRanks).ChangeIsotopeDistInfo(isotopeDistInfo); var transitionDocNode = new TransitionDocNode(transition, losses, precursorMassH, quantInfo, ExplicitTransitionValues.EMPTY); if (massIndex < 0) { transitionDocNode = transitionDocNode.ChangeQuantitative(false); } return(transitionDocNode); }
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)); } } }