Ejemplo n.º 1
0
        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.Adduct             = Adduct.NonProteomicProtonatedFromCharge(1);
            });
            OkDialog(moleculeDlg, moleculeDlg.OkDialog);
            var newDoc     = SkylineWindow.Document;
            var compareIon = new CustomIon(C12H12, Adduct.NonProteomicProtonatedFromCharge(1), null, null, 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 XmlReader HandleMassOnlyDeclarations(ref Peptide peptide)
        {
            for (var retry = 0; retry < 4; retry++)                                                                      // Looking for a common mass and set of adducts that all agree
            {
                var adjustParentMass = retry < 2;                                                                        // Do/don't try adjusting the neutral mass as if it had proton gain or loss built in
                var assumeProtonated = retry % 2 == 0;                                                                   // Do/don't try [M+H] vs [M+]
                foreach (var detail in _precursorRawDetails.OrderBy(d => d._declaredHeavy ? 1 : 0, SortOrder.Ascending)) // Look at lights first
                {
                    var parentMassAdjustment = adjustParentMass
                        ? Adduct.NonProteomicProtonatedFromCharge(detail._declaredCharge).ApplyToMass(TypedMass.ZERO_MONO_MASSH)
                        : TypedMass.ZERO_MONO_MASSH;
                    var parentMonoisotopicMass = ProposedMolecule.MonoisotopicMass - parentMassAdjustment;
                    if (_precursorRawDetails.TrueForAll(d =>
                    {
                        var adduct = assumeProtonated
                            ? Adduct.NonProteomicProtonatedFromCharge(d._declaredCharge)
                            : Adduct.FromChargeNoMass(d._declaredCharge);
                        if (d._declaredHeavy)
                        {
                            var unexplainedMass = adduct.MassFromMz(d._declaredMz, MassType.Monoisotopic) - parentMonoisotopicMass;
                            adduct = adduct.ChangeIsotopeLabels(unexplainedMass, _mzDecimalPlaces);
                        }
                        d._proposedAdduct = adduct;
                        return(Math.Abs(d._declaredMz - d._proposedAdduct.MzFromNeutralMass(parentMonoisotopicMass)) <= MzToler);
                    }))
                    {
                        var parentAverageMass = ProposedMolecule.AverageMass - parentMassAdjustment;
                        ProposedMolecule = new CustomMolecule(parentMonoisotopicMass, parentAverageMass,
                                                              peptide.CustomMolecule.Name);
                        return(UpdatePeptideAndInsertAdductsInXML(ref peptide, _precursorRawDetails.Select(d => d._proposedAdduct)));
                    }
                }
            }

            // Unexplained masses can be expressed as mass labels
            if (_precursorRawDetails.TrueForAll(d =>
            {
                var adduct = Adduct.FromChargeNoMass(d._declaredCharge);
                var unexplainedMass = adduct.MassFromMz(d._declaredMz, MassType.Monoisotopic) - ProposedMolecule.MonoisotopicMass;
                d._proposedAdduct = adduct.ChangeIsotopeLabels(unexplainedMass, _mzDecimalPlaces);
                return(Math.Abs(d._declaredMz - d._proposedAdduct.MzFromNeutralMass(ProposedMolecule.MonoisotopicMass)) <= MzToler);
            }))
            {
                return(UpdatePeptideAndInsertAdductsInXML(ref peptide, _precursorRawDetails.Select(d => d._proposedAdduct)));
            }

            // Should never arrive here
            Assume.Fail("Unable to to deduce adducts and common molecule for " + peptide); // Not L10N
            return(UpdatePeptideAndInsertAdductsInXML(ref peptide, _precursorRawDetails.Select(d => d._nominalAdduct)));
        }
Ejemplo n.º 3
0
        private void PerformTestMeasuredDriftValues(bool asSmallMolecules)
        {
            if (asSmallMolecules)
            {
                if (!RunSmallMoleculeTestVersions)
                {
                    Console.Write(MSG_SKIPPING_SMALLMOLECULE_TEST_VERSION);
                    return;
                }
                TestSmallMolecules = false;                                                          // No need to add the magic small molecule test node
            }
            var testFilesDir = new TestFilesDir(TestContext, @"Test\Results\BlibDriftTimeTest.zip"); // Re-used from BlibDriftTimeTest
            // Open document with some peptides but no results
            var docPath = testFilesDir.GetTestPath("BlibDriftTimeTest.sky");
            // This was a malformed document, which caused problems after a fix to not recalculate
            // document library settings on open. To avoid rewriting this test for the document
            // which now contains 2 precursors, the first precursor is removed immediately.
            SrmDocument docOriginal      = ResultsUtil.DeserializeDocument(docPath);
            var         pathFirstPeptide = docOriginal.GetPathTo((int)SrmDocument.Level.Molecules, 0);
            var         nodeFirstPeptide = (DocNodeParent)docOriginal.FindNode(pathFirstPeptide);

            docOriginal = (SrmDocument)docOriginal.RemoveChild(pathFirstPeptide, nodeFirstPeptide.Children[0]);
            if (asSmallMolecules)
            {
                var refine = new RefinementSettings();
                docOriginal = refine.ConvertToSmallMolecules(docOriginal, testFilesDir.FullPath);
            }
            using (var docContainer = new ResultsTestDocumentContainer(docOriginal, docPath))
            {
                var doc = docContainer.Document;

                // Import an mz5 file that contains drift info
                const string replicateName = "ID12692_01_UCA168_3727_040714";
                var          chromSets     = new[]
                {
                    new ChromatogramSet(replicateName, new[]
                                        { new MsDataFilePath(testFilesDir.GetTestPath("ID12692_01_UCA168_3727_040714" + ExtensionTestContext.ExtMz5)), }),
                };
                var docResults = doc.ChangeMeasuredResults(new MeasuredResults(chromSets));
                Assert.IsTrue(docContainer.SetDocument(docResults, docOriginal, true));
                docContainer.AssertComplete();
                var document = docContainer.Document;
                document = document.ChangeSettings(document.Settings.ChangePeptidePrediction(prediction => new PeptidePrediction(null, IonMobilityPredictor.EMPTY)));

                // Verify ability to extract predictions from raw data
                var newPred = document.Settings.PeptideSettings.Prediction.IonMobilityPredictor.ChangeMeasuredIonMobilityValuesFromResults(
                    document, docContainer.DocumentFilePath);
                var result = newPred.MeasuredMobilityIons;
                Assert.AreEqual(TestSmallMolecules ? 2 : 1, result.Count);
                const double expectedDT     = 4.0019;
                var          expectedOffset = .4829;
                Assert.AreEqual(expectedDT, result.Values.First().IonMobility.Mobility.Value, .001);
                Assert.AreEqual(expectedOffset, result.Values.First().HighEnergyIonMobilityValueOffset, .001);

                // Check ability to update, and to preserve unchanged
                var revised = new Dictionary <LibKey, IonMobilityAndCCS>();
                var libKey  = result.Keys.First();
                revised.Add(libKey, IonMobilityAndCCS.GetIonMobilityAndCCS(IonMobilityValue.GetIonMobilityValue(4, eIonMobilityUnits.drift_time_msec), null, 0.234));  // N.B. CCS handling would require actual raw data in this test, it's covered in a perf test
                var libKey2 = new LibKey("DEADEELS", asSmallMolecules ? Adduct.NonProteomicProtonatedFromCharge(2) : Adduct.DOUBLY_PROTONATED);
                revised.Add(libKey2, IonMobilityAndCCS.GetIonMobilityAndCCS(IonMobilityValue.GetIonMobilityValue(5, eIonMobilityUnits.drift_time_msec), null, 0.123));
                document =
                    document.ChangeSettings(
                        document.Settings.ChangePeptidePrediction(prediction => new PeptidePrediction(null, new IonMobilityPredictor("test", revised, null, null, IonMobilityWindowWidthCalculator.IonMobilityPeakWidthType.resolving_power, 40, 0, 0))));
                newPred = document.Settings.PeptideSettings.Prediction.ChangeDriftTimePredictor(
                    document.Settings.PeptideSettings.Prediction.IonMobilityPredictor.ChangeMeasuredIonMobilityValuesFromResults(
                        document, docContainer.DocumentFilePath)).IonMobilityPredictor;
                result = newPred.MeasuredMobilityIons;
                Assert.AreEqual(TestSmallMolecules ? 3 : 2, result.Count);
                Assert.AreEqual(expectedDT, result[libKey].IonMobility.Mobility.Value, .001);
                Assert.AreEqual(expectedOffset, result[libKey].HighEnergyIonMobilityValueOffset, .001);
                Assert.AreEqual(5, result[libKey2].IonMobility.Mobility.Value, .001);
                Assert.AreEqual(0.123, result[libKey2].HighEnergyIonMobilityValueOffset, .001);
            }
        }
Ejemplo n.º 4
0
        public void OkDialog()
        {
            var helper = new MessageBoxHelper(this);
            var charge = 0;

            if (textCharge.Visible &&
                !helper.ValidateSignedNumberTextBox(textCharge, _minCharge, _maxCharge, out charge))
            {
                return;
            }
            var adduct = Adduct.NonProteomicProtonatedFromCharge(charge);

            if (RetentionTimeWindow.HasValue && !RetentionTime.HasValue)
            {
                helper.ShowTextBoxError(textRetentionTimeWindow,
                                        Resources
                                        .Peptide_ExplicitRetentionTimeWindow_Explicit_retention_time_window_requires_an_explicit_retention_time_value_);
                return;
            }
            if (Adduct.IsEmpty || Adduct.AdductCharge != adduct.AdductCharge)
            {
                Adduct =
                    adduct; // Note: order matters here, this settor indirectly updates _formulaBox.MonoMass when formula is empty
            }
            if (string.IsNullOrEmpty(_formulaBox.NeutralFormula))
            {
                // Can the text fields be understood as mz?
                if (!_formulaBox.ValidateAverageText(helper))
                {
                    return;
                }
                if (!_formulaBox.ValidateMonoText(helper))
                {
                    return;
                }
            }
            var monoMass    = new TypedMass(_formulaBox.MonoMass ?? 0, MassType.Monoisotopic);
            var averageMass = new TypedMass(_formulaBox.AverageMass ?? 0, MassType.Average);

            if (monoMass < CustomMolecule.MIN_MASS || averageMass < CustomMolecule.MIN_MASS)
            {
                _formulaBox.ShowTextBoxErrorFormula(helper,
                                                    string.Format(
                                                        Resources
                                                        .EditCustomMoleculeDlg_OkDialog_Custom_molecules_must_have_a_mass_greater_than_or_equal_to__0__,
                                                        CustomMolecule.MIN_MASS));
                return;
            }
            if (monoMass > CustomMolecule.MAX_MASS || averageMass > CustomMolecule.MAX_MASS)
            {
                _formulaBox.ShowTextBoxErrorFormula(helper,
                                                    string.Format(
                                                        Resources
                                                        .EditCustomMoleculeDlg_OkDialog_Custom_molecules_must_have_a_mass_less_than_or_equal_to__0__,
                                                        CustomMolecule.MAX_MASS));
                return;
            }

            if ((_transitionSettings != null) &&
                (!_transitionSettings.IsMeasurablePrecursor(
                     adduct.MzFromNeutralMass(monoMass, MassType.Monoisotopic)) ||
                 !_transitionSettings.IsMeasurablePrecursor(adduct.MzFromNeutralMass(averageMass, MassType.Average))))
            {
                _formulaBox.ShowTextBoxErrorFormula(helper,
                                                    Resources
                                                    .SkylineWindow_AddMolecule_The_precursor_m_z_for_this_molecule_is_out_of_range_for_your_instrument_settings_);
                return;
            }
            if (_usageMode == UsageMode.precursor)
            {
                // Only the adduct should be changing
                SetResult(_resultCustomMolecule, Adduct);
            }
            else if (!string.IsNullOrEmpty(_formulaBox.NeutralFormula))
            {
                try
                {
                    var name = textName.Text;
                    if (string.IsNullOrEmpty(name))
                    {
                        name = _formulaBox.NeutralFormula; // Clip off any adduct description
                    }
                    SetResult(new CustomMolecule(_formulaBox.NeutralFormula, name), Adduct);
                }
                catch (InvalidDataException x)
                {
                    _formulaBox.ShowTextBoxErrorFormula(helper, x.Message);
                    return;
                }
            }
            else
            {
                SetResult(new CustomMolecule(monoMass, averageMass, textName.Text), Adduct);
            }
            // 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.PrecursorAdduct.AsFormula(),
                              Adduct
                              .AsFormula()) &&  // Compare AsFormula so proteomic and non-proteomic protonation are seen as same thing
                       !ReferenceEquals(t, _initialId));
            }))
            {
                helper.ShowTextBoxError(textName,
                                        Resources
                                        .EditCustomMoleculeDlg_OkDialog_A_precursor_with_that_adduct_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 && (Equals(transition.Adduct.AsFormula(), Adduct.AsFormula()) &&
                                              Equals(transition.CustomIon, ResultCustomMolecule)) &&
                       !ReferenceEquals(t, _initialId));
            })))
            {
                helper.ShowTextBoxError(textName,
                                        Resources.EditCustomMoleculeDlg_OkDialog_A_similar_transition_already_exists_, textName.Text);
                return;
            }
            DialogResult = DialogResult.OK;
        }
Ejemplo n.º 5
0
        private void TestAddingSmallMoleculePrecursor()
        {
            // Position ourselves on the first molecule
            var newDoc = SkylineWindow.Document;

            SelectNode(SrmDocument.Level.Molecules, 0);
            var moleculeDlg = ShowDialog <EditCustomMoleculeDlg>(SkylineWindow.AddSmallMolecule);
            var adduct      = moleculeDlg.FormulaBox.Adduct.ChangeIsotopeLabels(new Dictionary <string, int> {
                { "O'", 1 }
            });                                                                                                          // Not L10N

            RunUI(() =>
            {
                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 adduct and label conflict
                Assert.AreEqual(Resources.EditCustomMoleculeDlg_OkDialog_A_precursor_with_that_adduct_and_label_type_already_exists_, dlg.Message);
                dlg.OkDialog(); // Dismiss the warning
            });
            RunUI(() =>
            {
                moleculeDlg.FormulaBox.Adduct = adduct;
                moleculeDlg.IsotopeLabelType  = IsotopeLabelType.heavy;
            });
            OkDialog(moleculeDlg, moleculeDlg.OkDialog);

            newDoc = WaitForDocumentChange(newDoc);

            Assert.AreEqual(adduct, newDoc.MoleculeTransitionGroups.ElementAt(1).TransitionGroup.PrecursorAdduct);
            var predictedMz = BioMassCalc.MONOISOTOPIC.CalculateIonMz(COOO13H, adduct);
            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.Adduct           = Adduct.FromChargeProtonated(adduct.AdductCharge + 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.Adduct = Adduct.NonProteomicProtonatedFromCharge(5);
            });
            OkDialog(editMoleculeDlgB, editMoleculeDlgB.OkDialog);
            newDoc = WaitForDocumentChange(newDoc);
            CheckTransitionGroupSortOrder(newDoc);
            RunUI(SkylineWindow.Undo);
            newDoc = WaitForDocumentChange(newDoc);
            CheckTransitionGroupSortOrder(newDoc);
        }
Ejemplo n.º 6
0
        private static void TestAddingSmallMolecule()
        {
            RunUI(() => SkylineWindow.SelectedPath = new IdentityPath(SkylineWindow.Document.MoleculeGroups.ElementAt(0).Id));
            var doc             = SkylineWindow.Document;
            var editMoleculeDlg = ShowDialog <EditCustomMoleculeDlg>(SkylineWindow.AddSmallMolecule);

            // Less extreme values should trigger a warning about instrument limits
            RunUI(() =>
            {
                editMoleculeDlg.FormulaBox.MonoMass    = CustomMolecule.MAX_MASS - 100;
                editMoleculeDlg.FormulaBox.AverageMass = editMoleculeDlg.FormulaBox.MonoMass;
            });
            RunDlg <MessageDlg>(editMoleculeDlg.OkDialog, dlg =>
            {
                AssertEx.AreComparableStrings(
                    Resources
                    .SkylineWindow_AddMolecule_The_precursor_m_z_for_this_molecule_is_out_of_range_for_your_instrument_settings_,
                    dlg.Message);
                dlg.OkDialog(); // Dismiss the warning
            });


            RunUI(() =>
            {
                // Verify the interaction of explicitly set formula, mz and charge
                editMoleculeDlg.FormulaBox.Formula = C12H12;
                var mono    = editMoleculeDlg.FormulaBox.MonoMass ?? -1;
                var average = editMoleculeDlg.FormulaBox.AverageMass ?? -1;
                var massPrecisionTolerance = Math.Pow(10, -SequenceMassCalc.MassPrecision);
                Assert.AreEqual(BioMassCalc.MONOISOTOPIC.CalculateMassFromFormula(C12H12), mono, massPrecisionTolerance);
                Assert.AreEqual(BioMassCalc.AVERAGE.CalculateMassFromFormula(C12H12), average, massPrecisionTolerance);
                Assert.AreEqual(mono, double.Parse(editMoleculeDlg.FormulaBox.MonoText), massPrecisionTolerance);
                Assert.AreEqual(average, double.Parse(editMoleculeDlg.FormulaBox.AverageText), massPrecisionTolerance);
                editMoleculeDlg.Adduct = Adduct.NonProteomicProtonatedFromCharge(3);
                Assert.AreEqual(
                    Math.Round(BioMassCalc.MONOISOTOPIC.CalculateMassFromFormula(C12H12), SequenceMassCalc.MassPrecision),
                    mono); // Masses should not change
                Assert.AreEqual(
                    Math.Round(BioMassCalc.AVERAGE.CalculateMassFromFormula(C12H12), SequenceMassCalc.MassPrecision),
                    average);
                editMoleculeDlg.Adduct = Adduct.FromChargeProtonated(1);
                Assert.AreEqual(
                    Math.Round(BioMassCalc.MONOISOTOPIC.CalculateMassFromFormula(C12H12), SequenceMassCalc.MassPrecision),
                    mono); // Masses should not change
                Assert.AreEqual(
                    Math.Round(BioMassCalc.AVERAGE.CalculateMassFromFormula(C12H12), SequenceMassCalc.MassPrecision),
                    average);
                Assert.AreEqual(BioMassCalc.MONOISOTOPIC.CalculateIonMz(C12H12, editMoleculeDlg.Adduct),
                                mono + BioMassCalc.MassProton,
                                massPrecisionTolerance);
                Assert.AreEqual(BioMassCalc.AVERAGE.CalculateIonMz(C12H12, editMoleculeDlg.Adduct),
                                average + BioMassCalc.MassProton,
                                massPrecisionTolerance);
                editMoleculeDlg.Adduct = Adduct.NonProteomicProtonatedFromCharge(-1);  // Validate negative charges
                Assert.AreEqual(
                    Math.Round(BioMassCalc.MONOISOTOPIC.CalculateMassFromFormula(C12H12), SequenceMassCalc.MassPrecision),
                    mono); // Masses should not change
                Assert.AreEqual(
                    Math.Round(BioMassCalc.AVERAGE.CalculateMassFromFormula(C12H12), SequenceMassCalc.MassPrecision),
                    average);
                Assert.AreEqual(BioMassCalc.MONOISOTOPIC.CalculateIonMz(C12H12, editMoleculeDlg.Adduct),
                                mono - BioMassCalc.MassProton,
                                massPrecisionTolerance);
                Assert.AreEqual(BioMassCalc.AVERAGE.CalculateIonMz(C12H12, editMoleculeDlg.Adduct),
                                average - BioMassCalc.MassProton,
                                massPrecisionTolerance);

                editMoleculeDlg.FormulaBox.Formula = string.Empty;          // Simulate user blanking out the formula
                Assert.AreEqual(mono, editMoleculeDlg.FormulaBox.MonoMass); // Leaves masses untouched
                Assert.AreEqual(average, editMoleculeDlg.FormulaBox.AverageMass);
                editMoleculeDlg.FormulaBox.AverageMass = averageMass100;
                editMoleculeDlg.FormulaBox.MonoMass    = monoMass105;
                editMoleculeDlg.NameText = "test";
                Assert.IsTrue(string.IsNullOrEmpty(editMoleculeDlg.FormulaBox.Formula));
                Assert.AreEqual(averageMass100, editMoleculeDlg.FormulaBox.AverageMass);
                Assert.AreEqual(monoMass105, editMoleculeDlg.FormulaBox.MonoMass);
                var monoMzText         = editMoleculeDlg.FormulaBox.MonoText;
                var averageMzText      = editMoleculeDlg.FormulaBox.AverageText;
                var mzMonoAtMminusH    = double.Parse(monoMzText);
                var mzAverageAtMminusH = double.Parse(averageMzText);
                editMoleculeDlg.Adduct = Adduct.NonProteomicProtonatedFromCharge(3);
                Assert.AreEqual(monoMzText, editMoleculeDlg.FormulaBox.MonoText); // m/z readout should not change
                Assert.AreEqual(averageMzText, editMoleculeDlg.FormulaBox.AverageText);
                // If this mz is now said to be due to higher charge, then mass must greater
                Assert.AreEqual(3 * (mzAverageAtMminusH - BioMassCalc.MassProton),
                                editMoleculeDlg.FormulaBox.AverageMass.Value, massPrecisionTolerance);
                Assert.AreEqual(3 * (mzMonoAtMminusH - BioMassCalc.MassProton),
                                editMoleculeDlg.FormulaBox.MonoMass.Value, massPrecisionTolerance);
                // If this mz is now said to be due to lesser z, then mass must smaller
                editMoleculeDlg.Adduct = Adduct.NonProteomicProtonatedFromCharge(1);
                Assert.AreEqual(monoMzText, editMoleculeDlg.FormulaBox.MonoText); // m/z readout should not change
                Assert.AreEqual(averageMzText, editMoleculeDlg.FormulaBox.AverageText);
                var massAverage = editMoleculeDlg.FormulaBox.AverageMass.Value;
                var massMono    = editMoleculeDlg.FormulaBox.MonoMass.Value;
                Assert.AreEqual(averageMass100 - BioMassCalc.MassProton, massAverage, massPrecisionTolerance); // Mass should change back
                Assert.AreEqual(monoMass105 - BioMassCalc.MassProton, massMono, massPrecisionTolerance);
            });

            var adduct = Adduct.NonProteomicProtonatedFromCharge(1);

            RunUI(() =>
            {
                editMoleculeDlg.NameText           = COOO13H;
                editMoleculeDlg.FormulaBox.Formula = COOO13H + adduct.AdductFormula;
            });
            OkDialog(editMoleculeDlg, editMoleculeDlg.OkDialog);
            var compareIon = new CustomMolecule(COOO13H, COOO13H);
            var newDoc     = WaitForDocumentChange(doc);

            Assert.AreEqual(compareIon, newDoc.Molecules.ElementAt(0).CustomMolecule);
            Assert.AreEqual(compareIon, newDoc.MoleculeTransitionGroups.ElementAt(0).CustomMolecule);
            Assert.AreEqual(adduct.AdductCharge, newDoc.MoleculeTransitionGroups.ElementAt(0).PrecursorCharge);
            var predictedMz = BioMassCalc.MONOISOTOPIC.CalculateIonMz(COOO13H, adduct);
            var actualMz    = newDoc.MoleculeTransitionGroups.ElementAt(0).PrecursorMz;

            Assert.AreEqual(predictedMz, actualMz, Math.Pow(10, -SequenceMassCalc.MassPrecision));
        }
Ejemplo n.º 7
0
        private static void TestEditingTransition()
        {
            double massPrecisionTolerance = Math.Pow(10, -SequenceMassCalc.MassPrecision);
            var    doc = SkylineWindow.Document;

            RunUI(() =>
            {
                SkylineWindow.ExpandPrecursors();
                SkylineWindow.SequenceTree.SelectedNode = SkylineWindow.SequenceTree.Nodes[0].FirstNode.FirstNode.FirstNode;
            });
            var editMoleculeDlg =
                ShowDialog <EditCustomMoleculeDlg>(
                    () => SkylineWindow.ModifyTransition((TransitionTreeNode)SkylineWindow.SequenceTree.SelectedNode));
            var monoMass = new TypedMass(805, MassType.Monoisotopic);

            RunUI(() =>
            {
                Assert.AreEqual(C12H12 + Adduct.NonProteomicProtonatedFromCharge(1).AdductFormula, editMoleculeDlg.FormulaBox.Formula);
                Assert.AreEqual(BioMassCalc.MONOISOTOPIC.CalculateMassFromFormula(C12H12),
                                editMoleculeDlg.FormulaBox.MonoMass ?? -1, massPrecisionTolerance);
                Assert.AreEqual(BioMassCalc.AVERAGE.CalculateMassFromFormula(C12H12),
                                editMoleculeDlg.FormulaBox.AverageMass ?? -1, massPrecisionTolerance);
                Assert.AreEqual(Adduct.NonProteomicProtonatedFromCharge(1).AdductFormula, editMoleculeDlg.FormulaBox.Adduct.AdductFormula);
                editMoleculeDlg.FormulaBox.Formula = editMoleculeDlg.FormulaBox.Adduct.AdductFormula; // Remove neutral formula, should leave masses unchanged
                Assert.AreEqual(BioMassCalc.MONOISOTOPIC.CalculateMassFromFormula(C12H12),
                                editMoleculeDlg.FormulaBox.MonoMass ?? -1, massPrecisionTolerance);
                Assert.AreEqual(BioMassCalc.AVERAGE.CalculateMassFromFormula(C12H12),
                                editMoleculeDlg.FormulaBox.AverageMass ?? -1, massPrecisionTolerance);
                editMoleculeDlg.FormulaBox.AverageMass = 800;
                editMoleculeDlg.FormulaBox.MonoMass    = monoMass.Value;
                editMoleculeDlg.NameText = "Fragment";
            });
            OkDialog(editMoleculeDlg, editMoleculeDlg.OkDialog);
            var newdoc = WaitForDocumentChange(doc);

            Assert.AreEqual("Fragment", newdoc.MoleculeTransitions.ElementAt(0).Transition.CustomIon.ToString());
            Assert.AreEqual(BioMassCalc.CalculateIonMz(monoMass, editMoleculeDlg.Adduct), newdoc.MoleculeTransitions.ElementAt(0).Mz, massPrecisionTolerance);
            Assert.IsFalse(ReferenceEquals(doc.MoleculeTransitions.ElementAt(0).Id, newdoc.MoleculeTransitions.ElementAt(0).Id)); // Changing the mass changes the Id

            // 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.FirstNode);
            });

            // And test undo/redo
            RunUI(() => SkylineWindow.Undo());
            newdoc = WaitForDocumentChange(newdoc);
            Assert.AreNotEqual("Fragment", newdoc.MoleculeTransitions.ElementAt(0).Transition.CustomIon.ToString());
            Assert.AreNotEqual(BioMassCalc.CalculateIonMz(monoMass, editMoleculeDlg.Adduct), newdoc.MoleculeTransitions.ElementAt(0).Mz, massPrecisionTolerance);
            Assert.IsTrue(ReferenceEquals(doc.MoleculeTransitions.ElementAt(0).Id, newdoc.MoleculeTransitions.ElementAt(0).Id));
            RunUI(() => SkylineWindow.Redo());
            newdoc = WaitForDocumentChange(newdoc);
            Assert.AreEqual("Fragment", newdoc.MoleculeTransitions.ElementAt(0).Transition.CustomIon.ToString());
            Assert.AreEqual(BioMassCalc.CalculateIonMz(monoMass, editMoleculeDlg.Adduct), newdoc.MoleculeTransitions.ElementAt(0).Mz, massPrecisionTolerance);

            // 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.FirstNode);
            });
        }
Ejemplo n.º 8
0
        private static void TestEditingTransitionGroup()
        {
            RunUI(() =>
            {
                // Select the first precursor
                SkylineWindow.SequenceTree.SelectedNode = SkylineWindow.SequenceTree.Nodes[0].FirstNode.Nodes[0];
            });
            var docA = SkylineWindow.Document;

            var editMoleculeDlgA = ShowDialog <EditCustomMoleculeDlg>(SkylineWindow.ModifySmallMoleculeTransitionGroup);

            RunUI(() =>
            {
                // Test the "set" part of "Issue 371: Small molecules: need to be able to import and/or set CE, RT and DT for individual precursors and products"
                editMoleculeDlgA.IonMobility = TESTVALUES.IonMobility.Value;
                editMoleculeDlgA.IonMobilityHighEnergyOffset = TESTVALUES.IonMobilityHighEnergyOffset.Value;
                editMoleculeDlgA.IonMobilityUnits            = TESTVALUES.IonMobilityUnits;
                editMoleculeDlgA.CollisionalCrossSectionSqA  = TESTVALUES.CollisionalCrossSectionSqA.Value;
                editMoleculeDlgA.CollisionEnergy             = TESTVALUES.CollisionEnergy.Value;
                editMoleculeDlgA.SLens                 = TESTVALUES.SLens.Value;
                editMoleculeDlgA.ConeVoltage           = TESTVALUES.ConeVoltage;
                editMoleculeDlgA.DeclusteringPotential = TESTVALUES.DeclusteringPotential;
                editMoleculeDlgA.CompensationVoltage   = TESTVALUES.CompensationVoltage;
            });
            OkDialog(editMoleculeDlgA, editMoleculeDlgA.OkDialog);
            var doc            = WaitForDocumentChange(docA);
            var peptideDocNode = doc.Molecules.ElementAt(0);

            Assert.IsNotNull(peptideDocNode);
            Assert.IsTrue(peptideDocNode.EqualsId(docA.Molecules.ElementAt(0)));                                           // No Id change
            Assert.IsTrue(doc.MoleculeTransitionGroups.ElementAt(0).EqualsId(docA.MoleculeTransitionGroups.ElementAt(0))); // No change to Id node or its child Ids
            Assert.AreEqual(TESTVALUES, doc.MoleculeTransitionGroups.ElementAt(0).ExplicitValues);
            Assert.IsNull(peptideDocNode.ExplicitRetentionTime);
            var    editMoleculeDlg        = ShowDialog <EditCustomMoleculeDlg>(SkylineWindow.ModifySmallMoleculeTransitionGroup);
            double massPrecisionTolerance = Math.Pow(10, -SequenceMassCalc.MassPrecision);
            double massAverage            = 0;
            double massMono = 0;

            RunUI(() =>
            {
                Assert.AreEqual(COOO13H, editMoleculeDlg.NameText);                     // Comes from the docnode
                Assert.AreEqual(COOO13H, editMoleculeDlg.FormulaBox.NeutralFormula);    // Comes from the docnode
                Assert.AreEqual(COOO13H + "[M+H]", editMoleculeDlg.FormulaBox.Formula); // Comes from the docnode
                Assert.AreEqual(BioMassCalc.MONOISOTOPIC.CalculateMassFromFormula(COOO13H), editMoleculeDlg.FormulaBox.MonoMass ?? -1, massPrecisionTolerance);
                Assert.AreEqual(BioMassCalc.AVERAGE.CalculateMassFromFormula(COOO13H), editMoleculeDlg.FormulaBox.AverageMass ?? -1, massPrecisionTolerance);
                // Now try something crazy
                editMoleculeDlg.FormulaBox.Formula = "[M+500H]";
            });
            // Trying to exit the dialog should cause a warning about charge state
            RunDlg <MessageDlg>(editMoleculeDlg.OkDialog, dlg =>
            {
                AssertEx.AreComparableStrings(
                    string.Format(Resources.MessageBoxHelper_ValidateSignedNumberTextBox_Value__0__must_be_between__1__and__2__or__3__and__4__,
                                  500,
                                  -TransitionGroup.MAX_PRECURSOR_CHARGE,
                                  -TransitionGroup.MIN_PRECURSOR_CHARGE,
                                  TransitionGroup.MIN_PRECURSOR_CHARGE,
                                  TransitionGroup.MAX_PRECURSOR_CHARGE),
                    dlg.Message);
                dlg.OkDialog(); // Dismiss the warning
            });
            RunUI(() =>
            {
                editMoleculeDlg.FormulaBox.Formula = "[M+H]";
            });

            // Test charge state limits
            RunUI(() => editMoleculeDlg.Adduct = Adduct.FromChargeProtonated(TransitionGroup.MAX_PRECURSOR_CHARGE + 1));
            RunDlg <MessageDlg>(editMoleculeDlg.OkDialog, dlg =>
            {
                // Trying to exit the dialog should cause a warning about charge
                Assert.AreEqual(
                    String.Format(Resources.MessageBoxHelper_ValidateSignedNumberTextBox_Value__0__must_be_between__1__and__2__or__3__and__4__,
                                  TransitionGroup.MAX_PRECURSOR_CHARGE + 1,
                                  -TransitionGroup.MAX_PRECURSOR_CHARGE,
                                  -TransitionGroup.MIN_PRECURSOR_CHARGE,
                                  TransitionGroup.MIN_PRECURSOR_CHARGE,
                                  TransitionGroup.MAX_PRECURSOR_CHARGE), dlg.Message);
                dlg.OkDialog(); // Dismiss the warning
            });
            RunUI(() => editMoleculeDlg.Adduct = Adduct.FromChargeProtonated(-(TransitionGroup.MAX_PRECURSOR_CHARGE + 1)));
            RunDlg <MessageDlg>(editMoleculeDlg.OkDialog, dlg =>
            {
                // Trying to exit the dialog should cause a warning about charge
                Assert.AreEqual(
                    String.Format(Resources.MessageBoxHelper_ValidateSignedNumberTextBox_Value__0__must_be_between__1__and__2__or__3__and__4__,
                                  -(TransitionGroup.MAX_PRECURSOR_CHARGE + 1),
                                  -TransitionGroup.MAX_PRECURSOR_CHARGE,
                                  -TransitionGroup.MIN_PRECURSOR_CHARGE,
                                  TransitionGroup.MIN_PRECURSOR_CHARGE,
                                  TransitionGroup.MAX_PRECURSOR_CHARGE), dlg.Message);
                dlg.OkDialog(); // Dismiss the warning
            });

            // Restore
            RunUI(() =>
            {
                Assert.AreEqual(2.115335, double.Parse(editMoleculeDlg.FormulaBox.MonoText), .0001);
                Assert.AreEqual(2.116302, double.Parse(editMoleculeDlg.FormulaBox.AverageText), .0001);

                editMoleculeDlg.Adduct = Adduct.NonProteomicProtonatedFromCharge(2); // Back to sanity

                massAverage = editMoleculeDlg.FormulaBox.AverageMass.Value;
                massMono    = editMoleculeDlg.FormulaBox.MonoMass.Value;
                Assert.AreEqual(BioMassCalc.AVERAGE.CalculateMassFromFormula(COOO13H), massAverage, massPrecisionTolerance);
                Assert.AreEqual(BioMassCalc.MONOISOTOPIC.CalculateMassFromFormula(COOO13H), massMono, massPrecisionTolerance);
                Assert.AreEqual(.5 * massMono + AminoAcidFormulas.ProtonMass, double.Parse(editMoleculeDlg.FormulaBox.MonoText), .001);
                Assert.AreEqual(.5 * massAverage + AminoAcidFormulas.ProtonMass, double.Parse(editMoleculeDlg.FormulaBox.AverageText), .001);
            });
            OkDialog(editMoleculeDlg, editMoleculeDlg.OkDialog);
            var newdoc = WaitForDocumentChange(doc);

            Assert.AreEqual(massAverage, newdoc.MoleculeTransitionGroups.ElementAt(0).CustomMolecule.AverageMass, massPrecisionTolerance);
            Assert.AreEqual(massMono, newdoc.MoleculeTransitionGroups.ElementAt(0).CustomMolecule.MonoisotopicMass, massPrecisionTolerance);
            Assert.IsNotNull(newdoc.Molecules.ElementAt(0).CustomMolecule.Formula); // Molecule and children share base molecule
            Assert.AreEqual(.5 * massMono + BioMassCalc.MassProton, newdoc.MoleculeTransitionGroups.ElementAt(0).PrecursorMz, .001);

            Assert.IsFalse(newdoc.MoleculeTransitionGroups.ElementAt(0).EqualsId(peptideDocNode));  // Changing the adduct changes the Id node
            // Verify that CE overrides work
            Assert.AreEqual(TESTVALUES, newdoc.MoleculeTransitionGroups.ElementAt(0).ExplicitValues);
            Assert.IsNull(newdoc.Molecules.ElementAt(0).ExplicitRetentionTime);  // Not set yet

            // Verify that the explicitly set drift time overides any calculations
            double windowDT;
            double driftTimeMax    = 1000.0;
            var    centerDriftTime = newdoc.Settings.PeptideSettings.Prediction.GetIonMobility(
                newdoc.Molecules.First(), newdoc.MoleculeTransitionGroups.First(), null, null, driftTimeMax, out windowDT);

            Assert.AreEqual(TESTVALUES.IonMobility.Value, centerDriftTime.IonMobility.Mobility.Value, .0001);
            Assert.AreEqual(TESTVALUES.IonMobility.Value + TESTVALUES.IonMobilityHighEnergyOffset.Value, centerDriftTime.GetHighEnergyDriftTimeMsec() ?? 0, .0001);
            Assert.AreEqual(0, windowDT, .0001);

            // 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);
            });
        }
Ejemplo n.º 9
0
        public void OkDialog()
        {
            var helper = new MessageBoxHelper(this);
            var charge = 0;

            if (textCharge.Visible &&
                !helper.ValidateSignedNumberTextBox(textCharge, _minCharge, _maxCharge, out charge))
            {
                return;
            }
            var adduct = Adduct.NonProteomicProtonatedFromCharge(charge);

            if (RetentionTimeWindow.HasValue && !RetentionTime.HasValue)
            {
                helper.ShowTextBoxError(textRetentionTimeWindow,
                                        Resources
                                        .Peptide_ExplicitRetentionTimeWindow_Explicit_retention_time_window_requires_an_explicit_retention_time_value_);
                return;
            }
            if (Adduct.IsEmpty || Adduct.AdductCharge != adduct.AdductCharge)
            {
                Adduct =
                    adduct; // Note: order matters here, this settor indirectly updates _formulaBox.MonoMass when formula is empty
            }
            if (string.IsNullOrEmpty(_formulaBox.NeutralFormula))
            {
                // Can the text fields be understood as mz?
                if (!_formulaBox.ValidateAverageText(helper))
                {
                    return;
                }
                if (!_formulaBox.ValidateMonoText(helper))
                {
                    return;
                }
            }
            var monoMass    = new TypedMass(_formulaBox.MonoMass ?? 0, MassType.Monoisotopic);
            var averageMass = new TypedMass(_formulaBox.AverageMass ?? 0, MassType.Average);

            if (monoMass < CustomMolecule.MIN_MASS || averageMass < CustomMolecule.MIN_MASS)
            {
                _formulaBox.ShowTextBoxErrorFormula(helper,
                                                    string.Format(
                                                        Resources
                                                        .EditCustomMoleculeDlg_OkDialog_Custom_molecules_must_have_a_mass_greater_than_or_equal_to__0__,
                                                        CustomMolecule.MIN_MASS));
                return;
            }
            if (monoMass > CustomMolecule.MAX_MASS || averageMass > CustomMolecule.MAX_MASS)
            {
                _formulaBox.ShowTextBoxErrorFormula(helper,
                                                    string.Format(
                                                        Resources
                                                        .EditCustomMoleculeDlg_OkDialog_Custom_molecules_must_have_a_mass_less_than_or_equal_to__0__,
                                                        CustomMolecule.MAX_MASS));
                return;
            }

            if ((_transitionSettings != null) &&
                (!_transitionSettings.IsMeasurablePrecursor(
                     adduct.MzFromNeutralMass(monoMass, MassType.Monoisotopic)) ||
                 !_transitionSettings.IsMeasurablePrecursor(adduct.MzFromNeutralMass(averageMass, MassType.Average))))
            {
                _formulaBox.ShowTextBoxErrorFormula(helper,
                                                    Resources
                                                    .SkylineWindow_AddMolecule_The_precursor_m_z_for_this_molecule_is_out_of_range_for_your_instrument_settings_);
                return;
            }

            // Ion mobility value must have ion mobility units
            if (textIonMobility.Visible && IonMobility.HasValue)
            {
                if (IonMobilityUnits == eIonMobilityUnits.none)
                {
                    helper.ShowTextBoxError(textIonMobility, Resources.EditCustomMoleculeDlg_OkDialog_Please_specify_the_ion_mobility_units_);
                    comboBoxIonMobilityUnits.Focus();
                    return;
                }

                if (IonMobility.Value == 0 ||
                    (IonMobility.Value < 0 && !IonMobilityFilter.AcceptNegativeMobilityValues(IonMobilityUnits)))
                {
                    helper.ShowTextBoxError(textIonMobility,
                                            string.Format(Resources.SmallMoleculeTransitionListReader_ReadPrecursorOrProductColumns_Invalid_ion_mobility_value__0_, IonMobility));
                    textIonMobility.Focus();
                    return;
                }
            }
            if (_usageMode == UsageMode.precursor)
            {
                // Only the adduct should be changing
                SetResult(_resultCustomMolecule, Adduct);
            }
            else if (!string.IsNullOrEmpty(_formulaBox.NeutralFormula))
            {
                try
                {
                    var name = textName.Text;
                    if (string.IsNullOrEmpty(name))
                    {
                        name = _formulaBox.NeutralFormula; // Clip off any adduct description
                    }
                    SetResult(new CustomMolecule(_formulaBox.NeutralFormula, name), Adduct);
                }
                catch (InvalidDataException x)
                {
                    _formulaBox.ShowTextBoxErrorFormula(helper, x.Message);
                    return;
                }
            }
            else
            {
                SetResult(new CustomMolecule(monoMass, averageMass, textName.Text), Adduct);
            }
            // Did user change the list of heavy labels?
            if (_driverLabelType != null)
            {
                // This is the only thing the user may have altered
                var newHeavyMods = _driverLabelType.GetHeavyModifications().ToArray();
                if (!ArrayUtil.EqualsDeep(newHeavyMods, _peptideSettings.Modifications.HeavyModifications))
                {
                    var labelTypes = _peptideSettings.Modifications.InternalStandardTypes.Where(t =>
                                                                                                newHeavyMods.Any(m => Equals(m.LabelType, t))).ToArray();
                    if (labelTypes.Length == 0)
                    {
                        labelTypes = new[] { newHeavyMods.First().LabelType }
                    }
                    ;

                    PeptideModifications modifications = new PeptideModifications(
                        _peptideSettings.Modifications.StaticModifications,
                        _peptideSettings.Modifications.MaxVariableMods,
                        _peptideSettings.Modifications.MaxNeutralLosses,
                        newHeavyMods,
                        labelTypes);
                    var         settings    = _peptideSettings.ChangeModifications(modifications);
                    SrmSettings newSettings = _parent.DocumentUI.Settings.ChangePeptideSettings(settings);
                    if (!_parent.ChangeSettings(newSettings, true))
                    {
                        // Not expected, since we checked for a change before calling
                        // Otherwise, this is very confusing. The form just refuses to go away
                        // We would prefer to get an unhandled exception and fix this
                        Assume.Fail();
                        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.PrecursorAdduct.AsFormula(),
                              Adduct
                              .AsFormula()) &&  // Compare AsFormula so proteomic and non-proteomic protonation are seen as same thing
                       !ReferenceEquals(t, _initialId));
            }))
            {
                helper.ShowTextBoxError(textName,
                                        Resources
                                        .EditCustomMoleculeDlg_OkDialog_A_precursor_with_that_adduct_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 && (Equals(transition.Adduct.AsFormula(), Adduct.AsFormula()) &&
                                              Equals(transition.CustomIon, ResultCustomMolecule)) &&
                       !ReferenceEquals(t, _initialId));
            })))
            {
                helper.ShowTextBoxError(textName,
                                        Resources.EditCustomMoleculeDlg_OkDialog_A_similar_transition_already_exists_, textName.Text);
                return;
            }
            DialogResult = DialogResult.OK;
        }