Beispiel #1
0
        public static DocNodeCustomIon Deserialize(XmlReader reader)
        {
            DocNodeCustomIon ion = new DocNodeCustomIon();

            ion.ReadAttributes(reader);
            return(ion);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        public Peptide(DocNodeCustomIon customIon)
        {
            CustomIon = customIon;

            Validate();
        }
Beispiel #4
0
 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;
 }
Beispiel #5
0
 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);
 }
Beispiel #6
0
 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;
 }
Beispiel #9
0
 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;
        }
Beispiel #12
0
 public static DocNodeCustomIon Deserialize(XmlReader reader)
 {
     DocNodeCustomIon ion = new DocNodeCustomIon();
     ion.ReadAttributes(reader);
     return ion;
 }
Beispiel #13
0
 // 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));
 }