public static DocNodeCustomIon Deserialize(XmlReader reader) { DocNodeCustomIon ion = new DocNodeCustomIon(); ion.ReadAttributes(reader); return(ion); }
public TransitionGroup(Peptide peptide, DocNodeCustomIon customIon, int precursorCharge, IsotopeLabelType labelType, bool unlimitedCharge, int?decoyMassShift) { _peptide = peptide; CustomIon = customIon ?? Peptide.CustomIon; // If parent molecule is a custom ion, and none specified, use that PrecursorCharge = precursorCharge; LabelType = labelType; DecoyMassShift = decoyMassShift; Validate(unlimitedCharge ? 0 : precursorCharge); }
public Peptide(DocNodeCustomIon customIon) { CustomIon = customIon; Validate(); }
private static int? ValidateFormulaWithMz(SrmDocument document, ref string moleculeFormula, double mz, int? charge, out double monoMass, out double averageMass, out double? mzCalc) { // Is the ion's formula the old style where user expected us to add a hydrogen? var tolerance = document.Settings.TransitionSettings.Instrument.MzMatchTolerance; int massShift; var ion = new DocNodeCustomIon(moleculeFormula); monoMass = ion.GetMass(MassType.Monoisotopic); averageMass = ion.GetMass(MassType.Average); double mass = (document.Settings.TransitionSettings.Prediction.FragmentMassType == MassType.Monoisotopic) ? monoMass : averageMass; // Does given charge, if any, agree with mass and mz? mzCalc = charge.HasValue ? BioMassCalc.CalculateIonMz(mass, charge.Value) : (double?)null; if (mzCalc.HasValue && tolerance >= (Math.Abs(mzCalc.Value - mz))) { return charge; } int nearestCharge; charge = TransitionCalc.CalcCharge(mass, mz, tolerance, true, TransitionGroup.MIN_PRECURSOR_CHARGE, TransitionGroup.MAX_PRECURSOR_CHARGE, new int[0], TransitionCalc.MassShiftType.none, out massShift, out nearestCharge); if (!charge.HasValue) { // That formula and this mz don't yield a reasonable charge state - try adding an H var ion2 = new DocNodeCustomIon(BioMassCalc.AddH(ion.Formula)); monoMass = ion2.GetMass(MassType.Monoisotopic); averageMass = ion2.GetMass(MassType.Average); mass = (document.Settings.TransitionSettings.Prediction.FragmentMassType == MassType.Monoisotopic) ? monoMass : averageMass; charge = TransitionCalc.CalcCharge(mass, mz, tolerance, true, TransitionGroup.MIN_PRECURSOR_CHARGE, TransitionGroup.MAX_PRECURSOR_CHARGE, new int[0], TransitionCalc.MassShiftType.none, out massShift, out nearestCharge); if (charge.HasValue) { moleculeFormula = ion2.Formula; } else { monoMass = 0; averageMass = 0; } } return charge; }
private double ValidateFormulaWithCharge(SrmDocument document, string moleculeFormula, int charge, out double monoMass, out double averageMass) { var massType = document.Settings.TransitionSettings.Prediction.PrecursorMassType; var ion = new DocNodeCustomIon(moleculeFormula); double mass = ion.GetMass(massType); monoMass = ion.GetMass(MassType.Monoisotopic); averageMass = ion.GetMass(MassType.Average); return BioMassCalc.CalculateIonMz(mass, charge); }
private PeptideDocNode GetMoleculePeptide(SrmDocument document, DataGridViewRow row, PeptideGroup group, bool requireProductInfo) { DocNodeCustomIon ion; MoleculeInfo moleculeInfo; try { moleculeInfo = ReadPrecursorOrProductColumns(document, row, true); // Re-read the precursor columns if (moleculeInfo == null) return null; // Some failure, but exception was already handled ion = new DocNodeCustomIon(moleculeInfo.Formula, moleculeInfo.MonoMass, moleculeInfo.AverageMass, Convert.ToString(row.Cells[INDEX_MOLECULE_NAME].Value)); // Short name } catch (ArgumentException e) { ShowTransitionError(new PasteError { Column = INDEX_MOLECULE_FORMULA, Line = row.Index, Message = e.Message }); return null; } try { var pep = new Peptide(ion); var tranGroup = GetMoleculeTransitionGroup(document, row, pep, requireProductInfo); if (tranGroup == null) return null; return new PeptideDocNode(pep, document.Settings, null, null, moleculeInfo.ExplicitRetentionTime, new[] { tranGroup }, true); } catch (InvalidOperationException e) { ShowTransitionError(new PasteError { Column = INDEX_MOLECULE_FORMULA, Line = row.Index, Message = e.Message }); return null; } }
public SrmDocument ConvertToSmallMolecules(SrmDocument document, ConvertToSmallMoleculesMode mode = ConvertToSmallMoleculesMode.formulas, bool invertCharges = false, bool ignoreDecoys=false) { if (mode == ConvertToSmallMoleculesMode.none) return document; var newdoc = new SrmDocument(document.Settings); var note = new Annotations(TestingConvertedFromProteomic, null, 1); // Mark this as a testing node so we don't sort it newdoc = (SrmDocument)newdoc.ChangeIgnoreChangingChildren(true); // Retain copied results foreach (var peptideGroupDocNode in document.MoleculeGroups) { if (!peptideGroupDocNode.IsProteomic) { newdoc = (SrmDocument)newdoc.Add(peptideGroupDocNode); // Already a small molecule } else { var newPeptideGroup = new PeptideGroup(); var newPeptideGroupDocNode = new PeptideGroupDocNode(newPeptideGroup, peptideGroupDocNode.Annotations.Merge(note), peptideGroupDocNode.Name, peptideGroupDocNode.Description, new PeptideDocNode[0], peptideGroupDocNode.AutoManageChildren); foreach (var mol in peptideGroupDocNode.Molecules) { var peptideSequence = mol.Peptide.Sequence; // Create a PeptideDocNode with the presumably baseline charge and label var precursorCharge = (mol.TransitionGroups.Any() ? mol.TransitionGroups.First().TransitionGroup.PrecursorCharge : 0) * (invertCharges ? -1 : 1); var isotopeLabelType = mol.TransitionGroups.Any() ? mol.TransitionGroups.First().TransitionGroup.LabelType : IsotopeLabelType.light; var moleculeCustomIon = ConvertToSmallMolecule(mode, document, mol, precursorCharge, isotopeLabelType); var precursorCustomIon = moleculeCustomIon; var newPeptide = new Peptide(moleculeCustomIon); var newPeptideDocNode = new PeptideDocNode(newPeptide, newdoc.Settings, null, null, null, null, mol.ExplicitRetentionTime, note, mol.Results, new TransitionGroupDocNode[0], mol.AutoManageChildren); foreach (var transitionGroupDocNode in mol.TransitionGroups) { if (transitionGroupDocNode.IsDecoy) { if (ignoreDecoys) continue; throw new Exception("There is no translation from decoy to small molecules"); // Not L10N } if (transitionGroupDocNode.TransitionGroup.PrecursorCharge != Math.Abs(precursorCharge) || !Equals(isotopeLabelType, transitionGroupDocNode.TransitionGroup.LabelType)) { // Different charges or labels mean different ion formulas precursorCharge = transitionGroupDocNode.TransitionGroup.PrecursorCharge * (invertCharges ? -1 : 1); isotopeLabelType = transitionGroupDocNode.TransitionGroup.LabelType; precursorCustomIon = ConvertToSmallMolecule(mode, document, mol, precursorCharge, isotopeLabelType); } var newTransitionGroup = new TransitionGroup(newPeptide, precursorCustomIon, precursorCharge, isotopeLabelType); // Remove any library info, since for the moment at least small molecules don't support this and it won't roundtrip var resultsNew = RemoveTransitionGroupChromInfoLibraryInfo(transitionGroupDocNode); var newTransitionGroupDocNode = new TransitionGroupDocNode(newTransitionGroup, transitionGroupDocNode.Annotations.Merge(note), document.Settings, null, null, transitionGroupDocNode.ExplicitValues, resultsNew, null, transitionGroupDocNode.AutoManageChildren); var mzShift = invertCharges ? 2.0 * BioMassCalc.MassProton : 0; // We removed hydrogen rather than added Assume.IsTrue((Math.Abs(newTransitionGroupDocNode.PrecursorMz + mzShift - transitionGroupDocNode.PrecursorMz) - Math.Abs(transitionGroupDocNode.TransitionGroup.PrecursorCharge * BioMassCalc.MassElectron)) <= 1E-5); foreach (var transition in transitionGroupDocNode.Transitions) { double mass = 0; var transitionCharge = transition.Transition.Charge * (invertCharges ? -1 : 1); var ionType = IonType.custom; CustomIon transitionCustomIon; double mzShiftTransition = 0; if (transition.Transition.IonType == IonType.precursor) { ionType = IonType.precursor; transitionCustomIon = new DocNodeCustomIon(precursorCustomIon.Formula, string.IsNullOrEmpty(precursorCustomIon.Formula) ? precursorCustomIon.MonoisotopicMass : (double?) null, string.IsNullOrEmpty(precursorCustomIon.Formula) ? precursorCustomIon.AverageMass : (double?) null, SmallMoleculeNameFromPeptide(peptideSequence, transitionCharge)); mzShiftTransition = invertCharges ? 2.0 * BioMassCalc.MassProton : 0; // We removed hydrogen rather than added } else if (transition.Transition.IonType == IonType.custom) { transitionCustomIon = transition.Transition.CustomIon; mass = transitionCustomIon.MonoisotopicMass; } else { // TODO - try to get fragment formula? mass = BioMassCalc.CalculateIonMassFromMz(transition.Mz, transition.Transition.Charge); transitionCustomIon = new DocNodeCustomIon(mass, mass,// We can't really get at mono vs average mass from m/z, but for test purposes this is fine transition.Transition.FragmentIonName); } if (mode == ConvertToSmallMoleculesMode.masses_and_names) { // Discard the formula if we're testing the use of mass-with-names (for matching in ratio calcs) target specification transitionCustomIon = new DocNodeCustomIon(transitionCustomIon.MonoisotopicMass, transitionCustomIon.AverageMass, transition.Transition.FragmentIonName); } else if (mode == ConvertToSmallMoleculesMode.masses_only) { // Discard the formula and name if we're testing the use of mass-only target specification transitionCustomIon = new DocNodeCustomIon(transitionCustomIon.MonoisotopicMass, transitionCustomIon.AverageMass); } var newTransition = new Transition(newTransitionGroup, ionType, null, transition.Transition.MassIndex, transition.Transition.Charge * (invertCharges ? -1 : 1), null, transitionCustomIon); if (ionType == IonType.precursor) { mass = document.Settings.GetFragmentMass(transitionGroupDocNode.TransitionGroup.LabelType, null, newTransition, newTransitionGroupDocNode.IsotopeDist); } var newTransitionDocNode = new TransitionDocNode(newTransition, transition.Annotations.Merge(note), null, mass, transition.IsotopeDistInfo, null, transition.Results); Assume.IsTrue((Math.Abs(newTransitionDocNode.Mz + mzShiftTransition - transition.Mz) - Math.Abs(transitionGroupDocNode.TransitionGroup.PrecursorCharge * BioMassCalc.MassElectron)) <= 1E-5, String.Format("unexpected mz difference {0}-{1}={2}", newTransitionDocNode.Mz , transition.Mz, newTransitionDocNode.Mz - transition.Mz)); // Not L10N newTransitionGroupDocNode = (TransitionGroupDocNode)newTransitionGroupDocNode.Add(newTransitionDocNode); } if (newPeptideDocNode != null) newPeptideDocNode = (PeptideDocNode)newPeptideDocNode.Add(newTransitionGroupDocNode); } newPeptideGroupDocNode = (PeptideGroupDocNode)newPeptideGroupDocNode.Add(newPeptideDocNode); } newdoc = (SrmDocument)newdoc.Add(newPeptideGroupDocNode); } } // No retention time prediction for small molecules (yet?) newdoc = newdoc.ChangeSettings(newdoc.Settings.ChangePeptideSettings(newdoc.Settings.PeptideSettings.ChangePrediction( newdoc.Settings.PeptideSettings.Prediction.ChangeRetentionTime(null)))); return newdoc; }
public static DocNodeCustomIon ConvertToSmallMolecule(ConvertToSmallMoleculesMode mode, SrmDocument document, PeptideDocNode nodePep, int precursorCharge = 0, IsotopeLabelType isotopeLabelType = null) { // We're just using this masscalc to get the ion formula, so mono vs average doesn't matter isotopeLabelType = isotopeLabelType ?? IsotopeLabelType.light; var peptideSequence = nodePep.Peptide.Sequence; var masscalc = document.Settings.TryGetPrecursorCalc(isotopeLabelType, nodePep.ExplicitMods) ?? new SequenceMassCalc(MassType.Monoisotopic); // Determine the molecular formula of the charged/labeled peptide var moleculeFormula = masscalc.GetIonFormula(peptideSequence, precursorCharge); var moleculeCustomIon = new DocNodeCustomIon(moleculeFormula, SmallMoleculeNameFromPeptide(peptideSequence, precursorCharge)); if (mode == ConvertToSmallMoleculesMode.masses_only) { // No formulas or names, just masses - see how we handle that moleculeCustomIon = new DocNodeCustomIon(moleculeCustomIon.MonoisotopicMass, moleculeCustomIon.AverageMass); } else if (mode == ConvertToSmallMoleculesMode.masses_and_names) { // Just masses and names - see how we handle that moleculeCustomIon = new DocNodeCustomIon(moleculeCustomIon.MonoisotopicMass, moleculeCustomIon.AverageMass, moleculeCustomIon.Name); } return moleculeCustomIon; }
public TransitionGroup(Peptide peptide, DocNodeCustomIon customIon, int precursorCharge, IsotopeLabelType labelType) : this(peptide, customIon, precursorCharge, labelType, false, null) { }
protected override void DoTest() { const int molCount = 1; var doc = SkylineWindow.Document; for (var loop=0; loop < 3; loop++) { // Should be able to synchronize of both sibs have formula, or neither, but not one of each string testname; switch (loop) { case 0: testname = "ions_testing_mixed.sky"; break; case 1: testname = "ions_testing.sky"; break; default: testname = "ions_testing_masses.sky"; break; } string testPath = TestFilesDir.GetTestPath(testname); RunUI(() => SkylineWindow.OpenFile(testPath)); doc = WaitForDocumentChange(doc); SelectNode(SrmDocument.Level.Molecules, 0); Assert.AreEqual(molCount, SkylineWindow.Document.MoleculeCount); RunUI(SkylineWindow.ExpandPrecursors); Settings.Default.SynchronizeIsotopeTypes = true; // Select the first transition group SelectNode(SrmDocument.Level.TransitionGroups, 0); // Add precursor transition to it var pickList = ShowDialog<PopupPickList>(SkylineWindow.ShowPickChildrenInTest); RunUI(() => { pickList.ApplyFilter(false); pickList.SetItemChecked(0, true); pickList.AutoManageChildren = false; pickList.IsSynchSiblings = true; // Cause a precursor transition to be added to heavy group }); OkDialog(pickList, pickList.OnOk); WaitForClosedForm(pickList); doc = WaitForDocumentChange(doc); if (loop == 0) { // No synch is possible - one ion is formula based, the other mass only Assert.AreEqual(1, doc.MoleculeTransitions.Count()); } else { // There should now be a precursor transition for the second, heavy labeled transition group, and it // should match the mz of the transition group Assert.AreNotEqual(doc.MoleculeTransitionGroups.ToArray()[0].PrecursorMz, doc.MoleculeTransitions.ToArray()[1].Mz); Assert.AreEqual(doc.MoleculeTransitionGroups.ToArray()[1].PrecursorMz, doc.MoleculeTransitions.ToArray()[1].Mz); } } // // Now with isotope distributions // var documentPath = TestFilesDir.GetTestPath("ions_testing_isotopes.sky"); RunUI(() => SkylineWindow.OpenFile(documentPath)); WaitForDocumentLoaded(); SelectNode(SrmDocument.Level.Molecules, 0); Assert.AreEqual(molCount, SkylineWindow.Document.MoleculeCount); RunUI(SkylineWindow.ExpandPrecursors); Settings.Default.SynchronizeIsotopeTypes = true; // Select the first transition group SelectNode(SrmDocument.Level.TransitionGroups, 0); // Add isotope labeled precursor transitions to it var pickList0 = ShowDialog<PopupPickList>(SkylineWindow.ShowPickChildrenInTest); RunUI(() => { pickList0.ApplyFilter(false); pickList0.SetItemChecked(0, true); pickList0.SetItemChecked(1, true); pickList0.SetItemChecked(2, true); pickList0.AutoManageChildren = false; Assert.IsTrue(pickList0.CanSynchSiblings); pickList0.IsSynchSiblings = true; // Cause precursor transitions to be added to heavy group }); OkDialog(pickList0, pickList0.OnOk); WaitForClosedForm(pickList0); Assert.AreEqual(SkylineWindow.Document.MoleculeTransitionGroups.ToArray()[1].PrecursorMz, SkylineWindow.Document.MoleculeTransitions.ToArray()[4].Mz); Assert.AreEqual(SkylineWindow.Document.MoleculeTransitionGroups.ToArray()[1].PrecursorMz + 1.00349556477, SkylineWindow.Document.MoleculeTransitions.ToArray()[5].Mz, 1e-6); // Verify that adding a custom transition prevents the synch siblings checkbox from appearing RunUI(() => { SkylineWindow.ExpandPrecursors(); var node = SkylineWindow.SequenceTree.Nodes[0].FirstNode.FirstNode; SkylineWindow.SequenceTree.SelectedNode = node; }); var moleculeDlg = ShowDialog<EditCustomMoleculeDlg>(SkylineWindow.AddSmallMolecule); var C12H12 = "C12H12"; var testNametextA = "y1"; RunUI(() => { moleculeDlg.FormulaBox.Formula = C12H12; moleculeDlg.NameText = testNametextA; moleculeDlg.Charge = 1; }); OkDialog(moleculeDlg, moleculeDlg.OkDialog); var newDoc = SkylineWindow.Document; var compareIon = new DocNodeCustomIon(C12H12, testNametextA); const int transY1Index = 3; Assert.AreEqual(compareIon, newDoc.MoleculeTransitions.ElementAt(transY1Index).Transition.CustomIon); Assert.AreEqual(1, newDoc.MoleculeTransitions.ElementAt(transY1Index).Transition.Charge); var pickList1 = ShowDialog<PopupPickList>(SkylineWindow.ShowPickChildrenInTest); RunUI(() => { pickList1.AutoManageChildren = true; Assert.IsFalse(pickList1.CanSynchSiblings); }); OkDialog(pickList1, pickList1.OnOk); Assert.AreEqual(7, newDoc.MoleculeTransitions.Count()); // Long as we're here, check mz filtering var transitionSettings = ShowDialog<TransitionSettingsUI>(SkylineWindow.ShowTransitionSettingsUI); RunUI(() => { transitionSettings.SelectedTab = TransitionSettingsUI.TABS.Instrument; transitionSettings.MinMz = 160; // Should drop that custom ion }); OkDialog(transitionSettings, transitionSettings.OkDialog); newDoc = WaitForDocumentChange(newDoc); Assert.AreEqual(6, newDoc.MoleculeTransitions.Count()); RunUI(() => { SkylineWindow.Undo(); }); newDoc = WaitForDocumentChange(newDoc); Assert.AreEqual(7, newDoc.MoleculeTransitions.Count()); RunUI(() => { SkylineWindow.ExpandPrecursors(); var node = SkylineWindow.SequenceTree.Nodes[0].FirstNode.Nodes[1]; SkylineWindow.SequenceTree.SelectedNode = node; }); var pickList2 = ShowDialog<PopupPickList>(SkylineWindow.ShowPickChildrenInTest); RunUI(() => { Assert.IsFalse(pickList2.CanSynchSiblings); // The light set has a non-precursor transition }); OkDialog(pickList2, pickList2.OnOk); var transitionSettings2 = ShowDialog<TransitionSettingsUI>(SkylineWindow.ShowTransitionSettingsUI); RunUI(() => { transitionSettings2.SelectedTab = TransitionSettingsUI.TABS.Instrument; transitionSettings2.MinMz = 300; // Should drop that custom ion }); OkDialog(transitionSettings2, transitionSettings2.OkDialog); newDoc = WaitForDocumentChange(newDoc); Assert.AreEqual(6, newDoc.MoleculeTransitions.Count()); var pickList3 = ShowDialog<PopupPickList>(SkylineWindow.ShowPickChildrenInTest); RunUI(() => { Assert.IsTrue(pickList3.CanSynchSiblings); }); OkDialog(pickList3, pickList3.OnOk); }
public void OkDialog() { var helper = new MessageBoxHelper(this); var charge = 0; if (textCharge.Visible && !helper.ValidateSignedNumberTextBox(textCharge, _minCharge, _maxCharge, out charge)) return; if (RetentionTimeWindow.HasValue && !RetentionTime.HasValue) { helper.ShowTextBoxError(textRetentionTimeWindow, Resources.Peptide_ExplicitRetentionTimeWindow_Explicit_retention_time_window_requires_an_explicit_retention_time_value_); return; } Charge = charge; // Note: order matters here, this settor indirectly updates _formulaBox.MonoMass when formula is empty if (string.IsNullOrEmpty(_formulaBox.Formula)) { // Can the text fields be understood as mz? if (!_formulaBox.ValidateAverageText(helper)) return; if (!_formulaBox.ValidateMonoText(helper)) return; } var formula = _formulaBox.Formula; var monoMass = _formulaBox.MonoMass ?? 0; var averageMass = _formulaBox.AverageMass ?? 0; if (monoMass < CustomIon.MIN_MASS || averageMass < CustomIon.MIN_MASS) { _formulaBox.ShowTextBoxErrorFormula(helper, string.Format(Resources.EditCustomMoleculeDlg_OkDialog_Custom_molecules_must_have_a_mass_greater_than_or_equal_to__0__, CustomIon.MIN_MASS)); return; } if (monoMass > CustomIon.MAX_MASS || averageMass > CustomIon.MAX_MASS) { _formulaBox.ShowTextBoxErrorFormula(helper, string.Format(Resources.EditCustomMoleculeDlg_OkDialog_Custom_molecules_must_have_a_mass_less_than_or_equal_to__0__, CustomIon.MAX_MASS)); return; } if ((_transitionSettings != null) && (!_transitionSettings.IsMeasurablePrecursor(BioMassCalc.CalculateIonMz(monoMass, charge)) || !_transitionSettings.IsMeasurablePrecursor(BioMassCalc.CalculateIonMz(averageMass, charge)))) { _formulaBox.ShowTextBoxErrorFormula(helper, Resources.SkylineWindow_AddMolecule_The_precursor_m_z_for_this_molecule_is_out_of_range_for_your_instrument_settings_); return; } if (!string.IsNullOrEmpty(_formulaBox.Formula)) { try { ResultCustomIon = new DocNodeCustomIon(formula, textName.Text); } catch (InvalidDataException x) { _formulaBox.ShowTextBoxErrorFormula(helper, x.Message); return; } } else { ResultCustomIon = new DocNodeCustomIon(monoMass, averageMass, textName.Text); } // Did user change the list of heavy labels? if (_driverLabelType != null) { PeptideModifications modifications = new PeptideModifications( _peptideSettings.Modifications.StaticModifications, _peptideSettings.Modifications.MaxVariableMods, _peptideSettings.Modifications.MaxNeutralLosses, _driverLabelType.GetHeavyModifications(), // This is the only thing the user may have altered _peptideSettings.Modifications.InternalStandardTypes); var settings = _peptideSettings.ChangeModifications(modifications); // Only update if anything changed if (!Equals(settings, _peptideSettings)) { SrmSettings newSettings = _parent.DocumentUI.Settings.ChangePeptideSettings(settings); if (!_parent.ChangeSettings(newSettings, true)) { return; } _peptideSettings = newSettings.PeptideSettings; } } // See if this combination of charge and label would conflict with any existing transition groups if (_existingIds != null && _existingIds.Any(t => { var transitionGroup = t as TransitionGroup; return transitionGroup != null && Equals(transitionGroup.LabelType, IsotopeLabelType) && Equals(transitionGroup.PrecursorCharge, Charge) && !ReferenceEquals(t, _initialId); })) { helper.ShowTextBoxError(textName, Resources.EditCustomMoleculeDlg_OkDialog_A_precursor_with_that_charge_and_label_type_already_exists_, textName.Text); return; } // See if this would conflict with any existing transitions if (_existingIds != null && (_existingIds.Any(t => { var transition = t as Transition; return transition != null && ((transition.Charge == Charge) && Equals(transition.CustomIon, ResultCustomIon)) && !ReferenceEquals(t, _initialId); }))) { helper.ShowTextBoxError(textName, Resources.EditCustomMoleculeDlg_OkDialog_A_similar_transition_already_exists_, textName.Text); return; } DialogResult = DialogResult.OK; }
public static DocNodeCustomIon Deserialize(XmlReader reader) { DocNodeCustomIon ion = new DocNodeCustomIon(); ion.ReadAttributes(reader); return ion; }
// Note: this potentially returns a node with a different ID, which has to be Inserted rather than Replaced public PeptideDocNode ChangeCustomIonValues(SrmSettings settings, DocNodeCustomIon customIon, ExplicitRetentionTimeInfo explicitRetentionTime) { var newPeptide = new Peptide(customIon); Helpers.AssignIfEquals(ref newPeptide, Peptide); if (Equals(Peptide, newPeptide)) { return Equals(ExplicitRetentionTime, explicitRetentionTime) ? this : ChangeExplicitRetentionTime(explicitRetentionTime); } else { // ID Changes impact all children, because IDs have back pointers to their parents var children = new List<TransitionGroupDocNode>(); foreach (var nodeGroup in TransitionGroups) { children.Add(nodeGroup.UpdateSmallMoleculeTransitionGroup(newPeptide, null, settings)); } return new PeptideDocNode(newPeptide, settings, ExplicitMods, SourceKey, explicitRetentionTime, children.ToArray(), AutoManageChildren); } }
private void TestAddingSmallMoleculePrecursor() { // Position ourselves on the first molecule var newDoc = SkylineWindow.Document; SelectNode(SrmDocument.Level.Molecules, 0); var moleculeDlg = ShowDialog<EditCustomMoleculeDlg>(SkylineWindow.AddSmallMolecule); const int charge = 1; var heavyFormula = COOO13H.Replace("O13", "O12O'"); RunUI(() => { moleculeDlg.NameText = heavyFormula; moleculeDlg.FormulaBox.Formula = heavyFormula; moleculeDlg.IsotopeLabelType = IsotopeLabelType.light; // This should provoke a failure - can't have two of the same label and charge }); RunDlg<MessageDlg>(moleculeDlg.OkDialog, dlg => { // Trying to exit the dialog should cause a warning about charge Assert.AreEqual( Resources.EditCustomMoleculeDlg_OkDialog_A_precursor_with_that_charge_and_label_type_already_exists_, dlg.Message); dlg.OkDialog(); // Dismiss the warning }); RunUI(() => { moleculeDlg.IsotopeLabelType = IsotopeLabelType.heavy; }); OkDialog(moleculeDlg, moleculeDlg.OkDialog); var compareIonHeavy = new DocNodeCustomIon(heavyFormula, heavyFormula); newDoc = WaitForDocumentChange(newDoc); Assert.AreEqual(heavyFormula, newDoc.MoleculeTransitionGroups.ElementAt(1).CustomIon.Name); Assert.AreEqual(compareIonHeavy, newDoc.MoleculeTransitionGroups.ElementAt(1).CustomIon); Assert.AreEqual(charge, newDoc.MoleculeTransitionGroups.ElementAt(1).TransitionGroup.PrecursorCharge); var predictedMz = BioMassCalc.MONOISOTOPIC.CalculateIonMz(heavyFormula, charge); var actualMz = newDoc.MoleculeTransitionGroups.ElementAt(1).PrecursorMz; Assert.AreEqual(predictedMz, actualMz, Math.Pow(10, -SequenceMassCalc.MassPrecision)); // Now verify that we are OK with different charge same label SelectNode(SrmDocument.Level.Molecules, 0); var moleculeDlg2 = ShowDialog<EditCustomMoleculeDlg>(SkylineWindow.AddSmallMolecule); RunUI(() => { moleculeDlg2.FormulaBox.Formula = COOO13H + "H"; moleculeDlg2.Charge = charge + 1; moleculeDlg2.IsotopeLabelType = IsotopeLabelType.light; // This should not provoke a failure }); OkDialog(moleculeDlg2, moleculeDlg2.OkDialog); // Verify that the transition group sort order is enforced in the document // Select the last precursor, bump its charge state to drop its mz - should result in doc node reordering CheckTransitionGroupSortOrder(newDoc); RunUI(() => { SkylineWindow.SequenceTree.SelectedNode = SkylineWindow.SequenceTree.Nodes[0].FirstNode.LastNode; }); var editMoleculeDlgB = ShowDialog<EditCustomMoleculeDlg>(SkylineWindow.ModifySmallMoleculeTransitionGroup); RunUI(() => { editMoleculeDlgB.Charge = 5; }); OkDialog(editMoleculeDlgB, editMoleculeDlgB.OkDialog); newDoc = WaitForDocumentChange(newDoc); CheckTransitionGroupSortOrder(newDoc); RunUI(SkylineWindow.Undo); newDoc = WaitForDocumentChange(newDoc); CheckTransitionGroupSortOrder(newDoc); }
private static void TestAddingTransition() { RunUI(() => { SkylineWindow.ExpandPrecursors(); var node = SkylineWindow.SequenceTree.Nodes[0].FirstNode.FirstNode; SkylineWindow.SequenceTree.SelectedNode = node; }); var moleculeDlg = ShowDialog<EditCustomMoleculeDlg>(SkylineWindow.AddSmallMolecule); RunUI(() => { moleculeDlg.FormulaBox.Formula = C12H12; moleculeDlg.NameText = testNametextA; moleculeDlg.Charge = 1; }); OkDialog(moleculeDlg, moleculeDlg.OkDialog); var newDoc = SkylineWindow.Document; var compareIon = new DocNodeCustomIon(C12H12, testNametextA); Assert.AreEqual(compareIon,newDoc.MoleculeTransitions.ElementAt(0).Transition.CustomIon); Assert.AreEqual(1,newDoc.MoleculeTransitions.ElementAt(0).Transition.Charge); // Verify that tree selection doesn't change just because we changed an ID object // (formerly the tree node would collapse and focus would jump up a level) RunUI(() => { Assert.AreEqual(SkylineWindow.SequenceTree.SelectedNode, SkylineWindow.SequenceTree.Nodes[0].FirstNode.FirstNode); }); }
private static void TestAddingSmallMolecule() { RunUI(() => SkylineWindow.SelectedPath = new IdentityPath(SkylineWindow.Document.MoleculeGroups.ElementAt(0).Id)); var moleculeDlg = ShowDialog<EditCustomMoleculeDlg>(SkylineWindow.AddSmallMolecule); const int charge = 1; RunUI(() => { moleculeDlg.NameText = COOO13H; moleculeDlg.FormulaBox.Formula = COOO13H; moleculeDlg.Charge = charge; }); OkDialog(moleculeDlg, moleculeDlg.OkDialog); var compareIon = new DocNodeCustomIon(COOO13H, COOO13H); var newDoc = SkylineWindow.Document; Assert.AreEqual(compareIon, newDoc.Molecules.ElementAt(0).CustomIon); Assert.AreEqual(compareIon, newDoc.MoleculeTransitionGroups.ElementAt(0).CustomIon); Assert.AreEqual(charge, newDoc.MoleculeTransitionGroups.ElementAt(0).PrecursorCharge); var predictedMz = BioMassCalc.MONOISOTOPIC.CalculateIonMz(COOO13H, charge); var actualMz = newDoc.MoleculeTransitionGroups.ElementAt(0).PrecursorMz; Assert.AreEqual(predictedMz, actualMz, Math.Pow(10, -SequenceMassCalc.MassPrecision)); }