From 8be2574a0939e8db66ecc2126be4904d944b1025 Mon Sep 17 00:00:00 2001 From: nbollis Date: Tue, 21 May 2024 15:08:45 -0500 Subject: [PATCH 01/13] Updated to MzLib 1.0.548 and fixed custom ions in search tasks --- MetaMorpheus/CMD/CMD.csproj | 2 +- .../ClassicSearch/ClassicSearchEngine.cs | 9 +++++++++ .../ClassicSearch/MiniClassicSearchEngine.cs | 2 +- MetaMorpheus/EngineLayer/EngineLayer.csproj | 2 +- .../ModernSearch/ModernSearchEngine.cs | 7 +++++++ .../NonSpecificEnzymeSearchEngine.cs | 8 ++++++++ .../SpectralLibrarySearchFunction.cs | 7 +++++-- MetaMorpheus/GUI/GUI.csproj | 2 +- MetaMorpheus/GuiFunctions/GuiFunctions.csproj | 2 +- .../CalibrationTask/CalibrationTask.cs | 4 +++- MetaMorpheus/TaskLayer/TaskLayer.csproj | 2 +- MetaMorpheus/Test/CustomFragmentationTest.cs | 17 +++++++++++------ MetaMorpheus/Test/Test.csproj | 2 +- 13 files changed, 50 insertions(+), 16 deletions(-) diff --git a/MetaMorpheus/CMD/CMD.csproj b/MetaMorpheus/CMD/CMD.csproj index 2570c57f1..69e265fd3 100644 --- a/MetaMorpheus/CMD/CMD.csproj +++ b/MetaMorpheus/CMD/CMD.csproj @@ -24,7 +24,7 @@ - + diff --git a/MetaMorpheus/EngineLayer/ClassicSearch/ClassicSearchEngine.cs b/MetaMorpheus/EngineLayer/ClassicSearch/ClassicSearchEngine.cs index ee15ab360..c35007011 100644 --- a/MetaMorpheus/EngineLayer/ClassicSearch/ClassicSearchEngine.cs +++ b/MetaMorpheus/EngineLayer/ClassicSearch/ClassicSearchEngine.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Omics.Fragmentation.Peptide; using Omics.Modifications; namespace EngineLayer.ClassicSearch @@ -67,6 +68,10 @@ protected override MetaMorpheusEngineResults RunSpecific() myLocks[i] = new object(); } + if (CommonParameters.DissociationType == DissociationType.Custom) + DissociationTypeCollection.ProductsFromDissociationType[DissociationType.Custom] = + CommonParameters.CustomIons; + Status("Performing classic search..."); if (Proteins.Any()) @@ -168,6 +173,10 @@ protected override MetaMorpheusEngineResults RunSpecific() psm.ResolveAllAmbiguities(); } + if (CommonParameters.DissociationType == DissociationType.Custom) + DissociationTypeCollection.ProductsFromDissociationType[DissociationType.Custom] = + new List(); + return new MetaMorpheusEngineResults(this); } diff --git a/MetaMorpheus/EngineLayer/ClassicSearch/MiniClassicSearchEngine.cs b/MetaMorpheus/EngineLayer/ClassicSearch/MiniClassicSearchEngine.cs index 854609313..80ad9eff7 100644 --- a/MetaMorpheus/EngineLayer/ClassicSearch/MiniClassicSearchEngine.cs +++ b/MetaMorpheus/EngineLayer/ClassicSearch/MiniClassicSearchEngine.cs @@ -137,7 +137,7 @@ public static void CalculateSpectralAngles(SpectralLibrary spectralLibrary, Spec if (!Peptide.Parent.IsDecoy && spectralLibrary.TryGetSpectrum(Peptide.FullSequence, scan.PrecursorCharge, out var librarySpectrum)) { SpectralSimilarity s = new SpectralSimilarity(scan.TheScan.MassSpectrum, librarySpectrum.XArray, librarySpectrum.YArray, - SpectralSimilarity.SpectrumNormalizationScheme.squareRootSpectrumSum, fileSpecificParameters.ProductMassTolerance.Value, false); + SpectralSimilarity.SpectrumNormalizationScheme.SquareRootSpectrumSum, fileSpecificParameters.ProductMassTolerance.Value, false); if (s.SpectralContrastAngle().HasValue) { pwsms.Add((Notch, Peptide)); diff --git a/MetaMorpheus/EngineLayer/EngineLayer.csproj b/MetaMorpheus/EngineLayer/EngineLayer.csproj index f1d1a4102..b9fe7d104 100644 --- a/MetaMorpheus/EngineLayer/EngineLayer.csproj +++ b/MetaMorpheus/EngineLayer/EngineLayer.csproj @@ -21,7 +21,7 @@ - + diff --git a/MetaMorpheus/EngineLayer/ModernSearch/ModernSearchEngine.cs b/MetaMorpheus/EngineLayer/ModernSearch/ModernSearchEngine.cs index 137bc00fb..b9c01d392 100644 --- a/MetaMorpheus/EngineLayer/ModernSearch/ModernSearchEngine.cs +++ b/MetaMorpheus/EngineLayer/ModernSearch/ModernSearchEngine.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Omics.Fragmentation.Peptide; namespace EngineLayer.ModernSearch { @@ -46,6 +47,8 @@ protected override MetaMorpheusEngineResults RunSpecific() int maxThreadsPerFile = CommonParameters.MaxThreadsToUsePerFile; int[] threads = Enumerable.Range(0, maxThreadsPerFile).ToArray(); + if (CommonParameters.DissociationType == DissociationType.Custom) + DissociationTypeCollection.ProductsFromDissociationType[DissociationType.Custom] = CommonParameters.CustomIons; Parallel.ForEach(threads, (scanIndex) => { @@ -87,6 +90,10 @@ protected override MetaMorpheusEngineResults RunSpecific() psm.ResolveAllAmbiguities(); } + if (CommonParameters.DissociationType == DissociationType.Custom) + DissociationTypeCollection.ProductsFromDissociationType[DissociationType.Custom] = + new List(); + return new MetaMorpheusEngineResults(this); } diff --git a/MetaMorpheus/EngineLayer/NonSpecificEnzymeSearch/NonSpecificEnzymeSearchEngine.cs b/MetaMorpheus/EngineLayer/NonSpecificEnzymeSearch/NonSpecificEnzymeSearchEngine.cs index 1426bd4aa..f486835b8 100644 --- a/MetaMorpheus/EngineLayer/NonSpecificEnzymeSearch/NonSpecificEnzymeSearchEngine.cs +++ b/MetaMorpheus/EngineLayer/NonSpecificEnzymeSearch/NonSpecificEnzymeSearchEngine.cs @@ -56,6 +56,9 @@ protected override MetaMorpheusEngineResults RunSpecific() throw new NotImplementedException(); } + if (CommonParameters.DissociationType == DissociationType.Custom) + DissociationTypeCollection.ProductsFromDissociationType[DissociationType.Custom] = CommonParameters.CustomIons; + int maxThreadsPerFile = CommonParameters.MaxThreadsToUsePerFile; int[] threads = Enumerable.Range(0, maxThreadsPerFile).ToArray(); Parallel.ForEach(threads, (i) => @@ -163,6 +166,11 @@ protected override MetaMorpheusEngineResults RunSpecific() } } }); + + if (CommonParameters.DissociationType == DissociationType.Custom) + DissociationTypeCollection.ProductsFromDissociationType[DissociationType.Custom] = + new List(); + return new MetaMorpheusEngineResults(this); } diff --git a/MetaMorpheus/EngineLayer/SpectralLibrarySearch/SpectralLibrarySearchFunction.cs b/MetaMorpheus/EngineLayer/SpectralLibrarySearch/SpectralLibrarySearchFunction.cs index 10bf04fd6..bc2a30c99 100644 --- a/MetaMorpheus/EngineLayer/SpectralLibrarySearch/SpectralLibrarySearchFunction.cs +++ b/MetaMorpheus/EngineLayer/SpectralLibrarySearch/SpectralLibrarySearchFunction.cs @@ -47,7 +47,8 @@ public static void CalculateSpectralAngles(SpectralLibrary spectralLibrary, Spec //if peptide is target, directly look for the target's spectrum in the spectral library if (!Peptide.Parent.IsDecoy && spectralLibrary.TryGetSpectrum(Peptide.FullSequence, scan.PrecursorCharge, out var librarySpectrum)) { - SpectralSimilarity s = new SpectralSimilarity(scan.TheScan.MassSpectrum, librarySpectrum.XArray, librarySpectrum.YArray, SpectralSimilarity.SpectrumNormalizationScheme.squareRootSpectrumSum, commonParameters.ProductMassTolerance.Value, false); + SpectralSimilarity s = new SpectralSimilarity(scan.TheScan.MassSpectrum, librarySpectrum.XArray, librarySpectrum.YArray, + SpectralSimilarity.SpectrumNormalizationScheme.SquareRootSpectrumSum, commonParameters.ProductMassTolerance.Value, false); if (s.SpectralContrastAngle().HasValue) { pwsms.Add((Notch, Peptide)); @@ -61,7 +62,9 @@ public static void CalculateSpectralAngles(SpectralLibrary spectralLibrary, Spec var decoyPeptideTheorProducts = new List(); Peptide.Fragment(commonParameters.DissociationType, commonParameters.DigestionParams.FragmentationTerminus, decoyPeptideTheorProducts); var decoylibrarySpectrum = GetDecoyLibrarySpectrumFromTargetByReverse(targetlibrarySpectrum, decoyPeptideTheorProducts); - SpectralSimilarity s = new SpectralSimilarity(scan.TheScan.MassSpectrum, decoylibrarySpectrum.Select(x => x.Mz).ToArray(),decoylibrarySpectrum.Select(x => x.Intensity).ToArray(), SpectralSimilarity.SpectrumNormalizationScheme.squareRootSpectrumSum, commonParameters.ProductMassTolerance.Value, false); + SpectralSimilarity s = new SpectralSimilarity(scan.TheScan.MassSpectrum, decoylibrarySpectrum.Select(x => x.Mz).ToArray(), + decoylibrarySpectrum.Select(x => x.Intensity).ToArray(), SpectralSimilarity.SpectrumNormalizationScheme.SquareRootSpectrumSum, + commonParameters.ProductMassTolerance.Value, false); if (s.SpectralContrastAngle().HasValue) { pwsms.Add((Notch, Peptide)); diff --git a/MetaMorpheus/GUI/GUI.csproj b/MetaMorpheus/GUI/GUI.csproj index 64bb7e0f7..b1a326389 100644 --- a/MetaMorpheus/GUI/GUI.csproj +++ b/MetaMorpheus/GUI/GUI.csproj @@ -55,7 +55,7 @@ - + diff --git a/MetaMorpheus/GuiFunctions/GuiFunctions.csproj b/MetaMorpheus/GuiFunctions/GuiFunctions.csproj index b32fb72cc..b0692b247 100644 --- a/MetaMorpheus/GuiFunctions/GuiFunctions.csproj +++ b/MetaMorpheus/GuiFunctions/GuiFunctions.csproj @@ -14,7 +14,7 @@ - + diff --git a/MetaMorpheus/TaskLayer/CalibrationTask/CalibrationTask.cs b/MetaMorpheus/TaskLayer/CalibrationTask/CalibrationTask.cs index 82b2762a1..9472e7a18 100644 --- a/MetaMorpheus/TaskLayer/CalibrationTask/CalibrationTask.cs +++ b/MetaMorpheus/TaskLayer/CalibrationTask/CalibrationTask.cs @@ -254,7 +254,9 @@ private static bool ImprovGlobal(double prevPrecTol, double prevProdTol, int pre return countRatio > 0.9 && precRatio + prodRatio < 1.8; } - private DataPointAquisitionResults GetDataAcquisitionResults(MsDataFile myMsDataFile, string currentDataFile, List variableModifications, List fixedModifications, List proteinList, string taskId, CommonParameters combinedParameters, Tolerance initPrecTol, Tolerance initProdTol) + private DataPointAquisitionResults GetDataAcquisitionResults(MsDataFile myMsDataFile, string currentDataFile, + List variableModifications, List fixedModifications, List proteinList, + string taskId, CommonParameters combinedParameters, Tolerance initPrecTol, Tolerance initProdTol) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(currentDataFile); MassDiffAcceptor searchMode = initPrecTol is PpmTolerance ? diff --git a/MetaMorpheus/TaskLayer/TaskLayer.csproj b/MetaMorpheus/TaskLayer/TaskLayer.csproj index 57b70d433..f25ed1e44 100644 --- a/MetaMorpheus/TaskLayer/TaskLayer.csproj +++ b/MetaMorpheus/TaskLayer/TaskLayer.csproj @@ -21,7 +21,7 @@ - + diff --git a/MetaMorpheus/Test/CustomFragmentationTest.cs b/MetaMorpheus/Test/CustomFragmentationTest.cs index 3f0d6bac1..54904bc3c 100644 --- a/MetaMorpheus/Test/CustomFragmentationTest.cs +++ b/MetaMorpheus/Test/CustomFragmentationTest.cs @@ -64,13 +64,18 @@ public static void CustomFragmentationManyTasks() var customIons = new List { ProductType.b, ProductType.c, ProductType.zDot }; DissociationTypeCollection.ProductsFromDissociationType[DissociationType.Custom] = customIons; - CalibrationTask calibrationTask = new CalibrationTask(); - calibrationTask.CommonParameters.GetType().GetProperty("DissociationType")?.SetValue(calibrationTask.CommonParameters, DissociationType.Custom); - + var calibCommonParams = new CommonParameters( + dissociationType: DissociationType.Custom, + productMassTolerance: new PpmTolerance(25), + precursorMassTolerance: new PpmTolerance(15), + trimMsMsPeaks: false, + doPrecursorDeconvolution: false); + CalibrationTask calibrationTask = new CalibrationTask() {CommonParameters = calibCommonParams}; + DissociationTypeCollection.ProductsFromDissociationType[DissociationType.Custom] = customIons; - GptmdTask gptmdTask = new GptmdTask(); - gptmdTask.CommonParameters.GetType().GetProperty("DissociationType")?.SetValue(gptmdTask.CommonParameters, DissociationType.Custom); - + var gptmdCommonParam = new CommonParameters(dissociationType: DissociationType.Custom); + GptmdTask gptmdTask = new GptmdTask() {CommonParameters = gptmdCommonParam}; + SearchTask searchTask = Toml.ReadFile( Path.Combine(TestContext.CurrentContext.TestDirectory, @"TestData\customBCZ.toml"), MetaMorpheusTask.tomlConfig); diff --git a/MetaMorpheus/Test/Test.csproj b/MetaMorpheus/Test/Test.csproj index 427478765..9fe40fdd5 100644 --- a/MetaMorpheus/Test/Test.csproj +++ b/MetaMorpheus/Test/Test.csproj @@ -23,7 +23,7 @@ - + From a00af8a0c277dd52ac1b076d83e4c38ec856f432 Mon Sep 17 00:00:00 2001 From: nbollis Date: Tue, 21 May 2024 15:09:55 -0500 Subject: [PATCH 02/13] reverted calibration task change --- MetaMorpheus/TaskLayer/CalibrationTask/CalibrationTask.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/MetaMorpheus/TaskLayer/CalibrationTask/CalibrationTask.cs b/MetaMorpheus/TaskLayer/CalibrationTask/CalibrationTask.cs index 9472e7a18..82b2762a1 100644 --- a/MetaMorpheus/TaskLayer/CalibrationTask/CalibrationTask.cs +++ b/MetaMorpheus/TaskLayer/CalibrationTask/CalibrationTask.cs @@ -254,9 +254,7 @@ private static bool ImprovGlobal(double prevPrecTol, double prevProdTol, int pre return countRatio > 0.9 && precRatio + prodRatio < 1.8; } - private DataPointAquisitionResults GetDataAcquisitionResults(MsDataFile myMsDataFile, string currentDataFile, - List variableModifications, List fixedModifications, List proteinList, - string taskId, CommonParameters combinedParameters, Tolerance initPrecTol, Tolerance initProdTol) + private DataPointAquisitionResults GetDataAcquisitionResults(MsDataFile myMsDataFile, string currentDataFile, List variableModifications, List fixedModifications, List proteinList, string taskId, CommonParameters combinedParameters, Tolerance initPrecTol, Tolerance initProdTol) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(currentDataFile); MassDiffAcceptor searchMode = initPrecTol is PpmTolerance ? From f4695bb0547902527b97a59628816d11d1064fab Mon Sep 17 00:00:00 2001 From: nbollis Date: Mon, 10 Jun 2024 16:59:46 -0500 Subject: [PATCH 03/13] merged in master bbbyy --- .../ClassicSearch/ClassicSearchEngine.cs | 9 --- .../ModernSearch/ModernSearchEngine.cs | 7 -- .../NonSpecificEnzymeSearchEngine.cs | 8 -- .../CrosslinkSpectrumMatchPlot.cs | 4 +- .../Test/MetaDraw/SpectrumMatchPlotTests.cs | 77 +++++++++++++++++++ 5 files changed, 79 insertions(+), 26 deletions(-) diff --git a/MetaMorpheus/EngineLayer/ClassicSearch/ClassicSearchEngine.cs b/MetaMorpheus/EngineLayer/ClassicSearch/ClassicSearchEngine.cs index c35007011..ee15ab360 100644 --- a/MetaMorpheus/EngineLayer/ClassicSearch/ClassicSearchEngine.cs +++ b/MetaMorpheus/EngineLayer/ClassicSearch/ClassicSearchEngine.cs @@ -7,7 +7,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Omics.Fragmentation.Peptide; using Omics.Modifications; namespace EngineLayer.ClassicSearch @@ -68,10 +67,6 @@ protected override MetaMorpheusEngineResults RunSpecific() myLocks[i] = new object(); } - if (CommonParameters.DissociationType == DissociationType.Custom) - DissociationTypeCollection.ProductsFromDissociationType[DissociationType.Custom] = - CommonParameters.CustomIons; - Status("Performing classic search..."); if (Proteins.Any()) @@ -173,10 +168,6 @@ protected override MetaMorpheusEngineResults RunSpecific() psm.ResolveAllAmbiguities(); } - if (CommonParameters.DissociationType == DissociationType.Custom) - DissociationTypeCollection.ProductsFromDissociationType[DissociationType.Custom] = - new List(); - return new MetaMorpheusEngineResults(this); } diff --git a/MetaMorpheus/EngineLayer/ModernSearch/ModernSearchEngine.cs b/MetaMorpheus/EngineLayer/ModernSearch/ModernSearchEngine.cs index b9c01d392..137bc00fb 100644 --- a/MetaMorpheus/EngineLayer/ModernSearch/ModernSearchEngine.cs +++ b/MetaMorpheus/EngineLayer/ModernSearch/ModernSearchEngine.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Omics.Fragmentation.Peptide; namespace EngineLayer.ModernSearch { @@ -47,8 +46,6 @@ protected override MetaMorpheusEngineResults RunSpecific() int maxThreadsPerFile = CommonParameters.MaxThreadsToUsePerFile; int[] threads = Enumerable.Range(0, maxThreadsPerFile).ToArray(); - if (CommonParameters.DissociationType == DissociationType.Custom) - DissociationTypeCollection.ProductsFromDissociationType[DissociationType.Custom] = CommonParameters.CustomIons; Parallel.ForEach(threads, (scanIndex) => { @@ -90,10 +87,6 @@ protected override MetaMorpheusEngineResults RunSpecific() psm.ResolveAllAmbiguities(); } - if (CommonParameters.DissociationType == DissociationType.Custom) - DissociationTypeCollection.ProductsFromDissociationType[DissociationType.Custom] = - new List(); - return new MetaMorpheusEngineResults(this); } diff --git a/MetaMorpheus/EngineLayer/NonSpecificEnzymeSearch/NonSpecificEnzymeSearchEngine.cs b/MetaMorpheus/EngineLayer/NonSpecificEnzymeSearch/NonSpecificEnzymeSearchEngine.cs index f486835b8..1426bd4aa 100644 --- a/MetaMorpheus/EngineLayer/NonSpecificEnzymeSearch/NonSpecificEnzymeSearchEngine.cs +++ b/MetaMorpheus/EngineLayer/NonSpecificEnzymeSearch/NonSpecificEnzymeSearchEngine.cs @@ -56,9 +56,6 @@ protected override MetaMorpheusEngineResults RunSpecific() throw new NotImplementedException(); } - if (CommonParameters.DissociationType == DissociationType.Custom) - DissociationTypeCollection.ProductsFromDissociationType[DissociationType.Custom] = CommonParameters.CustomIons; - int maxThreadsPerFile = CommonParameters.MaxThreadsToUsePerFile; int[] threads = Enumerable.Range(0, maxThreadsPerFile).ToArray(); Parallel.ForEach(threads, (i) => @@ -166,11 +163,6 @@ protected override MetaMorpheusEngineResults RunSpecific() } } }); - - if (CommonParameters.DissociationType == DissociationType.Custom) - DissociationTypeCollection.ProductsFromDissociationType[DissociationType.Custom] = - new List(); - return new MetaMorpheusEngineResults(this); } diff --git a/MetaMorpheus/GuiFunctions/MetaDraw/SpectrumMatch/CrosslinkSpectrumMatchPlot.cs b/MetaMorpheus/GuiFunctions/MetaDraw/SpectrumMatch/CrosslinkSpectrumMatchPlot.cs index e4a01e443..e9945242f 100644 --- a/MetaMorpheus/GuiFunctions/MetaDraw/SpectrumMatch/CrosslinkSpectrumMatchPlot.cs +++ b/MetaMorpheus/GuiFunctions/MetaDraw/SpectrumMatch/CrosslinkSpectrumMatchPlot.cs @@ -58,7 +58,7 @@ public CrosslinkSpectrumMatchPlot(OxyPlot.Wpf.PlotView plotView, PsmFromTsv csm, double dpiScale = MetaDrawSettings.CanvasPdfExportDpi / 96.0; // render stationary sequence as bitmap and export as png - stationarySequence.Height += 30; + stationarySequence.Height += 80; stationarySequence.Width += 30; Size stationarySequenceSize = new Size((int)stationarySequence.Width, (int)stationarySequence.Height); stationarySequence.Measure(stationarySequenceSize); @@ -90,7 +90,7 @@ public CrosslinkSpectrumMatchPlot(OxyPlot.Wpf.PlotView plotView, PsmFromTsv csm, // render ptm legend as bitmap and export as png if used System.Drawing.Bitmap ptmLegendBitmap = null; Point ptmLegendPoint; - if (ptmLegend != null && MetaDrawSettings.ShowLegend) + if (ptmLegend != null && MetaDrawSettings.ShowLegend && ptmLegend.ActualHeight > 0) { // Saving Canvas as a usable Png RenderTargetBitmap ptmLegendRenderBitmap = new((int)(dpiScale * ptmLegend.ActualWidth), (int)(dpiScale * ptmLegend.ActualHeight), diff --git a/MetaMorpheus/Test/MetaDraw/SpectrumMatchPlotTests.cs b/MetaMorpheus/Test/MetaDraw/SpectrumMatchPlotTests.cs index fd77aaae3..f7f4e3232 100644 --- a/MetaMorpheus/Test/MetaDraw/SpectrumMatchPlotTests.cs +++ b/MetaMorpheus/Test/MetaDraw/SpectrumMatchPlotTests.cs @@ -12,6 +12,7 @@ using OxyPlot; using OxyPlot.Annotations; using Omics.Fragmentation; +using Readers; using TaskLayer; namespace Test.MetaDraw @@ -173,5 +174,81 @@ public void TestPeakColor(PeakAnnotationTestCase testCase) var annotation = ((TextAnnotation)plotView.Model.Annotations[testCase.FragmentIndex]); Assert.That(annotation.TextColor, Is.EqualTo(testCase.ExpectedColor)); } + + [Test] + public static void TestCrossLinkSpectrumMatchPlot() + { + // set up file paths + var outputFolderPath = Path.Combine(TestContext.CurrentContext.TestDirectory, "TestCrossLinkSpectrumMatchPlot"); + var psmFilePath = Path.Combine(TestContext.CurrentContext.TestDirectory, "XlTestData", "XL_Interlinks.tsv"); + var dataFilePath = Path.Combine(TestContext.CurrentContext.TestDirectory, "XlTestData", "2017-11-21_XL_DSSO_Ribosome_RT60min_28800-28898.mzML"); + + Directory.CreateDirectory(outputFolderPath); + + // load in files + MetaDrawLogic metaDrawLogic = new MetaDrawLogic(); + metaDrawLogic.SpectraFilePaths.Add(dataFilePath); + metaDrawLogic.PsmResultFilePaths.Add(psmFilePath); + + var errors = metaDrawLogic.LoadFiles(true, true); + + Assert.That(!errors.Any()); + Assert.That(metaDrawLogic.FilteredListOfPsms.Any()); + + // load in gui components + var plotView = new OxyPlot.Wpf.PlotView() { Name = "plotView" }; + var canvas = new Canvas(); + var scrollableCanvas = new Canvas(); + var stationaryCanvas = new Canvas(); + var sequenceAnnotationCanvas = new Canvas(); + var parentChildView = new ParentChildScanPlotsView(); + var psm = metaDrawLogic.FilteredListOfPsms.First(p => p.FullSequence == "GVTVDKMTELR(6)"); + + // perform black magic to set the scan number of the MS2 to match the mzML file number + var oldScanNum = psm.Ms2ScanNumber; + var field = typeof(PsmFromTsv).GetField("k__BackingField", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + field?.SetValue(psm, 28819); + + // display psm and check display has correct number of annotations + metaDrawLogic.DisplaySequences(stationaryCanvas, scrollableCanvas, sequenceAnnotationCanvas, psm); + int alphaPeptideAnnotations = psm.BaseSeq.Length + psm.MatchedIons.Count(p => p.NeutralTheoreticalProduct.ProductType is ProductType.b or ProductType.y); + int betaPeptideAnnotations = psm.BetaPeptideBaseSequence.Length + psm.BetaPeptideMatchedIons.Count(p => p.NeutralTheoreticalProduct.ProductType is ProductType.b or ProductType.y); + int crossLinkerAnnotations = 1; + int sequenceDisplayAnnotationCount = + alphaPeptideAnnotations + betaPeptideAnnotations + crossLinkerAnnotations; + Assert.That(stationaryCanvas.Children.Count, Is.EqualTo(sequenceDisplayAnnotationCount)); + Assert.That(scrollableCanvas.Children.Count, Is.EqualTo(alphaPeptideAnnotations)); + + var alphaPeptideSpectralMatchAnnotationCount = psm.MatchedIons.Count; + var betaPeptideSpectralMatchAnnotationCount = psm.BetaPeptideMatchedIons.Count; + var csmPlotIonAnnotationCount = alphaPeptideSpectralMatchAnnotationCount + betaPeptideSpectralMatchAnnotationCount; + metaDrawLogic.DisplaySpectrumMatch(plotView, psm, parentChildView, out errors); + Assert.That(plotView.Model.Annotations.Count, Is.EqualTo(csmPlotIonAnnotationCount + 1)); // Plus One for the annotation text describing the csm + + var scan = MsDataFileReader.GetDataFile(dataFilePath).LoadAllStaticData().GetOneBasedScan(oldScanNum); + var csmPlot = new CrosslinkSpectrumMatchPlot(plotView, psm, scan, stationaryCanvas, false); + Assert.That(csmPlot.Model.Annotations.Count, Is.EqualTo(csmPlotIonAnnotationCount)); + + // test each export type + foreach (var exportType in MetaDrawSettings.ExportTypes) + { + MetaDrawSettings.ExportType = exportType; + metaDrawLogic.ExportPlot(plotView, canvas, new List() { psm }, parentChildView, + outputFolderPath, out errors); + + Assert.That(File.Exists(Path.Combine(outputFolderPath, @$"{psm.Ms2ScanNumber}_{psm.FullSequence}{psm.BetaPeptideBaseSequence}.{exportType}"))); + } + + // clean up resources + metaDrawLogic.CleanUpSpectraFiles(); + Assert.That(!metaDrawLogic.SpectraFilePaths.Any()); + + metaDrawLogic.CleanUpPSMFiles(); + Assert.That(!metaDrawLogic.FilteredListOfPsms.Any()); + Assert.That(!metaDrawLogic.PsmResultFilePaths.Any()); + + // delete output + Directory.Delete(outputFolderPath, true); + } } } From 322235dde068f7f86e6cc8ccf5c15ab518578640 Mon Sep 17 00:00:00 2001 From: Nic Bollis Date: Tue, 23 Jul 2024 12:25:21 -0500 Subject: [PATCH 04/13] Spectral Library from Command Line (#2386) * Updated to MzLib 1.0.548 and fixed custom ions in search tasks * reverted calibration task change * merged in master bbbyy * Enabled Library Loading from command line --- MetaMorpheus/CMD/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MetaMorpheus/CMD/Program.cs b/MetaMorpheus/CMD/Program.cs index d328e44e1..c4f1a7640 100644 --- a/MetaMorpheus/CMD/Program.cs +++ b/MetaMorpheus/CMD/Program.cs @@ -178,7 +178,7 @@ private static int Run(CommandLineSettings settings) foreach (var db in settings.Databases) { - if (!Path.GetExtension(db).Equals(".fasta")) + if (Path.GetExtension(db).Equals(".xml")) { GlobalVariables.AddMods(UsefulProteomicsDatabases.ProteinDbLoader.GetPtmListFromProteinXml(db).OfType(), true); From 57c4e695b50da12d4013f80d05dc59158fdef644 Mon Sep 17 00:00:00 2001 From: Nic Bollis Date: Sat, 26 Oct 2024 12:36:59 -0500 Subject: [PATCH 05/13] Build ClassicDeconv Params View Model --- .../ClassicDeconParamsViewModel.cs | 42 +++++++++++++++++ .../Deconvolution/DeconParamsViewModel.cs | 46 +++++++++++++++++++ .../IsoDecDeconParamsViewModel.cs | 14 ++++++ MetaMorpheus/MetaMorpheus.sln.DotSettings | 1 + 4 files changed, 103 insertions(+) create mode 100644 MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/ClassicDeconParamsViewModel.cs create mode 100644 MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs create mode 100644 MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs diff --git a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/ClassicDeconParamsViewModel.cs b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/ClassicDeconParamsViewModel.cs new file mode 100644 index 000000000..06f6412cc --- /dev/null +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/ClassicDeconParamsViewModel.cs @@ -0,0 +1,42 @@ +using MassSpectrometry; + +namespace GuiFunctions; + +public class ClassicDeconParamsViewModel : DeconParamsViewModel +{ + private ClassicDeconvolutionParameters _parameters; + public override DeconvolutionParameters Parameters + { + get => _parameters; + protected set + { + _parameters = (ClassicDeconvolutionParameters)value; + OnPropertyChanged(nameof(Parameters)); + } + } + + public ClassicDeconParamsViewModel(ClassicDeconvolutionParameters parameters) + { + _parameters = parameters; + } + + public double DeconvolutionTolerancePpm + { + get => _parameters.DeconvolutionTolerancePpm; + set + { + _parameters.DeconvolutionTolerancePpm = value; + OnPropertyChanged(nameof(DeconvolutionTolerancePpm)); + } + } + + public double IntensityRatioLimit + { + get => _parameters.IntensityRatioLimit; + set + { + _parameters.IntensityRatioLimit = value; + OnPropertyChanged(nameof(IntensityRatioLimit)); + } + } +} \ No newline at end of file diff --git a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs new file mode 100644 index 000000000..a78099862 --- /dev/null +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MassSpectrometry; + +namespace GuiFunctions +{ + public abstract class DeconParamsViewModel : BaseViewModel + { + public DeconvolutionType DeconvolutionType => Parameters.DeconvolutionType; + public abstract DeconvolutionParameters Parameters { get; protected set; } + + + public int MinAssumedChargeState + { + get => Parameters.MinAssumedChargeState; + set + { + Parameters.MinAssumedChargeState = value; + OnPropertyChanged(nameof(MinAssumedChargeState)); + } + } + + public int MaxAssumedChargeState + { + get => Parameters.MaxAssumedChargeState; + set + { + Parameters.MaxAssumedChargeState = value; + OnPropertyChanged(nameof(MaxAssumedChargeState)); + } + } + + public Polarity Polarity + { + get => Parameters.Polarity; + set + { + Parameters.Polarity = value; + OnPropertyChanged(nameof(Polarity)); + } + } + } +} diff --git a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs new file mode 100644 index 000000000..11926d387 --- /dev/null +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MassSpectrometry; + +namespace GuiFunctions +{ + public class IsoDecDeconParamsViewModel : DeconParamsViewModel + { + public override DeconvolutionParameters Parameters { get; protected set; } + } +} diff --git a/MetaMorpheus/MetaMorpheus.sln.DotSettings b/MetaMorpheus/MetaMorpheus.sln.DotSettings index 3cb2a8c2a..fd93edf0a 100644 --- a/MetaMorpheus/MetaMorpheus.sln.DotSettings +++ b/MetaMorpheus/MetaMorpheus.sln.DotSettings @@ -6,6 +6,7 @@ True True True + True True True True From 0cef4fcce2126fcdb1cdf47c7bec4b82b913dcd9 Mon Sep 17 00:00:00 2001 From: Nic Bollis Date: Sat, 26 Oct 2024 13:59:58 -0500 Subject: [PATCH 06/13] Built classic deconvolution control and the Deconvolution Host Control --- .../ClassicDeconParamsControl.xaml | 24 ++++ .../ClassicDeconParamsControl.xaml.cs | 28 ++++ .../Deconvolution/HostDeconParamControl.xaml | 78 ++++++++++++ .../HostDeconParamControl.xaml.cs | 28 ++++ MetaMorpheus/GuiFunctions/MzLibExtensions.cs | 37 ++++++ .../ClassicDeconParamsViewModel.cs | 2 +- .../Deconvolution/DeconHostViewModel.cs | 120 ++++++++++++++++++ .../Deconvolution/DeconParamsViewModel.cs | 75 ++++++----- .../IsoDecDeconParamsViewModel.cs | 2 +- MetaMorpheus/MetaMorpheus.sln.DotSettings | 1 + 10 files changed, 362 insertions(+), 33 deletions(-) create mode 100644 MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml create mode 100644 MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml.cs create mode 100644 MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml create mode 100644 MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml.cs create mode 100644 MetaMorpheus/GuiFunctions/MzLibExtensions.cs create mode 100644 MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconHostViewModel.cs diff --git a/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml b/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml new file mode 100644 index 000000000..6ac579fc4 --- /dev/null +++ b/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml @@ -0,0 +1,24 @@ + + + + + + + diff --git a/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml.cs b/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml.cs new file mode 100644 index 000000000..ddd016932 --- /dev/null +++ b/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace MetaMorpheusGUI +{ + /// + /// Interaction logic for ClassicDeconParamsControl.xaml + /// + public partial class ClassicDeconParamsControl : UserControl + { + public ClassicDeconParamsControl() + { + InitializeComponent(); + } + } +} diff --git a/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml b/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml new file mode 100644 index 000000000..2203692ce --- /dev/null +++ b/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Use the charge states and precursor masses determined by the instrument controller. + + + + + + + + + + + Additionally searches for coisolated peptides, allowing for multiple peptides to be identified from a single MS2. + + + + + + + + + + + + The type of deconvolution to perform. + + + + + + + + + + + diff --git a/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml.cs b/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml.cs new file mode 100644 index 000000000..69c66a81a --- /dev/null +++ b/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace MetaMorpheusGUI +{ + /// + /// Interaction logic for HostDeconParamControl.xaml + /// + public partial class HostDeconParamControl : UserControl + { + public HostDeconParamControl() + { + InitializeComponent(); + } + } +} diff --git a/MetaMorpheus/GuiFunctions/MzLibExtensions.cs b/MetaMorpheus/GuiFunctions/MzLibExtensions.cs new file mode 100644 index 000000000..2883750f0 --- /dev/null +++ b/MetaMorpheus/GuiFunctions/MzLibExtensions.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MassSpectrometry; + +namespace GuiFunctions +{ + public static class MzLibExtensions + { + + /// + /// Converts the given to a . + /// + /// The deconvolution parameters to convert. + /// A representing the given parameters. + /// + /// Thrown when the type of is not supported. + /// + public static DeconParamsViewModel ToViewModel(this DeconvolutionParameters parameters) + { + if (parameters is ClassicDeconvolutionParameters classicParams) + { + return new ClassicDeconParamsViewModel(classicParams); + } + //else if (parameters is IsoDeconvolutionParameters isoParams) + //{ + // return new IsoDecDeconParamsViewModel(isoParams); + //} + else + { + throw new NotImplementedException(); + } + } + } +} diff --git a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/ClassicDeconParamsViewModel.cs b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/ClassicDeconParamsViewModel.cs index 06f6412cc..77fa830ff 100644 --- a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/ClassicDeconParamsViewModel.cs +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/ClassicDeconParamsViewModel.cs @@ -2,7 +2,7 @@ namespace GuiFunctions; -public class ClassicDeconParamsViewModel : DeconParamsViewModel +public sealed class ClassicDeconParamsViewModel : DeconParamsViewModel { private ClassicDeconvolutionParameters _parameters; public override DeconvolutionParameters Parameters diff --git a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconHostViewModel.cs b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconHostViewModel.cs new file mode 100644 index 000000000..37e29aa30 --- /dev/null +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconHostViewModel.cs @@ -0,0 +1,120 @@ +#nullable enable +using System; +using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; +using EngineLayer; +using MassSpectrometry; + +namespace GuiFunctions; + +public class DeconHostViewModel : BaseViewModel +{ + + public DeconHostViewModel(DeconvolutionParameters? initialPrecursorParameters = null, DeconvolutionParameters? initialFragmentParameters = null, + bool useProvidedPrecursor = false, bool deconvolutePrecursors = true) + { + // Always the same + DeconvolutionTypes = new ObservableCollection + { + DeconvolutionType.ClassicDeconvolution + }; + + // Parameter Dependent + UseProvidedPrecursors = useProvidedPrecursor; + DoPrecursorDeconvolution = deconvolutePrecursors; + + initialPrecursorParameters ??= GlobalVariables.AnalyteType switch + { + "Peptide" => new ClassicDeconvolutionParameters(1, 12, 4, 3), + "Proteoform" => new ClassicDeconvolutionParameters(1, 60, 4, 3), + "Oligo" => new ClassicDeconvolutionParameters(-20, -1, 4, 3), + _ => throw new ArgumentOutOfRangeException() + }; + PrecursorDeconvolutionParameters = initialPrecursorParameters.ToViewModel(); + + initialFragmentParameters ??= GlobalVariables.AnalyteType switch + { + "Peptide" => new ClassicDeconvolutionParameters(1, 12, 4, 3), + "Proteoform" => new ClassicDeconvolutionParameters(1, 60, 4, 3), + "Oligo" => new ClassicDeconvolutionParameters(-20, -1, 4, 3), + _ => throw new ArgumentOutOfRangeException() + }; + ProductDeconvolutionParameters = initialFragmentParameters.ToViewModel(); + } + + #region Common Parameters + + private bool _useProvidedPrecursors; + public bool UseProvidedPrecursors + { + get => _useProvidedPrecursors; + set + { + _useProvidedPrecursors = value; + OnPropertyChanged(nameof(UseProvidedPrecursors)); + } + } + + private bool _doPrecursorDeconvolution; + public bool DoPrecursorDeconvolution + { + get => _doPrecursorDeconvolution; + set + { + _doPrecursorDeconvolution = value; + OnPropertyChanged(nameof(DoPrecursorDeconvolution)); + } + } + + #endregion + + public ObservableCollection DeconvolutionTypes { get; private set; } + + private DeconvolutionType _selectedDeconvolutionType; + public DeconvolutionType SelectedDeconvolutionType + { + get => _selectedDeconvolutionType; + set + { + _selectedDeconvolutionType = value; + OnPropertyChanged(nameof(SelectedDeconvolutionType)); + } + } + + + private DeconParamsViewModel _precursorDeconvolutionParameters; + public DeconParamsViewModel PrecursorDeconvolutionParameters + { + get => _precursorDeconvolutionParameters; + set + { + _precursorDeconvolutionParameters = value; + OnPropertyChanged(nameof(PrecursorDeconvolutionParameters)); + } + } + + private DeconParamsViewModel _productDeconvolutionParameters; + public DeconParamsViewModel ProductDeconvolutionParameters + { + get => _productDeconvolutionParameters; + set + { + _productDeconvolutionParameters = value; + OnPropertyChanged(nameof(ProductDeconvolutionParameters)); + } + } +} + + + +[ExcludeFromCodeCoverage] // Model used only for visualizing the view +public class DeconHostModel : DeconHostViewModel +{ + public static DeconHostModel Instance => new DeconHostModel(); + + public DeconHostModel() : base (DeconParamsModel.Instance.Parameters, DeconParamsModel.Instance.Parameters) + { + UseProvidedPrecursors = false; + DoPrecursorDeconvolution = true; + } +} \ No newline at end of file diff --git a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs index a78099862..c836f0e6d 100644 --- a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs @@ -1,46 +1,59 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Diagnostics.CodeAnalysis; using MassSpectrometry; -namespace GuiFunctions +namespace GuiFunctions; + +public abstract class DeconParamsViewModel : BaseViewModel { - public abstract class DeconParamsViewModel : BaseViewModel - { - public DeconvolutionType DeconvolutionType => Parameters.DeconvolutionType; - public abstract DeconvolutionParameters Parameters { get; protected set; } + public DeconvolutionType DeconvolutionType => Parameters.DeconvolutionType; + public abstract DeconvolutionParameters Parameters { get; protected set; } + #region Wrapped Deconvolution Parameters - public int MinAssumedChargeState + public int MinAssumedChargeState + { + get => Parameters.MinAssumedChargeState; + set { - get => Parameters.MinAssumedChargeState; - set - { - Parameters.MinAssumedChargeState = value; - OnPropertyChanged(nameof(MinAssumedChargeState)); - } + Parameters.MinAssumedChargeState = value; + OnPropertyChanged(nameof(MinAssumedChargeState)); } + } - public int MaxAssumedChargeState + public int MaxAssumedChargeState + { + get => Parameters.MaxAssumedChargeState; + set { - get => Parameters.MaxAssumedChargeState; - set - { - Parameters.MaxAssumedChargeState = value; - OnPropertyChanged(nameof(MaxAssumedChargeState)); - } + Parameters.MaxAssumedChargeState = value; + OnPropertyChanged(nameof(MaxAssumedChargeState)); } + } - public Polarity Polarity + public Polarity Polarity + { + get => Parameters.Polarity; + set { - get => Parameters.Polarity; - set - { - Parameters.Polarity = value; - OnPropertyChanged(nameof(Polarity)); - } + Parameters.Polarity = value; + OnPropertyChanged(nameof(Polarity)); } } + + #endregion + } + + +[ExcludeFromCodeCoverage] // Model used only for visualizing the view +public class DeconParamsModel : DeconParamsViewModel +{ + public static DeconParamsModel Instance => new DeconParamsModel(); + + public sealed override DeconvolutionParameters Parameters { get; protected set; } + + public DeconParamsModel() + { + Parameters = new ClassicDeconvolutionParameters(1, 20, 5, 3, Polarity.Negative); + } +} \ No newline at end of file diff --git a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs index 11926d387..81472ed8d 100644 --- a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs @@ -7,7 +7,7 @@ namespace GuiFunctions { - public class IsoDecDeconParamsViewModel : DeconParamsViewModel + public sealed class IsoDecDeconParamsViewModel : DeconParamsViewModel { public override DeconvolutionParameters Parameters { get; protected set; } } diff --git a/MetaMorpheus/MetaMorpheus.sln.DotSettings b/MetaMorpheus/MetaMorpheus.sln.DotSettings index fd93edf0a..e9ee1d4cf 100644 --- a/MetaMorpheus/MetaMorpheus.sln.DotSettings +++ b/MetaMorpheus/MetaMorpheus.sln.DotSettings @@ -7,6 +7,7 @@ True True True + True True True True From 2a73a02a707dd3d6362dfd96d271305a93f523c2 Mon Sep 17 00:00:00 2001 From: Nic Bollis Date: Sat, 26 Oct 2024 14:00:19 -0500 Subject: [PATCH 07/13] Refactor deconvolution param management with ViewModel Streamlined deconvolution parameter management by introducing `DeconHostViewModel` and custom control `HostDeconParamControl`. Updated `CommonParameters.cs` to change default `ProductDeconvolutionParameters` in negative mode from `-10` to `-20`. Modified `SearchTaskWindow.xaml` and `SearchTaskWindow.xaml.cs` to use the new view model, improving separation of concerns and maintainability. Updated `SaveButton_Click` and other relevant methods to retrieve parameters via the view model. --- MetaMorpheus/EngineLayer/CommonParameters.cs | 2 +- .../GUI/TaskWindows/SearchTaskWindow.xaml | 34 +---------------- .../GUI/TaskWindows/SearchTaskWindow.xaml.cs | 38 ++++++++++++++----- 3 files changed, 30 insertions(+), 44 deletions(-) diff --git a/MetaMorpheus/EngineLayer/CommonParameters.cs b/MetaMorpheus/EngineLayer/CommonParameters.cs index f95d6cb12..27c4323ca 100644 --- a/MetaMorpheus/EngineLayer/CommonParameters.cs +++ b/MetaMorpheus/EngineLayer/CommonParameters.cs @@ -114,7 +114,7 @@ public CommonParameters( { PrecursorDeconvolutionParameters = precursorDeconParams ?? new ClassicDeconvolutionParameters(deconvolutionMaxAssumedChargeState, -1, DeconvolutionMassTolerance.Value, deconvolutionIntensityRatio, Polarity.Negative); - ProductDeconvolutionParameters = productDeconParams ?? new ClassicDeconvolutionParameters(-10, + ProductDeconvolutionParameters = productDeconParams ?? new ClassicDeconvolutionParameters(-20, -1, DeconvolutionMassTolerance.Value, deconvolutionIntensityRatio, Polarity.Negative); } } diff --git a/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml b/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml index 9f3205c57..aad380db5 100644 --- a/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml +++ b/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml @@ -661,39 +661,7 @@ - - - - - - Use the charge states and precursor masses determined by the instrument controller. - - - - - - - - - - - Additionally searches for coisolated peptides, allowing for multiple peptides to be identified from a single MS2. - - - - - - - - + diff --git a/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml.cs b/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml.cs index 678e1392c..447a93440 100644 --- a/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml.cs +++ b/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml.cs @@ -39,6 +39,7 @@ public partial class SearchTaskWindow : Window private bool AutomaticallyAskAndOrUpdateParametersBasedOnProtease = true; private CustomFragmentationWindow CustomFragmentationWindow; private string _defaultMultiplexType = "TMT10"; + private DeconHostViewModel DeconHostViewModel; internal SearchTask TheTask { get; private set; } @@ -51,6 +52,7 @@ public SearchTaskWindow(SearchTask task) PopulateChoices(); UpdateFieldsFromTask(TheTask); AutomaticallyAskAndOrUpdateParametersBasedOnProtease = true; + DeisotopingControl.DataContext = DeconHostViewModel; if (task == null) { @@ -291,18 +293,23 @@ private void UpdateFieldsFromTask(SearchTask task) PrecursorMassToleranceComboBox.SelectedIndex = task.CommonParameters.PrecursorMassTolerance is AbsoluteTolerance ? 0 : 1; AddCompIonCheckBox.IsChecked = task.CommonParameters.AddCompIons; NumberOfDatabaseSearchesTextBox.Text = task.CommonParameters.TotalPartitions.ToString(CultureInfo.InvariantCulture); - DeconvolutePrecursors.IsChecked = task.CommonParameters.DoPrecursorDeconvolution; - UseProvidedPrecursor.IsChecked = task.CommonParameters.UseProvidedPrecursorInfo; RemoveContaminantRadioBox.IsChecked = task.SearchParameters.TCAmbiguity == TargetContaminantAmbiguity.RemoveContaminant; RemoveTargetRadioBox.IsChecked = task.SearchParameters.TCAmbiguity == TargetContaminantAmbiguity.RemoveTarget; RenameTCProteinsRadioBox.IsChecked = task.SearchParameters.TCAmbiguity == TargetContaminantAmbiguity.RenameProtein; AllAmbiguity.IsChecked = task.CommonParameters.ReportAllAmbiguity; - DeconvolutionMaxAssumedChargeStateTextBox.Text = task.CommonParameters.DeconvolutionMaxAssumedChargeState.ToString(); MinScoreAllowed.Text = task.CommonParameters.ScoreCutoff.ToString(CultureInfo.InvariantCulture); TrimMs1.IsChecked = task.CommonParameters.TrimMs1Peaks; TrimMsMs.IsChecked = task.CommonParameters.TrimMsMsPeaks; AddTruncationsCheckBox.IsChecked = task.CommonParameters.AddTruncations; + + DeconHostViewModel = new DeconHostViewModel(TheTask.CommonParameters.PrecursorDeconvolutionParameters, + TheTask.CommonParameters.ProductDeconvolutionParameters, + TheTask.CommonParameters.UseProvidedPrecursorInfo, TheTask.CommonParameters.DoPrecursorDeconvolution); + //DeconvolutePrecursors.IsChecked = task.CommonParameters.DoPrecursorDeconvolution; + //UseProvidedPrecursor.IsChecked = task.CommonParameters.UseProvidedPrecursorInfo; + //DeconvolutionMaxAssumedChargeStateTextBox.Text = task.CommonParameters.DeconvolutionMaxAssumedChargeState.ToString(); + NumberOfPeaksToKeepPerWindowTextBox.Text = task.CommonParameters.NumberOfPeaksToKeepPerWindow == int.MaxValue || !task.CommonParameters.NumberOfPeaksToKeepPerWindow.HasValue ? "" : task.CommonParameters.NumberOfPeaksToKeepPerWindow.Value.ToString(CultureInfo.InvariantCulture); MinimumAllowedIntensityRatioToBasePeakTexBox.Text = task.CommonParameters.MinimumAllowedIntensityRatioToBasePeak == double.MaxValue || !task.CommonParameters.MinimumAllowedIntensityRatioToBasePeak.HasValue ? "" : task.CommonParameters.MinimumAllowedIntensityRatioToBasePeak.Value.ToString(CultureInfo.InvariantCulture); WindowWidthThomsonsTextBox.Text = task.CommonParameters.WindowWidthThomsons == double.MaxValue || !task.CommonParameters.WindowWidthThomsons.HasValue ? "" : task.CommonParameters.WindowWidthThomsons.Value.ToString(CultureInfo.InvariantCulture); @@ -431,6 +438,7 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) CleavageSpecificity searchModeType = GetSearchModeType(); //change search type to semi or non if selected SnesUpdates(searchModeType); //decide on singleN/C, make comp ion changes + // TODO: Reconcile Isodec params with Mass difference acceptor if (!GlobalGuiSettings.CheckTaskSettingsValidity( PrecursorMassToleranceTextBox.Text, ProductMassToleranceTextBox.Text, @@ -442,7 +450,7 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) MinScoreAllowed.Text, PeakFindingToleranceTextBox.Text, HistogramBinWidthTextBox.Text, - DeconvolutionMaxAssumedChargeStateTextBox.Text, + DeconHostViewModel.PrecursorDeconvolutionParameters.MaxAssumedChargeState.ToString(), NumberOfPeaksToKeepPerWindowTextBox.Text, MinimumAllowedIntensityRatioToBasePeakTexBox.Text, WindowWidthThomsonsTextBox.Text, @@ -573,14 +581,22 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) bool parseMaxThreadsPerFile = !MaxThreadsTextBox.Text.Equals("") && (int.Parse(MaxThreadsTextBox.Text) <= Environment.ProcessorCount && int.Parse(MaxThreadsTextBox.Text) > 0); + + DeconvolutionParameters precursorDeconvolutionParameters = DeconHostViewModel.PrecursorDeconvolutionParameters.Parameters; + DeconvolutionParameters productDeconvolutionParameters = DeconHostViewModel.ProductDeconvolutionParameters.Parameters; + bool useProvidedPrecursorInfo = DeconHostViewModel.UseProvidedPrecursors; + bool doPrecursorDeconvolution = DeconHostViewModel.DoPrecursorDeconvolution; + + + CommonParameters commonParamsToSave = new CommonParameters( taskDescriptor: OutputFileNameTextBox.Text != "" ? OutputFileNameTextBox.Text : "SearchTask", maxThreadsToUsePerFile: parseMaxThreadsPerFile ? int.Parse(MaxThreadsTextBox.Text, CultureInfo.InvariantCulture) : new CommonParameters().MaxThreadsToUsePerFile, reportAllAmbiguity: AllAmbiguity.IsChecked.Value, - deconvolutionMaxAssumedChargeState: int.Parse(DeconvolutionMaxAssumedChargeStateTextBox.Text, CultureInfo.InvariantCulture), + //deconvolutionMaxAssumedChargeState: int.Parse(DeconvolutionMaxAssumedChargeStateTextBox.Text, CultureInfo.InvariantCulture), totalPartitions: int.Parse(NumberOfDatabaseSearchesTextBox.Text, CultureInfo.InvariantCulture), - doPrecursorDeconvolution: DeconvolutePrecursors.IsChecked.Value, - useProvidedPrecursorInfo: UseProvidedPrecursor.IsChecked.Value, + doPrecursorDeconvolution: doPrecursorDeconvolution, + useProvidedPrecursorInfo: useProvidedPrecursorInfo, qValueThreshold: !PepQValueThresholdCheckbox.IsChecked.Value ? double.Parse(QValueThresholdTextBox.Text, CultureInfo.InvariantCulture) : 1.0, pepQValueThreshold: PepQValueThresholdCheckbox.IsChecked.Value ? double.Parse(PepQValueThresholdTextBox.Text, CultureInfo.InvariantCulture) : 1.0, scoreCutoff: double.Parse(MinScoreAllowed.Text, CultureInfo.InvariantCulture), @@ -602,7 +618,9 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) addCompIons: AddCompIonCheckBox.IsChecked.Value, assumeOrphanPeaksAreZ1Fragments: protease.Name != "top-down", minVariantDepth: MinVariantDepth, - maxHeterozygousVariants: MaxHeterozygousVariants); + maxHeterozygousVariants: MaxHeterozygousVariants, + precursorDeconParams: precursorDeconvolutionParameters, + productDeconParams: productDeconvolutionParameters); if (ClassicSearchRadioButton.IsChecked.Value) { @@ -886,8 +904,8 @@ private void ProteaseSpecificUpdate(object sender, SelectionChangedEventArgs e) case "top-down": if (UpdateGUISettings.UseTopDownRecommendedSettings()) { - UseProvidedPrecursor.IsChecked = false; - DeconvolutionMaxAssumedChargeStateTextBox.Text = "60"; + DeconHostViewModel.DoPrecursorDeconvolution = true; + DeconHostViewModel.PrecursorDeconvolutionParameters.MaxAssumedChargeState = 60; TrimMsMs.IsChecked = false; CheckBoxNoQuant.IsChecked = true; MassDiffAccept3mm.IsChecked = true; From 1735439c1c58cff5a6434b5daddfcab897df474b Mon Sep 17 00:00:00 2001 From: Nic Bollis Date: Sat, 26 Oct 2024 17:07:30 -0500 Subject: [PATCH 08/13] Completed the first phase of the new structure. Parameters can now be set from the GUI with the new code structure --- MetaMorpheus/EngineLayer/CommonParameters.cs | 2 +- .../DeconvolutionTypeToControlConverter.cs | 33 ++++ .../ClassicDeconParamsControl.xaml | 2 +- .../Deconvolution/HostDeconParamControl.xaml | 24 ++- .../HostDeconParamControl.xaml.cs | 15 +- .../ClassicDeconParamsViewModel.cs | 2 + .../Deconvolution/DeconHostViewModel.cs | 150 +++++++++++++----- .../Deconvolution/DeconParamsViewModel.cs | 32 +++- .../IsoDecDeconParamsViewModel.cs | 3 + 9 files changed, 200 insertions(+), 63 deletions(-) create mode 100644 MetaMorpheus/GUI/Util/Converters/DeconvolutionTypeToControlConverter.cs diff --git a/MetaMorpheus/EngineLayer/CommonParameters.cs b/MetaMorpheus/EngineLayer/CommonParameters.cs index 27c4323ca..f95d6cb12 100644 --- a/MetaMorpheus/EngineLayer/CommonParameters.cs +++ b/MetaMorpheus/EngineLayer/CommonParameters.cs @@ -114,7 +114,7 @@ public CommonParameters( { PrecursorDeconvolutionParameters = precursorDeconParams ?? new ClassicDeconvolutionParameters(deconvolutionMaxAssumedChargeState, -1, DeconvolutionMassTolerance.Value, deconvolutionIntensityRatio, Polarity.Negative); - ProductDeconvolutionParameters = productDeconParams ?? new ClassicDeconvolutionParameters(-20, + ProductDeconvolutionParameters = productDeconParams ?? new ClassicDeconvolutionParameters(-10, -1, DeconvolutionMassTolerance.Value, deconvolutionIntensityRatio, Polarity.Negative); } } diff --git a/MetaMorpheus/GUI/Util/Converters/DeconvolutionTypeToControlConverter.cs b/MetaMorpheus/GUI/Util/Converters/DeconvolutionTypeToControlConverter.cs new file mode 100644 index 000000000..599d82645 --- /dev/null +++ b/MetaMorpheus/GUI/Util/Converters/DeconvolutionTypeToControlConverter.cs @@ -0,0 +1,33 @@ +using System; +using System.Globalization; +using GuiFunctions; +using MassSpectrometry; + +namespace MetaMorpheusGUI +{ + public class DeconvolutionTypeToControlConverter : BaseValueConverter + { + public override object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + // Assuming value is of an enum type DeconvolutionType + if (value is DeconParamsViewModel viewModel) + { + switch (viewModel.DeconvolutionType) + { + case DeconvolutionType.ClassicDeconvolution: + return new ClassicDeconParamsControl() { DataContext = value as ClassicDeconParamsViewModel }; + + case DeconvolutionType.ExampleNewDeconvolutionTemplate: + default: + throw new ArgumentException("Invalid DeconvolutionType", nameof(value)); + } + } + throw new ArgumentException("Invalid value type", nameof(value)); + } + + public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml b/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml index 6ac579fc4..679967de5 100644 --- a/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml +++ b/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml @@ -15,7 +15,7 @@ Text="{Binding MaxAssumedChargeState}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"> - The maximum charge state that deconvolution should allow. Minimum is 1. + The maximum charge state that deconvolution should allow. Minimum is 1 for positive mode. diff --git a/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml b/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml index 2203692ce..7c7db0761 100644 --- a/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml +++ b/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml @@ -8,9 +8,12 @@ mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600"> + + + + - - + @@ -60,7 +63,7 @@ @@ -71,7 +74,20 @@ - + + + + + + + + + + + diff --git a/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml.cs b/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml.cs index 69c66a81a..3c4c7f862 100644 --- a/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml.cs +++ b/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml.cs @@ -1,17 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; +using System.Windows.Controls; namespace MetaMorpheusGUI { diff --git a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/ClassicDeconParamsViewModel.cs b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/ClassicDeconParamsViewModel.cs index 77fa830ff..1cb0b7358 100644 --- a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/ClassicDeconParamsViewModel.cs +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/ClassicDeconParamsViewModel.cs @@ -39,4 +39,6 @@ public double IntensityRatioLimit OnPropertyChanged(nameof(IntensityRatioLimit)); } } + + public override string ToString() => "Classic"; } \ No newline at end of file diff --git a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconHostViewModel.cs b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconHostViewModel.cs index 37e29aa30..f4d0f1644 100644 --- a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconHostViewModel.cs +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconHostViewModel.cs @@ -2,44 +2,101 @@ using System; using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; +using System.Linq; +using Easy.Common.Extensions; using EngineLayer; using MassSpectrometry; namespace GuiFunctions; +/// +/// This class holds all of the information in the Deconvolution tab of the GUI +/// One instance will be create per Task Window +/// +/// The Task window will populate this view model with the appropriate parameters from +/// The user can then modify these parameters as needed via the gui +/// The Task window will use the PrecursorDeconvolutionParameters and teh ProductDeconvolutionParameters to create a new object +/// public class DeconHostViewModel : BaseViewModel { - public DeconHostViewModel(DeconvolutionParameters? initialPrecursorParameters = null, DeconvolutionParameters? initialFragmentParameters = null, + /// + /// + /// + /// This is where default deconvolution parameters are set for GUI display + /// + /// + /// + /// + /// + /// + public DeconHostViewModel(DeconvolutionParameters? initialPrecursorParameters = null, DeconvolutionParameters? initialProductParameters = null, bool useProvidedPrecursor = false, bool deconvolutePrecursors = true) { - // Always the same - DeconvolutionTypes = new ObservableCollection - { - DeconvolutionType.ClassicDeconvolution - }; - // Parameter Dependent UseProvidedPrecursors = useProvidedPrecursor; DoPrecursorDeconvolution = deconvolutePrecursors; - initialPrecursorParameters ??= GlobalVariables.AnalyteType switch - { - "Peptide" => new ClassicDeconvolutionParameters(1, 12, 4, 3), - "Proteoform" => new ClassicDeconvolutionParameters(1, 60, 4, 3), - "Oligo" => new ClassicDeconvolutionParameters(-20, -1, 4, 3), - _ => throw new ArgumentOutOfRangeException() - }; - PrecursorDeconvolutionParameters = initialPrecursorParameters.ToViewModel(); - - initialFragmentParameters ??= GlobalVariables.AnalyteType switch + // Order matters here, construct the lists before setting the selected parameters + PrecursorDeconvolutionParametersList = new ObservableCollection(); + ProductDeconvolutionParametersList = new ObservableCollection(); + + + + // populate the lists by adding the default parameters for each deconvolution type or the provided parameters + foreach (var deconType in Enum.GetValues()) { - "Peptide" => new ClassicDeconvolutionParameters(1, 12, 4, 3), - "Proteoform" => new ClassicDeconvolutionParameters(1, 60, 4, 3), - "Oligo" => new ClassicDeconvolutionParameters(-20, -1, 4, 3), - _ => throw new ArgumentOutOfRangeException() - }; - ProductDeconvolutionParameters = initialFragmentParameters.ToViewModel(); + switch (deconType) + { + case DeconvolutionType.ExampleNewDeconvolutionTemplate: + continue; + + case DeconvolutionType.ClassicDeconvolution: + + if (initialPrecursorParameters is { DeconvolutionType: DeconvolutionType.ClassicDeconvolution }) + PrecursorDeconvolutionParametersList.Add(initialPrecursorParameters.ToViewModel()); + else + { + var toAdd = GlobalVariables.AnalyteType switch + { + "Peptide" => new ClassicDeconvolutionParameters(1, 12, 4, 3), + "Proteoform" => new ClassicDeconvolutionParameters(1, 60, 4, 3), + "Oligo" => new ClassicDeconvolutionParameters(-20, -1, 4, 3), + _ => throw new ArgumentOutOfRangeException() + }; + PrecursorDeconvolutionParametersList.Add(toAdd.ToViewModel()); + } + + if (initialProductParameters is { DeconvolutionType: DeconvolutionType.ClassicDeconvolution }) + ProductDeconvolutionParametersList.Add(initialProductParameters.ToViewModel()); + else + { + var toAdd = GlobalVariables.AnalyteType switch + { + "Peptide" => new ClassicDeconvolutionParameters(1, 10, 4, 3), + "Proteoform" => new ClassicDeconvolutionParameters(1, 10, 4, 3), + "Oligo" => new ClassicDeconvolutionParameters(-10, -1, 4, 3), + _ => throw new ArgumentOutOfRangeException() + }; + ProductDeconvolutionParametersList.Add(toAdd.ToViewModel()); + } + + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + // If deconvolution parameters are not set, default to MetaMorpheus defaults + if (initialPrecursorParameters is null) + PrecursorDeconvolutionParameters = PrecursorDeconvolutionParametersList.First(); + else + PrecursorDeconvolutionParameters = PrecursorDeconvolutionParametersList.First(x => x.Parameters == initialPrecursorParameters); + + if (initialProductParameters is null) + ProductDeconvolutionParameters = ProductDeconvolutionParametersList.First(); + else + ProductDeconvolutionParameters = ProductDeconvolutionParametersList.First(x => x.Parameters == initialProductParameters); } #region Common Parameters @@ -68,24 +125,22 @@ public bool DoPrecursorDeconvolution #endregion - public ObservableCollection DeconvolutionTypes { get; private set; } - - private DeconvolutionType _selectedDeconvolutionType; - public DeconvolutionType SelectedDeconvolutionType - { - get => _selectedDeconvolutionType; - set - { - _selectedDeconvolutionType = value; - OnPropertyChanged(nameof(SelectedDeconvolutionType)); - } - } - - - private DeconParamsViewModel _precursorDeconvolutionParameters; + /// + /// All of the possible precursor deconvolution parameters that can be selected + /// + /// Their ToString() method sets the name of the combo box + /// Stored in memory while task window is open, only the selected one is used for + /// This enables the user to set parameters, switch to another, and switch back without losing their settings + /// + public ObservableCollection PrecursorDeconvolutionParametersList { get; protected set; } + private DeconParamsViewModel? _precursorDeconvolutionParameters; + + /// + /// The selected precursor deconvolution parameters + /// public DeconParamsViewModel PrecursorDeconvolutionParameters { - get => _precursorDeconvolutionParameters; + get => _precursorDeconvolutionParameters!; set { _precursorDeconvolutionParameters = value; @@ -93,10 +148,23 @@ public DeconParamsViewModel PrecursorDeconvolutionParameters } } - private DeconParamsViewModel _productDeconvolutionParameters; + + /// + /// All of the possible product deconvolution parameters that can be selected + /// + /// Their ToString() method sets the name of the combo box + /// Stored in memory while task window is open, only the selected one is used for + /// This enables the user to set parameters, switch to another, and switch back without losing their settings + /// + public ObservableCollection ProductDeconvolutionParametersList { get; protected set; } + private DeconParamsViewModel? _productDeconvolutionParameters; + + /// + /// The selected product deconvolution parameters + /// public DeconParamsViewModel ProductDeconvolutionParameters { - get => _productDeconvolutionParameters; + get => _productDeconvolutionParameters!; set { _productDeconvolutionParameters = value; diff --git a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs index c836f0e6d..a893db6b7 100644 --- a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs @@ -1,9 +1,15 @@ -using System.Diagnostics.CodeAnalysis; +using System; +using System.Diagnostics.CodeAnalysis; using MassSpectrometry; namespace GuiFunctions; -public abstract class DeconParamsViewModel : BaseViewModel +/// +/// Base Deconovolution Parameters view model +/// Used to wrap the DeconvolutionParameters object +/// Contains only shared information between different DeconvolutionParameters +/// +public abstract class DeconParamsViewModel : BaseViewModel, IEquatable { public DeconvolutionType DeconvolutionType => Parameters.DeconvolutionType; public abstract DeconvolutionParameters Parameters { get; protected set; } @@ -42,6 +48,28 @@ public Polarity Polarity #endregion + + public override string ToString() => DeconvolutionType.ToString(); + + public bool Equals(DeconParamsViewModel other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Equals(Parameters, other.Parameters); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((DeconParamsViewModel)obj); + } + + public override int GetHashCode() + { + return (Parameters != null ? Parameters.DeconvolutionType.GetHashCode() + Parameters.Polarity.GetHashCode() + MaxAssumedChargeState.GetHashCode() : 0); + } } diff --git a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs index 81472ed8d..fd3702d96 100644 --- a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs @@ -10,5 +10,8 @@ namespace GuiFunctions public sealed class IsoDecDeconParamsViewModel : DeconParamsViewModel { public override DeconvolutionParameters Parameters { get; protected set; } + + + public override string ToString() => "IsoDec"; } } From 4eff135a257cad6aff22dd190f363b18d6bf93ca Mon Sep 17 00:00:00 2001 From: Nic Bollis Date: Sun, 27 Oct 2024 15:54:03 -0500 Subject: [PATCH 09/13] Refactor UI and add comprehensive unit tests Refactored several XAML files to improve UI structure and readability: - Removed unnecessary `GroupBox` in `SearchTaskWindow.xaml` and added a new one for "Peak Trimming". - Adjusted layout in `ClassicDeconParamsControl.xaml` and `HostDeconParamControl.xaml`. Enhanced ViewModel logic: - Updated `DeconHostViewModel.cs` and `DeconParamsViewModel.cs` to include additional properties and validation logic. - Added `[ExcludeFromCodeCoverage]` attribute to `IsoDecDeconParamsViewModel.cs`. Expanded unit tests: - Removed obsolete `GuiFunctionsTest.cs`. - Added new test classes for `ClassicDeconParamsViewModel`, `DeconParamsViewModel`, `DeconHostViewModel`, and `MzLibExtensions`. - Included tests for property changes, validation logic, and conversion methods. --- .../GUI/TaskWindows/SearchTaskWindow.xaml | 4 +- .../ClassicDeconParamsControl.xaml | 43 ++-- .../Deconvolution/HostDeconParamControl.xaml | 143 +++++++----- .../Deconvolution/DeconHostViewModel.cs | 29 +-- .../Deconvolution/DeconParamsViewModel.cs | 114 +++++++++- .../IsoDecDeconParamsViewModel.cs | 3 + .../ClassicDeconParamsViewModelTest.cs | 43 ++++ .../Test/GuiTests/DeconParamsViewModelTest.cs | 211 ++++++++++++++++++ .../GuiTests/DeconvolutionViewModelsTests.cs | 160 +++++++++++++ .../Test/{ => GuiTests}/GuiFunctionsTest.cs | 11 +- .../Test/GuiTests/MzLibExtensionsTests.cs | 34 +++ 11 files changed, 683 insertions(+), 112 deletions(-) create mode 100644 MetaMorpheus/Test/GuiTests/ClassicDeconParamsViewModelTest.cs create mode 100644 MetaMorpheus/Test/GuiTests/DeconParamsViewModelTest.cs create mode 100644 MetaMorpheus/Test/GuiTests/DeconvolutionViewModelsTests.cs rename MetaMorpheus/Test/{ => GuiTests}/GuiFunctionsTest.cs (92%) create mode 100644 MetaMorpheus/Test/GuiTests/MzLibExtensionsTests.cs diff --git a/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml b/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml index aad380db5..eed76f169 100644 --- a/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml +++ b/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml @@ -660,9 +660,7 @@ - - - + diff --git a/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml b/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml index 679967de5..4afc6f5bc 100644 --- a/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml +++ b/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml @@ -6,19 +6,36 @@ xmlns:local="clr-namespace:MetaMorpheusGUI" xmlns:guiFunctions="clr-namespace:GuiFunctions;assembly=GuiFunctions" mc:Ignorable="d" - d:DesignHeight="200" d:DesignWidth="600"> - + d:DesignHeight="60" d:DesignWidth="600"> + + + + + + + + + + + diff --git a/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml b/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml index 7c7db0761..f1d72d3d8 100644 --- a/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml +++ b/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml @@ -10,85 +10,104 @@ + - + + - + - - + + - - - + + + + + - - - + + + - - + + - - - - - - - - - - - - Use the charge states and precursor masses determined by the instrument controller. - - - - + + + - - - - - - Additionally searches for coisolated peptides, allowing for multiple peptides to be identified from a single MS2. - - - + + + + + + + Use the charge states and precursor masses determined by the instrument controller. + + + + + + + + + + + Additionally searches for coisolated peptides, allowing for multiple peptides to be identified from a single MS2. + + + + - - - - - - - - The type of deconvolution to perform. - - - - - - - + + + + + + The type of deconvolution to perform. + + + + + + + - + - - - - + + diff --git a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconHostViewModel.cs b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconHostViewModel.cs index f4d0f1644..1442e3d4e 100644 --- a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconHostViewModel.cs +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconHostViewModel.cs @@ -1,5 +1,6 @@ #nullable enable using System; +using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -19,21 +20,17 @@ namespace GuiFunctions; /// public class DeconHostViewModel : BaseViewModel { - /// - /// - /// /// This is where default deconvolution parameters are set for GUI display /// - /// - /// + /// precursor params to display first + /// product params to display first /// /// /// public DeconHostViewModel(DeconvolutionParameters? initialPrecursorParameters = null, DeconvolutionParameters? initialProductParameters = null, bool useProvidedPrecursor = false, bool deconvolutePrecursors = true) { - UseProvidedPrecursors = useProvidedPrecursor; DoPrecursorDeconvolution = deconvolutePrecursors; @@ -41,8 +38,6 @@ public DeconHostViewModel(DeconvolutionParameters? initialPrecursorParameters = PrecursorDeconvolutionParametersList = new ObservableCollection(); ProductDeconvolutionParametersList = new ObservableCollection(); - - // populate the lists by adding the default parameters for each deconvolution type or the provided parameters foreach (var deconType in Enum.GetValues()) { @@ -88,15 +83,13 @@ public DeconHostViewModel(DeconvolutionParameters? initialPrecursorParameters = } // If deconvolution parameters are not set, default to MetaMorpheus defaults - if (initialPrecursorParameters is null) - PrecursorDeconvolutionParameters = PrecursorDeconvolutionParametersList.First(); - else - PrecursorDeconvolutionParameters = PrecursorDeconvolutionParametersList.First(x => x.Parameters == initialPrecursorParameters); - - if (initialProductParameters is null) - ProductDeconvolutionParameters = ProductDeconvolutionParametersList.First(); - else - ProductDeconvolutionParameters = ProductDeconvolutionParametersList.First(x => x.Parameters == initialProductParameters); + PrecursorDeconvolutionParameters = initialPrecursorParameters is null + ? PrecursorDeconvolutionParametersList.First(x => x.DeconvolutionType == DeconvolutionType.ClassicDeconvolution) + : PrecursorDeconvolutionParametersList.First(x => x.Parameters == initialPrecursorParameters); + + ProductDeconvolutionParameters = initialProductParameters is null + ? ProductDeconvolutionParametersList.First(x => x.DeconvolutionType == DeconvolutionType.ClassicDeconvolution) + : ProductDeconvolutionParametersList.First(x => x.Parameters == initialProductParameters); } #region Common Parameters @@ -175,7 +168,7 @@ public DeconParamsViewModel ProductDeconvolutionParameters -[ExcludeFromCodeCoverage] // Model used only for visualizing the view +[ExcludeFromCodeCoverage] // Model used only for visualizing the view in visual studio public class DeconHostModel : DeconHostViewModel { public static DeconHostModel Instance => new DeconHostModel(); diff --git a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs index a893db6b7..19a8e2eff 100644 --- a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using MassSpectrometry; @@ -11,51 +12,142 @@ namespace GuiFunctions; /// public abstract class DeconParamsViewModel : BaseViewModel, IEquatable { + + private int _previousMinAssumedChargeState; + private int _previousMaxAssumedChargeState; + public DeconvolutionType DeconvolutionType => Parameters.DeconvolutionType; public abstract DeconvolutionParameters Parameters { get; protected set; } - #region Wrapped Deconvolution Parameters + /// + /// Gets or sets the minimum assumed charge state. + /// Ensures the value is within valid range based on the polarity. + /// public int MinAssumedChargeState { get => Parameters.MinAssumedChargeState; set { - Parameters.MinAssumedChargeState = value; - OnPropertyChanged(nameof(MinAssumedChargeState)); + if (value == 0) + return; + switch (Polarity) + { + case Polarity.Positive when value < 0: + case Polarity.Positive when value > MaxAssumedChargeState: + case Polarity.Negative when value > 0: + case Polarity.Negative when value > MaxAssumedChargeState: + return; + + default: + _previousMinAssumedChargeState = Parameters.MinAssumedChargeState; + Parameters.MinAssumedChargeState = value; + OnPropertyChanged(nameof(MinAssumedChargeState)); + break; + } } } + + /// + /// Gets or sets the maximum assumed charge state. + /// Ensures the value is within valid range based on the polarity. + /// public int MaxAssumedChargeState { get => Parameters.MaxAssumedChargeState; set { - Parameters.MaxAssumedChargeState = value; - OnPropertyChanged(nameof(MaxAssumedChargeState)); + if (value == 0) + return; + switch (Polarity) + { + case Polarity.Positive when value < 0: + case Polarity.Positive when value < MinAssumedChargeState: + case Polarity.Negative when value > 0: + case Polarity.Negative when value < MinAssumedChargeState: + return; + + default: + _previousMaxAssumedChargeState = Parameters.MaxAssumedChargeState; + Parameters.MaxAssumedChargeState = value; + OnPropertyChanged(nameof(MaxAssumedChargeState)); + break; + + } } } + // TODO: When RNA is added to MetaMorpheus, add the polarity to the GUI public Polarity Polarity { get => Parameters.Polarity; set { + // Update based upon the new polarity Parameters.Polarity = value; OnPropertyChanged(nameof(Polarity)); - } - } - - #endregion + // Update min and max charge to be valid with the new polarity + // switch from negative to positive + if (value == Polarity.Positive) + { + if (MaxAssumedChargeState < 0) + { + if (_previousMaxAssumedChargeState > 0) + MaxAssumedChargeState = _previousMaxAssumedChargeState; + else + MaxAssumedChargeState = 12; + } + + if (MinAssumedChargeState < 1) + { + if (_previousMinAssumedChargeState > 0 && _previousMinAssumedChargeState < MaxAssumedChargeState) + MinAssumedChargeState = _previousMinAssumedChargeState; + else + MinAssumedChargeState = 1; + } + } + + // switch from positive to negative + if (value == Polarity.Negative) + { + if (MinAssumedChargeState > 0) + { + if (_previousMinAssumedChargeState < 0) + MinAssumedChargeState = _previousMinAssumedChargeState; + else + MinAssumedChargeState = -20; + } + + if (MaxAssumedChargeState > 0) + { + if (_previousMaxAssumedChargeState < 0 && _previousMaxAssumedChargeState > MinAssumedChargeState) + MaxAssumedChargeState = _previousMaxAssumedChargeState; + else + MaxAssumedChargeState = -1; + } + } + } + } + public override string ToString() => DeconvolutionType.ToString(); public bool Equals(DeconParamsViewModel other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; - return Equals(Parameters, other.Parameters); + + if (Parameters.DeconvolutionType != other.Parameters.DeconvolutionType) + return false; + if (Parameters.Polarity != other.Parameters.Polarity) + return false; + if (Parameters.MinAssumedChargeState != other.Parameters.MinAssumedChargeState) + return false; + if (Parameters.MaxAssumedChargeState != other.Parameters.MaxAssumedChargeState) + return false; + return true; } public override bool Equals(object obj) @@ -73,7 +165,7 @@ public override int GetHashCode() } -[ExcludeFromCodeCoverage] // Model used only for visualizing the view +[ExcludeFromCodeCoverage] // Model used only for visualizing the view in visual studio public class DeconParamsModel : DeconParamsViewModel { public static DeconParamsModel Instance => new DeconParamsModel(); diff --git a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs index fd3702d96..1a09d8090 100644 --- a/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -7,6 +8,8 @@ namespace GuiFunctions { + // Coming Soon + [ExcludeFromCodeCoverage] public sealed class IsoDecDeconParamsViewModel : DeconParamsViewModel { public override DeconvolutionParameters Parameters { get; protected set; } diff --git a/MetaMorpheus/Test/GuiTests/ClassicDeconParamsViewModelTest.cs b/MetaMorpheus/Test/GuiTests/ClassicDeconParamsViewModelTest.cs new file mode 100644 index 000000000..4d8a6c112 --- /dev/null +++ b/MetaMorpheus/Test/GuiTests/ClassicDeconParamsViewModelTest.cs @@ -0,0 +1,43 @@ +using GuiFunctions; +using MassSpectrometry; +using NUnit.Framework; + +namespace Test.GuiTests; + +[TestFixture] +public class ClassicDeconParamsViewModelTest +{ + private ClassicDeconParamsViewModel _viewModel; + private ClassicDeconvolutionParameters _parameters; + + [SetUp] + public void SetUp() + { + _parameters = new ClassicDeconvolutionParameters(1, 12, 10, 0.5); + _viewModel = new ClassicDeconParamsViewModel(_parameters); + } + + [Test] + public void TestDeconvolutionTolerancePpm() + { + Assert.That(_viewModel.DeconvolutionTolerancePpm, Is.EqualTo(10.0)); + _viewModel.DeconvolutionTolerancePpm = 20.0; + Assert.That(_viewModel.DeconvolutionTolerancePpm, Is.EqualTo(20.0)); + Assert.That(_parameters.DeconvolutionTolerancePpm, Is.EqualTo(20.0)); + } + + [Test] + public void TestIntensityRatioLimit() + { + Assert.That(_viewModel.IntensityRatioLimit, Is.EqualTo(0.5)); + _viewModel.IntensityRatioLimit = 1.0; + Assert.That(_viewModel.IntensityRatioLimit, Is.EqualTo(1.0)); + Assert.That(_parameters.IntensityRatioLimit, Is.EqualTo(1.0)); + } + + [Test] + public void TestToString() + { + Assert.That(_viewModel.ToString(), Is.EqualTo("Classic")); + } +} \ No newline at end of file diff --git a/MetaMorpheus/Test/GuiTests/DeconParamsViewModelTest.cs b/MetaMorpheus/Test/GuiTests/DeconParamsViewModelTest.cs new file mode 100644 index 000000000..aaf001cb8 --- /dev/null +++ b/MetaMorpheus/Test/GuiTests/DeconParamsViewModelTest.cs @@ -0,0 +1,211 @@ +using GuiFunctions; +using MassSpectrometry; +using NUnit.Framework; + +namespace Test.GuiTests; + +[TestFixture] +public class DeconParamsViewModelTest +{ + private class TestDeconParamsViewModel : DeconParamsViewModel + { + public sealed override DeconvolutionParameters Parameters { get; protected set; } + + public TestDeconParamsViewModel(DeconvolutionParameters parameters) + { + Parameters = parameters; + } + } + + private DeconvolutionParameters _negativeModeParameters; + private TestDeconParamsViewModel _negativeModeViewModel; + private DeconvolutionParameters _positiveModeParameters; + private TestDeconParamsViewModel _positiveModeViewModel; + + [SetUp] + public void SetUp() + { + _negativeModeParameters = new ClassicDeconvolutionParameters(-20, -2, 5, 3, Polarity.Negative); + _negativeModeViewModel = new TestDeconParamsViewModel(_negativeModeParameters); + + _positiveModeParameters = new ClassicDeconvolutionParameters(2, 20, 5, 3, Polarity.Positive); + _positiveModeViewModel = new TestDeconParamsViewModel(_positiveModeParameters); + } + + [TestCase(0, false, TestName = "MinAssumedChargeState_SetToZero_DoesNotChange")] + [TestCase(-1, false, TestName = "MinAssumedChargeState_SetToNegativeInPositiveMode_DoesNotChange")] + [TestCase(21, false, TestName = "MinAssumedChargeState_SetAboveMaxInPositiveMode_DoesNotChange")] + [TestCase(3, true, TestName = "MinAssumedChargeState_SetToValidPositiveValue_Changes")] + public void TestMinAssumedChargeState_PositiveMode(int newValue, bool shouldChange) + { + _positiveModeViewModel.MinAssumedChargeState = newValue; + if (shouldChange) + { + Assert.That(_positiveModeViewModel.MinAssumedChargeState, Is.EqualTo(newValue)); + } + else + { + Assert.That(_positiveModeViewModel.MinAssumedChargeState, Is.EqualTo(2)); + } + } + + [TestCase(0, false, TestName = "MaxAssumedChargeState_SetToZero_DoesNotChange")] + [TestCase(-4, false, TestName = "MaxAssumedChargeState_SetToNegativeInPositiveMode_DoesNotChange")] + [TestCase(1, false, TestName = "MaxAssumedChargeState_SetBelowMinInPositiveMode_DoesNotChange")] + [TestCase(25, true, TestName = "MaxAssumedChargeState_SetToValidPositiveValue_Changes")] + public void TestMaxAssumedChargeState_PositiveMode(int newValue, bool shouldChange) + { + _positiveModeViewModel.MaxAssumedChargeState = newValue; + if (shouldChange) + { + Assert.That(_positiveModeViewModel.MaxAssumedChargeState, Is.EqualTo(newValue)); + } + else + { + Assert.That(_positiveModeViewModel.MaxAssumedChargeState, Is.EqualTo(20)); + } + } + + [TestCase(0, false, TestName = "MinAssumedChargeState_SetToZero_DoesNotChange")] + [TestCase(1, false, TestName = "MinAssumedChargeState_SetToPositiveInNegativeMode_DoesNotChange")] + [TestCase(-1, false, TestName = "MinAssumedChargeState_SetAboveMaxInNegativeMode_DoesNotChange")] + [TestCase(-21, true, TestName = "MinAssumedChargeState_SetToValidNegativeValue_Changes")] + public void TestMinAssumedChargeState_NegativeMode(int newValue, bool shouldChange) + { + _negativeModeViewModel.MinAssumedChargeState = newValue; + if (shouldChange) + { + Assert.That(_negativeModeViewModel.MinAssumedChargeState, Is.EqualTo(newValue)); + } + else + { + Assert.That(_negativeModeViewModel.MinAssumedChargeState, Is.EqualTo(-20)); + } + } + + [TestCase(0, false, TestName = "MaxAssumedChargeState_SetToZero_DoesNotChange")] + [TestCase(1, false, TestName = "MaxAssumedChargeState_SetToPositiveInNegativeMode_DoesNotChange")] + [TestCase(-21, false, TestName = "MaxAssumedChargeState_SetBelowMinInNegativeMode_DoesNotChange")] + [TestCase(-1, true, TestName = "MaxAssumedChargeState_SetToValidNegativeValue_Changes")] + public void TestMaxAssumedChargeState_NegativeMode(int newValue, bool shouldChange) + { + _negativeModeViewModel.MaxAssumedChargeState = newValue; + if (shouldChange) + { + Assert.That(_negativeModeViewModel.MaxAssumedChargeState, Is.EqualTo(newValue)); + } + else + { + Assert.That(_negativeModeViewModel.MaxAssumedChargeState, Is.EqualTo(-2)); + } + } + + [TestCase(Polarity.Positive, Polarity.Positive, 5, 12, TestName = "Polarity_SwitchFromPositiveToPositive_NoChange")] + [TestCase(Polarity.Negative, Polarity.Negative, -25, -5, TestName = "Polarity_SwitchFromNegativeToNegative_NoChange")] + [TestCase(Polarity.Positive, Polarity.Negative, -20, -1, TestName = "Polarity_SwitchFromPositiveToNegative_UpdatesChargeStates")] + [TestCase(Polarity.Negative, Polarity.Positive, 1, 12, TestName = "Polarity_SwitchFromNegativeToPositive_UpdatesChargeStates")] + public void TestPolaritySwitch(Polarity initialPolarity, Polarity newPolarity, int expectedMinChargeState, int expectedMaxChargeState) + { + var parameters = new ClassicDeconvolutionParameters(initialPolarity == Polarity.Positive ? 5 : -25, initialPolarity == Polarity.Positive ? 12 : -5, 5, 3, initialPolarity); + var viewModel = new TestDeconParamsViewModel(parameters); + + viewModel.Polarity = newPolarity; + + Assert.That(viewModel.Polarity, Is.EqualTo(newPolarity)); + Assert.That(viewModel.MinAssumedChargeState, Is.EqualTo(expectedMinChargeState)); + Assert.That(viewModel.MaxAssumedChargeState, Is.EqualTo(expectedMaxChargeState)); + } + + [Test] + public void TestPolaritySwitchWithPreviousValues() + { + // Initial setup with positive polarity + var parameters = new ClassicDeconvolutionParameters(1, 12, 5, 3, Polarity.Positive); + var viewModel = new TestDeconParamsViewModel(parameters); + + // Change to negative polarity + viewModel.Polarity = Polarity.Negative; + + // Set previous values + viewModel.MinAssumedChargeState = -10; + viewModel.MaxAssumedChargeState = -5; + + // Change back to positive polarity + viewModel.Polarity = Polarity.Positive; + + // Assert that previous values are restored correctly + Assert.That(viewModel.MinAssumedChargeState, Is.EqualTo(1)); + Assert.That(viewModel.MaxAssumedChargeState, Is.EqualTo(12)); + + // Change to negative polarity again + viewModel.Polarity = Polarity.Negative; + + // Assert that previous negative values are restored correctly + Assert.That(viewModel.MinAssumedChargeState, Is.EqualTo(-10)); + Assert.That(viewModel.MaxAssumedChargeState, Is.EqualTo(-5)); + } + [Test] + public void TestToString() + { + var parameters = new ClassicDeconvolutionParameters(1, 12, 5, 3, Polarity.Positive); + var viewModel = new TestDeconParamsViewModel(parameters); + Assert.That(viewModel.ToString(), Is.EqualTo(parameters.DeconvolutionType.ToString())); + } + + [Test] + public void TestEquals_SameObject() + { + var parameters = new ClassicDeconvolutionParameters(1, 12, 5, 3, Polarity.Positive); + var viewModel = new TestDeconParamsViewModel(parameters); + Assert.That(viewModel.Equals(viewModel), Is.True); + } + + [Test] + public void TestEquals_NullObject() + { + var parameters = new ClassicDeconvolutionParameters(1, 12, 5, 3, Polarity.Positive); + var viewModel = new TestDeconParamsViewModel(parameters); + Assert.That(viewModel.Equals(null), Is.False); + } + + [Test] + public void TestEquals_DifferentType() + { + var parameters = new ClassicDeconvolutionParameters(1, 12, 5, 3, Polarity.Positive); + var viewModel = new TestDeconParamsViewModel(parameters); + Assert.That(viewModel.Equals(new object()), Is.False); + } + + [Test] + [TestCase(1, 15, Polarity.Negative, TestName = "MinChargeDiffers_NotEqual")] + [TestCase(2, 12, Polarity.Negative, TestName = "MaxChargeDiffers_NotEqual")] + [TestCase(2, 15, Polarity.Positive, TestName = "PolarityDiffers_NotEqual")] + public void TestEquals_DifferentParameters(int minCharge, int maxCharge, Polarity polarity) + { + var parameters1 = new ClassicDeconvolutionParameters(minCharge, maxCharge, 5, 3, polarity); + var viewModel1 = new TestDeconParamsViewModel(parameters1); + + var parameters2 = new ClassicDeconvolutionParameters(2, 15, 5, 3, Polarity.Negative); + var viewModel2 = new TestDeconParamsViewModel(parameters2); + Assert.That(viewModel1.Equals(viewModel2), Is.False); + } + + [Test] + public void TestEquals_SameParameters() + { + var parameters1 = new ClassicDeconvolutionParameters(1, 12, 5, 3, Polarity.Positive); + var viewModel1 = new TestDeconParamsViewModel(parameters1); + var parameters2 = new ClassicDeconvolutionParameters(1, 12, 5, 3, Polarity.Positive); + var viewModel2 = new TestDeconParamsViewModel(parameters2); + Assert.That(viewModel1.Equals(viewModel2), Is.True); + } + + [Test] + public void TestGetHashCode() + { + var parameters = new ClassicDeconvolutionParameters(1, 12, 5, 3, Polarity.Positive); + var viewModel = new TestDeconParamsViewModel(parameters); + var expectedHashCode = parameters.DeconvolutionType.GetHashCode() + parameters.Polarity.GetHashCode() + parameters.MaxAssumedChargeState.GetHashCode(); + Assert.That(viewModel.GetHashCode(), Is.EqualTo(expectedHashCode)); + } +} \ No newline at end of file diff --git a/MetaMorpheus/Test/GuiTests/DeconvolutionViewModelsTests.cs b/MetaMorpheus/Test/GuiTests/DeconvolutionViewModelsTests.cs new file mode 100644 index 000000000..2806405b9 --- /dev/null +++ b/MetaMorpheus/Test/GuiTests/DeconvolutionViewModelsTests.cs @@ -0,0 +1,160 @@ +using System.Linq; +using EngineLayer; +using GuiFunctions; +using MassSpectrometry; +using NUnit.Framework; + +namespace Test.GuiTests; + +[TestFixture] +public class TestDeconHostViewModel +{ + internal ClassicDeconvolutionParameters ClassicPrecursorDeconvolutionParameters = new ClassicDeconvolutionParameters(1, 12, 4, 3); + internal ClassicDeconvolutionParameters ClassicProductDeconvolutionParameters = new ClassicDeconvolutionParameters(1, 10, 4, 3); + + [Test] + public void Constructor_DefaultParameters_ShouldInitializeCorrectly() + { + // Arrange + var initialPrecursorParameters = ClassicPrecursorDeconvolutionParameters; + var initialProductParameters = ClassicProductDeconvolutionParameters; + + // Act + var viewModel = new DeconHostViewModel(initialPrecursorParameters, initialProductParameters); + + // Assert + Assert.That(viewModel.UseProvidedPrecursors, Is.False); + Assert.That(viewModel.DoPrecursorDeconvolution, Is.True); + Assert.That(viewModel.PrecursorDeconvolutionParametersList, Is.Not.Null); + Assert.That(viewModel.ProductDeconvolutionParametersList, Is.Not.Null); + Assert.That(viewModel.PrecursorDeconvolutionParametersList.Any(), Is.True); + Assert.That(viewModel.ProductDeconvolutionParametersList.Any(), Is.True); + } + + [Test] + public void Constructor_WithProvidedParameters_ShouldSetCorrectly() + { + // Arrange + var initialPrecursorParameters = ClassicPrecursorDeconvolutionParameters; + var initialProductParameters = ClassicProductDeconvolutionParameters; + + // Act + var viewModel = new DeconHostViewModel(initialPrecursorParameters, initialProductParameters, true, false); + + // Assert + Assert.That(viewModel.UseProvidedPrecursors, Is.True); + Assert.That(viewModel.DoPrecursorDeconvolution, Is.False); + Assert.That(viewModel.PrecursorDeconvolutionParameters, Is.EqualTo(initialPrecursorParameters.ToViewModel())); + Assert.That(viewModel.ProductDeconvolutionParameters, Is.EqualTo(initialProductParameters.ToViewModel())); + } + + [Test] + public void TestDeconHostViewModel_DefaultParameters() + { + // Arrange + DeconHostViewModel viewModel = new DeconHostViewModel(null, null); + + // Act + var precursorParams = viewModel.PrecursorDeconvolutionParameters; + var productParams = viewModel.ProductDeconvolutionParameters; + + // Assert + Assert.That(precursorParams, Is.Not.Null); + Assert.That(productParams, Is.Not.Null); + Assert.That(precursorParams.DeconvolutionType, Is.EqualTo(DeconvolutionType.ClassicDeconvolution)); + Assert.That(productParams.DeconvolutionType, Is.EqualTo(DeconvolutionType.ClassicDeconvolution)); + } + + [Test] + public void PrecursorDeconvolutionParameters_Setter_ShouldTriggerPropertyChanged() + { + // Arrange + var viewModel = new DeconHostViewModel(); + var newParameters = new ClassicDeconParamsViewModel(ClassicPrecursorDeconvolutionParameters); + bool propertyChangedTriggered = false; + viewModel.PropertyChanged += (sender, args) => + { + if (args.PropertyName == nameof(viewModel.PrecursorDeconvolutionParameters)) + propertyChangedTriggered = true; + }; + + // Act + viewModel.PrecursorDeconvolutionParameters = newParameters; + + // Assert + Assert.That(propertyChangedTriggered, Is.True); + } + + [Test] + public void ProductDeconvolutionParameters_Setter_ShouldTriggerPropertyChanged() + { + // Arrange + var viewModel = new DeconHostViewModel(); + var newParameters = new ClassicDeconParamsViewModel(ClassicProductDeconvolutionParameters); + bool propertyChangedTriggered = false; + viewModel.PropertyChanged += (sender, args) => + { + if (args.PropertyName == nameof(viewModel.ProductDeconvolutionParameters)) + propertyChangedTriggered = true; + }; + + // Act + viewModel.ProductDeconvolutionParameters = newParameters; + + // Assert + Assert.That(propertyChangedTriggered, Is.True); + } + + + [Test] + [NonParallelizable] + public void TestDeconHostViewModel_GlobalVariablesProteoform() + { + // Arrange + GlobalVariables.AnalyteType = "Proteoform"; + DeconHostViewModel viewModel = new DeconHostViewModel(null, null); + + // Act + var precursorParams = viewModel.PrecursorDeconvolutionParameters; + var productParams = viewModel.ProductDeconvolutionParameters; + + // Assert + Assert.That(precursorParams, Is.Not.Null); + Assert.That(productParams, Is.Not.Null); + Assert.That(precursorParams.DeconvolutionType, Is.EqualTo(DeconvolutionType.ClassicDeconvolution)); + Assert.That(productParams.DeconvolutionType, Is.EqualTo(DeconvolutionType.ClassicDeconvolution)); + Assert.That(precursorParams.Parameters, Is.InstanceOf()); + Assert.That(productParams.Parameters, Is.InstanceOf()); + Assert.That(((ClassicDeconvolutionParameters)precursorParams.Parameters).MaxAssumedChargeState, Is.EqualTo(60)); + Assert.That(((ClassicDeconvolutionParameters)productParams.Parameters).MaxAssumedChargeState, Is.EqualTo(10)); + + // Revert back to default + GlobalVariables.AnalyteType = "Peptide"; + } + + [Test] + [NonParallelizable] + public void TestDeconHostViewModel_GlobalVariablesOligo() + { + // Arrange + GlobalVariables.AnalyteType = "Oligo"; + DeconHostViewModel viewModel = new DeconHostViewModel(null, null); + + // Act + var precursorParams = viewModel.PrecursorDeconvolutionParameters; + var productParams = viewModel.ProductDeconvolutionParameters; + + // Assert + Assert.That(precursorParams, Is.Not.Null); + Assert.That(productParams, Is.Not.Null); + Assert.That(precursorParams.DeconvolutionType, Is.EqualTo(DeconvolutionType.ClassicDeconvolution)); + Assert.That(productParams.DeconvolutionType, Is.EqualTo(DeconvolutionType.ClassicDeconvolution)); + Assert.That(precursorParams.Parameters, Is.InstanceOf()); + Assert.That(productParams.Parameters, Is.InstanceOf()); + Assert.That(((ClassicDeconvolutionParameters)precursorParams.Parameters).MinAssumedChargeState, Is.EqualTo(-20)); + Assert.That(((ClassicDeconvolutionParameters)productParams.Parameters).MinAssumedChargeState, Is.EqualTo(-10)); + + // Revert back to default + GlobalVariables.AnalyteType = "Peptide"; + } +} \ No newline at end of file diff --git a/MetaMorpheus/Test/GuiFunctionsTest.cs b/MetaMorpheus/Test/GuiTests/GuiFunctionsTest.cs similarity index 92% rename from MetaMorpheus/Test/GuiFunctionsTest.cs rename to MetaMorpheus/Test/GuiTests/GuiFunctionsTest.cs index 139bd705a..65da9b2d6 100644 --- a/MetaMorpheus/Test/GuiFunctionsTest.cs +++ b/MetaMorpheus/Test/GuiTests/GuiFunctionsTest.cs @@ -1,5 +1,6 @@ using GuiFunctions.Databases; -using NUnit.Framework; using Assert = NUnit.Framework.Legacy.ClassicAssert; +using NUnit.Framework; +using Assert = NUnit.Framework.Legacy.ClassicAssert; using Proteomics; using System; using System.Collections.Generic; @@ -8,7 +9,7 @@ using System.Threading.Tasks; using UsefulProteomicsDatabases; -namespace Test +namespace Test.GuiTests { [TestFixture] public static class GuiFunctionsTest @@ -28,7 +29,7 @@ public static class GuiFunctionsTest [TestCase("UP000000625", false, false, false, false, "\\UP000000625_withUnreviewed.fasta")] public static void TestGetUniprotFilename(string proteomeID, bool reviewed, bool isoforms, bool xmlFormat, bool compressed, string expectedResult) { - if(expectedResult.Equals("\\UP000000625_reviewed.xml.gz") && isoforms) // This should only be written once, during the first test case + if (expectedResult.Equals("\\UP000000625_reviewed.xml.gz") && isoforms) // This should only be written once, during the first test case { Console.WriteLine("Beginning Uniprot database test."); } @@ -101,12 +102,12 @@ public static async Task UniprotHtmlQueryTest(string proteomeID, bool reviewed, File.Delete(filePath); - if(testName.Equals("11.fasta")) // only triggers for last test cases + if (testName.Equals("11.fasta")) // only triggers for last test cases { Console.WriteLine("Finished with Uniprot HTML query test."); } - Assert.That(reader.Count == listCount); + NUnit.Framework.Assert.That(reader.Count == listCount); } } } \ No newline at end of file diff --git a/MetaMorpheus/Test/GuiTests/MzLibExtensionsTests.cs b/MetaMorpheus/Test/GuiTests/MzLibExtensionsTests.cs new file mode 100644 index 000000000..6d063bbba --- /dev/null +++ b/MetaMorpheus/Test/GuiTests/MzLibExtensionsTests.cs @@ -0,0 +1,34 @@ +using System; +using GuiFunctions; +using MassSpectrometry; +using NUnit.Framework; +using Assert = NUnit.Framework.Assert; + +namespace Test.GuiTests; + +[TestFixture] +public class MzLibExtensionsTests +{ + [Test] + public void ToViewModel_WithClassicDeconvolutionParameters_ReturnsClassicDeconParamsViewModel() + { + // Arrange + var classicParams = new ClassicDeconvolutionParameters(1, 12, 10, 1); + + // Act + var result = classicParams.ToViewModel(); + + // Assert + Assert.That(result, Is.InstanceOf()); + } + + [Test] + public void ToViewModel_WithUnsupportedParameters_ThrowsNotImplementedException() + { + // Arrange + var unsupportedParams = new ExampleNewDeconvolutionParametersTemplate(1, 20); + + // Act & Assert + Assert.That(() => unsupportedParams.ToViewModel(), Throws.TypeOf()); + } +} \ No newline at end of file From d32800c73401515ccb4780240f9c9230c7d174e1 Mon Sep 17 00:00:00 2001 From: Nic Bollis Date: Sun, 27 Oct 2024 16:30:15 -0500 Subject: [PATCH 10/13] Expanded test coverage and cleaned up code --- .../GUI/TaskWindows/SearchTaskWindow.xaml.cs | 7 --- .../DeconvolutionTypeToControlConverter.cs | 42 +++++++++++++----- .../ClassicDeconParamsControl.xaml | 1 - .../ClassicDeconParamsControl.xaml.cs | 15 +------ .../Deconvolution/HostDeconParamControl.xaml | 7 ++- MetaMorpheus/GuiFunctions/MzLibExtensions.cs | 7 ++- .../ClassicDeconParamsViewModel.cs | 2 +- .../Deconvolution/DeconHostViewModel.cs | 8 ++-- .../Deconvolution/DeconParamsViewModel.cs | 3 +- ...delsTests.cs => DeconHostViewModelTest.cs} | 43 ++++++++++++++++++- .../Test/GuiTests/DeconParamsViewModelTest.cs | 34 ++++++++++++--- 11 files changed, 116 insertions(+), 53 deletions(-) rename MetaMorpheus/Test/GuiTests/{DeconvolutionViewModelsTests.cs => DeconHostViewModelTest.cs} (84%) diff --git a/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml.cs b/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml.cs index 447a93440..da53aa8ae 100644 --- a/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml.cs +++ b/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml.cs @@ -302,13 +302,9 @@ private void UpdateFieldsFromTask(SearchTask task) TrimMsMs.IsChecked = task.CommonParameters.TrimMsMsPeaks; AddTruncationsCheckBox.IsChecked = task.CommonParameters.AddTruncations; - DeconHostViewModel = new DeconHostViewModel(TheTask.CommonParameters.PrecursorDeconvolutionParameters, TheTask.CommonParameters.ProductDeconvolutionParameters, TheTask.CommonParameters.UseProvidedPrecursorInfo, TheTask.CommonParameters.DoPrecursorDeconvolution); - //DeconvolutePrecursors.IsChecked = task.CommonParameters.DoPrecursorDeconvolution; - //UseProvidedPrecursor.IsChecked = task.CommonParameters.UseProvidedPrecursorInfo; - //DeconvolutionMaxAssumedChargeStateTextBox.Text = task.CommonParameters.DeconvolutionMaxAssumedChargeState.ToString(); NumberOfPeaksToKeepPerWindowTextBox.Text = task.CommonParameters.NumberOfPeaksToKeepPerWindow == int.MaxValue || !task.CommonParameters.NumberOfPeaksToKeepPerWindow.HasValue ? "" : task.CommonParameters.NumberOfPeaksToKeepPerWindow.Value.ToString(CultureInfo.InvariantCulture); MinimumAllowedIntensityRatioToBasePeakTexBox.Text = task.CommonParameters.MinimumAllowedIntensityRatioToBasePeak == double.MaxValue || !task.CommonParameters.MinimumAllowedIntensityRatioToBasePeak.HasValue ? "" : task.CommonParameters.MinimumAllowedIntensityRatioToBasePeak.Value.ToString(CultureInfo.InvariantCulture); @@ -587,13 +583,10 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) bool useProvidedPrecursorInfo = DeconHostViewModel.UseProvidedPrecursors; bool doPrecursorDeconvolution = DeconHostViewModel.DoPrecursorDeconvolution; - - CommonParameters commonParamsToSave = new CommonParameters( taskDescriptor: OutputFileNameTextBox.Text != "" ? OutputFileNameTextBox.Text : "SearchTask", maxThreadsToUsePerFile: parseMaxThreadsPerFile ? int.Parse(MaxThreadsTextBox.Text, CultureInfo.InvariantCulture) : new CommonParameters().MaxThreadsToUsePerFile, reportAllAmbiguity: AllAmbiguity.IsChecked.Value, - //deconvolutionMaxAssumedChargeState: int.Parse(DeconvolutionMaxAssumedChargeStateTextBox.Text, CultureInfo.InvariantCulture), totalPartitions: int.Parse(NumberOfDatabaseSearchesTextBox.Text, CultureInfo.InvariantCulture), doPrecursorDeconvolution: doPrecursorDeconvolution, useProvidedPrecursorInfo: useProvidedPrecursorInfo, diff --git a/MetaMorpheus/GUI/Util/Converters/DeconvolutionTypeToControlConverter.cs b/MetaMorpheus/GUI/Util/Converters/DeconvolutionTypeToControlConverter.cs index 599d82645..1daf97137 100644 --- a/MetaMorpheus/GUI/Util/Converters/DeconvolutionTypeToControlConverter.cs +++ b/MetaMorpheus/GUI/Util/Converters/DeconvolutionTypeToControlConverter.cs @@ -5,26 +5,46 @@ namespace MetaMorpheusGUI { + /// + /// Converts a DeconvolutionType to a corresponding control. + /// public class DeconvolutionTypeToControlConverter : BaseValueConverter { + /// + /// Converts a DeconvolutionType to a corresponding control. + /// + /// The value to convert, expected to be of type DeconParamsViewModel. + /// The type of the target property. + /// Optional parameter to be used in the converter logic. + /// The culture to use in the converter. + /// A control corresponding to the DeconvolutionType. + /// Thrown when the value is not of type DeconParamsViewModel or the DeconvolutionType is invalid. public override object Convert(object value, Type targetType, object parameter, CultureInfo culture) { // Assuming value is of an enum type DeconvolutionType - if (value is DeconParamsViewModel viewModel) + if (value is not DeconParamsViewModel viewModel) + throw new ArgumentException("Invalid value type", nameof(value)); + + switch (viewModel.DeconvolutionType) { - switch (viewModel.DeconvolutionType) - { - case DeconvolutionType.ClassicDeconvolution: - return new ClassicDeconParamsControl() { DataContext = value as ClassicDeconParamsViewModel }; - - case DeconvolutionType.ExampleNewDeconvolutionTemplate: - default: - throw new ArgumentException("Invalid DeconvolutionType", nameof(value)); - } + case DeconvolutionType.ClassicDeconvolution: + return new ClassicDeconParamsControl() { DataContext = value as ClassicDeconParamsViewModel }; + + case DeconvolutionType.ExampleNewDeconvolutionTemplate: + default: + throw new ArgumentException("Invalid DeconvolutionType", nameof(value)); } - throw new ArgumentException("Invalid value type", nameof(value)); } + /// + /// Converts a value back to its source type. Not implemented. + /// + /// The value produced by the binding target. + /// The type to convert to. + /// Optional parameter to be used in the converter logic. + /// The culture to use in the converter. + /// Throws NotImplementedException. + /// Always thrown as this method is not implemented. public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); diff --git a/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml b/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml index 4afc6f5bc..dcd2e62ba 100644 --- a/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml +++ b/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml @@ -36,6 +36,5 @@ - diff --git a/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml.cs b/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml.cs index ddd016932..c866b44c9 100644 --- a/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml.cs +++ b/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml.cs @@ -1,17 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; +using System.Windows.Controls; namespace MetaMorpheusGUI { diff --git a/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml b/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml index f1d72d3d8..ca2a2f1fe 100644 --- a/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml +++ b/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml @@ -10,6 +10,7 @@ + - - - - - - - - - - - - - - + diff --git a/MetaMorpheus/GUI/TaskWindows/GlycoSearchTaskWindow.xaml.cs b/MetaMorpheus/GUI/TaskWindows/GlycoSearchTaskWindow.xaml.cs index eb28a08cd..5f1e8c48c 100644 --- a/MetaMorpheus/GUI/TaskWindows/GlycoSearchTaskWindow.xaml.cs +++ b/MetaMorpheus/GUI/TaskWindows/GlycoSearchTaskWindow.xaml.cs @@ -29,6 +29,7 @@ public partial class GlycoSearchTaskWindow : Window private readonly ObservableCollection FixedModTypeForTreeViewObservableCollection = new ObservableCollection(); private readonly ObservableCollection VariableModTypeForTreeViewObservableCollection = new ObservableCollection(); private CustomFragmentationWindow CustomFragmentationWindow; + private DeconHostViewModel DeconHostViewModel; public GlycoSearchTaskWindow() : this(null) { @@ -40,6 +41,7 @@ public GlycoSearchTaskWindow(GlycoSearchTask task) PopulateChoices(); TheTask = task ?? new GlycoSearchTask(); UpdateFieldsFromTask(TheTask); + DeisotopingControl.DataContext = DeconHostViewModel; if (task == null) { @@ -164,8 +166,9 @@ private void UpdateFieldsFromTask(GlycoSearchTask task) CheckBoxDecoy.IsChecked = task._glycoSearchParameters.DecoyType != DecoyType.None; RadioButtonReverseDecoy.IsChecked = task._glycoSearchParameters.DecoyType == DecoyType.Reverse; RadioButtonSlideDecoy.IsChecked = task._glycoSearchParameters.DecoyType == DecoyType.Slide; - deconvolutePrecursors.IsChecked = task.CommonParameters.DoPrecursorDeconvolution; - useProvidedPrecursor.IsChecked = task.CommonParameters.UseProvidedPrecursorInfo; + DeconHostViewModel = new DeconHostViewModel(TheTask.CommonParameters.PrecursorDeconvolutionParameters, + TheTask.CommonParameters.ProductDeconvolutionParameters, + TheTask.CommonParameters.UseProvidedPrecursorInfo, TheTask.CommonParameters.DoPrecursorDeconvolution); missedCleavagesTextBox.Text = task.CommonParameters.DigestionParams.MaxMissedCleavages.ToString(CultureInfo.InvariantCulture); MinPeptideLengthTextBox.Text = task.CommonParameters.DigestionParams.MinPeptideLength.ToString(CultureInfo.InvariantCulture); MaxPeptideLengthTextBox.Text = task.CommonParameters.DigestionParams.MaxPeptideLength == int.MaxValue ? "" : task.CommonParameters.DigestionParams.MaxPeptideLength.ToString(CultureInfo.InvariantCulture); @@ -248,7 +251,7 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) if (!GlobalGuiSettings.CheckTaskSettingsValidity(PrecusorMsTlTextBox.Text, productMassToleranceTextBox.Text, missedCleavagesTextBox.Text, maxModificationIsoformsTextBox.Text, MinPeptideLengthTextBox.Text, MaxPeptideLengthTextBox.Text, maxThreadsTextBox.Text, minScoreAllowed.Text, - fieldNotUsed, fieldNotUsed, fieldNotUsed, TopNPeaksTextBox.Text, MinRatioTextBox.Text, null, null, numberOfDatabaseSearchesTextBox.Text, TxtBoxMaxModPerPep.Text, + fieldNotUsed, fieldNotUsed, DeconHostViewModel.PrecursorDeconvolutionParameters.MaxAssumedChargeState.ToString(), TopNPeaksTextBox.Text, MinRatioTextBox.Text, null, null, numberOfDatabaseSearchesTextBox.Text, TxtBoxMaxModPerPep.Text, fieldNotUsed, null, null, null)) { return; @@ -374,12 +377,17 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) listOfModsFixed.AddRange(heh.Children.Where(b => b.Use).Select(b => (b.Parent.DisplayName, b.ModName))); } + DeconvolutionParameters precursorDeconvolutionParameters = DeconHostViewModel.PrecursorDeconvolutionParameters.Parameters; + DeconvolutionParameters productDeconvolutionParameters = DeconHostViewModel.ProductDeconvolutionParameters.Parameters; + bool useProvidedPrecursorInfo = DeconHostViewModel.UseProvidedPrecursors; + bool doPrecursorDeconvolution = DeconHostViewModel.DoPrecursorDeconvolution; + CommonParameters commonParamsToSave = new CommonParameters( precursorMassTolerance: PrecursorMassTolerance, taskDescriptor: OutputFileNameTextBox.Text != "" ? OutputFileNameTextBox.Text : "GlycoSearchTask", productMassTolerance: ProductMassTolerance, - doPrecursorDeconvolution: deconvolutePrecursors.IsChecked.Value, - useProvidedPrecursorInfo: useProvidedPrecursor.IsChecked.Value, + doPrecursorDeconvolution: doPrecursorDeconvolution, + useProvidedPrecursorInfo: useProvidedPrecursorInfo, digestionParams: digestionParamsToSave, trimMs1Peaks: trimMs1.IsChecked.Value, trimMsMsPeaks: trimMsMs.IsChecked.Value, @@ -392,7 +400,9 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) maxThreadsToUsePerFile: int.Parse(maxThreadsTextBox.Text, CultureInfo.InvariantCulture), listOfModsVariable: listOfModsVariable, listOfModsFixed: listOfModsFixed, - assumeOrphanPeaksAreZ1Fragments: protease.Name != "top-down"); + assumeOrphanPeaksAreZ1Fragments: protease.Name != "top-down", + precursorDeconParams: precursorDeconvolutionParameters, + productDeconParams: productDeconvolutionParameters); TheTask.CommonParameters = commonParamsToSave; diff --git a/MetaMorpheus/GUI/TaskWindows/XLSearchTaskWindow.xaml b/MetaMorpheus/GUI/TaskWindows/XLSearchTaskWindow.xaml index 8c3ae3c27..984c7da06 100644 --- a/MetaMorpheus/GUI/TaskWindows/XLSearchTaskWindow.xaml +++ b/MetaMorpheus/GUI/TaskWindows/XLSearchTaskWindow.xaml @@ -147,20 +147,7 @@ - - - - - - - - - - - - - - + diff --git a/MetaMorpheus/GUI/TaskWindows/XLSearchTaskWindow.xaml.cs b/MetaMorpheus/GUI/TaskWindows/XLSearchTaskWindow.xaml.cs index 477d53d2f..9be2b83f2 100644 --- a/MetaMorpheus/GUI/TaskWindows/XLSearchTaskWindow.xaml.cs +++ b/MetaMorpheus/GUI/TaskWindows/XLSearchTaskWindow.xaml.cs @@ -29,6 +29,7 @@ public partial class XLSearchTaskWindow : Window private readonly ObservableCollection FixedModTypeForTreeViewObservableCollection = new ObservableCollection(); private readonly ObservableCollection VariableModTypeForTreeViewObservableCollection = new ObservableCollection(); private CustomFragmentationWindow CustomFragmentationWindow; + private DeconHostViewModel DeconHostViewModel; public XLSearchTaskWindow(XLSearchTask task) { @@ -36,6 +37,7 @@ public XLSearchTaskWindow(XLSearchTask task) PopulateChoices(); TheTask = task ?? new XLSearchTask(); UpdateFieldsFromTask(TheTask); + DeisotopingControl.DataContext = DeconHostViewModel; if (task == null) { @@ -155,8 +157,9 @@ private void UpdateFieldsFromTask(XLSearchTask task) } checkBoxDecoy.IsChecked = task.XlSearchParameters.DecoyType != DecoyType.None; - deconvolutePrecursors.IsChecked = task.CommonParameters.DoPrecursorDeconvolution; - useProvidedPrecursor.IsChecked = task.CommonParameters.UseProvidedPrecursorInfo; + DeconHostViewModel = new DeconHostViewModel(TheTask.CommonParameters.PrecursorDeconvolutionParameters, + TheTask.CommonParameters.ProductDeconvolutionParameters, + TheTask.CommonParameters.UseProvidedPrecursorInfo, TheTask.CommonParameters.DoPrecursorDeconvolution); missedCleavagesTextBox.Text = task.CommonParameters.DigestionParams.MaxMissedCleavages.ToString(CultureInfo.InvariantCulture); MinPeptideLengthTextBox.Text = task.CommonParameters.DigestionParams.MinPeptideLength.ToString(CultureInfo.InvariantCulture); MaxPeptideLengthTextBox.Text = task.CommonParameters.DigestionParams.MaxPeptideLength == int.MaxValue ? "" : task.CommonParameters.DigestionParams.MaxPeptideLength.ToString(CultureInfo.InvariantCulture); @@ -240,7 +243,7 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) if (!GlobalGuiSettings.CheckTaskSettingsValidity(XLPrecusorMsTlTextBox.Text, productMassToleranceTextBox.Text, missedCleavagesTextBox.Text, maxModificationIsoformsTextBox.Text, MinPeptideLengthTextBox.Text, MaxPeptideLengthTextBox.Text, maxThreadsTextBox.Text, minScoreAllowed.Text, - fieldNotUsed, fieldNotUsed, fieldNotUsed, TopNPeaksTextBox.Text, MinRatioTextBox.Text, null, null, numberOfDatabaseSearchesTextBox.Text, + fieldNotUsed, fieldNotUsed, DeconHostViewModel.PrecursorDeconvolutionParameters.MaxAssumedChargeState.ToString(), TopNPeaksTextBox.Text, MinRatioTextBox.Text, null, null, numberOfDatabaseSearchesTextBox.Text, fieldNotUsed, fieldNotUsed, null, null, null)) { return; @@ -322,12 +325,17 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) } bool _addCompIons = ckbAddCompIon.IsChecked.Value; + DeconvolutionParameters precursorDeconvolutionParameters = DeconHostViewModel.PrecursorDeconvolutionParameters.Parameters; + DeconvolutionParameters productDeconvolutionParameters = DeconHostViewModel.ProductDeconvolutionParameters.Parameters; + bool useProvidedPrecursorInfo = DeconHostViewModel.UseProvidedPrecursors; + bool doPrecursorDeconvolution = DeconHostViewModel.DoPrecursorDeconvolution; + CommonParameters commonParamsToSave = new CommonParameters( precursorMassTolerance: PrecursorMassTolerance, taskDescriptor: OutputFileNameTextBox.Text != "" ? OutputFileNameTextBox.Text : "XLSearchTask", productMassTolerance: ProductMassTolerance, - doPrecursorDeconvolution: deconvolutePrecursors.IsChecked.Value, - useProvidedPrecursorInfo: useProvidedPrecursor.IsChecked.Value, + doPrecursorDeconvolution: doPrecursorDeconvolution, + useProvidedPrecursorInfo: useProvidedPrecursorInfo, digestionParams: digestionParamsToSave, trimMs1Peaks: trimMs1.IsChecked.Value, trimMsMsPeaks: trimMsMs.IsChecked.Value, @@ -343,7 +351,9 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) totalPartitions: int.Parse(numberOfDatabaseSearchesTextBox.Text, CultureInfo.InvariantCulture), listOfModsVariable: listOfModsVariable, listOfModsFixed: listOfModsFixed, - assumeOrphanPeaksAreZ1Fragments: protease.Name != "top-down"); + assumeOrphanPeaksAreZ1Fragments: protease.Name != "top-down", + precursorDeconParams: precursorDeconvolutionParameters, + productDeconParams: productDeconvolutionParameters); TheTask.CommonParameters = commonParamsToSave;