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 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 static Size RenderTip(PeptideDocNode nodePep, TransitionGroupDocNode nodeGroup, TransitionDocNode nodeTranSelected, SrmSettings settings, Graphics g, Size sizeMax, bool draw) { if (nodeGroup.TransitionGroup.IsCustomIon) // TODO(bspratt) this seems to leave out a lot of detail { var customTable = new TableDesc(); using (RenderTools rt = new RenderTools()) { customTable.AddDetailRow(Resources.TransitionGroupTreeNode_RenderTip_Molecule, nodeGroup.CustomMolecule.Name, rt); customTable.AddDetailRow(Resources.TransitionGroupTreeNode_RenderTip_Precursor_charge, nodeGroup.TransitionGroup.PrecursorAdduct.AdductCharge.ToString(LocalizationHelper.CurrentCulture), rt); customTable.AddDetailRow(Resources.TransitionGroupTreeNode_RenderTip_Precursor_mz, string.Format(@"{0:F04}", nodeGroup.PrecursorMz), rt); if (nodeGroup.CustomMolecule.Formula != null) { customTable.AddDetailRow(Resources.TransitionTreeNode_RenderTip_Formula, nodeGroup.CustomMolecule.Formula + nodeGroup.TransitionGroup.PrecursorAdduct.AdductFormula.ToString(LocalizationHelper.CurrentCulture), rt); } SizeF size = customTable.CalcDimensions(g); customTable.Draw(g); return(new Size((int)size.Width + 2, (int)size.Height + 2)); } } ExplicitMods mods = (nodePep != null ? nodePep.ExplicitMods : null); IEnumerable <DocNode> choices = nodeGroup.GetPrecursorChoices(settings, mods, true).ToArray(); HashSet <DocNode> chosen = new HashSet <DocNode>(nodeGroup.Children); // Make sure all chosen peptides get listed HashSet <DocNode> setChoices = new HashSet <DocNode>(choices); setChoices.UnionWith(chosen); choices = setChoices.ToArray(); Transition tranSelected = (nodeTranSelected != null ? nodeTranSelected.Transition : null); IFragmentMassCalc calc = settings.GetFragmentCalc(nodeGroup.TransitionGroup.LabelType, mods); var aa = nodeGroup.TransitionGroup.Peptide.Target.Sequence; // We handled custom ions above, and returned var masses = calc.GetFragmentIonMasses(nodeGroup.TransitionGroup.Peptide.Target); var filter = settings.TransitionSettings.Filter; // Get charges and type pairs, making sure all chosen charges are included var setCharges = new HashSet <Adduct>(filter.PeptideProductCharges.Where(charge => Math.Abs(charge.AdductCharge) <= Math.Abs(nodeGroup.TransitionGroup.PrecursorCharge) && Math.Sign(charge.AdductCharge) == Math.Sign(nodeGroup.TransitionGroup.PrecursorCharge))); HashSet <IonType> setTypes = new HashSet <IonType>(filter.PeptideIonTypes); foreach (TransitionDocNode nodTran in chosen) { var type = nodTran.Transition.IonType; if (!Transition.IsPeptideFragment(type)) { continue; } setCharges.Add(nodTran.Transition.Adduct); setTypes.Add(type); } setTypes.RemoveWhere(t => !Transition.IsPeptideFragment(t)); var charges = setCharges.Where(c => c.IsProteomic).ToArray(); Array.Sort(charges); IonType[] types = Transition.GetTypePairs(setTypes); var tableDetails = new TableDesc(); var table = new TableDesc(); using (RenderTools rt = new RenderTools()) { var seqModified = GetModifiedSequence(nodePep, nodeGroup, settings); if (!Equals(seqModified, nodeGroup.TransitionGroup.Peptide.Target)) { tableDetails.AddDetailRow(Resources.TransitionGroupTreeNode_RenderTip_Modified, seqModified.Sequence, rt); } var precursorCharge = nodeGroup.TransitionGroup.PrecursorAdduct; var precursorMz = nodeGroup.PrecursorMz; tableDetails.AddDetailRow(Resources.TransitionGroupTreeNode_RenderTip_Precursor_charge, precursorCharge.AdductCharge.ToString(LocalizationHelper.CurrentCulture), rt); tableDetails.AddDetailRow(Resources.TransitionGroupTreeNode_RenderTip_Precursor_mz, string.Format(@"{0:F04}", precursorMz), rt); tableDetails.AddDetailRow(Resources.TransitionGroupTreeNode_RenderTip_Precursor_mh, string.Format(@"{0:F04}", nodeGroup.GetPrecursorIonMass()), rt); int?decoyMassShift = nodeGroup.TransitionGroup.DecoyMassShift; if (decoyMassShift.HasValue) { tableDetails.AddDetailRow(Resources.TransitionGroupTreeNode_RenderTip_Decoy_Mass_Shift, decoyMassShift.Value.ToString(LocalizationHelper.CurrentCulture), rt); } if (nodeGroup.HasLibInfo) { foreach (KeyValuePair <PeptideRankId, string> pair in nodeGroup.LibInfo.RankValues) { tableDetails.AddDetailRow(pair.Key.Label, pair.Value, rt); } } if (charges.Length > 0 && types.Length > 0) { var headers = new RowDesc { CreateHead(@"#", rt), CreateHead(@"AA", rt), CreateHead(@"#", rt) }; foreach (var charge in charges) { string plusSub = Transition.GetChargeIndicator(charge); foreach (IonType type in types) { CellDesc cell = CreateHead(type.ToString().ToLower() + plusSub, rt); if (Transition.IsNTerminal(type)) { headers.Insert(0, cell); } else { headers.Add(cell); } } } table.Add(headers); int len = aa.Length; for (int i = 0; i < len; i++) { CellDesc cellAA = CreateRowLabel(aa.Substring(i, 1), rt); cellAA.Align = StringAlignment.Center; var row = new RowDesc { CreateRowLabel(i == len - 1 ? string.Empty : (i + 1).ToString(CultureInfo.InvariantCulture), rt), cellAA, CreateRowLabel(i == 0 ? string.Empty : (len - i).ToString(CultureInfo.InvariantCulture), rt) }; foreach (var charge in charges) { foreach (IonType type in types) { CellDesc cell; if (Transition.IsNTerminal(type)) { if (i == len - 1) { cell = CreateData(string.Empty, rt); } else { var massH = masses[type, i]; cell = CreateIon(type, i + 1, massH, charge, choices, chosen, tranSelected, rt); } row.Insert(0, cell); } else { if (i == 0) { cell = CreateData(string.Empty, rt); } else { var massH = masses[type, i - 1]; cell = CreateIon(type, len - i, massH, charge, choices, chosen, tranSelected, rt); } row.Add(cell); } } } table.Add(row); } } SizeF sizeDetails = tableDetails.CalcDimensions(g); sizeDetails.Height += TableDesc.TABLE_SPACING; // Spacing between details and fragments SizeF size = table.CalcDimensions(g); if (draw) { tableDetails.Draw(g); g.TranslateTransform(0, sizeDetails.Height); table.Draw(g); g.TranslateTransform(0, -sizeDetails.Height); } int width = (int)Math.Round(Math.Max(sizeDetails.Width, size.Width)); int height = (int)Math.Round(sizeDetails.Height + size.Height); return(new Size(width + 2, height + 2)); } }
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> 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)); } } }