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(); }
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); } }