private static void AddOptimizationStepAreas(TransitionDocNode nodeTran, int iResult, TReg regression, IDictionary <int, OptimizationStep <TReg> > optTotals) { var results = (nodeTran.HasResults ? nodeTran.Results[iResult] : null); // Skip the result set if it only has step 0, the predicted value. This happens // when someone mistakenly sets "Optimizing" on a data set that does not contain // optimization steps. if (results == null || results.All(c => c.OptimizationStep == 0 || c.IsEmpty)) { return; } foreach (var chromInfo in results) { if (chromInfo.Area == 0) { continue; } int step = chromInfo.OptimizationStep; OptimizationStep <TReg> optStep; if (!optTotals.TryGetValue(step, out optStep)) { optTotals.Add(step, optStep = new OptimizationStep <TReg>(regression, step)); } optStep.AddArea(chromInfo.Area); } }
private bool OtherLabelTypesAllowed(SrmSettings settings, double minMz, double maxMz, int start, int end, double startMz, bool accept, TransitionGroupDocNode nodeGroupMatching, TransitionDocNode nodeTran, IEnumerable <Tuple <TransitionGroupDocNode, IFragmentMassCalc> > listOtherTypes) { foreach (var otherType in listOtherTypes) { var nodeGroupOther = otherType.Item1; var tranGroupOther = nodeGroupOther.TransitionGroup; var nodeTranMatching = tranGroupOther.GetMatchingTransition(settings, nodeGroupMatching, nodeTran, otherType.Item2); if (minMz > nodeTranMatching.Mz || nodeTranMatching.Mz > maxMz) { return(false); } if (accept && !settings.TransitionSettings.Accept(Peptide.Sequence, nodeGroupOther.PrecursorMz, nodeTranMatching.Transition.IonType, nodeTranMatching.Transition.CleavageOffset, nodeTranMatching.Mz, start, end, startMz)) { return(false); } } return(true); }
private TransitionDocNode GetMatchingTransition(SrmSettings settings, TransitionGroupDocNode nodeGroupMatching, TransitionDocNode nodeTran, IFragmentMassCalc calc) { var transition = nodeTran.Transition; var losses = nodeTran.Losses; var libInfo = nodeTran.LibInfo; int?decoyMassShift = transition.IsPrecursor() ? DecoyMassShift : transition.DecoyMassShift; var tranNew = new Transition(this, transition.IonType, transition.CleavageOffset, transition.MassIndex, transition.Charge, decoyMassShift, transition.CustomIon ?? CustomIon); // Handle reporter ions as well as small molecules var isotopeDist = nodeGroupMatching.IsotopeDist; double massH; if (tranNew.IsCustom()) { massH = tranNew.CustomIon.GetMass(settings.TransitionSettings.Prediction.FragmentMassType); } else { massH = calc.GetFragmentMass(tranNew, isotopeDist); } var isotopeDistInfo = TransitionDocNode.GetIsotopeDistInfo(tranNew, losses, isotopeDist); var nodeTranMatching = new TransitionDocNode(tranNew, losses, massH, isotopeDistInfo, libInfo); return(nodeTranMatching); }
public TransitionLossKey(TransitionGroupDocNode parent, TransitionDocNode transition, TransitionLosses losses) { Transition = transition.Transition; Losses = losses; if (Transition.IsCustom()) { if (!string.IsNullOrEmpty(transition.PrimaryCustomIonEquivalenceKey)) { CustomIonEquivalenceTestValue = transition.PrimaryCustomIonEquivalenceKey; } else if (!string.IsNullOrEmpty(transition.SecondaryCustomIonEquivalenceKey)) { CustomIonEquivalenceTestValue = transition.SecondaryCustomIonEquivalenceKey; } else if (Transition.IsNonReporterCustomIon()) { CustomIonEquivalenceTestValue = @"_mzSortIndex_" + parent.Children.IndexOf(transition); } else { CustomIonEquivalenceTestValue = null; } } else { CustomIonEquivalenceTestValue = null; } }
public void Add(TransitionDocNode nodeTran, float abundance) { string ion = nodeTran.FragmentIonName; float current = !_abundances.ContainsKey(ion) ? 0 : _abundances[ion]; _abundances[ion] = current + abundance; }
private TransitionDocNode GetMatchingTransition(SrmSettings settings, TransitionGroupDocNode nodeGroupMatching, TransitionDocNode nodeTran, IFragmentMassCalc calc) { var transition = nodeTran.Transition; var losses = nodeTran.Losses; var libInfo = nodeTran.LibInfo; int?decoyMassShift = transition.IsPrecursor() ? DecoyMassShift : transition.DecoyMassShift; var tranNew = new Transition(this, transition.IonType, transition.CleavageOffset, transition.MassIndex, transition.Adduct, decoyMassShift, transition.CustomIon ?? CustomMolecule); // Handle reporter ions as well as small molecules var isotopeDist = nodeGroupMatching.IsotopeDist; TypedMass massH; var massType = calc.MassType; if (tranNew.IsCustom()) { massH = tranNew.CustomIon.GetMass(massType); } else { massH = calc.GetFragmentMass(tranNew, isotopeDist); } var isotopeDistInfo = TransitionDocNode.GetIsotopeDistInfo(tranNew, losses, isotopeDist); var nodeTranMatching = new TransitionDocNode(tranNew, losses, massH, new TransitionDocNode.TransitionQuantInfo(isotopeDistInfo, libInfo, nodeTran.IsQuantitative(settings)), nodeTran.ExplicitValues); return(nodeTranMatching); }
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)); }
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 static int CompareTransitions(TransitionDocNode node1, TransitionDocNode node2) { int result = CompareTransitionIds(node1.Transition, node2.Transition); if (result == 0) { result = node1.LostMass.CompareTo(node2.LostMass); } return(result); }
public static double FindOptimizedValue(SrmSettings settings, PeptideDocNode nodePep, TransitionGroupDocNode nodeGroup, TransitionDocNode nodeTran, OptimizedMethodType methodType, TReg regressionDocument, GetRegressionValue getRegressionValue) { double?optimizedValue = FindOptimizedValueFromResults(settings, nodePep, nodeGroup, nodeTran, methodType, getRegressionValue); return(optimizedValue.HasValue ? optimizedValue.Value : getRegressionValue(settings, nodePep, nodeGroup, regressionDocument, 0)); }
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); var transitionDocNode = new TransitionDocNode(transition, losses, precursorMassH, quantInfo); if (massIndex < 0) { transitionDocNode = transitionDocNode.ChangeQuantitative(false); } return(transitionDocNode); }
public TransitionDocNode MergeUserInfo(SrmSettings settings, TransitionDocNode nodeTranMerge) { var result = this; var annotations = Annotations.Merge(nodeTranMerge.Annotations); if (!ReferenceEquals(annotations, Annotations)) { result = (TransitionDocNode)result.ChangeAnnotations(annotations); } var resultsInfo = MergeResultsUserInfo(settings, nodeTranMerge.Results); if (!ReferenceEquals(resultsInfo, Results)) { result = result.ChangeResults(resultsInfo); } return(result); }
public bool Equals(TransitionDocNode obj) { if (ReferenceEquals(null, obj)) { return(false); } if (ReferenceEquals(this, obj)) { return(true); } var equal = base.Equals(obj) && obj.Mz == Mz && Equals(obj.IsotopeDistInfo, IsotopeDistInfo) && Equals(obj.LibInfo, LibInfo) && Equals(obj.Results, Results); return(equal); // For debugging convenience }
public static int CompareTransitions(TransitionDocNode node1, TransitionDocNode node2) { Transition tran1 = node1.Transition, tran2 = node2.Transition; int diffType = GetOrder(tran1.IonType) - GetOrder(tran2.IonType); if (diffType != 0) { return(diffType); } int diffCharge = tran1.Charge - tran2.Charge; if (diffCharge != 0) { return(diffCharge); } int diffOffset = tran1.CleavageOffset - tran2.CleavageOffset; if (diffOffset != 0) { return(diffOffset); } return(Comparer <double> .Default.Compare(node1.LostMass, node2.LostMass)); }
public static FragmentedMolecule GetFragmentedMolecule(SrmSettings settings, PeptideDocNode peptideDocNode, TransitionGroupDocNode transitionGroupDocNode, TransitionDocNode transitionDocNode) { FragmentedMolecule fragmentedMolecule = EMPTY .ChangePrecursorMassShift(0, settings.TransitionSettings.Prediction.PrecursorMassType) .ChangeFragmentMassShift(0, settings.TransitionSettings.Prediction.FragmentMassType); if (peptideDocNode == null) { return(fragmentedMolecule); } var labelType = transitionGroupDocNode == null ? IsotopeLabelType.light : transitionGroupDocNode.TransitionGroup.LabelType; if (peptideDocNode.IsProteomic) { fragmentedMolecule = fragmentedMolecule.ChangeModifiedSequence( ModifiedSequence.GetModifiedSequence(settings, peptideDocNode, labelType)); if (transitionGroupDocNode != null) { fragmentedMolecule = fragmentedMolecule .ChangePrecursorCharge(transitionGroupDocNode.PrecursorCharge); } if (transitionDocNode == null || transitionDocNode.IsMs1) { return(fragmentedMolecule); } var transition = transitionDocNode.Transition; fragmentedMolecule = fragmentedMolecule .ChangeFragmentIon(transition.IonType, transition.Ordinal) .ChangeFragmentCharge(transition.Charge); var transitionLosses = transitionDocNode.Losses; if (transitionLosses != null) { var fragmentLosses = transitionLosses.Losses.Select(transitionLoss => transitionLoss.Loss); fragmentedMolecule = fragmentedMolecule.ChangeFragmentLosses(fragmentLosses); } return(fragmentedMolecule); } if (transitionGroupDocNode == null) { return(fragmentedMolecule .ChangePrecursorFormula( Molecule.Parse(peptideDocNode.CustomMolecule.Formula ?? string.Empty))); } var customMolecule = transitionGroupDocNode.CustomMolecule; fragmentedMolecule = fragmentedMolecule.ChangePrecursorCharge(transitionGroupDocNode.TransitionGroup .PrecursorCharge); if (customMolecule.Formula != null) { var ionInfo = new IonInfo(customMolecule.Formula, transitionGroupDocNode.PrecursorAdduct); fragmentedMolecule = fragmentedMolecule .ChangePrecursorFormula(Molecule.Parse(ionInfo.FormulaWithAdductApplied)); } else { fragmentedMolecule = fragmentedMolecule.ChangePrecursorMassShift( transitionGroupDocNode.PrecursorAdduct.MassFromMz( transitionGroupDocNode.PrecursorMz, transitionGroupDocNode.PrecursorMzMassType), transitionGroupDocNode.PrecursorMzMassType); } if (transitionDocNode == null || transitionDocNode.IsMs1) { return(fragmentedMolecule); } var customIon = transitionDocNode.Transition.CustomIon; if (customIon.Formula != null) { fragmentedMolecule = fragmentedMolecule.ChangeFragmentFormula( Molecule.Parse(customIon.FormulaWithAdductApplied)); } else { fragmentedMolecule = fragmentedMolecule.ChangeFragmentMassShift( transitionDocNode.Transition.Adduct.MassFromMz( transitionDocNode.Mz, transitionDocNode.MzMassType), transitionDocNode.MzMassType); } fragmentedMolecule = fragmentedMolecule .ChangeFragmentCharge(transitionDocNode.Transition.Charge); return(fragmentedMolecule); }
public Chromatogram[] GetChromatograms(DocumentLocation documentLocation) { if (documentLocation == null) { return(new Chromatogram[0]); } var result = new List <Chromatogram>(); SrmDocument document = Program.MainWindow.Document; Bookmark bookmark = Bookmark.ToBookmark(documentLocation, document); IdentityPath identityPath = bookmark.IdentityPath; var nodeList = GetDocNodes(identityPath, document); TransitionDocNode transitionDocNode = null; if (nodeList.Count > 3) { transitionDocNode = (TransitionDocNode)nodeList[3]; } var measuredResults = document.Settings.MeasuredResults; var nodePep = (PeptideDocNode)(nodeList.Count > 1 ? nodeList[1] : null); if (null == nodePep) { return(result.ToArray()); } int iColor = 0; foreach (var chromatogramSet in measuredResults.Chromatograms) { foreach (var msDataFileInfo in chromatogramSet.MSDataFileInfos) { if (bookmark.ChromFileInfoId != null && !ReferenceEquals(msDataFileInfo.FileId, bookmark.ChromFileInfoId)) { continue; } foreach (var nodeGroup in nodePep.TransitionGroups) { if (nodeList.Count > 2 && !Equals(nodeGroup, nodeList[2])) { continue; } ChromatogramGroupInfo[] arrayChromInfo; measuredResults.TryLoadChromatogram( chromatogramSet, nodePep, nodeGroup, (float)document.Settings.TransitionSettings.Instrument.MzMatchTolerance, true, out arrayChromInfo); foreach (var transition in nodeGroup.Transitions) { if (transitionDocNode != null && !Equals(transitionDocNode, transition)) { continue; } foreach (var chromatogramGroup in arrayChromInfo) { for (int iTransition = 0; iTransition < chromatogramGroup.NumTransitions; iTransition++) { ChromatogramInfo transitionInfo = chromatogramGroup.GetTransitionInfo(iTransition); if (Math.Abs(transitionInfo.ProductMz - transition.Mz) > document.Settings.TransitionSettings.Instrument.MzMatchTolerance) { continue; } Color color = GraphChromatogram.COLORS_LIBRARY[iColor % GraphChromatogram.COLORS_LIBRARY.Count]; iColor++; result.Add(new Chromatogram { Intensities = transitionInfo.Intensities.ToArray(), ProductMz = transitionInfo.ProductMz.RawValue, // For negative ion mode data this will be a negative value PrecursorMz = chromatogramGroup.PrecursorMz.RawValue, // For negative ion mode data this will be a negative value Times = transitionInfo.Times.ToArray(), Color = color }); } } } } } } if (result.Count == 1) { result[0].Color = ChromGraphItem.ColorSelected; } return(result.ToArray()); }
/// <summary> /// In the case of small molecule transitions specified by mass only, position within /// the parent's list of transitions is the only meaningful key. So we need to know our parent. /// </summary> public TransitionLossEquivalentKey(TransitionGroupDocNode parent, TransitionDocNode transition, TransitionLosses losses) { Key = new TransitionEquivalentKey(parent, transition); Losses = losses; }
protected virtual bool SkipTransition(PeptideGroupDocNode nodePepGroup, PeptideDocNode nodePep, TransitionGroupDocNode nodeGroup, TransitionGroupDocNode nodeGroupPrimary, TransitionDocNode nodeTran) { return(false); }
private readonly string _customIonEquivalenceTestText; // For use with small molecules public TransitionEquivalentKey(TransitionGroupDocNode parent, TransitionDocNode nodeTran) { _nodeTran = nodeTran.Transition; _customIonEquivalenceTestText = new TransitionLossKey(parent, nodeTran, null).CustomIonEquivalenceTestValue; }
public static double?FindOptimizedValueFromResults(SrmSettings settings, PeptideDocNode nodePep, TransitionGroupDocNode nodeGroup, TransitionDocNode nodeTran, OptimizedMethodType methodType, GetRegressionValue getRegressionValue) { // Collect peak area for var dictOptTotals = new Dictionary <TReg, Dictionary <int, OptimizationStep <TReg> > >(); if (settings.HasResults) { var chromatograms = settings.MeasuredResults.Chromatograms; for (int i = 0; i < chromatograms.Count; i++) { var chromSet = chromatograms[i]; var regression = chromSet.OptimizationFunction as TReg; if (regression == null) { continue; } Dictionary <int, OptimizationStep <TReg> > stepAreas; if (!dictOptTotals.TryGetValue(regression, out stepAreas)) { dictOptTotals.Add(regression, stepAreas = new Dictionary <int, OptimizationStep <TReg> >()); } if (methodType == OptimizedMethodType.Precursor) { TransitionGroupDocNode[] listGroups = FindCandidateGroups(nodePep, nodeGroup); foreach (var nodeGroupCandidate in listGroups) { AddOptimizationStepAreas(nodeGroupCandidate, i, regression, stepAreas); } } else if (methodType == OptimizedMethodType.Transition) { IEnumerable <TransitionDocNode> listTransitions = FindCandidateTransitions(nodePep, nodeGroup, nodeTran); foreach (var nodeTranCandidate in listTransitions) { AddOptimizationStepAreas(nodeTranCandidate, i, regression, stepAreas); } } } } // If no candidate values were found, use the document regressor. if (dictOptTotals.Count == 0) { return(null); } // Get the CE value with the maximum total peak area double maxArea = 0; double bestValue = 0; foreach (var optTotals in dictOptTotals.Values) { foreach (var optStep in optTotals.Values) { if (maxArea < optStep.TotalArea) { maxArea = optStep.TotalArea; bestValue = getRegressionValue(settings, nodePep, nodeGroup, optStep.Regression, optStep.Step); } } } // Use value for candidate with the largest area return(bestValue); }
private static IEnumerable <TransitionDocNode> FindCandidateTransitions(PeptideDocNode nodePep, TransitionGroupDocNode nodeGroup, TransitionDocNode nodeTran) { var candidateGroups = FindCandidateGroups(nodePep, nodeGroup); if (candidateGroups.Length < 2) { return new[] { nodeTran } } ; Debug.Assert(ReferenceEquals(nodeGroup, candidateGroups[0])); var listCandidates = new List <TransitionDocNode> { nodeTran }; var transition = nodeTran.Transition; for (int i = 1; i < candidateGroups.Length; i++) { foreach (TransitionDocNode nodeTranCandidate in candidateGroups[i].Children) { var transitionCandidate = nodeTranCandidate.Transition; if (transition.Charge == transitionCandidate.Charge && transition.Ordinal == transitionCandidate.Ordinal && transition.IonType == transitionCandidate.IonType) { listCandidates.Add(nodeTranCandidate); break; } } } return(listCandidates.ToArray()); }
public static ExplicitTransitionValues Get(TransitionDocNode node) { return(node == null ? EMPTY : node.ExplicitValues); } // Convenience function
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); } } } } } }