public IsotopeDistInfo GetPrecursorIsotopeDistInfo(Adduct adduct, double decoyMassShift) { var massDistribution = GetPrecursorMassDistribution(); var mzDistribution = massDistribution.OffsetAndDivide( adduct.AdductCharge * (BioMassCalc.MassProton + decoyMassShift), adduct.AdductCharge); return(IsotopeDistInfo.MakeIsotopeDistInfo(mzDistribution, GetPrecursorMass(MassType.MonoisotopicMassH), adduct, Settings.TransitionSettings.FullScan)); }
public TransitionDocNode MakeTransitionDocNode(SrmSettings settings, ExplicitMods explicitMods, IsotopeDistInfo isotopeDist, Annotations annotations, TransitionDocNode.TransitionQuantInfo transitionQuantInfo, ExplicitTransitionValues explicitTransitionValues, Results <TransitionChromInfo> results) { return(GetCrosslinkBuilder(settings, explicitMods).MakeTransitionDocNode(this, isotopeDist, annotations, transitionQuantInfo, explicitTransitionValues, results)); }
public static bool IsValidIsotopeTransition(Transition transition, IsotopeDistInfo isotopeDist) { if (isotopeDist == null || !transition.IsPrecursor()) { return(true); } int i = isotopeDist.MassIndexToPeakIndex(transition.MassIndex); return(0 <= i && i < isotopeDist.CountPeaks); }
public override int GetHashCode() { unchecked { int result = base.GetHashCode(); result = (result * 397) ^ Mz.GetHashCode(); result = (result * 397) ^ (IsotopeDistInfo != null ? IsotopeDistInfo.GetHashCode() : 0); result = (result * 397) ^ (LibInfo != null ? LibInfo.GetHashCode() : 0); result = (result * 397) ^ (Results != null ? Results.GetHashCode() : 0); return(result); } }
public IEnumerable <TransitionDocNode> GetComplexTransitions(TransitionGroup transitionGroup, double precursorMz, IsotopeDistInfo isotopeDist, Dictionary <double, LibraryRankedSpectrumInfo.RankedMI> transitionRanks, IEnumerable <TransitionDocNode> simpleTransitions, bool useFilter) { var allTransitions = RemoveUnmeasurable(precursorMz, RemoveDuplicates( GetAllComplexTransitions(transitionGroup, isotopeDist, simpleTransitions, useFilter))) .OrderBy(tran => tran.ComplexFragmentIon) .ToList(); IList <TransitionDocNode> ms2transitions; IList <TransitionDocNode> ms1transitions; if (Settings.TransitionSettings.FullScan.IsEnabledMs) { ms2transitions = allTransitions.Where(tran => !tran.IsMs1).ToList(); ms1transitions = allTransitions.Where(tran => tran.IsMs1).ToList(); if (Settings.TransitionSettings.FullScan.IsHighResPrecursor) { ms1transitions = ms1transitions.SelectMany(tran => ExpandPrecursorIsotopes(tran, isotopeDist, useFilter)).ToList(); } } else { ms2transitions = allTransitions; ms1transitions = new TransitionDocNode[0]; } if (useFilter) { if (!Settings.TransitionSettings.Filter.PeptideIonTypes.Contains(IonType.precursor)) { ms1transitions = new TransitionDocNode[0]; } ms2transitions = FilterTransitions(transitionRanks, ms2transitions).ToList(); } return(ms1transitions.Concat(ms2transitions)); }
public TransitionDocNode MakeTransitionDocNode(ComplexFragmentIon complexFragmentIon, IsotopeDistInfo isotopeDist, Annotations annotations, TransitionDocNode.TransitionQuantInfo transitionQuantInfo, ExplicitTransitionValues explicitTransitionValues, Results <TransitionChromInfo> results) { var neutralFormula = GetNeutralFormula(complexFragmentIon); var productMass = GetFragmentMassFromFormula(Settings, neutralFormula); if (complexFragmentIon.Children.Count > 0) { complexFragmentIon = complexFragmentIon.CloneTransition(); } if (complexFragmentIon.IsMs1 && Settings.TransitionSettings.FullScan.IsHighResPrecursor) { isotopeDist = isotopeDist ?? GetPrecursorIsotopeDistInfo(complexFragmentIon.Transition.Adduct, 0); productMass = isotopeDist.GetMassI(complexFragmentIon.Transition.MassIndex, complexFragmentIon.Transition.DecoyMassShift); transitionQuantInfo = transitionQuantInfo.ChangeIsotopeDistInfo(new TransitionIsotopeDistInfo( isotopeDist.GetRankI(complexFragmentIon.Transition.MassIndex), isotopeDist.GetProportionI(complexFragmentIon.Transition.MassIndex))); } return(new TransitionDocNode(complexFragmentIon, annotations, productMass, transitionQuantInfo, explicitTransitionValues, results)); }
private static double GetMassDelta(IsotopeDistInfo isotopeDist, int massIndex) { return(isotopeDist.GetMassI(massIndex) - isotopeDist.GetMassI(massIndex - 1)); }
public static TransitionIsotopeDistInfo GetIsotopeDistInfo(Transition transition, TransitionLosses losses, IsotopeDistInfo isotopeDist) { if (isotopeDist == null || !transition.IsPrecursor() || losses != null) { return(null); } return(new TransitionIsotopeDistInfo(isotopeDist.GetRankI(transition.MassIndex), isotopeDist.GetProportionI(transition.MassIndex))); }
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)); } } }
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); } } } } } }
public static TransitionQuantInfo GetTransitionQuantInfo(Transition transition, TransitionLosses losses, IsotopeDistInfo isotopeDist, TypedMass massH, IDictionary <double, LibraryRankedSpectrumInfo.RankedMI> ranks) { var transitionIsotopeDistInfo = GetIsotopeDistInfo(transition, losses, isotopeDist); return(GetLibTransitionQuantInfo(transition, losses, massH, ranks).ChangeIsotopeDistInfo(transitionIsotopeDistInfo)); }
public TransitionDocNode MakeTransitionDocNode(ComplexFragmentIon complexFragmentIon, IsotopeDistInfo isotopeDist = null) { return(MakeTransitionDocNode(complexFragmentIon, isotopeDist, Annotations.EMPTY, TransitionDocNode.TransitionQuantInfo.DEFAULT, ExplicitTransitionValues.EMPTY, null)); }
public IEnumerable <TransitionDocNode> ExpandPrecursorIsotopes(TransitionDocNode transitionNode, IsotopeDistInfo isotopeDist, bool useFilter) { var fullScan = Settings.TransitionSettings.FullScan; foreach (int massIndex in fullScan.SelectMassIndices(isotopeDist, useFilter)) { var complexFragmentIon = transitionNode.ComplexFragmentIon.ChangeMassIndex(massIndex); yield return(MakeTransitionDocNode(complexFragmentIon, isotopeDist)); } }
public IEnumerable <TransitionDocNode> GetAllComplexTransitions( TransitionGroup transitionGroup, IsotopeDistInfo isotopeDist, IEnumerable <TransitionDocNode> simpleTransitions, bool useFilter) { var startingFragmentIons = new List <ComplexFragmentIon>(); var productAdducts = Settings.TransitionSettings.Filter.PeptideProductCharges.ToHashSet(); var precursorLosses = new HashSet <TransitionLosses>(); foreach (var simpleTransition in simpleTransitions) { var startingFragmentIon = simpleTransition.ComplexFragmentIon .ChangeCrosslinkStructure(ExplicitMods.Crosslinks); startingFragmentIons.Add(startingFragmentIon); if (startingFragmentIon.IsIonTypePrecursor) { precursorLosses.Add(startingFragmentIon.TransitionLosses); } } bool excludePrecursors = false; IEnumerable <Adduct> allProductAdducts; if (useFilter) { allProductAdducts = Settings.TransitionSettings.Filter.PeptideProductCharges; excludePrecursors = !Settings.TransitionSettings.Filter.PeptideIonTypes.Contains(IonType.precursor); } else { allProductAdducts = Settings.TransitionSettings.Filter.PeptideProductCharges .Concat(Transition.DEFAULT_PEPTIDE_CHARGES); } allProductAdducts = allProductAdducts.Append(transitionGroup.PrecursorAdduct); // Add ions representing the precursor waiting to be joined with a crosslinked peptide foreach (var productAdduct in allProductAdducts.Distinct()) { foreach (var transitionLosses in precursorLosses) { if (productAdduct.IsValidProductAdduct(transitionGroup.PrecursorAdduct, null)) { var precursorTransition = new Transition(transitionGroup, IonType.precursor, Peptide.Sequence.Length - 1, 0, productAdduct); startingFragmentIons.Add(new ComplexFragmentIon(precursorTransition, transitionLosses, ExplicitMods.Crosslinks, true)); startingFragmentIons.Add(new ComplexFragmentIon(precursorTransition, transitionLosses, ExplicitMods.Crosslinks)); } } } foreach (var complexFragmentIon in LinkedPeptide.PermuteComplexFragmentIons(ExplicitMods, Settings, Settings.PeptideSettings.Modifications.MaxNeutralLosses, useFilter, startingFragmentIons.Distinct()).Distinct()) { bool isPrecursor = complexFragmentIon.IsIonTypePrecursor; if (isPrecursor) { if (excludePrecursors) { continue; } var expectedCharge = transitionGroup.PrecursorAdduct.AdductCharge; if (complexFragmentIon.TransitionLosses != null) { if (complexFragmentIon.Transition.MassIndex != 0) { continue; } expectedCharge -= complexFragmentIon.TransitionLosses.TotalCharge; } if (expectedCharge != complexFragmentIon.Transition.Adduct.AdductCharge) { continue; } } else { if (complexFragmentIon.Transition.MassIndex != 0) { continue; } if (useFilter) { if (!productAdducts.Contains(complexFragmentIon.Transition.Adduct)) { continue; } } } if (!complexFragmentIon.Transition.Adduct.IsValidProductAdduct(transitionGroup.PrecursorAdduct, complexFragmentIon.TransitionLosses)) { continue; } var complexTransitionDocNode = MakeTransitionDocNode(complexFragmentIon, isotopeDist); yield return(complexTransitionDocNode); } }
public TransitionDocNode MakeTransitionDocNode(SrmSettings settings, ExplicitMods explicitMods, IsotopeDistInfo isotopeDist) { return(MakeTransitionDocNode(settings, explicitMods, isotopeDist, Annotations.EMPTY, TransitionDocNode.TransitionQuantInfo.DEFAULT, ExplicitTransitionValues.EMPTY, null)); }
public static TransitionDocNode FromTransitionProto(AnnotationScrubber scrubber, SrmSettings settings, TransitionGroup group, ExplicitMods mods, IsotopeDistInfo isotopeDist, ExplicitTransitionValues pre422ExplicitTransitionValues, SkylineDocumentProto.Types.Transition transitionProto) { var stringPool = scrubber.StringPool; IonType ionType = DataValues.FromIonType(transitionProto.FragmentType); MeasuredIon measuredIon = null; if (transitionProto.MeasuredIonName != null) { measuredIon = settings.TransitionSettings.Filter.MeasuredIons.SingleOrDefault( i => i.Name.Equals(transitionProto.MeasuredIonName.Value)); if (measuredIon == null) { throw new InvalidDataException(string.Format(Resources.TransitionInfo_ReadXmlAttributes_The_reporter_ion__0__was_not_found_in_the_transition_filter_settings_, transitionProto.MeasuredIonName)); } ionType = IonType.custom; } bool isCustom = Transition.IsCustom(ionType, group); bool isPrecursor = Transition.IsPrecursor(ionType); CustomMolecule customIon = null; if (isCustom) { if (measuredIon != null) { customIon = measuredIon.SettingsCustomIon; } else if (isPrecursor) { customIon = group.CustomMolecule; } else { var formula = DataValues.FromOptional(transitionProto.Formula); var moleculeID = MoleculeAccessionNumbers.FromString(DataValues.FromOptional(transitionProto.MoleculeId)); // Tab separated list of InChiKey, CAS etc var monoMassH = DataValues.FromOptional(transitionProto.MonoMassH); var averageMassH = DataValues.FromOptional(transitionProto.AverageMassH); var monoMass = DataValues.FromOptional(transitionProto.MonoMass) ?? monoMassH; var averageMass = DataValues.FromOptional(transitionProto.AverageMass) ?? averageMassH; customIon = new CustomMolecule(formula, new TypedMass(monoMass.Value, monoMassH.HasValue ? MassType.MonoisotopicMassH : MassType.Monoisotopic), new TypedMass(averageMass.Value, averageMassH.HasValue ? MassType.AverageMassH : MassType.Average), DataValues.FromOptional(transitionProto.CustomIonName), moleculeID); } } Transition transition; var adductString = DataValues.FromOptional(transitionProto.Adduct); var adduct = string.IsNullOrEmpty(adductString) ? Adduct.FromChargeProtonated(transitionProto.Charge) : Adduct.FromStringAssumeChargeOnly(adductString); if (isCustom) { transition = new Transition(group, isPrecursor ? group.PrecursorAdduct :adduct, transitionProto.MassIndex, customIon, ionType); } else if (isPrecursor) { transition = new Transition(group, ionType, group.Peptide.Length - 1, transitionProto.MassIndex, group.PrecursorAdduct, DataValues.FromOptional(transitionProto.DecoyMassShift)); } else { int offset = Transition.OrdinalToOffset(ionType, transitionProto.FragmentOrdinal, group.Peptide.Length); transition = new Transition(group, ionType, offset, transitionProto.MassIndex, adduct, DataValues.FromOptional(transitionProto.DecoyMassShift)); } var losses = TransitionLosses.FromLossProtos(settings, transitionProto.Losses); var mass = settings.GetFragmentMass(group, mods, transition, isotopeDist); var isotopeDistInfo = GetIsotopeDistInfo(transition, losses, isotopeDist); if (group.DecoyMassShift.HasValue && transitionProto.DecoyMassShift == null) { throw new InvalidDataException(Resources.SrmDocument_ReadTransitionXml_All_transitions_of_decoy_precursors_must_have_a_decoy_mass_shift); } TransitionLibInfo libInfo = null; if (transitionProto.LibInfo != null) { libInfo = new TransitionLibInfo(transitionProto.LibInfo.Rank, transitionProto.LibInfo.Intensity); } var annotations = scrubber.ScrubAnnotations(Annotations.FromProtoAnnotations(transitionProto.Annotations), AnnotationDef.AnnotationTarget.transition); var results = TransitionChromInfo.FromProtoTransitionResults(scrubber, settings, transitionProto.Results); var explicitTransitionValues = pre422ExplicitTransitionValues ?? ExplicitTransitionValues.Create( DataValues.FromOptional(transitionProto.ExplicitCollisionEnergy), DataValues.FromOptional(transitionProto.ExplicitIonMobilityHighEnergyOffset), DataValues.FromOptional(transitionProto.ExplicitSLens), DataValues.FromOptional(transitionProto.ExplicitConeVoltage), DataValues.FromOptional(transitionProto.ExplicitDeclusteringPotential)); return(new TransitionDocNode(transition, annotations, losses, mass, new TransitionQuantInfo(isotopeDistInfo, libInfo, !transitionProto.NotQuantitative), explicitTransitionValues, results)); }
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)); } } }