diff --git a/MetaMorpheus/GUI/TaskWindows/GPTMDTaskWindow.xaml b/MetaMorpheus/GUI/TaskWindows/GPTMDTaskWindow.xaml index bfb5d6c8a..2341862a1 100644 --- a/MetaMorpheus/GUI/TaskWindows/GPTMDTaskWindow.xaml +++ b/MetaMorpheus/GUI/TaskWindows/GPTMDTaskWindow.xaml @@ -48,34 +48,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/GPTMDTaskWindow.xaml.cs b/MetaMorpheus/GUI/TaskWindows/GPTMDTaskWindow.xaml.cs index 4c3449f93..37d595cfa 100644 --- a/MetaMorpheus/GUI/TaskWindows/GPTMDTaskWindow.xaml.cs +++ b/MetaMorpheus/GUI/TaskWindows/GPTMDTaskWindow.xaml.cs @@ -29,6 +29,7 @@ public partial class GptmdTaskWindow : Window private readonly ObservableCollection GptmdModTypeForTreeViewObservableCollection = new ObservableCollection(); private bool AutomaticallyAskAndOrUpdateParametersBasedOnProtease = true; private CustomFragmentationWindow CustomFragmentationWindow; + private DeconHostViewModel DeconHostViewModel; public GptmdTaskWindow(GptmdTask myGPTMDtask) { @@ -39,6 +40,7 @@ public GptmdTaskWindow(GptmdTask myGPTMDtask) PopulateChoices(); UpdateFieldsFromTask(TheTask); AutomaticallyAskAndOrUpdateParametersBasedOnProtease = true; + DeisotopingControl.DataContext = DeconHostViewModel; if (myGPTMDtask == null) { @@ -62,10 +64,10 @@ private void Row_DoubleClick(object sender, MouseButtonEventArgs e) private void UpdateFieldsFromTask(GptmdTask task) { + DeconHostViewModel = new DeconHostViewModel(TheTask.CommonParameters.PrecursorDeconvolutionParameters, + TheTask.CommonParameters.ProductDeconvolutionParameters, + TheTask.CommonParameters.UseProvidedPrecursorInfo, TheTask.CommonParameters.DoPrecursorDeconvolution); ProteaseComboBox.SelectedItem = task.CommonParameters.DigestionParams.Protease; //protease needs to come first or recommended settings can overwrite the actual settings - UseProvidedPrecursor.IsChecked = task.CommonParameters.UseProvidedPrecursorInfo; - DeconvolutePrecursors.IsChecked = task.CommonParameters.DoPrecursorDeconvolution; - DeconvolutionMaxAssumedChargeStateTextBox.Text = task.CommonParameters.DeconvolutionMaxAssumedChargeState.ToString(); MissedCleavagesTextBox.Text = task.CommonParameters.DigestionParams.MaxMissedCleavages == int.MaxValue ? "" : 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); @@ -260,8 +262,8 @@ private void ProteaseSpecificUpdate(object sender, SelectionChangedEventArgs e) case "top-down": if (UpdateGUISettings.UseTopDownRecommendedSettings()) { - UseProvidedPrecursor.IsChecked = false; - DeconvolutionMaxAssumedChargeStateTextBox.Text = "60"; + DeconHostViewModel.UseProvidedPrecursors = false; + DeconHostViewModel.PrecursorDeconvolutionParameters.MaxAssumedChargeState = 60; TrimMsMs.IsChecked = false; //uncheck all variable mods foreach (var mod in VariableModTypeForTreeViewObservableCollection) @@ -354,7 +356,7 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) if (!GlobalGuiSettings.CheckTaskSettingsValidity(PrecursorMassToleranceTextBox.Text, ProductMassToleranceTextBox.Text, MissedCleavagesTextBox.Text, MaxModificationIsoformsTextBox.Text, MinPeptideLengthTextBox.Text, MaxPeptideLengthTextBox.Text, MaxThreadsTextBox.Text, MinScoreAllowed.Text, - fieldNotUsed, fieldNotUsed, DeconvolutionMaxAssumedChargeStateTextBox.Text, NumberOfPeaksToKeepPerWindowTextBox.Text, MinimumAllowedIntensityRatioToBasePeakTexBox.Text, + fieldNotUsed, fieldNotUsed, DeconHostViewModel.PrecursorDeconvolutionParameters.MaxAssumedChargeState.ToString(), NumberOfPeaksToKeepPerWindowTextBox.Text, MinimumAllowedIntensityRatioToBasePeakTexBox.Text, null, null, fieldNotUsed, fieldNotUsed, fieldNotUsed, null, null, null)) { return; @@ -441,10 +443,14 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) } bool parseMaxThreadsPerFile = int.Parse(MaxThreadsTextBox.Text, CultureInfo.InvariantCulture) <= Environment.ProcessorCount && int.Parse(MaxThreadsTextBox.Text, CultureInfo.InvariantCulture) > 0; + DeconvolutionParameters precursorDeconvolutionParameters = DeconHostViewModel.PrecursorDeconvolutionParameters.Parameters; + DeconvolutionParameters productDeconvolutionParameters = DeconHostViewModel.ProductDeconvolutionParameters.Parameters; + bool useProvidedPrecursorInfo = DeconHostViewModel.UseProvidedPrecursors; + bool doPrecursorDeconvolution = DeconHostViewModel.DoPrecursorDeconvolution; + CommonParameters commonParamsToSave = new CommonParameters( - useProvidedPrecursorInfo: UseProvidedPrecursor.IsChecked.Value, - deconvolutionMaxAssumedChargeState: int.Parse(DeconvolutionMaxAssumedChargeStateTextBox.Text, CultureInfo.InvariantCulture), - doPrecursorDeconvolution: DeconvolutePrecursors.IsChecked.Value, + useProvidedPrecursorInfo: useProvidedPrecursorInfo, + doPrecursorDeconvolution: doPrecursorDeconvolution, taskDescriptor: OutputFileNameTextBox.Text != "" ? OutputFileNameTextBox.Text : "GPTMDTask", maxThreadsToUsePerFile: parseMaxThreadsPerFile ? int.Parse(MaxThreadsTextBox.Text, CultureInfo.InvariantCulture) : new CommonParameters().MaxThreadsToUsePerFile, digestionParams: new DigestionParams( @@ -468,7 +474,9 @@ private void SaveButton_Click(object sender, RoutedEventArgs e) assumeOrphanPeaksAreZ1Fragments: protease.Name != "top-down", addCompIons: AddCompIonCheckBox.IsChecked.Value, minVariantDepth: minVariantDepth, - maxHeterozygousVariants: maxHeterozygousVariants); + maxHeterozygousVariants: maxHeterozygousVariants, + precursorDeconParams: precursorDeconvolutionParameters, + productDeconParams: productDeconvolutionParameters); TheTask.GptmdParameters.ListOfModsGptmd = new List<(string, string)>(); foreach (var heh in GptmdModTypeForTreeViewObservableCollection) diff --git a/MetaMorpheus/GUI/TaskWindows/GlycoSearchTaskWindow.xaml b/MetaMorpheus/GUI/TaskWindows/GlycoSearchTaskWindow.xaml index 7be5c8b7d..5e546dc80 100644 --- a/MetaMorpheus/GUI/TaskWindows/GlycoSearchTaskWindow.xaml +++ b/MetaMorpheus/GUI/TaskWindows/GlycoSearchTaskWindow.xaml @@ -159,20 +159,7 @@ - - - - - - - - - - - - - - + diff --git a/MetaMorpheus/GUI/TaskWindows/GlycoSearchTaskWindow.xaml.cs b/MetaMorpheus/GUI/TaskWindows/GlycoSearchTaskWindow.xaml.cs index e63556f94..59034fe9c 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) { @@ -159,8 +161,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); @@ -243,7 +246,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; @@ -369,12 +372,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, @@ -387,7 +395,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/SearchTaskWindow.xaml b/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml index 98514670c..3b0914ecf 100644 --- a/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml +++ b/MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml @@ -661,41 +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 1767492b3..124ceebd5 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) { @@ -285,18 +287,19 @@ 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); + 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); @@ -425,6 +428,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, @@ -436,7 +440,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, @@ -567,14 +571,19 @@ 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), 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), @@ -596,7 +605,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) { @@ -880,8 +891,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; diff --git a/MetaMorpheus/GUI/TaskWindows/XLSearchTaskWindow.xaml b/MetaMorpheus/GUI/TaskWindows/XLSearchTaskWindow.xaml index 81de1944f..9de85d76b 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 42eac5f43..47c07d2cb 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) { @@ -150,8 +152,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); @@ -235,7 +238,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; @@ -317,12 +320,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, @@ -338,7 +346,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; diff --git a/MetaMorpheus/GUI/Util/Converters/DeconvolutionTypeToControlConverter.cs b/MetaMorpheus/GUI/Util/Converters/DeconvolutionTypeToControlConverter.cs new file mode 100644 index 000000000..1daf97137 --- /dev/null +++ b/MetaMorpheus/GUI/Util/Converters/DeconvolutionTypeToControlConverter.cs @@ -0,0 +1,53 @@ +using System; +using System.Globalization; +using GuiFunctions; +using MassSpectrometry; + +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 not DeconParamsViewModel viewModel) + throw new ArgumentException("Invalid value type", nameof(value)); + + switch (viewModel.DeconvolutionType) + { + case DeconvolutionType.ClassicDeconvolution: + return new ClassicDeconParamsControl() { DataContext = value as ClassicDeconParamsViewModel }; + + case DeconvolutionType.ExampleNewDeconvolutionTemplate: + default: + throw new ArgumentException("Invalid DeconvolutionType", 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 new file mode 100644 index 000000000..dcd2e62ba --- /dev/null +++ b/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + diff --git a/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml.cs b/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml.cs new file mode 100644 index 000000000..c866b44c9 --- /dev/null +++ b/MetaMorpheus/GUI/Views/Deconvolution/ClassicDeconParamsControl.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +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..ca2a2f1fe --- /dev/null +++ b/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..3c4c7f862 --- /dev/null +++ b/MetaMorpheus/GUI/Views/Deconvolution/HostDeconParamControl.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +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..07fc8fc60 --- /dev/null +++ b/MetaMorpheus/GuiFunctions/MzLibExtensions.cs @@ -0,0 +1,36 @@ +using System; +using MassSpectrometry; + +namespace GuiFunctions +{ + /// + /// Provides additional functionality for the MzLib library. + /// + 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 new file mode 100644 index 000000000..87374963f --- /dev/null +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/ClassicDeconParamsViewModel.cs @@ -0,0 +1,44 @@ +using MassSpectrometry; + +namespace GuiFunctions; + +public sealed 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)); + } + } + + 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 new file mode 100644 index 000000000..b192a349c --- /dev/null +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconHostViewModel.cs @@ -0,0 +1,184 @@ +#nullable enable +using System; +using System.Collections.Generic; +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 +{ + /// + /// 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; + + // 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()) + { + 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: // This will only be hit if a new deconvolution type is added to mzlib and not handled here + throw new ArgumentOutOfRangeException(); + } + } + + // If deconvolution parameters are not set, default to MetaMorpheus defaults + 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 + + 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 + + /// + /// 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!; + set + { + _precursorDeconvolutionParameters = value; + OnPropertyChanged(nameof(PrecursorDeconvolutionParameters)); + } + } + + /// + /// 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!; + set + { + _productDeconvolutionParameters = value; + OnPropertyChanged(nameof(ProductDeconvolutionParameters)); + } + } + + /// + /// Hides the decon type selection combo box if only one options is present + /// + public bool DisplayDeconSelectionComboBox => PrecursorDeconvolutionParametersList.Count > 1 || ProductDeconvolutionParametersList.Count > 1; +} + +[ExcludeFromCodeCoverage] // Model used only for visualizing the view in visual studio +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 new file mode 100644 index 000000000..a09e00169 --- /dev/null +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/DeconParamsViewModel.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using MassSpectrometry; + +namespace GuiFunctions; + +/// +/// Base Deconvolution Parameters view model +/// Used to wrap the DeconvolutionParameters object +/// Contains only shared information between different DeconvolutionParameters +/// +public abstract class DeconParamsViewModel : BaseViewModel, IEquatable +{ + + private int _previousMinAssumedChargeState; + private int _previousMaxAssumedChargeState; + + public DeconvolutionType DeconvolutionType => Parameters.DeconvolutionType; + public abstract DeconvolutionParameters Parameters { get; protected set; } + + + /// + /// 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 + { + 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 + { + 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)); + + // 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; + + 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) + { + 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); + } +} + + +[ExcludeFromCodeCoverage] // Model used only for visualizing the view in visual studio +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 new file mode 100644 index 000000000..1a09d8090 --- /dev/null +++ b/MetaMorpheus/GuiFunctions/ViewModels/Deconvolution/IsoDecDeconParamsViewModel.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MassSpectrometry; + +namespace GuiFunctions +{ + // Coming Soon + [ExcludeFromCodeCoverage] + public sealed class IsoDecDeconParamsViewModel : DeconParamsViewModel + { + public override DeconvolutionParameters Parameters { get; protected set; } + + + public override string ToString() => "IsoDec"; + } +} diff --git a/MetaMorpheus/MetaMorpheus.sln.DotSettings b/MetaMorpheus/MetaMorpheus.sln.DotSettings index 3cb2a8c2a..e9ee1d4cf 100644 --- a/MetaMorpheus/MetaMorpheus.sln.DotSettings +++ b/MetaMorpheus/MetaMorpheus.sln.DotSettings @@ -6,6 +6,8 @@ True True True + True + True True True True 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/DeconHostViewModelTest.cs b/MetaMorpheus/Test/GuiTests/DeconHostViewModelTest.cs new file mode 100644 index 000000000..7301ed4e0 --- /dev/null +++ b/MetaMorpheus/Test/GuiTests/DeconHostViewModelTest.cs @@ -0,0 +1,224 @@ +using System; +using System.Linq; +using EngineLayer; +using GuiFunctions; +using MassSpectrometry; +using NUnit.Framework; + +namespace Test.GuiTests; + +[TestFixture] +public class DeconHostViewModelTests +{ + 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_GlobalVariables_Proteoform() + { + // 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_GlobalVariables_Oligo() + { + // 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"; + } + + [Test] + [NonParallelizable] + public void TestDeconHostViewModel_GlobalVariables_Unknown() + { + // Arrange + GlobalVariables.AnalyteType = "ThisWasSetWrong"; + + // Act & Assert + Assert.Throws(() => + { + var deconHostViewModel = new DeconHostViewModel(null, null); + }); + + Assert.Throws(() => + { + var deconHostViewModel = new DeconHostViewModel(ClassicPrecursorDeconvolutionParameters, null); + }); + + // Revert back to default + GlobalVariables.AnalyteType = "Peptide"; + } + + [Test] + public void TestDisplayDeconSelectionComboBox_MultipleOptions_Precursor() + { + // Arrange + var viewModel = new DeconHostViewModel(); + viewModel.PrecursorDeconvolutionParametersList.Add(ClassicPrecursorDeconvolutionParameters.ToViewModel()); + + // Act + var result = viewModel.DisplayDeconSelectionComboBox; + + // Assert + Assert.That(result, Is.True); + } + + [Test] + public void TestDisplayDeconSelectionComboBox_MultipleOptions_Product() + { + // Arrange + var viewModel = new DeconHostViewModel(); + viewModel.ProductDeconvolutionParametersList.Add(ClassicProductDeconvolutionParameters.ToViewModel()); + + // Act + var result = viewModel.DisplayDeconSelectionComboBox; + + // Assert + Assert.That(result, Is.True); + } + + [Test] + public void TestDisplayDeconSelectionComboBox_SingleOption() + { + // Arrange + var viewModel = new DeconHostViewModel(); + + // Act + var result = viewModel.DisplayDeconSelectionComboBox; + + // Assert + Assert.That(result, Is.False); + } +} \ 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..1093d9d1e --- /dev/null +++ b/MetaMorpheus/Test/GuiTests/DeconParamsViewModelTest.cs @@ -0,0 +1,267 @@ +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_PositiveMode() + { + // Initial setup with positive polarity + var parameters = new ClassicDeconvolutionParameters(1, 12, 5, 3, Polarity.Positive); + var viewModel = new TestDeconParamsViewModel(parameters); + + // Set previous values + viewModel.MinAssumedChargeState = 5; + viewModel.MaxAssumedChargeState = 10; + + // Change to negative polarity + viewModel.Polarity = Polarity.Negative; + + // Check that defaults got set properly + Assert.That(viewModel.MinAssumedChargeState, Is.EqualTo(-20)); + Assert.That(viewModel.MaxAssumedChargeState, Is.EqualTo(-1)); + + // Change back to positive polarity + viewModel.Polarity = Polarity.Positive; + + // Assert that previous values are restored correctly + Assert.That(viewModel.MinAssumedChargeState, Is.EqualTo(5)); + Assert.That(viewModel.MaxAssumedChargeState, Is.EqualTo(10)); + } + + [Test] + public void TestPolaritySwitchWithPreviousValues_NegativeMode() + { + // Initial setup with negative polarity + var parameters = new ClassicDeconvolutionParameters(-20, -1, 5, 3, Polarity.Negative); + var viewModel = new TestDeconParamsViewModel(parameters); + + // Set previous values + viewModel.MinAssumedChargeState = -10; + viewModel.MaxAssumedChargeState = -5; + + // Change to positive polarity + viewModel.Polarity = Polarity.Positive; + + // Check that defaults got set properly + Assert.That(viewModel.MinAssumedChargeState, Is.EqualTo(1)); + Assert.That(viewModel.MaxAssumedChargeState, Is.EqualTo(12)); + + // Change back to negative polarity + viewModel.Polarity = Polarity.Negative; + + // Assert that previous 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); + Assert.That(viewModel.Equals((object)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); + Assert.That(viewModel.Equals((object)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); + Assert.That(viewModel.Equals((object)new BaseViewModel()), 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); + Assert.That(viewModel1.Equals(null), 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_obj(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((object)viewModel2), Is.False); + Assert.That(viewModel1.Equals((object)null), 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 TestEquals_SameParameters_Obj() + { + 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((object)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)); + + viewModel = new TestDeconParamsViewModel(null); + Assert.That(viewModel.GetHashCode(), Is.EqualTo(0)); + } +} \ 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