From 98ebdaf3604fcc52455d3cccdb2ef306fe8315cf Mon Sep 17 00:00:00 2001 From: Yuki Matsuzawa Date: Fri, 7 Aug 2026 13:45:15 +0900 Subject: [PATCH 1/2] Improve LCMS alignment initialization Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../Model/Dims/DimsMethodModel.cs | 16 ++++++------- .../Model/Lcimms/LcimmsMethodModel.cs | 6 ++--- .../Model/Lcms/LcmsMethodModel.cs | 23 +++++++++---------- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/MSDIAL5/MsdialGuiApp/Model/Dims/DimsMethodModel.cs b/src/MSDIAL5/MsdialGuiApp/Model/Dims/DimsMethodModel.cs index 7c3e9207c..c46b77d4f 100644 --- a/src/MSDIAL5/MsdialGuiApp/Model/Dims/DimsMethodModel.cs +++ b/src/MSDIAL5/MsdialGuiApp/Model/Dims/DimsMethodModel.cs @@ -184,17 +184,17 @@ public override async Task RunAsync(ProcessOption processOption, CancellationTok _matchResultEvaluator = FacadeMatchResultEvaluator.FromDataBases(Storage.DataBases); - IAnnotationProcess annotationProcess; - if (Storage.Parameter.TargetOmics == TargetOmics.Lipidomics && - (Storage.Parameter.CollistionType == CollisionType.EIEIO || Storage.Parameter.CollistionType == CollisionType.OAD || Storage.Parameter.CollistionType == CollisionType.EID)) { - annotationProcess = BuildEadLipidomicsAnnotationProcess(); - } - else { - annotationProcess = BuildAnnotationProcess(); - } // Run Identification if (processOption.HasFlag(ProcessOption.Identification)) { + IAnnotationProcess annotationProcess; + if (Storage.Parameter.TargetOmics == TargetOmics.Lipidomics && + (Storage.Parameter.CollistionType == CollisionType.EIEIO || Storage.Parameter.CollistionType == CollisionType.OAD || Storage.Parameter.CollistionType == CollisionType.EID)) { + annotationProcess = BuildEadLipidomicsAnnotationProcess(); + } + else { + annotationProcess = BuildAnnotationProcess(); + } var usable = Math.Max(Storage.Parameter.ProcessBaseParam.UsableNumThreads / 2, 1); var processor = new ProcessFile(ProviderFactory, Storage, annotationProcess, _matchResultEvaluator); var runner = new ProcessRunner(processor, usable); diff --git a/src/MSDIAL5/MsdialGuiApp/Model/Lcimms/LcimmsMethodModel.cs b/src/MSDIAL5/MsdialGuiApp/Model/Lcimms/LcimmsMethodModel.cs index e65b3fb42..f5fa30d58 100644 --- a/src/MSDIAL5/MsdialGuiApp/Model/Lcimms/LcimmsMethodModel.cs +++ b/src/MSDIAL5/MsdialGuiApp/Model/Lcimms/LcimmsMethodModel.cs @@ -220,11 +220,11 @@ public override async Task RunAsync(ProcessOption processOption, CancellationTok var starttimestamp = DateTime.Now.ToString("yyyyMMddHHmm"); var stopwatch = Stopwatch.StartNew(); - // Set analysis param - var annotationProcess = BuildAnnotationProcess(); - // Run Identification if (processOption.HasFlag(ProcessOption.Identification)) { + // Set analysis param + var annotationProcess = BuildAnnotationProcess(); + int usable = Math.Max(Storage.Parameter.ProcessBaseParam.UsableNumThreads / 2, 1); FileProcess processor = new FileProcess(providerFactory, accProviderFactory, annotationProcess, matchResultEvaluator, Storage, isGuiProcess: true); var runner = new ProcessRunner(processor, usable); diff --git a/src/MSDIAL5/MsdialGuiApp/Model/Lcms/LcmsMethodModel.cs b/src/MSDIAL5/MsdialGuiApp/Model/Lcms/LcmsMethodModel.cs index a3a0126ec..20388a4cb 100644 --- a/src/MSDIAL5/MsdialGuiApp/Model/Lcms/LcmsMethodModel.cs +++ b/src/MSDIAL5/MsdialGuiApp/Model/Lcms/LcmsMethodModel.cs @@ -22,7 +22,6 @@ using Reactive.Bindings.Notifiers; using System; using System.Collections.Generic; -using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Reactive.Linq; @@ -252,20 +251,20 @@ public override async Task RunAsync(ProcessOption processOption, CancellationTok var parameter = _storage.Parameter; var starttimestamp = DateTime.Now.ToString("yyyyMMddHHmm"); var stopwatch = Stopwatch.StartNew(); - IAnnotationProcess annotationProcess; - if (parameter.TargetOmics == TargetOmics.Proteomics) { - annotationProcess = BuildProteoMetabolomicsAnnotationProcess(); - } - else if(parameter.TargetOmics == TargetOmics.Lipidomics && - (parameter.CollistionType == CollisionType.EIEIO || parameter.CollistionType == CollisionType.OAD || parameter.CollistionType == CollisionType.EID)) { - annotationProcess = BuildEadLipidomicsAnnotationProcess(); - } - else { - annotationProcess = BuildAnnotationProcess(); - } // Run Identification if (processOption.HasFlag(ProcessOption.Identification)) { + IAnnotationProcess annotationProcess; + if (parameter.TargetOmics == TargetOmics.Proteomics) { + annotationProcess = BuildProteoMetabolomicsAnnotationProcess(); + } + else if(parameter.TargetOmics == TargetOmics.Lipidomics && + (parameter.CollistionType == CollisionType.EIEIO || parameter.CollistionType == CollisionType.OAD || parameter.CollistionType == CollisionType.EID)) { + annotationProcess = BuildEadLipidomicsAnnotationProcess(); + } + else { + annotationProcess = BuildAnnotationProcess(); + } var processor = new MsdialLcMsApi.Process.FileProcess(_providerFactory, _storage, annotationProcess, _matchResultEvaluator); var runner = new ProcessRunner(processor, Math.Max(1, _storage.Parameter.ProcessBaseParam.UsableNumThreads / 2)); if (!ProcessFiles(_storage.AnalysisFiles, runner, processOption)) { From 71135f46a86e9f471f8a6fc8184e5ee3a7e11c95 Mon Sep 17 00:00:00 2001 From: Yuki Matsuzawa Date: Fri, 7 Aug 2026 18:04:03 +0900 Subject: [PATCH 2/2] Lazy-load MS-FINDER databases Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../Setting/InternalMsfinderSettingModel.cs | 78 ++++++++++--------- 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/src/MSDIAL5/MsdialGuiApp/Model/Setting/InternalMsfinderSettingModel.cs b/src/MSDIAL5/MsdialGuiApp/Model/Setting/InternalMsfinderSettingModel.cs index 83c863e19..724da7b27 100644 --- a/src/MSDIAL5/MsdialGuiApp/Model/Setting/InternalMsfinderSettingModel.cs +++ b/src/MSDIAL5/MsdialGuiApp/Model/Setting/InternalMsfinderSettingModel.cs @@ -25,56 +25,62 @@ namespace CompMs.App.Msdial.Model.Setting { internal class InternalMsfinderSettingModel : BindableBase { - internal readonly MsfinderParameterSetting parameter; - internal readonly AnalysisParamOfMsfinder analysisParam; - internal readonly AlignmentSpectraExportGroupModel exporter; - internal readonly ReadOnlyReactivePropertySlim CurrentAlignmentModel; + private readonly MsfinderParameterSetting _parameter; + private readonly AnalysisParamOfMsfinder _analysisParam; + private readonly AlignmentSpectraExportGroupModel _exporter; + private readonly ReadOnlyReactivePropertySlim _currentAlignmentModel; public InternalMsfinderSettingModel(MsfinderParameterSetting projectParameter, AlignmentSpectraExportGroupModel alignmentExporter, ReadOnlyReactivePropertySlim currentAlignmentModel) { - parameter = projectParameter; - exporter = alignmentExporter; - CurrentAlignmentModel = currentAlignmentModel; - analysisParam = projectParameter.AnalysisParameter; + _parameter = projectParameter; + _exporter = alignmentExporter; + _currentAlignmentModel = currentAlignmentModel; + _analysisParam = projectParameter.AnalysisParameter; } - private readonly List productIonDB = CompMs.Common.FormulaGenerator.Parser.FragmentDbParser.GetProductIonDB( + private List ProductIonDB => _productIonDB ??= CompMs.Common.FormulaGenerator.Parser.FragmentDbParser.GetProductIonDB( @"Resources\msfinderLibrary\ProductIonLib_vs1.pid", out string _); - private readonly List neutralLossDB = CompMs.Common.FormulaGenerator.Parser.FragmentDbParser.GetNeutralLossDB( + private List? _productIonDB; + private List NeutralLossDB => _neutralLossDB ??= CompMs.Common.FormulaGenerator.Parser.FragmentDbParser.GetNeutralLossDB( @"Resources\msfinderLibrary\NeutralLossDB_vs2.ndb", out string _); - private readonly List existFormulaDB = ExistFormulaDbParcer.ReadExistFormulaDB( + private List? _neutralLossDB; + private List ExistFormulaDB => _existFormulaDB ??= ExistFormulaDbParcer.ReadExistFormulaDB( @"Resources\msfinderLibrary\MsfinderFormulaDB-VS13.efd", out string _); - private readonly List existStructureDB = FileStorageUtility.GetExistStructureDB(); + private List? _existFormulaDB; + private List ExistStructureDB => _existStructureDB ??= FileStorageUtility.GetExistStructureDB(); + private List? _existStructureDB; + private List MineStructureDB => _mineStructureDB ??= FileStorageUtility.GetMinesStructureDB(); + private List? _mineStructureDB; + private List FragmentOntologyDB => _fragmentOntologyDB ??= FileStorageUtility.GetUniqueFragmentDB(); + private List? _fragmentOntologyDB; + private List EiFragmentDB => _eiFragmentDB ??= FileStorageUtility.GetEiFragmentDB(); + private List? _eiFragmentDB; - private readonly List mineStructureDB = FileStorageUtility.GetMinesStructureDB(); - private readonly List fragmentOntologyDB = FileStorageUtility.GetUniqueFragmentDB(); private readonly List mspDB = []; private List userDefinedStructureDB = []; - private readonly List eiFragmentDB = FileStorageUtility.GetEiFragmentDB(); - public InternalMsFinder? Process() { - if (CurrentAlignmentModel.Value is null) { + if (_currentAlignmentModel.Value is null) { return null; } SetUserDefinedStructureDB(); string fullpath; var dt = DateTime.Now; - if (parameter.IsCreateNewProject) { - var directory = Path.GetDirectoryName(CurrentAlignmentModel.Value.AlignmentFile.FilePath); // project folder + if (_parameter.IsCreateNewProject) { + var directory = Path.GetDirectoryName(_currentAlignmentModel.Value.AlignmentFile.FilePath); // project folder string foldername; - if (parameter.IsUseAutoDefinedFolderName) { - foldername = $"{CurrentAlignmentModel.Value.AlignmentFile.FileName}_{dt:yyyyMMddHHmmss}"; + if (_parameter.IsUseAutoDefinedFolderName) { + foldername = $"{_currentAlignmentModel.Value.AlignmentFile.FileName}_{dt:yyyyMMddHHmmss}"; }else{ - foldername = parameter.UserDefinedProjectFolderName; + foldername = _parameter.UserDefinedProjectFolderName; } fullpath = Path.Combine(directory, foldername); // export folder if (!Directory.Exists(fullpath)) { Directory.CreateDirectory(fullpath); } - exporter.Export(CurrentAlignmentModel.Value.AlignmentFile, fullpath, null); + _exporter.Export(_currentAlignmentModel.Value.AlignmentFile, fullpath, null); }else{ - fullpath = parameter.ExistProjectPath; + fullpath = _parameter.ExistProjectPath; } var matFilePaths = Directory.GetFiles(fullpath, "*.mat"); @@ -89,30 +95,30 @@ public InternalMsfinderSettingModel(MsfinderParameterSetting projectParameter, A msfinderQueryFiles.Add(msfinderQueryFile); } - if (parameter.IsFormulaFinder) { + if (_parameter.IsFormulaFinder) { var paramfile = Path.Combine(fullpath, $"batchparam-{dt:yyyy_MM_dd_HH_mm_ss}.txt"); - MsFinderIniParser.Write(analysisParam, paramfile); + MsFinderIniParser.Write(_analysisParam, paramfile); foreach (var msfinderQueryFile in msfinderQueryFiles) { - var rawData = RawDataParcer.RawDataFileReader(msfinderQueryFile.RawDataFilePath, analysisParam); - var formulaResults = MolecularFormulaFinder.GetMolecularFormulaList(productIonDB, neutralLossDB, existFormulaDB, rawData, analysisParam); + var rawData = RawDataParcer.RawDataFileReader(msfinderQueryFile.RawDataFilePath, _analysisParam); + var formulaResults = MolecularFormulaFinder.GetMolecularFormulaList(ProductIonDB, NeutralLossDB, ExistFormulaDB, rawData, _analysisParam); FormulaResultParcer.FormulaResultsWriter(msfinderQueryFile.FormulaFilePath, formulaResults); } } - if (parameter.IsStructureFinder) { + if (_parameter.IsStructureFinder) { var finder = new StructureFinderBatchProcess(); - finder.Process(msfinderQueryFiles, analysisParam, existStructureDB, userDefinedStructureDB, mineStructureDB, fragmentOntologyDB, mspDB, eiFragmentDB); + finder.Process(msfinderQueryFiles, _analysisParam, ExistStructureDB, userDefinedStructureDB, MineStructureDB, FragmentOntologyDB, mspDB, EiFragmentDB); } - if (CurrentAlignmentModel.Value.AlignmentSpotSource.Spots is null) { + if (_currentAlignmentModel.Value.AlignmentSpotSource.Spots is null) { return null; } - return new InternalMsFinder(msfinderQueryFiles, analysisParam, userDefinedStructureDB); + return new InternalMsFinder(msfinderQueryFiles, _analysisParam, userDefinedStructureDB); } private void SetUserDefinedStructureDB() { - if (parameter.IsUserDefinedDB) { - var userDefinedDbFilePath = parameter.UserDefinedDbFilePath; + if (_parameter.IsUserDefinedDB) { + var userDefinedDbFilePath = _parameter.UserDefinedDbFilePath; if (userDefinedDbFilePath == null || userDefinedDbFilePath == string.Empty) { MessageBox.Show("Select your own structure database, or uncheck the user-defined database option.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return; @@ -122,13 +128,13 @@ private void SetUserDefinedStructureDB() { return; } - var userDefinedDb = ExistStructureDbParser.ReadExistStructureDB(parameter.UserDefinedDbFilePath); + var userDefinedDb = ExistStructureDbParser.ReadExistStructureDB(_parameter.UserDefinedDbFilePath); if (userDefinedDb == null || userDefinedDb.Count == 0) { MessageBox.Show("Your own structure DB does not have the queries or the data format is not correct.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return; } - ExistStructureDbParser.SetExistStructureDbInfoToUserDefinedDB(existStructureDB, userDefinedDb); + ExistStructureDbParser.SetExistStructureDbInfoToUserDefinedDB(ExistStructureDB, userDefinedDb); userDefinedStructureDB = userDefinedDb; } else