Exemple #1
0
        public void TestCustomMoleculeToTSV()
        {
            var moleculeAccessionNumbers = new MoleculeAccessionNumbers(new Dictionary <string, string>
            {
                { MoleculeAccessionNumbers.TagCAS, "MyCAS" },
                { MoleculeAccessionNumbers.TagHMDB, "MyHMDB" },
                { MoleculeAccessionNumbers.TagInChI, "MyInChI" },
                { MoleculeAccessionNumbers.TagSMILES, "MySmiles" },
                { MoleculeAccessionNumbers.TagKEGG, "MyKegg" }
            });
            var smallMoleculeLibraryAttributes =
                SmallMoleculeLibraryAttributes.Create("MyMolecule", "H2O", "MyInChiKey", moleculeAccessionNumbers.GetNonInChiKeys());

            for (var loop = 0; loop < 2; loop++)
            {
                var customMolecule     = CustomMolecule.FromSmallMoleculeLibraryAttributes(smallMoleculeLibraryAttributes);
                var target             = new Target(customMolecule);
                var serializableString = target.ToSerializableString();

                var roundTrip = Target.FromSerializableString(serializableString);
                Assert.AreEqual(target, roundTrip);
                Assert.AreEqual(customMolecule, roundTrip.Molecule);
                Assert.AreEqual(customMolecule.AccessionNumbers, roundTrip.Molecule.AccessionNumbers);
                smallMoleculeLibraryAttributes = // Masses instead of formula
                                                 SmallMoleculeLibraryAttributes.Create("MyMolecule", null, new TypedMass(123.4, MassType.Monoisotopic), new TypedMass(123.45, MassType.Average), "MyInChiKey", moleculeAccessionNumbers.GetNonInChiKeys());
            }
        }
Exemple #2
0
        private static void TestAddingSmallMoleculeAsMasses()
        {
            RunUI(() => SkylineWindow.SelectedPath = new IdentityPath(SkylineWindow.Document.MoleculeGroups.ElementAt(0).Id));
            var doc             = SkylineWindow.Document;
            var formula         = COOO13H;
            var editMoleculeDlg = ShowDialog <EditCustomMoleculeDlg>(SkylineWindow.AddSmallMolecule);
            var monoMass        = BioMassCalc.MONOISOTOPIC.CalculateMassFromFormula(formula);
            var averageMass     = BioMassCalc.AVERAGE.CalculateMassFromFormula(formula);
            var adduct          = Adduct.M_PLUS_Na;

            RunUI(() =>
            {
                // Verify the interaction of explicitly set mz and charge without formula
                editMoleculeDlg.NameText = formula;
                editMoleculeDlg.Adduct   = adduct;
                var mzMono    = editMoleculeDlg.Adduct.MzFromNeutralMass(monoMass);
                var mzAverage = editMoleculeDlg.Adduct.MzFromNeutralMass(averageMass);
                editMoleculeDlg.FormulaBox.MonoMass    = monoMass;
                editMoleculeDlg.FormulaBox.AverageMass = averageMass;
                var massPrecisionTolerance             = 0.00001;
                Assert.AreEqual(mzMono, double.Parse(editMoleculeDlg.FormulaBox.MonoText), massPrecisionTolerance);
                Assert.AreEqual(mzAverage, double.Parse(editMoleculeDlg.FormulaBox.AverageText), massPrecisionTolerance);
            });
            OkDialog(editMoleculeDlg, editMoleculeDlg.OkDialog);
            var newDoc     = WaitForDocumentChange(doc);
            var compareIon = new CustomMolecule(new TypedMass(monoMass, MassType.Monoisotopic), new TypedMass(averageMass, MassType.Average), formula);

            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(formula, adduct);
            var actualMz    = newDoc.MoleculeTransitionGroups.ElementAt(0).PrecursorMz;

            Assert.AreEqual(predictedMz, actualMz, Math.Pow(10, -SequenceMassCalc.MassPrecision));
        }
        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)));
        }
        private void ProposeMoleculeWithCommonFormula(Peptide peptide)
        {
            // Examine any provided formulas (including parent molecule and/or precursor ions) and find common basis
            ProposedMolecule = peptide.CustomMolecule;
            var precursorsWithFormulas = _precursorRawDetails.Where(d => !string.IsNullOrEmpty(d._formulaUnlabeled)).ToList();
            var parentFormula          = peptide.CustomMolecule.UnlabeledFormula;
            var commonFormula          = string.IsNullOrEmpty(parentFormula)
                ? BioMassCalc.MONOISOTOPIC.FindFormulaIntersectionUnlabeled(
                precursorsWithFormulas.Select(p => p._formulaUnlabeled))
                : parentFormula;

            // Check for consistent and correctly declared precursor formula+adduct
            var precursorsWithFormulasAndAdducts = precursorsWithFormulas.Where(d => !Adduct.IsNullOrEmpty(d._nominalAdduct)).ToList();

            if (precursorsWithFormulasAndAdducts.Any() &&
                precursorsWithFormulas.All(
                    d => d._formulaUnlabeled.Equals(precursorsWithFormulasAndAdducts[0]._formulaUnlabeled)))
            {
                commonFormula = precursorsWithFormulasAndAdducts[0]._formulaUnlabeled;
            }

            if (!string.IsNullOrEmpty(commonFormula))
            {
                var parentComposition = Molecule.ParseExpression(commonFormula);
                // Check for children proposing to label more atoms than parent provides, adjust parent as needed
                foreach (var precursor in _precursorRawDetails.Where(d => d._labels != null))
                {
                    foreach (var kvpIsotopeCount in precursor._labels)
                    {
                        var unlabeled = BioMassCalc.UnlabeledFromIsotopeSymbol(kvpIsotopeCount.Key);
                        int parentCount;
                        parentComposition.TryGetValue(unlabeled, out parentCount);
                        if (kvpIsotopeCount.Value > parentCount)
                        {
                            // Child proposes to label more of an atom than the parent possesses (seen in the wild) - update the parent
                            commonFormula =
                                Molecule.AdjustElementCount(commonFormula, unlabeled, kvpIsotopeCount.Value - parentCount);
                            parentComposition = Molecule.ParseExpression(commonFormula);
                        }
                    }
                }
                if (!Equals(peptide.CustomMolecule.Formula, commonFormula))
                {
                    ProposedMolecule = new CustomMolecule(commonFormula, peptide.CustomMolecule.Name);
                }
            }
        }
        private bool DeriveAdductsForCommonFormula(Peptide peptide)
        {
            // Try to come up with a set of adducts to common formula that explain the declared mz values
            var success = false;

            if (_precursorRawDetails.TrueForAll(d => Adduct.IsNullOrEmpty(d._nominalAdduct)))
            {
                // No explicit adducts, just charges.
                // Start with the most common scenario, which is that the user meant (de)protonation
                // See if we can arrive at a common formula ( by adding or removing H) that works with all charges as (de)protonations
                // N.B. the parent molecule may well be completely unrelated to the children, as users were allowed to enter anything they wanted
                var commonFormula          = ProposedMolecule.Formula;
                var precursorsWithFormulas = _precursorRawDetails.Where(d => !string.IsNullOrEmpty(d._formulaUnlabeled)).ToList();
                foreach (var detail in precursorsWithFormulas)
                {
                    var revisedCommonFormula = Molecule.AdjustElementCount(commonFormula, BioMassCalc.H, -detail._declaredCharge);
                    var adjustedMolecule     = new CustomMolecule(revisedCommonFormula, peptide.CustomMolecule.Name);
                    var mass = adjustedMolecule.MonoisotopicMass;
                    if (precursorsWithFormulas.TrueForAll(d =>
                    {
                        d._proposedAdduct = Adduct.ProtonatedFromFormulaDiff(d._formulaUnlabeled, revisedCommonFormula, d._declaredCharge)
                                            .ChangeIsotopeLabels(d._labels);
                        return(Math.Abs(d._declaredMz - d._proposedAdduct.MzFromNeutralMass(mass)) <= MzToler);
                    }))
                    {
                        ProposedMolecule = adjustedMolecule;
                        success          = true;
                        break;
                    }
                }
                success &= _precursorRawDetails.All(d => !Adduct.IsNullOrEmpty(d._proposedAdduct));
                if (!success)
                {
                    foreach (var d in _precursorRawDetails)
                    {
                        d._proposedAdduct = Adduct.EMPTY;
                    }
                }
            }
            return(success);
        }
Exemple #6
0
        public void TestCustomMoleculeToTSV()
        {
            var moleculeAccessionNumbers = new MoleculeAccessionNumbers(new Dictionary <string, string>
            {
                { MoleculeAccessionNumbers.TagCAS, "MyCAS" },
                { MoleculeAccessionNumbers.TagHMDB, "MyHMDB" },
                { MoleculeAccessionNumbers.TagInChI, "MyInChI" },
                { MoleculeAccessionNumbers.TagSMILES, "MySmiles" }
            });
            var smallMoleculeLibraryAttributes =
                SmallMoleculeLibraryAttributes.Create("MyMolecule", "H2O", "MyInChiKey", moleculeAccessionNumbers.GetNonInChiKeys());
            var customMolecule     = new CustomMolecule(smallMoleculeLibraryAttributes);
            var target             = new Target(customMolecule);
            var serializableString = target.ToSerializableString();

            var roundTrip = Target.FromSerializableString(serializableString);

            Assert.AreEqual(target, roundTrip);
            Assert.AreEqual(customMolecule, roundTrip.Molecule);
            Assert.AreEqual(customMolecule.AccessionNumbers, roundTrip.Molecule.AccessionNumbers);
        }
Exemple #7
0
        public void TestLibIonMobilityInfo()
        {
            const string caffeineFormula  = "C8H10N4O2";
            const string caffeineInChiKey = "RYYVLZVUVIJVGH-UHFFFAOYSA-N";
            const string caffeineHMDB     = "HMDB01847";
            const double HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC = -.01;
            var          dbIon1 = new DbIonMobilityPeptide(new Target("JKLMN"), Adduct.SINGLY_PROTONATED, 1.2, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC)
            {
                Id = 12345
            };

            for (var loop = 0; loop < 2; loop++)
            {
                var dbIon2 = new DbIonMobilityPeptide(dbIon1);
                DbIonMobilityPeptide dbIon3 = null;
                Assert.AreEqual(dbIon1.GetHashCode(), dbIon2.GetHashCode());
                Assert.IsFalse(dbIon1.Equals(null));
                Assert.IsTrue(dbIon1.Equals(dbIon2 as object));
                // ReSharper disable once ExpressionIsAlwaysNull
                Assert.IsFalse(dbIon1.Equals(dbIon3 as object));
                Assert.IsTrue(dbIon1.Equals(dbIon1));
                Assert.IsTrue(dbIon1.Equals(dbIon1 as object));
                Assert.IsTrue(dbIon1.Equals(dbIon2));
                dbIon1.CollisionalCrossSection = 1.3;
                Assert.AreNotEqual(dbIon1.CollisionalCrossSection, dbIon2.CollisionalCrossSection);
                if (loop == 1)
                {
                    dbIon1.ModifiedTarget = new Target("foo");
                    Assert.AreNotEqual(dbIon1.Target, dbIon2.Target);
                    Assert.AreNotEqual(dbIon1.ModifiedTarget, dbIon2.ModifiedTarget);
                }
                else
                {
                    Assert.AreEqual(dbIon1.ModifiedTarget, dbIon2.ModifiedTarget);
                    Assert.AreEqual(dbIon1.ModifiedTarget.Molecule, dbIon2.ModifiedTarget.Molecule);
                }
                dbIon1 = new DbIonMobilityPeptide(
                    SmallMoleculeLibraryAttributes.Create("caffeine", caffeineFormula, caffeineInChiKey, caffeineHMDB),
                    Adduct.FromStringAssumeProtonated("M+Na"),
                    1.2, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC)
                {
                    Id = 12345
                };
            }

            var dictCCS1 = new Dictionary <LibKey, IonMobilityAndCCS[]>();
            var ccs1     = new List <IonMobilityAndCCS> {
                IonMobilityAndCCS.GetIonMobilityAndCCS(IonMobilityValue.EMPTY, 1, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC), IonMobilityAndCCS.GetIonMobilityAndCCS(IonMobilityValue.EMPTY, 2, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC)
            };                                                                                                                                                                                                                                                         // Collisional cross sections
            var ccs2 = new List <IonMobilityAndCCS> {
                IonMobilityAndCCS.GetIonMobilityAndCCS(IonMobilityValue.EMPTY, 3, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC), IonMobilityAndCCS.GetIonMobilityAndCCS(IonMobilityValue.EMPTY, 4, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC)
            };                                                                                                                                                                                                                                                         // Collisional cross sections
            const string seq1 = "JKLM";
            const string seq2 = "KLMN";

            dictCCS1.Add(new LibKey(seq1, 1), ccs1.ToArray());
            dictCCS1.Add(new LibKey(seq2, 1), ccs2.ToArray());
            var lib = new List <LibraryIonMobilityInfo> {
                new LibraryIonMobilityInfo("test", dictCCS1)
            };

            var peptideTimes = CollisionalCrossSectionGridViewDriver.ConvertDriftTimesToCollisionalCrossSections(null,
                                                                                                                 lib, 1, null);
            var validatingIonMobilityPeptides = peptideTimes as ValidatingIonMobilityPeptide[] ?? peptideTimes.ToArray();

            Assert.AreEqual(2, validatingIonMobilityPeptides.Length);
            Assert.AreEqual(1.5, validatingIonMobilityPeptides[0].CollisionalCrossSection);
            Assert.AreEqual(3.5, validatingIonMobilityPeptides[1].CollisionalCrossSection);
            Assert.AreEqual(HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC, validatingIonMobilityPeptides[1].HighEnergyDriftTimeOffsetMsec);

            // Test serialization of molecule with '$' in it, which we use as a tab replacement against XML parser variability
            var molser = new CustomMolecule(SmallMoleculeLibraryAttributes.Create("caffeine$", caffeineFormula, caffeineInChiKey, caffeineHMDB));
            var text   = molser.ToSerializableString();

            Assert.AreEqual(molser, CustomMolecule.FromSerializableString(text));

            var dictCCS2 = new Dictionary <LibKey, IonMobilityAndCCS[]>();
            var ccs3     = new List <IonMobilityAndCCS> {
                IonMobilityAndCCS.GetIonMobilityAndCCS(IonMobilityValue.GetIonMobilityValue(4, eIonMobilityUnits.drift_time_msec), null, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC), IonMobilityAndCCS.GetIonMobilityAndCCS(IonMobilityValue.GetIonMobilityValue(5, eIonMobilityUnits.drift_time_msec), null, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC)
            };                                                                                                                                                                                                                                                                                                                                                                     // Drift times
            const string seq3 = "KLMNJ";

            dictCCS2.Add(new LibKey(seq3, Adduct.SINGLY_PROTONATED), ccs3.ToArray());
            lib.Add(new LibraryIonMobilityInfo("test2", dictCCS2));
            List <LibraryIonMobilityInfo> lib1 = lib;

            AssertEx.ThrowsException <Exception>(() => CollisionalCrossSectionGridViewDriver.ConvertDriftTimesToCollisionalCrossSections(null,
                                                                                                                                         lib1, 2, null),
                                                 String.Format(
                                                     Resources.CollisionalCrossSectionGridViewDriver_ProcessIonMobilityValues_Cannot_import_measured_ion_mobility_for_sequence__0___no_collisional_cross_section_conversion_parameters_were_provided_for_charge_state__1__,
                                                     seq3, 1));

            var regressions = new Dictionary <int, RegressionLine> {
                { 1, new RegressionLine(2, 1) }
            };

            lib = new List <LibraryIonMobilityInfo> {
                new LibraryIonMobilityInfo("test", dictCCS2)
            };
            peptideTimes = CollisionalCrossSectionGridViewDriver.ConvertDriftTimesToCollisionalCrossSections(null,
                                                                                                             lib, 1, regressions);
            validatingIonMobilityPeptides = peptideTimes as ValidatingIonMobilityPeptide[] ?? peptideTimes.ToArray();
            Assert.AreEqual(1, validatingIonMobilityPeptides.Length);
            Assert.AreEqual(1.75, validatingIonMobilityPeptides[0].CollisionalCrossSection);
        }
Exemple #8
0
        /// <summary>
        /// For creating at the Molecule level (create molecule and first transition group) or modifying at the transition level
        /// Null values imply "don't ask user for this"
        /// </summary>
        public EditCustomMoleculeDlg(SkylineWindow parent, UsageMode usageMode, string title, Identity initialId,
                                     IEnumerable <Identity> existingIds, int minCharge, int maxCharge,
                                     SrmSettings settings, CustomMolecule molecule, Adduct defaultCharge,
                                     ExplicitTransitionGroupValues explicitTransitionGroupAttributes,
                                     ExplicitTransitionValues explicitTransitionAttributes,
                                     ExplicitRetentionTimeInfo explicitRetentionTime,
                                     IsotopeLabelType defaultIsotopeLabelType)
        {
            Text                  = title;
            _parent               = parent;
            _initialId            = initialId;
            _existingIds          = existingIds;
            _minCharge            = minCharge;
            _maxCharge            = maxCharge;
            _transitionSettings   = settings != null ? settings.TransitionSettings : null;
            _peptideSettings      = settings != null ? settings.PeptideSettings : null;
            _resultAdduct         = Adduct.EMPTY;
            _resultCustomMolecule = molecule;
            _usageMode            = usageMode;

            var enableFormulaEditing = usageMode == UsageMode.moleculeNew || usageMode == UsageMode.moleculeEdit ||
                                       usageMode == UsageMode.fragment;
            var enableAdductEditing = usageMode == UsageMode.moleculeNew || usageMode == UsageMode.precursor ||
                                      usageMode == UsageMode.fragment;
            var suggestOnlyAdductsWithMass        = usageMode != UsageMode.fragment;
            var needExplicitTransitionValues      = usageMode == UsageMode.fragment;
            var needExplicitTransitionGroupValues = usageMode == UsageMode.moleculeNew || usageMode == UsageMode.precursor;

            InitializeComponent();

            NameText         = molecule == null ? String.Empty : molecule.Name;
            textName.Enabled = usageMode == UsageMode.moleculeNew || usageMode == UsageMode.moleculeEdit ||
                               usageMode == UsageMode.fragment; // Can user edit name?

            var needOptionalValuesBox = explicitRetentionTime != null || explicitTransitionGroupAttributes != null || explicitTransitionAttributes != null;

            if (!needExplicitTransitionValues)
            {
                labelCollisionEnergy.Visible             = false;
                textCollisionEnergy.Visible              = false;
                labelSLens.Visible                       = false;
                textSLens.Visible                        = false;
                labelConeVoltage.Visible                 = false;
                textConeVoltage.Visible                  = false;
                labelIonMobilityHighEnergyOffset.Visible = false;
                textIonMobilityHighEnergyOffset.Visible  = false;
                labelDeclusteringPotential.Visible       = false;
                textDeclusteringPotential.Visible        = false;
            }

            if (!needExplicitTransitionGroupValues)
            {
                labelCCS.Visible                 = false;
                textBoxCCS.Visible               = false;
                labelIonMobility.Visible         = false;
                textIonMobility.Visible          = false;
                labelIonMobilityUnits.Visible    = false;
                comboBoxIonMobilityUnits.Visible = false;
            }

            var heightDelta = 0;

            // Initialise the ion mobility units dropdown with L10N values
            foreach (eIonMobilityUnits t in Enum.GetValues(typeof(eIonMobilityUnits)))
            {
                comboBoxIonMobilityUnits.Items.Add(IonMobilityFilter.IonMobilityUnitsL10NString(t));
            }

            if (needOptionalValuesBox)
            {
                var newHeight = groupBoxOptionalValues.Height;
                var movers    = new List <Control>();
                int offset    = 0;
                if (!needExplicitTransitionGroupValues && !needExplicitTransitionValues)
                {
                    // We blanked out everything but the retention time
                    newHeight = labelCollisionEnergy.Location.Y;
                }
                else if (!needExplicitTransitionGroupValues)
                {
                    // We need to shift transition-level items up to where retention time was
                    movers.AddRange(new Control[] {
                        textCollisionEnergy, labelCollisionEnergy, textDeclusteringPotential, labelDeclusteringPotential, textSLens,
                        labelSLens, textConeVoltage, labelConeVoltage, textIonMobilityHighEnergyOffset, labelIonMobilityHighEnergyOffset
                    });
                    labelIonMobilityHighEnergyOffset.Location = labelIonMobility.Location;
                    textIonMobilityHighEnergyOffset.Location  = textIonMobility.Location;
                    offset    = labelCollisionEnergy.Location.Y - labelRetentionTime.Location.Y;
                    newHeight = textBoxCCS.Location.Y;
                }
                else if (!needExplicitTransitionValues)
                {
                    // We need to shift precursor-level items up to where retention time was
                    movers.AddRange(new Control[] { textBoxCCS, labelCCS, textIonMobility,
                                                    labelIonMobility, comboBoxIonMobilityUnits, labelIonMobilityUnits });
                    offset    = labelIonMobility.Location.Y - (explicitRetentionTime == null ? labelRetentionTime.Location.Y : labelCollisionEnergy.Location.Y);
                    newHeight = explicitRetentionTime == null ? textSLens.Location.Y : textIonMobility.Location.Y;
                }

                foreach (var mover in movers)
                {
                    mover.Anchor   = AnchorStyles.Left | AnchorStyles.Top;
                    mover.Location = new Point(mover.Location.X, mover.Location.Y - offset);
                }

                heightDelta = groupBoxOptionalValues.Height - newHeight;
                groupBoxOptionalValues.Height = newHeight;
            }

            ResultExplicitTransitionGroupValues = new ExplicitTransitionGroupValues(explicitTransitionGroupAttributes);
            ResultExplicitTransitionValues      = new ExplicitTransitionValues(explicitTransitionAttributes);

            string labelAverage = !defaultCharge.IsEmpty
                ? Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg_A_verage_m_z_
                : Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg_A_verage_mass_;
            string labelMono = !defaultCharge.IsEmpty
                ? Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg__Monoisotopic_m_z_
                : Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg__Monoisotopic_mass_;
            var defaultFormula = molecule == null ? string.Empty : molecule.Formula;
            var transition     = initialId as Transition;

            FormulaBox.EditMode editMode;
            if (enableAdductEditing && !enableFormulaEditing)
            {
                editMode = FormulaBox.EditMode.adduct_only;
            }
            else if (!enableAdductEditing && enableFormulaEditing)
            {
                editMode = FormulaBox.EditMode.formula_only;
            }
            else
            {
                editMode = FormulaBox.EditMode.formula_and_adduct;
            }
            string formulaBoxLabel;

            if (defaultCharge.IsEmpty)
            {
                formulaBoxLabel = Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg_Chemi_cal_formula_;
            }
            else if (editMode == FormulaBox.EditMode.adduct_only)
            {
                var prompt = defaultFormula;
                if (string.IsNullOrEmpty(defaultFormula) && molecule != null)
                {
                    // Defined by mass only
                    prompt = molecule.ToString();
                }
                formulaBoxLabel = string.Format(Resources.EditCustomMoleculeDlg_EditCustomMoleculeDlg_Addu_ct_for__0__,
                                                prompt);
            }
            else
            {
                formulaBoxLabel = Resources.EditMeasuredIonDlg_EditMeasuredIonDlg_Ion__chemical_formula_;
            }

            double?averageMass = null;
            double?monoMass    = null;

            if (transition != null && string.IsNullOrEmpty(defaultFormula) && transition.IsCustom())
            {
                averageMass = transition.CustomIon.AverageMass;
                monoMass    = transition.CustomIon.MonoisotopicMass;
            }
            else if (molecule != null)
            {
                averageMass = molecule.AverageMass;
                monoMass    = molecule.MonoisotopicMass;
            }

            _formulaBox =
                new FormulaBox(false, // Not proteomic, so offer Cl and Br in atoms popup
                               formulaBoxLabel,
                               labelAverage,
                               labelMono,
                               defaultCharge,
                               editMode,
                               suggestOnlyAdductsWithMass)
            {
                NeutralFormula = defaultFormula,
                AverageMass    = averageMass,
                MonoMass       = monoMass,
                Location       = new Point(textName.Left, textName.Bottom + 12)
            };
            _formulaBox.ChargeChange += (sender, args) =>
            {
                if (!_formulaBox.Adduct.IsEmpty)
                {
                    Adduct = _formulaBox.Adduct;
                    var revisedFormula = _formulaBox.NeutralFormula + Adduct.AdductFormula;
                    if (!Equals(revisedFormula, _formulaBox.Formula))
                    {
                        _formulaBox.Formula = revisedFormula;
                    }
                    if (string.IsNullOrEmpty(_formulaBox.NeutralFormula) && averageMass.HasValue)
                    {
                        _formulaBox.AverageMass = averageMass;
                        _formulaBox.MonoMass    = monoMass;
                    }
                }
            };
            Controls.Add(_formulaBox);
            _formulaBox.TabIndex = 2;
            _formulaBox.Enabled  = enableFormulaEditing || enableAdductEditing;
            Adduct = defaultCharge;
            var needCharge = !Adduct.IsEmpty;

            textCharge.Visible = labelCharge.Visible = needCharge;
            if (needOptionalValuesBox && !needCharge)
            {
                heightDelta += groupBoxOptionalValues.Location.Y - labelCharge.Location.Y;
                groupBoxOptionalValues.Location = new Point(groupBoxOptionalValues.Location.X, labelCharge.Location.Y);
            }
            if (explicitRetentionTime == null)
            {
                // Don't ask user for retetention times
                RetentionTime                    = null;
                RetentionTimeWindow              = null;
                labelRetentionTime.Visible       = false;
                labelRetentionTimeWindow.Visible = false;
                textRetentionTime.Visible        = false;
                textRetentionTimeWindow.Visible  = false;
            }
            else
            {
                RetentionTime       = explicitRetentionTime.RetentionTime;
                RetentionTimeWindow = explicitRetentionTime.RetentionTimeWindow;
            }
            if (!needOptionalValuesBox)
            {
                groupBoxOptionalValues.Visible = false;
                heightDelta = groupBoxOptionalValues.Height;
            }
            // Initialize label
            if (settings != null && defaultIsotopeLabelType != null)
            {
                _driverLabelType = new PeptideSettingsUI.LabelTypeComboDriver(PeptideSettingsUI.LabelTypeComboDriver.UsageType.InternalStandardPicker, comboIsotopeLabelType,
                                                                              settings.PeptideSettings.Modifications, null, null, null, null)
                {
                    SelectedName = defaultIsotopeLabelType.Name
                };
            }
            else
            {
                comboIsotopeLabelType.Visible = false;
                labelIsotopeLabelType.Visible = false;
            }
            Height -= heightDelta;
        }
Exemple #9
0
 /// <summary>
 /// For modifying at the Molecule level
 /// </summary>
 public EditCustomMoleculeDlg(SkylineWindow parent, string title,
                              SrmSettings settings, CustomMolecule molecule, ExplicitRetentionTimeInfo explicitRetentionTime) :
     this(parent, UsageMode.moleculeEdit, title, null, null, 0, 0, null, molecule, Adduct.EMPTY, null, null,
          explicitRetentionTime, null)
 {
 }
Exemple #10
0
 public void SetResult(CustomMolecule mol, Adduct adduct)
 {
     _resultCustomMolecule = mol;
     _resultAdduct         = adduct;
     SetNameAndFormulaBoxText();
 }
Exemple #11
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));
        }
        public void TestLibIonMobilityInfo()
        {
            const string caffeineFormula  = "C8H10N4O2";
            const string caffeineInChiKey = "RYYVLZVUVIJVGH-UHFFFAOYSA-N";
            const string caffeineHMDB     = "HMDB01847";
            const double HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC = -.01;
            var          dbMolecule = new DbMolecule(new Target("JKLMN"))
            {
                Id = 123456
            };
            var dbPrecursorIon = new DbPrecursorIon(dbMolecule, Adduct.SINGLY_PROTONATED)
            {
                Id = 1234567
            };
            var dbIonMobilityValue = new DbPrecursorAndIonMobility(dbPrecursorIon,
                                                                   1.2, 2.3, eIonMobilityUnits.drift_time_msec, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC)
            {
                Id = 12345
            };
            DbPrecursorAndIonMobility dbPrecursorAndIonMobilityValue2 = new DbPrecursorAndIonMobility(dbIonMobilityValue);

            for (var loop = 0; loop < 2; loop++)
            {
                Assert.AreEqual(dbIonMobilityValue.GetHashCode(), dbPrecursorAndIonMobilityValue2.GetHashCode());
                Assert.IsFalse(dbIonMobilityValue.Equals(null));
                Assert.IsTrue(dbIonMobilityValue.Equals(dbPrecursorAndIonMobilityValue2 as object));
                Assert.IsTrue(dbIonMobilityValue.Equals(dbIonMobilityValue));
                Assert.IsTrue(dbIonMobilityValue.Equals(dbIonMobilityValue as object));
                Assert.IsTrue(dbPrecursorAndIonMobilityValue2.Equals(dbIonMobilityValue));
                dbIonMobilityValue.CollisionalCrossSectionSqA = 1.3;
                Assert.AreNotEqual(dbIonMobilityValue.CollisionalCrossSectionSqA, dbPrecursorAndIonMobilityValue2.CollisionalCrossSectionSqA);
                if (loop == 1)
                {
                    dbIonMobilityValue.DbPrecursorIon = new DbPrecursorIon(new Target("foo"), Adduct.SINGLY_PROTONATED)
                    {
                        Id = 1234567
                    };
                    Assert.AreNotEqual(dbIonMobilityValue.DbPrecursorIon.GetTarget(), dbMolecule);
                }
                else
                {
                    Assert.AreEqual(dbIonMobilityValue.DbPrecursorIon.DbMolecule, dbMolecule);
                }
                dbIonMobilityValue = new DbPrecursorAndIonMobility(
                    new DbPrecursorIon(
                        SmallMoleculeLibraryAttributes.Create("caffeine", caffeineFormula, caffeineInChiKey, caffeineHMDB),
                        Adduct.FromStringAssumeProtonated("M+Na"))
                {
                    Id = 23456
                },
                    1.2, 2.3, eIonMobilityUnits.drift_time_msec, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC)
                {
                    Id = 12345
                };
                dbPrecursorAndIonMobilityValue2 = new DbPrecursorAndIonMobility(dbIonMobilityValue);
            }

            var dictCCS1 = new Dictionary <LibKey, IonMobilityAndCCS[]>();
            var im       = IonMobilityValue.GetIonMobilityValue(12, eIonMobilityUnits.drift_time_msec);
            var ccs1     = new List <IonMobilityAndCCS> {
                IonMobilityAndCCS.GetIonMobilityAndCCS(IonMobilityValue.EMPTY, 1, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC), IonMobilityAndCCS.GetIonMobilityAndCCS(IonMobilityValue.EMPTY, 2, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC)
            };                                                                                                                                                                                                                                                         // Collisional cross sections
            var ccs2 = new List <IonMobilityAndCCS> {
                IonMobilityAndCCS.GetIonMobilityAndCCS(im, 3, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC), IonMobilityAndCCS.GetIonMobilityAndCCS(IonMobilityValue.EMPTY, 4, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC)
            };                                                                                                                                                                                                                                     // Collisional cross sections
            const string seq1 = "JKLM";
            const string seq2 = "KLMN";

            dictCCS1.Add(new LibKey(seq1, 1), ccs1.ToArray());
            dictCCS1.Add(new LibKey(seq2, 1), ccs2.ToArray());
            var lib = new List <LibraryIonMobilityInfo> {
                new LibraryIonMobilityInfo("test", false, dictCCS1)
            };

            var peptideTimes = CollisionalCrossSectionGridViewDriver.CollectIonMobilitiesAndCollisionalCrossSections(null,
                                                                                                                     lib, 1);
            var validatingIonMobilityPeptides = peptideTimes as ValidatingIonMobilityPrecursor[] ?? peptideTimes.ToArray();

            Assert.AreEqual(2, validatingIonMobilityPeptides.Length);
            Assert.AreEqual(1.5, validatingIonMobilityPeptides[0].CollisionalCrossSectionSqA);
            Assert.AreEqual(3.5, validatingIonMobilityPeptides[1].CollisionalCrossSectionSqA);
            Assert.AreEqual(HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC, validatingIonMobilityPeptides[1].HighEnergyIonMobilityOffset);

            // This time with multiple CCS conformers supported
            lib = new List <LibraryIonMobilityInfo> {
                new LibraryIonMobilityInfo("test", true, dictCCS1)
            };

            peptideTimes = CollisionalCrossSectionGridViewDriver.CollectIonMobilitiesAndCollisionalCrossSections(null,
                                                                                                                 lib, 1);
            validatingIonMobilityPeptides = peptideTimes as ValidatingIonMobilityPrecursor[] ?? peptideTimes.ToArray();
            Assert.AreEqual(4, validatingIonMobilityPeptides.Length);
            Assert.AreEqual(1, validatingIonMobilityPeptides[0].CollisionalCrossSectionSqA);
            Assert.AreEqual(2, validatingIonMobilityPeptides[1].CollisionalCrossSectionSqA);
            Assert.AreEqual(3, validatingIonMobilityPeptides[2].CollisionalCrossSectionSqA);
            Assert.AreEqual(4, validatingIonMobilityPeptides[3].CollisionalCrossSectionSqA);
            Assert.AreEqual(HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC, validatingIonMobilityPeptides[1].HighEnergyIonMobilityOffset);


            // Test serialization of molecule with '$' in it, which we use as a tab replacement against XML parser variability
            var molser = CustomMolecule.FromSmallMoleculeLibraryAttributes(SmallMoleculeLibraryAttributes.Create("caffeine$", caffeineFormula, caffeineInChiKey, caffeineHMDB));
            var text   = molser.ToSerializableString();

            Assert.AreEqual(molser, CustomMolecule.FromSerializableString(text));

            // Test handling of SmallMoleculeLibraryAttributes for mass-only descriptions
            var molserB = CustomMolecule.FromSmallMoleculeLibraryAttributes(SmallMoleculeLibraryAttributes.Create("caffeine$", null, new TypedMass(123.4, MassType.Monoisotopic), new TypedMass(123.45, MassType.Average), caffeineInChiKey, caffeineHMDB));
            var textB   = molserB.ToSerializableString();

            Assert.AreEqual(molserB, CustomMolecule.FromSerializableString(textB));

            var dictCCS2 = new Dictionary <LibKey, IonMobilityAndCCS[]>();
            var ccs3     = new List <IonMobilityAndCCS> {
                IonMobilityAndCCS.GetIonMobilityAndCCS(IonMobilityValue.GetIonMobilityValue(4, eIonMobilityUnits.drift_time_msec), 1.75, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC), IonMobilityAndCCS.GetIonMobilityAndCCS(IonMobilityValue.GetIonMobilityValue(5, eIonMobilityUnits.drift_time_msec), null, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC)
            };                                                                                                                                                                                                                                                                                                                                                                     // Drift times
            const string seq3 = "KLMNJ";

            dictCCS2.Add(new LibKey(seq3, Adduct.SINGLY_PROTONATED), ccs3.ToArray());

            lib = new List <LibraryIonMobilityInfo> {
                new LibraryIonMobilityInfo("test", false, dictCCS2)
            };
            peptideTimes = CollisionalCrossSectionGridViewDriver.CollectIonMobilitiesAndCollisionalCrossSections(null,
                                                                                                                 lib, 1);
            validatingIonMobilityPeptides = peptideTimes as ValidatingIonMobilityPrecursor[] ?? peptideTimes.ToArray();
            Assert.AreEqual(1, validatingIonMobilityPeptides.Length);
            Assert.AreEqual(1.75, validatingIonMobilityPeptides[0].CollisionalCrossSectionSqA);
        }
Exemple #13
0
        public Dictionary <LibKey, IonMobilityAndCCS> GetTableMeasuredIonMobility(bool useHighEnergyOffsets, eIonMobilityUnits units)
        {
            var e    = new CancelEventArgs();
            var dict = new Dictionary <LibKey, IonMobilityAndCCS>();

            foreach (DataGridViewRow row in _gridMeasuredDriftTimePeptides.Rows)
            {
                if (row.IsNewRow)
                {
                    continue;
                }

                string seq;
                if (!ValidateSequence(e, row.Cells[EditDriftTimePredictorDlg.COLUMN_SEQUENCE], out seq))
                {
                    return(null);
                }

                // OK, we have a non-empty "sequence" string, but is that actually a peptide or a molecule?
                // See if there's anything in the document whose text representation matches what's in the list
                var target = Program.MainWindow.Document.Molecules.Select(m => m.Target).FirstOrDefault(t => seq.Equals(t.ToString()));
                if (target == null || target.IsEmpty)
                {
                    // Does seq evaluate as a peptide?
                    target = !seq.All(c => char.IsUpper(c) || char.IsDigit(c) || @"[+-,.]()".Contains(c))
                        ? new Target(CustomMolecule.FromSerializableString(seq))
                        : Target.FromSerializableString(seq);
                }

                Adduct charge;
                if (!ValidateCharge(e, row.Cells[EditDriftTimePredictorDlg.COLUMN_CHARGE], target.IsProteomic, out charge))
                {
                    return(null);
                }

                double mobility;
                if (!ValidateDriftTime(e, row.Cells[EditDriftTimePredictorDlg.COLUMN_ION_MOBILITY], out mobility))
                {
                    return(null);
                }

                double?ccs;
                if (!ValidateCCS(e, row.Cells[EditDriftTimePredictorDlg.COLUMN_CCS], out ccs))
                {
                    return(null);
                }

                double highEnergyOffset = 0; // Set default value in case user does not provide one
                if (useHighEnergyOffsets && !ValidateHighEnergyDriftTimeOffset(e, row.Cells[EditDriftTimePredictorDlg.COLUMN_HIGH_ENERGY_OFFSET], out highEnergyOffset))
                {
                    return(null);
                }
                var ionMobility = IonMobilityValue.GetIonMobilityValue(mobility, units);
                try
                {
                    dict.Add(new LibKey(target, charge), IonMobilityAndCCS.GetIonMobilityAndCCS(ionMobility, ccs, highEnergyOffset));
                }
                // ReSharper disable once EmptyGeneralCatchClause
                catch
                {
                    // just take the first seen
                }
            }
            return(dict);
        }