Пример #1
0
        protected override void DoTest()
        {
            // IsPauseForScreenShots = true; // For a quick demo when you need it
            string skyFile = TestFilesDir.GetTestPath("test_measured_drift_times_perf.sky");

            Program.ExtraRawFileSearchFolder = TestFilesDir.PersistentFilesDir; // So we don't have to reload the raw files, which have moved relative to skyd file
            RunUI(() => SkylineWindow.OpenFile(skyFile));

            var document = WaitForDocumentLoaded(240000);  // If it decides to remake chromatograms this can take awhile

            AssertEx.IsDocumentState(document, null, 1, 34, 38, 398);
            RunUI(() =>
            {
                SkylineWindow.SaveDocument(TestFilesDir.GetTestPath("local.sky")); // Avoid "document changed since last edit" message
                document = SkylineWindow.DocumentUI;
            });
            List <ValidatingIonMobilityPrecursor> curatedDTs = null;
            var measuredDTs = new List <List <ValidatingIonMobilityPrecursor> >();
            var precursors  = new LibKeyIndex(document.MoleculePrecursorPairs.Select(
                                                  p => p.NodePep.ModifiedTarget.GetLibKey(p.NodeGroup.PrecursorAdduct).LibraryKey));

            PauseForScreenShot(@"Legacy ion mobility values loaded, placed in .imsdb database file"); // For a quick demo when you need it
            for (var pass = 0; pass < 2; pass++)
            {
                // Verify ability to extract predictions from raw data
                var transitionSettingsDlg = ShowDialog <TransitionSettingsUI>(
                    () => SkylineWindow.ShowTransitionSettingsUI(TransitionSettingsUI.TABS.IonMobility));
                PauseForScreenShot("new Transition Settings tab"); // For a quick demo when you need it
                // Simulate user picking Edit Current from the Ion Mobility Library combo control
                var ionMobilityLibraryDlg = ShowDialog <EditIonMobilityLibraryDlg>(transitionSettingsDlg.IonMobilityControl.EditIonMobilityLibrary);
                PauseForScreenShot("next, we'll update values with 'Use Results' button"); // For a quick demo when you need it
                RunUI(() =>
                {
                    if (curatedDTs == null)
                    {
                        curatedDTs = ionMobilityLibraryDlg.LibraryMobilitiesFlat.ToList();
                    }
                    ionMobilityLibraryDlg.SetOffsetHighEnergySpectraCheckbox(true);
                    ionMobilityLibraryDlg.GetIonMobilitiesFromResults();
                });
                PauseForScreenShot("values updated");// For a quick demo when you need it
                RunUI(() =>
                {
                    measuredDTs.Add(ionMobilityLibraryDlg.LibraryMobilitiesFlat.ToList());
                    ionMobilityLibraryDlg.OkDialog();
                });
                WaitForClosedForm(ionMobilityLibraryDlg);
                RunUI(() =>
                {
                    transitionSettingsDlg.OkDialog();
                });
                WaitForClosedForm(transitionSettingsDlg);

                document = SkylineWindow.Document;
                var count = 0;
                for (var n = 0; n < curatedDTs.Count; n++)
                {
                    var cdt         = curatedDTs[n];
                    var key         = cdt.Precursor;
                    var indexM      = measuredDTs[pass].FindIndex(m => m.Precursor.Equals(key));
                    var measured    = measuredDTs[pass][indexM];
                    var measuredDT  = measured.IonMobility;
                    var measuredHEO = measured.HighEnergyIonMobilityOffset;
                    if (precursors.ItemsMatching(key, true).Any())
                    {
                        count++;
                        AssertEx.AreNotEqual(cdt.IonMobility, measuredDT, "measured drift time should differ somewhat for " + measured.Precursor);
                    }

                    AssertEx.AreEqual(cdt.IonMobility, measuredDT, 1.0, "measured drift time differs too much for " + key);
                    AssertEx.AreEqual(cdt.HighEnergyIonMobilityOffset, measuredHEO, 2.0, "measured drift time high energy offset differs too much for " + key);
                }
                AssertEx.AreEqual(document.MoleculeTransitionGroupCount, count, "did not find drift times for all precursors"); // Expect to find a value for each precursor

                if (pass == 1)
                {
                    break;
                }

                // Verify that we select based on strongest results by removing the training set and relying on the other noisier set
                RunDlg <ManageResultsDlg>(SkylineWindow.ManageResults, dlg =>
                {
                    var chromatograms         = document.Settings.MeasuredResults.Chromatograms;
                    var chromTraining         = chromatograms[0];
                    var chroms                = new[] { chromTraining };
                    dlg.SelectedChromatograms = chroms; // Passing this chromatograms[0] results in the other set being deleted - compiler problem?
                    dlg.RemoveReplicates();
                    dlg.OkDialog();
                });

                document = WaitForDocumentChange(document);
                AssertEx.AreEqual(1, document.Settings.MeasuredResults.Chromatograms.Count);
            }
            // Results should be slightly different without the training set of chromatograms to contain a potentially stronger peak
            var ccount   = 0;
            var noChange = new List <LibKey>();

            for (var n = 0; n < measuredDTs[0].Count; n++)
            {
                var validatingIonMobilityPeptide0 = measuredDTs[0][n];
                var validatingIonMobilityPeptide1 = measuredDTs[1][n];
                var key = measuredDTs[0][n].Precursor;
                if (precursors.ItemsMatching(key, true).Any())
                {
                    ccount++;
                    if (validatingIonMobilityPeptide0.HighEnergyIonMobilityOffset == validatingIonMobilityPeptide1.HighEnergyIonMobilityOffset)
                    {
                        noChange.Add(key);
                    }
                }
                AssertEx.AreEqual(validatingIonMobilityPeptide0.IonMobility, validatingIonMobilityPeptide1.IonMobility, 1.0, "averaged measured drift time differs for " + key);
                AssertEx.AreEqual(validatingIonMobilityPeptide0.HighEnergyIonMobilityOffset, validatingIonMobilityPeptide1.HighEnergyIonMobilityOffset, 2.0, "averaged measured drift time high energy offset differs for " + key);
                AssertEx.AreEqual(validatingIonMobilityPeptide0.CollisionalCrossSectionSqA, validatingIonMobilityPeptide1.CollisionalCrossSectionSqA, 1.0, "averaged measured CCS differs for " + key);
            }
            AssertEx.AreEqual(document.MoleculeTransitionGroupCount, ccount, "did not find drift times for all precursors"); // Expect to find a value for each precursor
            AssertEx.IsTrue(noChange.Count < ccount / 2, "expected most values to shift a little without the nice clean training data");


            // And finally verify ability to reimport with altered drift filter (would formerly fail on an erroneous Assume)

            // Simulate user picking Edit Current from the Ion Mobility Library combo control, and messing with all the measured drift time values
            var transitionSettingsDlg2 = ShowDialog <TransitionSettingsUI>(
                () => SkylineWindow.ShowTransitionSettingsUI(TransitionSettingsUI.TABS.Prediction));
            var editIonMobilityLibraryDlg = ShowDialog <EditIonMobilityLibraryDlg>(transitionSettingsDlg2.IonMobilityControl.EditIonMobilityLibrary);

            RunUI(() =>
            {
                var revised = new List <ValidatingIonMobilityPrecursor>();
                foreach (var item in editIonMobilityLibraryDlg.LibraryMobilitiesFlat)
                {
                    var im  = item.IonMobility;
                    var heo = item.HighEnergyIonMobilityOffset;
                    revised.Add(new ValidatingIonMobilityPrecursor(item.Precursor,
                                                                   IonMobilityAndCCS.GetIonMobilityAndCCS(IonMobilityValue.GetIonMobilityValue(im * 1.02, item.IonMobilityUnits),
                                                                                                          item.CollisionalCrossSectionSqA * 1.02, heo * 1.02)));
                }
                editIonMobilityLibraryDlg.LibraryMobilitiesFlat = revised;
                editIonMobilityLibraryDlg.OkDialog();
            });
            WaitForClosedForm(editIonMobilityLibraryDlg);
            RunUI(() =>
            {
                transitionSettingsDlg2.OkDialog();
            });
            WaitForClosedForm(transitionSettingsDlg2);
            var docChangedDriftTimePredictor = WaitForDocumentChange(document);

            // Reimport data for a replicate - without the fix this will throw
            RunDlg <ManageResultsDlg>(SkylineWindow.ManageResults, dlg =>
            {
                var chromatograms         = docChangedDriftTimePredictor.Settings.MeasuredResults.Chromatograms;
                dlg.SelectedChromatograms = new[] { chromatograms[0] };
                dlg.ReimportResults();
                dlg.OkDialog();
            });

            WaitForDocumentChangeLoaded(docChangedDriftTimePredictor, WAIT_TIME * 2);
        }
Пример #2
0
        private void EvaluateBestIonMobilityValue(int msLevel, LibKey libKey, float tolerance, List <TransitionFullScanInfo> transitions)
        {
            IonMobilityValue ionMobilityValue = IonMobilityValue.EMPTY;
            double           maxIntensity     = 0;

            // Avoid picking MS2 ion mobility values wildly different from MS1 valuess
            IonMobilityValue ms1IonMobilityBest;

            if ((msLevel == 2) && _ms1IonMobilities.ContainsKey(libKey))
            {
                ms1IonMobilityBest =
                    _ms1IonMobilities[libKey].OrderByDescending(p => p.Intensity)
                    .FirstOrDefault()
                    .IonMobility.IonMobility;
            }
            else
            {
                ms1IonMobilityBest = IonMobilityValue.EMPTY;
            }

            const int maxHighEnergyDriftOffsetMsec = 2; // CONSIDER(bspratt): user definable? or dynamically set by looking at scan to scan drift delta? Or resolving power?

            foreach (var scan in _msDataFileScanHelper.MsDataSpectra.Where(scan => scan != null))
            {
                if (!scan.IonMobility.HasValue || !scan.Mzs.Any())
                {
                    continue;
                }
                if (ms1IonMobilityBest.HasValue &&
                    (scan.IonMobility.Mobility <
                     ms1IonMobilityBest.Mobility - maxHighEnergyDriftOffsetMsec ||
                     scan.IonMobility.Mobility >
                     ms1IonMobilityBest.Mobility + maxHighEnergyDriftOffsetMsec))
                {
                    continue;
                }

                // Get the total intensity for all transitions of current msLevel
                double totalIntensity = 0;
                foreach (var t in transitions)
                {
                    Assume.IsTrue(t.ProductMz.IsNegative == scan.NegativeCharge);  // It would be strange if associated scan did not have same polarity
                    var mzPeak  = t.ProductMz;
                    var halfwin = (t.ExtractionWidth ?? tolerance) / 2;
                    var mzLow   = mzPeak - halfwin;
                    var mzHigh  = mzPeak + halfwin;
                    var first   = Array.BinarySearch(scan.Mzs, mzLow);
                    if (first < 0)
                    {
                        first = ~first;
                    }
                    for (var i = first; i < scan.Mzs.Length; i++)
                    {
                        if (scan.Mzs[i] > mzHigh)
                        {
                            break;
                        }
                        totalIntensity += scan.Intensities[i];
                    }
                }
                if (maxIntensity < totalIntensity)
                {
                    ionMobilityValue = scan.IonMobility;
                    maxIntensity     = totalIntensity;
                }
            }
            if (ionMobilityValue.HasValue)
            {
                var dict   = (msLevel == 1) ? _ms1IonMobilities : _ms2IonMobilities;
                var ccs    = msLevel == 1 && _msDataFileScanHelper.ProvidesCollisionalCrossSectionConverter ? _msDataFileScanHelper.CCSFromIonMobility(ionMobilityValue, transitions.First().PrecursorMz, libKey.Charge) : null;
                var result = new IonMobilityIntensityPair
                {
                    IonMobility = IonMobilityAndCCS.GetIonMobilityAndCCS(ionMobilityValue, ccs, 0),
                    Intensity   = maxIntensity
                };
                List <IonMobilityIntensityPair> listPairs;
                if (!dict.TryGetValue(libKey, out listPairs))
                {
                    listPairs = new List <IonMobilityIntensityPair>();
                    dict.Add(libKey, listPairs);
                }
                listPairs.Add(result);
            }
        }
Пример #3
0
        /// <summary>
        /// Looks through the result and finds ion mobility values.
        /// Note that this method only returns new values that were found in results.
        /// The returned dictionary should be merged with the existing values in
        /// order to preserve those existing values.
        /// </summary>
        public Dictionary <LibKey, IonMobilityAndCCS> FindIonMobilityPeaks()
        {
            // Overwrite any existing measurements with newly derived ones
            var measured = new Dictionary <LibKey, IonMobilityAndCCS>();

            if (_document.Settings.MeasuredResults == null)
            {
                return(measured);
            }

            var filepaths = _document.Settings.MeasuredResults.MSDataFilePaths.ToArray();

            _totalSteps = filepaths.Length * _document.MoleculeTransitionGroupCount;
            if (_totalSteps == 0)
            {
                return(measured);
            }

            using (_msDataFileScanHelper = new MsDataFileScanHelper(SetScans, HandleLoadScanException))
            {
                //
                // Avoid opening and re-opening raw files - make these the outer loop
                //

                _ms1IonMobilities = new Dictionary <LibKey, List <IonMobilityIntensityPair> >();
                _ms2IonMobilities = new Dictionary <LibKey, List <IonMobilityIntensityPair> >();
                var twopercent = (int)Math.Ceiling(_totalSteps * 0.02);
                _totalSteps += twopercent;
                _currentStep = twopercent;
                if (_progressMonitor != null)
                {
                    _progressStatus = new ProgressStatus(filepaths.First().GetFileName());
                    _progressStatus = _progressStatus.UpdatePercentCompleteProgress(_progressMonitor, _currentStep, _totalSteps); // Make that inital lag seem less dismal to the user
                }
                foreach (var fp in filepaths)
                {
                    if (!ProcessFile(fp))
                    {
                        return(null); // User cancelled
                    }
                }
                // Find ion mobilitiess based on MS1 data
                foreach (var dt in _ms1IonMobilities)
                {
                    // Choose the ion mobility which gave the largest signal
                    // CONSIDER: average IM and CCS values that fall "near" the IM of largest signal?
                    var ms1IonMobility = dt.Value.OrderByDescending(p => p.Intensity).First().IonMobility;
                    // Check for MS2 data to use for high energy offset
                    List <IonMobilityIntensityPair> listDt;
                    var ms2IonMobility = _ms2IonMobilities.TryGetValue(dt.Key, out listDt)
                        ? listDt.OrderByDescending(p => p.Intensity).First().IonMobility
                        : ms1IonMobility;
                    var value = IonMobilityAndCCS.GetIonMobilityAndCCS(ms1IonMobility.IonMobility, ms1IonMobility.CollisionalCrossSectionSqA, ms2IonMobility.IonMobility.Mobility.Value - ms1IonMobility.IonMobility.Mobility.Value);
                    if (!measured.ContainsKey(dt.Key))
                    {
                        measured.Add(dt.Key, value);
                    }
                    else
                    {
                        measured[dt.Key] = value;
                    }
                }
                // Check for data for which we have only MS2 to go on
                foreach (var im in _ms2IonMobilities)
                {
                    if (!_ms1IonMobilities.ContainsKey(im.Key))
                    {
                        // Only MS2 ion mobility values found, use that
                        var driftTimeIntensityPair = im.Value.OrderByDescending(p => p.Intensity).First();
                        var value = driftTimeIntensityPair.IonMobility;
                        // Note collisional cross section
                        if (_msDataFileScanHelper.ProvidesCollisionalCrossSectionConverter)
                        {
                            var ccs = _msDataFileScanHelper.CCSFromIonMobility(value.IonMobility,
                                                                               im.Key.PrecursorMz.Value, im.Key.Charge);
                            if (ccs.HasValue)
                            {
                                value = IonMobilityAndCCS.GetIonMobilityAndCCS(value.IonMobility, ccs, value.HighEnergyIonMobilityValueOffset);
                            }
                        }

                        if (!measured.ContainsKey(im.Key))
                        {
                            measured.Add(im.Key, value);
                        }
                        else
                        {
                            measured[im.Key] = value;
                        }
                    }
                }
            }
            return(measured);
        }
Пример #4
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 = _targetResolver.ResolveTarget(seq);
                if (target == null || target.IsEmpty)
                {
                    return(null);
                }

                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);
        }
Пример #5
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.mz5")), }),
                };
                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, MsDataFileImpl.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, MsDataFileImpl.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);
            }
        }
Пример #6
0
        private void ProcessTransitionGroup(IDictionary <LibKey, SpectrumMzInfo> spectra,
                                            PeptideGroupDocNode nodePepGroup, PeptideDocNode nodePep, TransitionGroupDocNode nodeTranGroup, int replicateIndex)
        {
            LibKey key;

            if (nodePep.IsProteomic)
            {
                var sequence = Document.Settings.GetPrecursorCalc(nodeTranGroup.TransitionGroup.LabelType, nodePep.ExplicitMods)
                               .GetModifiedSequence(nodePep.Peptide.Target, SequenceModFormatType.lib_precision, false);
                key = new LibKey(sequence, nodeTranGroup.PrecursorAdduct.AdductCharge);
            }
            else
            {
                // For small molecules, the "modification" is expressed in the adduct
                key = new LibKey(nodeTranGroup.CustomMolecule.GetSmallMoleculeLibraryAttributes(), nodeTranGroup.PrecursorAdduct);
            }
            var mi              = new List <SpectrumPeaksInfo.MI>();
            var rt              = 0.0;
            var im              = IonMobilityAndCCS.EMPTY;
            var imGroup         = TransitionGroupIonMobilityInfo.EMPTY; // CCS may be available only at group level
            var groupChromInfos = nodeTranGroup.GetSafeChromInfo(replicateIndex);

            if (!groupChromInfos.IsEmpty)
            {
                var chromInfo = groupChromInfos.First(info => info.OptimizationStep == 0);
                imGroup = chromInfo.IonMobilityInfo;
            }
            var    maxApex       = float.MinValue;
            var    maxApexMs1    = float.MinValue;
            string chromFileName = null;
            double?mobilityMs1   = null; // Track MS1 ion mobility in order to derive high energy ion mobility offset value

            foreach (var nodeTran in nodeTranGroup.Transitions)
            {
                var chromInfos = nodeTran.GetSafeChromInfo(replicateIndex);
                if (chromInfos.IsEmpty)
                {
                    continue;
                }
                var chromInfo = chromInfos.First(info => info.OptimizationStep == 0);
                if (chromInfo.Area == 0)
                {
                    continue;
                }
                if (nodeTran.IsMs1)
                {
                    // Track MS1 ion mobility in order to derive high energy ion mobility offset value
                    if (chromInfo.Height > maxApexMs1)
                    {
                        maxApexMs1  = chromInfo.Height;
                        mobilityMs1 = chromInfo.IonMobility.IonMobility.Mobility;
                    }
                    continue;
                }
                if (chromFileName == null)
                {
                    var chromFileInfo = Document.Settings.MeasuredResults.Chromatograms[replicateIndex].MSDataFileInfos.FirstOrDefault(file => ReferenceEquals(file.Id, chromInfo.FileId));
                    if (chromFileInfo != null)
                    {
                        chromFileName = chromFileInfo.FilePath.GetFileName();
                    }
                }
                List <SpectrumPeakAnnotation> annotations = null;
                if (nodeTran.Transition.IsNonReporterCustomIon()) // CONSIDER(bspratt) include annotation for all non-peptide-fragment transitions?
                {
                    var smallMoleculeLibraryAttributes = nodeTran.Transition.CustomIon.GetSmallMoleculeLibraryAttributes();
                    var ion = new CustomIon(smallMoleculeLibraryAttributes, nodeTran.Transition.Adduct, nodeTran.GetMoleculeMass());
                    annotations = new List <SpectrumPeakAnnotation> {
                        SpectrumPeakAnnotation.Create(ion, nodeTran.Annotations.Note)
                    };
                }
                mi.Add(new SpectrumPeaksInfo.MI {
                    Mz = nodeTran.Mz, Intensity = chromInfo.Area, Quantitative = nodeTran.ExplicitQuantitative, Annotations = annotations
                });
                if (chromInfo.Height > maxApex)
                {
                    maxApex = chromInfo.Height;
                    rt      = chromInfo.RetentionTime;
                    var mobility = chromInfo.IonMobility.IonMobility;
                    var mobilityHighEnergyOffset = 0.0;
                    if (mobilityMs1.HasValue && mobility.HasValue && mobility.Mobility != mobilityMs1)
                    {
                        // Note any difference in MS1 and MS2 ion mobilities - the "high energy ion mobility offset"
                        mobilityHighEnergyOffset = mobility.Mobility.Value - mobilityMs1.Value;
                        mobility = mobility.ChangeIonMobility(mobilityMs1);
                    }
                    im = IonMobilityAndCCS.GetIonMobilityAndCCS(mobility, chromInfo.IonMobility.CollisionalCrossSectionSqA ?? imGroup.CollisionalCrossSection, mobilityHighEnergyOffset);
                }
            }
            if (chromFileName == null)
            {
                return;
            }
            SpectrumMzInfo spectrumMzInfo;

            if (!spectra.TryGetValue(key, out spectrumMzInfo))
            {
                spectrumMzInfo = new SpectrumMzInfo
                {
                    SourceFile     = DocumentFilePath,
                    Key            = key,
                    PrecursorMz    = nodeTranGroup.PrecursorMz,
                    SpectrumPeaks  = new SpectrumPeaksInfo(mi.ToArray()),
                    RetentionTimes = new List <SpectrumMzInfo.IonMobilityAndRT>(),
                    IonMobility    = im,
                    Protein        = nodePepGroup.Name,
                    RetentionTime  = rt
                };
                spectra[key] = spectrumMzInfo;
            }
            var isBest = replicateIndex == nodePep.BestResult;

            if (isBest)
            {
                spectrumMzInfo.IonMobility   = im;
                spectrumMzInfo.RetentionTime = rt;
            }
            spectrumMzInfo.RetentionTimes.Add(new SpectrumMzInfo.IonMobilityAndRT(chromFileName, im, rt, isBest));
        }
Пример #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);
        }
Пример #8
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          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);
        }
Пример #9
0
 public virtual IonMobilityAndCCS GetIonMobilityAndCCS()
 {
     return(IonMobilityAndCCS.GetIonMobilityAndCCS(IonMobilityValue.GetIonMobilityValue(IonMobilityNullable,
                                                                                        IonMobilityUnits), CollisionalCrossSectionNullable, HighEnergyIonMobilityOffset));
 }
Пример #10
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);
        }