Exemple #1
0
        public SpectrumFilter(SrmDocument document, MsDataFileUri msDataFileUri, IFilterInstrumentInfo instrumentInfo,
                              IRetentionTimePredictor retentionTimePredictor = null, bool firstPass = false)
        {
            _fullScan          = document.Settings.TransitionSettings.FullScan;
            _instrument        = document.Settings.TransitionSettings.Instrument;
            _acquisitionMethod = _fullScan.AcquisitionMethod;
            if (instrumentInfo != null)
            {
                _isWatersFile = instrumentInfo.IsWatersFile;
            }
            IsFirstPass = firstPass;

            var comparer = PrecursorTextId.PrecursorTextIdComparerInstance;
            var dictPrecursorMzToFilter = new SortedDictionary <PrecursorTextId, SpectrumFilterPair>(comparer);

            if (EnabledMs || EnabledMsMs)
            {
                if (EnabledMs)
                {
                    _isHighAccMsFilter = !Equals(_fullScan.PrecursorMassAnalyzer,
                                                 FullScanMassAnalyzerType.qit);

                    if (!firstPass)
                    {
                        var key = new PrecursorTextId(SignedMz.ZERO, null, ChromExtractor.summed);  // TIC
                        dictPrecursorMzToFilter.Add(key, new SpectrumFilterPair(key, PeptideDocNode.UNKNOWN_COLOR, dictPrecursorMzToFilter.Count,
                                                                                _instrument.MinTime, _instrument.MaxTime, null, null, 0, _isHighAccMsFilter, _isHighAccProductFilter));
                        key = new PrecursorTextId(SignedMz.ZERO, null, ChromExtractor.base_peak);   // BPC
                        dictPrecursorMzToFilter.Add(key, new SpectrumFilterPair(key, PeptideDocNode.UNKNOWN_COLOR, dictPrecursorMzToFilter.Count,
                                                                                _instrument.MinTime, _instrument.MaxTime, null, null, 0, _isHighAccMsFilter, _isHighAccProductFilter));
                    }
                }
                if (EnabledMsMs)
                {
                    _isHighAccProductFilter = !Equals(_fullScan.ProductMassAnalyzer,
                                                      FullScanMassAnalyzerType.qit);

                    if (_fullScan.AcquisitionMethod == FullScanAcquisitionMethod.DIA &&
                        _fullScan.IsolationScheme.IsAllIons)
                    {
                        if (instrumentInfo != null)
                        {
                            _isWatersMse  = _isWatersFile;
                            _isAgilentMse = instrumentInfo.IsAgilentFile;
                        }
                        _mseLevel = 1;
                    }
                }

                Func <double, double> calcWindowsQ1 = _fullScan.GetPrecursorFilterWindow;
                Func <double, double> calcWindowsQ3 = _fullScan.GetProductFilterWindow;
                _minTime = _instrument.MinTime;
                _maxTime = _instrument.MaxTime;
                bool canSchedule = CanSchedule(document, retentionTimePredictor);
                // TODO: Figure out a way to turn off time sharing on first SIM scan so that
                //       times can be shared for MS1 without SIM scans
                _isSharedTime = !canSchedule;

                // If we're using bare measured drift times from spectral libraries, go get those now
                var libraryIonMobilityInfo = document.Settings.PeptideSettings.Prediction.UseLibraryDriftTimes
                    ? document.Settings.GetIonMobilities(msDataFileUri)
                    : null;

                foreach (var nodePep in document.Molecules)
                {
                    if (firstPass && !retentionTimePredictor.IsFirstPassPeptide(nodePep))
                    {
                        continue;
                    }

                    foreach (TransitionGroupDocNode nodeGroup in nodePep.Children)
                    {
                        if (nodeGroup.Children.Count == 0)
                        {
                            continue;
                        }

                        double?       minTime = _minTime, maxTime = _maxTime;
                        double?       startDriftTimeMsec = null, endDriftTimeMsec = null;
                        double        windowDT;
                        double        highEnergyDriftTimeOffsetMsec = 0;
                        DriftTimeInfo centerDriftTime               = document.Settings.PeptideSettings.Prediction.GetDriftTime(
                            nodePep, nodeGroup, libraryIonMobilityInfo, out windowDT);
                        if (centerDriftTime.DriftTimeMsec(false).HasValue)
                        {
                            startDriftTimeMsec            = centerDriftTime.DriftTimeMsec(false) - windowDT / 2; // Get the low energy drift time
                            endDriftTimeMsec              = startDriftTimeMsec + windowDT;
                            highEnergyDriftTimeOffsetMsec = centerDriftTime.HighEnergyDriftTimeOffsetMsec;
                        }

                        if (canSchedule)
                        {
                            if (RetentionTimeFilterType.scheduling_windows == _fullScan.RetentionTimeFilterType)
                            {
                                double?centerTime = null;
                                double windowRT   = 0;
                                if (retentionTimePredictor != null)
                                {
                                    centerTime = retentionTimePredictor.GetPredictedRetentionTime(nodePep);
                                }
                                else
                                {
                                    var prediction = document.Settings.PeptideSettings.Prediction;
                                    if (prediction.RetentionTime == null || !prediction.RetentionTime.IsAutoCalculated)
                                    {
                                        centerTime = document.Settings.PeptideSettings.Prediction.PredictRetentionTimeForChromImport(
                                            document, nodePep, nodeGroup, out windowRT);
                                    }
                                }
                                // Force the center time to be at least zero
                                if (centerTime.HasValue && centerTime.Value < 0)
                                {
                                    centerTime = 0;
                                }
                                if (_fullScan.RetentionTimeFilterLength != 0)
                                {
                                    windowRT = _fullScan.RetentionTimeFilterLength * 2;
                                }
                                if (centerTime != null)
                                {
                                    double startTime = centerTime.Value - windowRT / 2;
                                    double endTime   = startTime + windowRT;
                                    minTime = Math.Max(minTime ?? 0, startTime);
                                    maxTime = Math.Min(maxTime ?? double.MaxValue, endTime);
                                }
                            }
                            else if (RetentionTimeFilterType.ms2_ids == _fullScan.RetentionTimeFilterType)
                            {
                                var times = document.Settings.GetBestRetentionTimes(nodePep, msDataFileUri);
                                if (times.Length > 0)
                                {
                                    minTime = Math.Max(minTime ?? 0, times.Min() - _fullScan.RetentionTimeFilterLength);
                                    maxTime = Math.Min(maxTime ?? double.MaxValue, times.Max() + _fullScan.RetentionTimeFilterLength);
                                }
                            }
                        }

                        SpectrumFilterPair filter;
                        string             textId = nodePep.RawTextId; // Modified Sequence for peptides, or some other string for custom ions
                        var mz  = new SignedMz(nodeGroup.PrecursorMz, nodeGroup.PrecursorCharge < 0);
                        var key = new PrecursorTextId(mz, textId, ChromExtractor.summed);
                        if (!dictPrecursorMzToFilter.TryGetValue(key, out filter))
                        {
                            filter = new SpectrumFilterPair(key, nodePep.Color, dictPrecursorMzToFilter.Count, minTime, maxTime,
                                                            startDriftTimeMsec, endDriftTimeMsec, highEnergyDriftTimeOffsetMsec,
                                                            _isHighAccMsFilter, _isHighAccProductFilter);
                            dictPrecursorMzToFilter.Add(key, filter);
                        }

                        if (!EnabledMs)
                        {
                            filter.AddQ3FilterValues(from TransitionDocNode nodeTran in nodeGroup.Children
                                                     select nodeTran.Mz, calcWindowsQ3);
                        }
                        else if (!EnabledMsMs)
                        {
                            filter.AddQ1FilterValues(GetMS1MzValues(nodeGroup), calcWindowsQ1);
                        }
                        else
                        {
                            filter.AddQ1FilterValues(GetMS1MzValues(nodeGroup), calcWindowsQ1);
                            filter.AddQ3FilterValues(from TransitionDocNode nodeTran in nodeGroup.Children
                                                     where !nodeTran.IsMs1
                                                     select nodeTran.Mz, calcWindowsQ3);
                        }
                    }
                }
                _filterMzValues = dictPrecursorMzToFilter.Values.ToArray();

                var listChromKeyFilterIds = new List <ChromKey>();
                foreach (var spectrumFilterPair in _filterMzValues)
                {
                    spectrumFilterPair.AddChromKeys(listChromKeyFilterIds);
                }
                _productChromKeys = listChromKeyFilterIds.ToArray();

                // Sort a copy of the filter pairs by maximum retention time so that we can detect when
                // filters are no longer active.
                _filterRTValues = new SpectrumFilterPair[_filterMzValues.Length];
                Array.Copy(_filterMzValues, _filterRTValues, _filterMzValues.Length);
                Array.Sort(_filterRTValues, CompareByRT);
            }

            InitRTLimits();
        }
        protected override void DoTest()
        {
            using (var testFilesDir = new TestFilesDir(TestContext, TestFilesZip))
            {
                const double HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC = -.1;

                // do a few unit tests on the UI error handlers
                TestGetIonMobilityDBErrorHandling(testFilesDir);
                TestImportIonMobilityFromSpectralLibraryErrorHandling();
                TestEditIonMobilityLibraryDlgErrorHandling();
                TestEditDriftTimePredictorDlgErrorHandling();

                // Now exercise the UI

                var goodPeptide = new ValidatingIonMobilityPeptide("SISIVGSYVGNR", 133.3210342, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC);
                Assert.IsNull(goodPeptide.Validate());
                var badPeptides = new[]
                {
                    new ValidatingIonMobilityPeptide("@#$!", 133.3210342, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("SISIVGSYVGNR", 0, 0),
                    new ValidatingIonMobilityPeptide("SISIVGSYVGNR", -133.3210342, -HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                };
                foreach (var badPeptide in badPeptides)
                {
                    Assert.IsNotNull(badPeptide.Validate());
                }

                var ionMobilityPeptides = new[]
                {
                    new ValidatingIonMobilityPeptide("SISIVGSYVGNR", 133.3210342, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),  // These are made-up values
                    new ValidatingIonMobilityPeptide("SISIVGSYVGNR", 133.3210342, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("CCSDVFNQVVK", 131.2405487, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("CCSDVFNQVVK", 131.2405487, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("ANELLINVK", 119.2825783, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("ANELLINVK", 119.2825783, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("EALDFFAR", 110.6867676, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("EALDFFAR", 110.6867676, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("GVIFYESHGK", 123.7844632, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("GVIFYESHGK", 123.7844632, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("EKDIVGAVLK", 124.3414249, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("EKDIVGAVLK", 124.3414249, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("VVGLSTLPEIYEK", 149.857687, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("VVGLSTLPEIYEK", 149.857687, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("VVGLSTLPEIYEK", 149.857687, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("ANGTTVLVGMPAGAK", 144.7461979, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("ANGTTVLVGMPAGAK", 144.7461979, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("IGDYAGIK", 102.2694763, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("IGDYAGIK", 102.2694763, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("GDYAGIK", 91.09155861, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("GDYAGIK", 91.09155861, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("IFYESHGK", 111.2756406, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("EALDFFAR", 110.6867676, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                };
                List <ValidatingIonMobilityPeptide> minimalSet;
                var message = EditIonMobilityLibraryDlg.ValidateUniqueChargedPeptides(ionMobilityPeptides, out minimalSet); // Check for conflicts, strip out dupes
                Assert.IsNull(message, "known good data set failed import");
                Assert.AreEqual(11, minimalSet.Count, "known good data imported but with wrong result count");

                var save = ionMobilityPeptides[0].CollisionalCrossSection;
                ionMobilityPeptides[0].CollisionalCrossSection += 1.0;                                                  // Same sequence and charge, different cross section
                message = EditIonMobilityLibraryDlg.ValidateUniqueChargedPeptides(ionMobilityPeptides, out minimalSet); // Check for conflicts, strip out dupes
                Assert.IsNotNull(message, message);
                Assert.IsNull(minimalSet, "bad inputs to drift time library paste should be rejected wholesale");
                ionMobilityPeptides[0].CollisionalCrossSection = save; // restore

                // Present the Prediction tab of the peptide settings dialog
                var peptideSettingsDlg1 = ShowDialog <PeptideSettingsUI>(
                    () => SkylineWindow.ShowPeptideSettingsUI(PeptideSettingsUI.TABS.Prediction));

                // Simulate picking "Add..." from the Ion Mobility Libraries button context menu
                var ionMobilityLibDlg1 = ShowDialog <EditIonMobilityLibraryDlg>(peptideSettingsDlg1.AddIonMobilityLibrary);
                // Simulate user pasting in collisional cross section data to create a new drift time library
                const string testlibName  = "testlib";
                string       databasePath = testFilesDir.GetTestPath(testlibName + IonMobilityDb.EXT);
                RunUI(() =>
                {
                    string libraryText             = BuildPasteLibraryText(ionMobilityPeptides, seq => seq.Substring(0, seq.Length - 1));
                    ionMobilityLibDlg1.LibraryName = testlibName;
                    ionMobilityLibDlg1.CreateDatabase(databasePath);
                    SetClipboardText(libraryText);
                    ionMobilityLibDlg1.DoPasteLibrary();
                    ionMobilityLibDlg1.OkDialog();
                });
                WaitForClosedForm(ionMobilityLibDlg1);
                RunUI(peptideSettingsDlg1.OkDialog);
                WaitForClosedForm(peptideSettingsDlg1);

                // Use that drift time database in a differently named library
                const string testlibName2        = "testlib2";
                var          peptideSettingsDlg2 = ShowDialog <PeptideSettingsUI>(
                    () => SkylineWindow.ShowPeptideSettingsUI(PeptideSettingsUI.TABS.Prediction));
                // Simulate user picking Add... from the Drift Time Predictor combo control
                var driftTimePredictorDlg = ShowDialog <EditDriftTimePredictorDlg>(peptideSettingsDlg2.AddDriftTimePredictor);
                // ... and reopening an existing drift time database
                var ionMobility = ShowDialog <EditIonMobilityLibraryDlg>(driftTimePredictorDlg.AddIonMobilityLibrary);
                RunUI(() =>
                {
                    ionMobility.LibraryName = testlibName2;
                    ionMobility.OpenDatabase(databasePath);
                    ionMobility.OkDialog();
                });
                WaitForClosedForm(ionMobility);

                // Set other parameters - name, resolving power, per-charge slope+intercept
                const string predictorName  = "test";
                const double resolvingPower = 123.4;
                RunUI(() =>
                {
                    driftTimePredictorDlg.SetResolvingPower(resolvingPower);
                    driftTimePredictorDlg.SetPredictorName(predictorName);
                    SetClipboardText("1\t2\t3\n2\t4\t5"); // Silly values: z=1 s=2 i=3, z=2 s=4 i=5
                    driftTimePredictorDlg.PasteRegressionValues();
                });
                var olddoc = SkylineWindow.Document;
                RunUI(() =>
                {
                    // Go back to the first library we created
                    driftTimePredictorDlg.ChooseIonMobilityLibrary(testlibName);
                    driftTimePredictorDlg.OkDialog();
                    var docUI = SkylineWindow.DocumentUI;
                    if (docUI != null)
                    {
                        SetUiDocument(docUI.ChangeSettings(docUI.Settings.ChangePeptideSettings(
                                                               docUI.Settings.PeptideSettings.ChangePrediction(
                                                                   docUI.Settings.PeptideSettings.Prediction.ChangeDriftTimePredictor(driftTimePredictorDlg.Predictor)))));
                    }
                });

                WaitForClosedForm(driftTimePredictorDlg);
                RunUI(peptideSettingsDlg2.OkDialog);

                /*
                 * Check that the database was created successfully
                 * Check that it has the correct number peptides
                 */
                IonMobilityDb db = IonMobilityDb.GetIonMobilityDb(databasePath, null);
                Assert.AreEqual(11, db.GetPeptides().Count());
                WaitForDocumentChange(olddoc);

                // Check serialization and background loader
                WaitForDocumentLoaded();
                RunUI(() =>
                {
                    SkylineWindow.SaveDocument(TestContext.GetTestPath("test.sky"));
                    SkylineWindow.NewDocument();
                    SkylineWindow.OpenFile(TestContext.GetTestPath("test.sky"));
                });

                var doc = WaitForDocumentLoaded();

                // Verify that the schema has been updated to include these new settings
                AssertEx.ValidatesAgainstSchema(doc);

                // Do some DT calculations
                double        windowDT;
                DriftTimeInfo centerDriftTime = doc.Settings.PeptideSettings.Prediction.GetDriftTimeHelper(
                    new LibKey("ANELLINV", 2), null, out windowDT);
                Assert.AreEqual((4 * (119.2825783)) + 5, centerDriftTime.DriftTimeMsec(false));
                Assert.AreEqual(2 * ((4 * (119.2825783)) + 5) / resolvingPower, windowDT);
                Assert.AreEqual((4 * (119.2825783)) + 5 + HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC, centerDriftTime.DriftTimeMsec(true));

                //
                // Test importing collisional cross sections from a spectral lib that has drift times but no high energy offset info
                //
                var          peptideSettingsUI = ShowDialog <PeptideSettingsUI>(SkylineWindow.ShowPeptideSettingsUI);
                const string libname           = "libIMS";
                var          blibPath          = TestContext.GetTestPath("IonMobilityTest\\mse-mobility.filtered-scaled.blib");
                var          editListUI        =
                    ShowDialog <EditListDlg <SettingsListBase <LibrarySpec>, LibrarySpec> >(peptideSettingsUI.EditLibraryList);
                RunDlg <EditLibraryDlg>(editListUI.AddItem, editLibraryDlg =>
                {
                    editLibraryDlg.LibrarySpec = new BiblioSpecLibSpec(libname, blibPath);
                    editLibraryDlg.OkDialog();
                });
                OkDialog(editListUI, editListUI.OkDialog);
                RunUI(() => peptideSettingsUI.PickedLibraries = new[] { libname });

                // Check error cases for resolving power (caused unexpected excption)
                RunUI(() =>
                {
                    peptideSettingsUI.IsUseSpectralLibraryDriftTimes         = true;
                    peptideSettingsUI.SpectralLibraryDriftTimeResolvingPower = null;
                });
                RunDlg <MessageDlg>(peptideSettingsUI.OkDialog, dlg =>
                {
                    AssertEx.AreComparableStrings(Resources.MessageBoxHelper_ValidateDecimalTextBox__0__must_contain_a_decimal_value, dlg.Message);
                    dlg.OkDialog();
                });
                RunUI(() => peptideSettingsUI.SpectralLibraryDriftTimeResolvingPower = 0);
                RunDlg <MessageDlg>(peptideSettingsUI.OkDialog, dlg =>
                {
                    Assert.AreEqual(Resources.EditDriftTimePredictorDlg_ValidateResolvingPower_Resolving_power_must_be_greater_than_0_, dlg.Message);
                    dlg.OkDialog();
                });

                RunUI(() => peptideSettingsUI.IsUseSpectralLibraryDriftTimes = false);

                OkDialog(peptideSettingsUI, peptideSettingsUI.OkDialog);
                WaitForDocumentLoaded(); // Let that library load

                // In this lib: ANGTTVLVGMPAGAK at z=2, with drift time 4.99820623749102
                // and, a single CCS value, for ANELLINVK, which is 3.8612432898618

                // Present the Prediction tab of the peptide settings dialog
                var peptideSettingsDlg3 = ShowDialog <PeptideSettingsUI>(
                    () => SkylineWindow.ShowPeptideSettingsUI(PeptideSettingsUI.TABS.Prediction));
                // Simulate picking "Add..." from the Drift Time Predictor combo control
                var          driftTimePredictorDlg3     = ShowDialog <EditDriftTimePredictorDlg>(peptideSettingsDlg3.AddDriftTimePredictor);
                const double deadeelsDT                 = 3.456;
                const double deadeelsDTHighEnergyOffset = -0.1;
                var          threeCols = "DEADEELS\t5\t" + deadeelsDT.ToString(CultureInfo.CurrentCulture);
                var          fourCols  = "DEADEELS\t5\t" + deadeelsDT.ToString(CultureInfo.CurrentCulture) + "\t" +
                                         deadeelsDTHighEnergyOffset.ToString(CultureInfo.CurrentCulture);
                RunUI(() =>
                {
                    driftTimePredictorDlg3.SetResolvingPower(resolvingPower);
                    driftTimePredictorDlg3.SetPredictorName("test3");
                    SetClipboardText("1\t2\t3\n2\t4\t5"); // Silly values: z=1 s=2 i=3, z=2 s=4 i=5
                    driftTimePredictorDlg3.PasteRegressionValues();
                    // Simulate user pasting in some measured drift time info without high energy offset, even though its enabled - should not throw
                    driftTimePredictorDlg3.SetOffsetHighEnergySpectraCheckbox(true);
                    SetClipboardText(threeCols);
                    driftTimePredictorDlg3.PasteMeasuredDriftTimes();
                    // Simulate user pasting in some measured drift time info with high energy offset
                    SetClipboardText(fourCols);
                    driftTimePredictorDlg3.PasteMeasuredDriftTimes();
                    // Now turn off the high energy column and paste in four columns - should fail
                    driftTimePredictorDlg3.SetOffsetHighEnergySpectraCheckbox(false);
                    SetClipboardText(fourCols);
                });
                // An error will appear because the column count is wrong
                ShowDialog <MessageDlg>(driftTimePredictorDlg3.PasteMeasuredDriftTimes);
                var errorDlg = WaitForOpenForm <MessageDlg>();
                Assert.AreEqual(string.Format(Resources.SettingsUIUtil_DoPasteText_Incorrect_number_of_columns__0__found_on_line__1__, 4, 1), errorDlg.Message);
                errorDlg.OkDialog();
                RunUI(() =>
                {
                    // And now paste in three columns, should be OK
                    SetClipboardText(threeCols);
                    driftTimePredictorDlg3.PasteMeasuredDriftTimes();

                    // Finally turn the high energy column back on, and put in a value
                    driftTimePredictorDlg3.SetOffsetHighEnergySpectraCheckbox(true);
                    SetClipboardText(fourCols);
                    driftTimePredictorDlg3.PasteMeasuredDriftTimes();
                });
                // Simulate picking "Add..." from the Ion Mobility Library combo control
                var          ionMobilityLibDlg3 = ShowDialog <EditIonMobilityLibraryDlg>(driftTimePredictorDlg3.AddIonMobilityLibrary);
                const string testlibName3       = "testlib3";
                string       databasePath3      = testFilesDir.GetTestPath(testlibName3 + IonMobilityDb.EXT);
                RunUI(() =>
                {
                    ionMobilityLibDlg3.LibraryName = testlibName3;
                    ionMobilityLibDlg3.CreateDatabase(databasePath3);
                });
                // Simulate pressing "Import" button from the Edit Ion Mobility Library dialog
                var importSpectralLibDlg =
                    ShowDialog <ImportIonMobilityFromSpectralLibraryDlg>(ionMobilityLibDlg3.ImportFromSpectralLibrary);
                RunUI(() =>
                {
                    // Set up to fail - don't provide z=2 info
                    importSpectralLibDlg.Source = SpectralLibrarySource.settings; // Simulate user selecting 1st radio button
                    SetClipboardText("1\t1\t0");                                  // This will fail - no z=2 information
                    importSpectralLibDlg.PasteRegressionValues();
                });
                importSpectralLibDlg.BeginInvoke(new Action(importSpectralLibDlg.OkDialog)); // User clicks OK - we expect an error dialog to follow
                WaitForOpenForm <MessageDlg>().OkDialog();                                   // Dismiss the error message, we'll be dropped back into the dialog
                RunUI(() =>
                {
                    importSpectralLibDlg.Source   = SpectralLibrarySource.file; // Simulate user selecting 2nd radio button
                    importSpectralLibDlg.FilePath = blibPath;                   // Simulate user entering filename
                    SetClipboardText("1\t1\t0\n2\t2\t2");                       // Note non-unity slope and charge for z=2, for test purposes
                    importSpectralLibDlg.PasteRegressionValues();
                    importSpectralLibDlg.OkDialog();
                });
                WaitForClosedForm(importSpectralLibDlg);
                WaitForCondition(() => ionMobilityLibDlg3.LibraryPeptideCount > 8); // Let that library load
                RunUI(ionMobilityLibDlg3.OkDialog);
                WaitForClosedForm(ionMobilityLibDlg3);
                RunUI(driftTimePredictorDlg3.OkDialog);
                WaitForClosedForm(driftTimePredictorDlg3);
                RunUI(peptideSettingsDlg3.OkDialog);
                WaitForClosedForm(peptideSettingsDlg3);
                doc = WaitForDocumentChangeLoaded(doc); // Let that library load

                // Do some DT calculations with this new library
                centerDriftTime = doc.Settings.PeptideSettings.Prediction.GetDriftTimeHelper(
                    new LibKey("ANELLINVK", 2), null, out windowDT);
                double ccs = 3.8612432898618; // should have imported CCS without any transformation
                Assert.AreEqual((4 * (ccs)) + 5, centerDriftTime.DriftTimeMsec(false) ?? ccs, .000001);
                Assert.AreEqual(2 * ((4 * (ccs)) + 5) / resolvingPower, windowDT, .000001);
                centerDriftTime = doc.Settings.PeptideSettings.Prediction.GetDriftTimeHelper(
                    new LibKey("ANGTTVLVGMPAGAK", 2), null, out windowDT);
                ccs = (4.99820623749102 - 2) / 2; // should have imported CCS as a converted drift time
                Assert.AreEqual((4 * (ccs)) + 5, centerDriftTime.DriftTimeMsec(false) ?? ccs, .000001);
                Assert.AreEqual(2 * ((4 * (ccs)) + 5) / resolvingPower, windowDT, .000001);

                // Do some DT calculations with the measured drift time
                centerDriftTime = doc.Settings.PeptideSettings.Prediction.GetDriftTimeHelper(
                    new LibKey("DEADEELS", 3), null, out windowDT); // Should fail
                Assert.AreEqual(windowDT, 0);
                Assert.IsFalse(centerDriftTime.DriftTimeMsec(false).HasValue);

                centerDriftTime = doc.Settings.PeptideSettings.Prediction.GetDriftTimeHelper(
                    new LibKey("DEADEELS", 5), null, out windowDT);
                Assert.AreEqual(deadeelsDT, centerDriftTime.DriftTimeMsec(false) ?? -1, .000001);
                Assert.AreEqual(deadeelsDT + deadeelsDTHighEnergyOffset, centerDriftTime.DriftTimeMsec(true) ?? -1, .000001);
                Assert.AreEqual(2 * (deadeelsDT / resolvingPower), windowDT, .0001); // Directly measured, should match

                // Now check handling of scenario where user pastes in high energy offsets then unchecks the "Use High Energy Offsets" box
                var peptideSettingsDlg4 = ShowDialog <PeptideSettingsUI>(
                    () => SkylineWindow.ShowPeptideSettingsUI(PeptideSettingsUI.TABS.Prediction));
                // Simulate picking "Edit Current..." from the Drift Time Predictor combo control
                var driftTimePredictorDlg4 = ShowDialog <EditDriftTimePredictorDlg>(peptideSettingsDlg4.EditDriftTimePredictor);
                RunUI(() =>
                {
                    Assert.IsTrue(driftTimePredictorDlg4.GetOffsetHighEnergySpectraCheckbox()); // Should start out enabled if we have offsets
                    driftTimePredictorDlg4.SetOffsetHighEnergySpectraCheckbox(false);           // Turn off the high energy offset column
                    driftTimePredictorDlg4.SetPredictorName("test4");
                });
                RunUI(driftTimePredictorDlg4.OkDialog);
                WaitForClosedForm(driftTimePredictorDlg4);
                RunUI(peptideSettingsDlg4.OkDialog);
                WaitForClosedForm(peptideSettingsDlg4);
                doc             = WaitForDocumentChangeLoaded(doc);
                centerDriftTime = doc.Settings.PeptideSettings.Prediction.GetDriftTimeHelper(
                    new LibKey("DEADEELS", 5), null, out windowDT);
                Assert.AreEqual(deadeelsDT, centerDriftTime.DriftTimeMsec(false) ?? -1, .000001);
                Assert.AreEqual(deadeelsDT, centerDriftTime.DriftTimeMsec(true) ?? -1, .000001); // High energy value should now be same as low energy value
                Assert.AreEqual(2 * (deadeelsDT / resolvingPower), windowDT, .0001);             // Directly measured, should match

                // Now make sure that high energy checkbox initial state is as we expect
                var peptideSettingsDlg5 = ShowDialog <PeptideSettingsUI>(
                    () => SkylineWindow.ShowPeptideSettingsUI(PeptideSettingsUI.TABS.Prediction));
                // Simulate picking "Edit Current..." from the Drift Time Predictor combo control
                var driftTimePredictorDlg5 = ShowDialog <EditDriftTimePredictorDlg>(peptideSettingsDlg5.EditDriftTimePredictor);
                RunUI(() => Assert.IsFalse(driftTimePredictorDlg5.GetOffsetHighEnergySpectraCheckbox()));
                RunUI(driftTimePredictorDlg5.CancelDialog);
                WaitForClosedForm(driftTimePredictorDlg5);
                RunUI(peptideSettingsDlg5.OkDialog);
                WaitForClosedForm(peptideSettingsDlg5);
            }
            TestMeasuredDriftTimes();
        }
Exemple #3
0
        public Dictionary <LibKey, DriftTimeInfo> FindDriftTimePeaks()
        {
            // Overwrite any existing measurements with newly derived ones
            var measured = new Dictionary <LibKey, DriftTimeInfo>();

            if (_existing != null && _existing.MeasuredDriftTimePeptides != null)
            {
                foreach (var existingPair in _existing.MeasuredDriftTimePeptides)
                {
                    measured.Add(existingPair.Key, existingPair.Value);
                }
            }

            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
                //

                _ms1DriftTimes = new Dictionary <LibKey, List <DriftTimeIntensityPair> >();
                _ms2DriftTimes = new Dictionary <LibKey, List <DriftTimeIntensityPair> >();
                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 drift times based on MS1 data
                foreach (var dt in _ms1DriftTimes)
                {
                    // Choose the drift time which gave the largest signal
                    var ms1DriftTime = dt.Value.OrderByDescending(p => p.Intensity).First().DriftTime;
                    // Check for MS2 data to use for high energy offset
                    List <DriftTimeIntensityPair> listDt;
                    var ms2DriftTime = _ms2DriftTimes.TryGetValue(dt.Key, out listDt)
                        ? listDt.OrderByDescending(p => p.Intensity).First().DriftTime
                        : (ms1DriftTime ?? 0);
                    var value = new DriftTimeInfo(ms1DriftTime, ms2DriftTime - ms1DriftTime ?? 0);
                    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 dt in _ms2DriftTimes)
                {
                    if (!_ms1DriftTimes.ContainsKey(dt.Key))
                    {
                        // Only MS2 drift times found, use that
                        var value = new DriftTimeInfo(dt.Value.OrderByDescending(p => p.Intensity).First().DriftTime, 0);
                        if (!measured.ContainsKey(dt.Key))
                        {
                            measured.Add(dt.Key, value);
                        }
                        else
                        {
                            measured[dt.Key] = value;
                        }
                    }
                }
            }
            return(measured);
        }
        public Dictionary<LibKey, DriftTimeInfo> FindDriftTimePeaks()
        {
            // Overwrite any existing measurements with newly derived ones
            var measured = new Dictionary<LibKey, DriftTimeInfo>();
            if (_existing != null && _existing.MeasuredDriftTimePeptides != null)
            {
                foreach (var existingPair in _existing.MeasuredDriftTimePeptides)
                    measured.Add(existingPair.Key, existingPair.Value);
            }

            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
                //

                _ms1DriftTimes = new Dictionary<LibKey, List<DriftTimeIntensityPair>>();
                _ms2DriftTimes = new Dictionary<LibKey, List<DriftTimeIntensityPair>>();
                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 drift times based on MS1 data
                foreach (var dt in _ms1DriftTimes)
                {
                    // Choose the drift time which gave the largest signal
                    var ms1DriftTime = dt.Value.OrderByDescending(p => p.Intensity).First().DriftTime;
                    // Check for MS2 data to use for high energy offset
                    List<DriftTimeIntensityPair> listDt;
                    var ms2DriftTime = _ms2DriftTimes.TryGetValue(dt.Key, out listDt)
                        ? listDt.OrderByDescending(p => p.Intensity).First().DriftTime
                        : (ms1DriftTime ?? 0);
                    var value = new DriftTimeInfo(ms1DriftTime, ms2DriftTime - ms1DriftTime ?? 0);
                    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 dt in _ms2DriftTimes)
                {
                    if (!_ms1DriftTimes.ContainsKey(dt.Key))
                    {
                        // Only MS2 drift times found, use that
                        var value = new DriftTimeInfo(dt.Value.OrderByDescending(p => p.Intensity).First().DriftTime, 0);
                        if (!measured.ContainsKey(dt.Key))
                            measured.Add(dt.Key, value);
                        else
                            measured[dt.Key] = value;
                    }
                }
            }
            return measured;
        }
 /// <summary>
 /// Get drift time for the charged peptide from explicitly set values, or our drift time predictor, or,
 /// failing that, from the provided spectral library if it has bare drift times.
 /// If no drift info is available, returns a new zero'd out drift time info object.
 /// </summary>
 public DriftTimeInfo GetDriftTime(PeptideDocNode  nodePep,
     TransitionGroupDocNode nodeGroup,
     LibraryIonMobilityInfo libraryIonMobilityInfo, out double windowDtMsec)
 {
     if (nodeGroup.ExplicitValues.DriftTimeMsec.HasValue)
     {
         // Use the explicitly specified value
         var result = new DriftTimeInfo(nodeGroup.ExplicitValues.DriftTimeMsec,
             nodeGroup.ExplicitValues.DriftTimeHighEnergyOffsetMsec ?? 0);
         // Now get the resolving power
         if (DriftTimePredictor != null)
         {
             windowDtMsec = DriftTimePredictor.InverseResolvingPowerTimesTwo*result.DriftTimeMsec(false).Value;
         }
         else if (LibraryDriftTimesResolvingPower.HasValue)
         {
             windowDtMsec = 2.0 * result.DriftTimeMsec(false).Value / LibraryDriftTimesResolvingPower.Value;
         }
         else
         {
             windowDtMsec = 0;
         }
         return result;
     }
     else
     {
         return GetDriftTimeHelper(
             new LibKey(nodePep.RawTextId, nodeGroup.TransitionGroup.PrecursorCharge), libraryIonMobilityInfo,
             out windowDtMsec);
     }
 }