Skip to content

Added MS/MS Spectra Similarity Display Across Samples for Aligned Ions#610

Merged
YukiMatsuzawa merged 83 commits intomasterfrom
feature/spectra-match-grouping
Aug 20, 2025
Merged

Added MS/MS Spectra Similarity Display Across Samples for Aligned Ions#610
YukiMatsuzawa merged 83 commits intomasterfrom
feature/spectra-match-grouping

Conversation

@YukiMatsuzawa
Copy link
Copy Markdown
Contributor

This pull request introduces a new feature that visualizes MS/MS spectral similarity across samples for each aligned ion.

Key Updates:

  • SpectraSimilarityMapViewModel.cs / SpectraGroupingViewModel.cs: Implemented to manage the logic for grouping and comparing spectra across samples.

  • Ms2Quantifier.cs / Ms2QuantResult.cs: Added to support MS/MS data handling and quantification.

  • HeatmapControl.cs: Enhanced to support similarity-based visualizations with configurable value ranges.

  • MsScanMatchingBenchmark.cs: Added for performance evaluation of MS/MS spectrum matching methods.

This feature enables users to assess the consistency of MS/MS spectra across samples after alignment, improving interpretability and data quality checks in multi-sample analyses.

Added GetBatchSimpleDotProduct method in MsScanMatching class to calculate dot product similarity for a batch of IMSScanProperty objects. Introduced MsScanMatchingTests class with tests for self-comparison, commutativity, and batch vs individual similarity. Added helper methods CreateScan and CreateScanBatch for test data generation.
Modified `GetBatchSimpleDotProduct_MatchesIndividual` in `MsScanMatchingTests` to use `[DataTestMethod]` and `[DataRow]` attributes for data-driven testing. Updated method to accept parameters `size`, `nPeak`, `vPeak`, and `seed`. Initialized `scans` with a random number generator using `seed` and `CreateScanBatch`. This enhances test robustness and coverage.
Improved code readability and maintainability by adding curly braces to all if-else statements. This change helps prevent potential errors when adding new lines of code in the future. Additionally, moved the `size++` operation to a new line for better readability and enclosed `break` statements within curly braces for consistency.
Replaced `SummedPeak` arrays with `double` arrays for storing intensity values. Updated `measuredMassBuffer` and `referenceMassBuffer` to `measuredIntensityBuffer` and `referenceIntensityBuffer`. Allocations now use `ArrayPool<double>.Shared`. Normalization and final result calculation have been simplified.
Updated CommonStandardTestHelper.csproj to use the latest C# language version. Added two new extension methods: ToStringForTest and ShowForTest.
- Added using directive for `CompMs.Common.Components.Tests` in `MsScanMatchingTests.cs`.
- Introduced `GetSimpleDotProduct_MassBeginWorks` test method.
- Added data-driven `GetBatchSimpleDotProduct_MassBeginWorks` test method.
- Refined `CreateScan` method with concise increment operation.
- Enhanced error handling in `GetBatchSimpleDotProduct_MassBeginWorks` for detailed assertion output.
Added GetSimpleDotProduct_MergeIfClose test to MsScanMatchingTests.
This test ensures that the GetSimpleDotProduct method correctly merges
spectra with close mass values within a specified tolerance. The test
asserts that the dot product is 0.5 with a tolerance of 0.00001. The
spectra of the scans are printed for verification. Existing tests
remain unchanged.
Reorganized variable declarations for better readability and
maintainability. Simplified loop logic by updating index
variables within the loop headers and removing redundant
assignments. Added a condition to handle cases where one
peak list is exhausted before the other, ensuring `focusedMz`
is updated correctly. Adjusted `focusedMz` initialization to
start within the specified mass range. Updated test
expectations in `MsScanMatchingTests` to reflect the correct
similarity value of `1d` for a scan compared to itself.
Simplify intensity buffer handling by removing rented arrays and
accumulating scalar values directly within the main loop. This
eliminates post-loop processing and buffer management, reduces
memory allocation overhead, and potentially improves performance.
Remove `baseM` and `baseR` variables to streamline calculations.
Introduce GetBatchSimpleDotProduct_ContainsNoPeakScan test in MsScanMatchingTests to handle scans with null spectra. Modify existing test to ensure self-similarity is always 1. Initialize scans with null spectra and assert similarity matrix with tolerance of 0.00001.
Added a private static method `IsAvailableSpectrum` to check if the `Spectrum` property of an `IMSScanProperty` object is not null and has a count greater than zero. Modified `GetBatchSimpleDotProduct` to iterate over `props.Length` for initializing the `result` array and added conditional compilation for filling the array with `-1` values. Refactored nested loops to use a list of indices (`availableIndex`) where the `Spectrum` is available, improving readability and performance by focusing only on available spectra and reducing redundant checks.
Enhanced efficiency and accuracy in `MsScanMatching.cs` by using a merged and sorted array of peaks, and updated scalar value and covariance calculations.

In `MsScanMatchingTests.cs`, added new test cases and made tests more flexible to enhance coverage and debugging capabilities.
Refactored code to improve efficiency and readability:
- Replaced nested loops with a single merged and sorted peaks array.
- Adjusted logic for updating `focusedlasts`, `summed`, `isExists`, `existsID`, `scalars`, and `covariances` arrays.
Utilize ArrayPool for temporary arrays to reduce allocation overhead:
- Rent `summed` array from `ArrayPool<double>.Shared` instead of using `Enumerable.Repeat`.
- Rent `existsID` array from `ArrayPool<int>.Shared` instead of using `Enumerable.Repeat`.
- Return rented arrays to their respective pools at the end of the method.

These changes aim to improve performance by reducing frequent allocations and deallocations, leading to better memory management and potentially lower garbage collection pressure.
Introduce MsScanMatchingBenchmark class using BenchmarkDotNet to measure performance of MsScanMatching methods. Add parameters for Seed, Size, and SpectrumLength. Implement Setup method to initialize random IMSScanProperty data. Add Batch and Each benchmark methods for batch vs individual processing. Include CreateScan helper method for random scan data generation. Modify Program.cs to run MsScanMatchingBenchmark.
Updated GetBatchSimpleDotProduct to use IReadOnlyList<IMSScanProperty>
instead of IMSScanProperty[]. This change enhances safety by preventing
modifications to the input list. Adjusted internal array initialization
and loops to use props.Count instead of props.Length to reflect the new
type. Updated availableIndex variable to match the new type of props.
Introduce SpectraSimilarityMapModel in CompMs.App.Msdial.Model.Statistics.
This class, inheriting from BindableBase, handles spectral similarity map
computations. It includes properties for m/z bin size and range, and a
result storage. The constructor initializes parameters based on
ProjectBaseParameter. The UpdateSimilaritiesAsync method computes spectral
similarities asynchronously using MsScanMatching.GetBatchSimpleDotProduct.
A new ViewModel class `SpectraSimilarityMapViewModel` has been added to the `CompMs.App.Msdial.ViewModel.Information` namespace. This class is designed to work with a model of type `SpectraSimilarityMapModel` and includes properties `MzBin`, `MzBegin`, `MzEnd`, and `Result`, which are synchronized with the model using ReactiveProperty. An `UpdateCommand` property of type `AsyncReactiveCommand` has been added, bound to the `UpdateSimilaritiesAsync` method of the model. The class inherits from `ViewModelBase` and uses Reactive Extensions for property synchronization and command handling. Necessary using directives have also been added.
Introduce SpectraSimilarityMapView UserControl in XAML and code-behind.
- Add Grid layout with ItemsControl and StackPanel in XAML.
- Bind TextBlock elements to Similarity, Left.AnalysisFileName, and Right.AnalysisFileName.
- Add LabeledContent controls with TextBox bindings for MzBegin, MzEnd, and MzBin.
- Define styles for LabeledContent and TextBox elements.
- Implement partial class SpectraSimilarityMapView in code-behind with constructor.
Updated IsAvailableSpectrum and GetBatchSimpleDotProduct methods in MsScanMatching.cs to handle nullable IMSScanProperty objects. Added ClearSimilarities method to SpectraSimilarityMapModel.cs. Updated UpdateSimilaritiesAsync in SpectraSimilarityMapModel.cs for nullable IMSScanProperty. Modified LcmsAlignmentModel.cs to use AlignmentPeaksSpectraLoader and handle null values in Target subscription. Added new constructor to AlignmentSpotSpectraLoader.cs. Created SpectraSimilarityMapViewModel and added SpectraSimilarityMapCommand in LcmsAlignmentViewModel.cs.
- Updated MsScanMatching.cs to handle empty mergedPeaks safely using FirstOrDefault and LastOrDefault with null-coalescing operators.
- Added "Peak spectra alignment" menu item in AlignmentPeakPlotView.xaml, binding it to SpectraSimilarityMapCommand.
- Added new using directives and subscription in MainWindow.xaml.cs to handle SpectraSimilarityMapViewModel and display the "Aligned peaks spectra similarity" view.
- Wrapped ItemsControl in ScrollViewer and added margins to TextBlock elements in SpectraSimilarityMapView.xaml for better spacing.
- Added SpectraSimilarityMapCommand property in AlignmentPeakPlotViewModel.cs.
- Initialized SpectraSimilarityMapViewModel and its command in LcmsAlignmentViewModel.cs, redefining the command within PlotViewModel.
- Removed SpectraSimilarityMapCommand property from LcmsAlignmentViewModel.cs
Enhanced SpectraSimilarityMapModel:
- Added public properties `Files` and `MzBin` with change notifications.

Updated SpectraSimilarityMapView.xaml:
- Introduced `chart` XML namespace.
- Added `SimpleChartControl` with `HeatmapControl` to display heatmap.
- Implemented `ToolTip` for `HeatmapControl`.
- Commented out previous `ScrollViewer` and `ItemsControl`.

Updated SpectraSimilarityMapViewModel:
- Added properties for managing chart axes: `VerticalAxis`, `HorizontalAxis`, and `ValueAxis`.
- Initialized axis properties in the constructor using `model.Files.AnalysisFiles`.

These changes improve data visualization by integrating a heatmap chart and providing detailed tooltips for better user insights.
Added `DegreeMin` and `DegreeMax` properties to `HeatmapControl`
to allow explicit control over degree ranges. Updated heatmap
rendering to use these properties when set, falling back to
dynamic calculation otherwise. Clamped `offset` in
`GetGradientColor` to ensure valid gradient calculations.
Enhances flexibility and robustness of heatmap rendering.
Refactored the `PriorityQueue` class to improve design, usability,
and adherence to .NET conventions. Key changes include:
- Switched to file-scoped namespaces.
- Made `_data` readonly and replaced `_comp` with `_comparer`
  of type `IComparer<T>`.
- Added new constructors for flexibility, including support for
  `IReadOnlyList<T>` and custom comparers.
- Refactored `shiftup` and `shiftdown` methods for cleaner code
  using tuple swapping and `IComparer<T>`.
- Updated `Push` and `Pop` methods to align with the new structure.
- Introduced a static helper class with factory methods for
  creating priority queues.

Updated `PriorityQueueTest` to reflect these changes:
- Refactored test methods to validate new functionality and
  ensure correct behavior of `Push` and `Pop`.

These changes enhance maintainability, usability, and test coverage.
YukiMatsuzawa and others added 24 commits July 2, 2025 14:47
Refactor the `DataTemplate` for the chart control by removing the old `SimpleChartControl` and its resources. Introduce a new `SimpleChartControl` wrapped in a `Border`, with updated height and axis bindings. The new setup maintains data bindings for sample names and intensities while enhancing the overall layout.
- Added a `Visibility` setter to collapse the `GraphTitle` `TextBlock` when empty.
- Changed the first `RowDefinition` height to `Auto` for dynamic sizing.
- Set a fixed `Height` of `30` for the `GraphTitle` `TextBlock`.
The `MzMapper` class has been updated to include a new method `MapMzByReferenceGroups`, which groups m/z values based on a specified m/z tolerance, replacing the removed `MapMzValues` method. A private method `EnumeratePeaks` has been added to assist with peak grouping, and a new `SetComparer` class has been introduced for comparing `HashSet` objects. Additionally, the `SpectraGroupingModel` class has been modified to utilize the new grouping method, enhancing the way molecule references are processed.
- Added `SelectedReference` property to `SpectraGroupingModel`.
- Changed `ProductIonAbundances` to use `GroupProductIonAbundancesModel`.
- Updated `SpectraGroupingView.xaml` layout for better reference selection and display.
- Synchronized new `SelectedReference` in `SpectraGroupingViewModel`.
- Introduced new `graphio` namespace for enhanced charting capabilities.
- Updated `Quantify` method in `Ms2Quantifier` to include a `tolerance` parameter for flexible m/z matching.
- Added `_evaluator` field in `LcmsAlignmentModel` to improve match result evaluation.
- Modified `SpectraGroupingModel` to accept `_evaluator` and `_mzTolerance` parameters for enhanced quantification and reference selection.
- Updated quantification logic in `SpectraGroupingModel` to utilize the new tolerance and evaluator for improved accuracy.
- Added `Ms2Quantifier` variable in `SpectraGroupingModel` for future quantification functionality.
- Introduced a new labeled section for "Adduct" in `SpectraGroupingView.xaml` to improve UI information.
- Wrapped `LineSpectrumControlSlim` elements in a `Grid` and added `Annotator` controls for better spectrum visualization and annotation.
- Configured `Annotator` to bind to spectrum data, enhancing interpretability with mass and intensity labels.
This commit updates the way references are extracted from the `peaks` collection by creating pairs of references and their match results. It introduces a scoring mechanism for references, which is used to order the resulting groups. The sorting is modified to prioritize the maximum score of references in descending order, followed by the length of references in ascending order.
Updated the calculation of `productIonAbundances` to use `Select` instead of `Zip`, leveraging `r.QuantMass` for the `Mz` property. Improved the construction of `References` by using a more descriptive variable name (`kvp`), enhancing code clarity while preserving functionality.
- Introduced `_evaluator` for match result evaluation.
- Implemented `ExportProductIonAbundanceResultAsync` for exporting results to JSON.
- Implemented `AdhocExportProductIonAbundanceResultCommand` as an `AsyncReactiveCommand` in `LcmsAnalysisViewModel.cs`.
- Added a new key binding in `LcmsMainView.xaml` to trigger the export command.
- Made the export command property accessible for binding in the view.
- Added `Focusable` property set to `False` for `NumericUpDown` and `ItemsControl` styles to prevent them from receiving keyboard focus.
- Updated `LabeledContent` control to also have `Focusable` set to `False`.
- Adjusted the `Height` of `StackPanel` and `CheckBox` from `30` to `24` for improved layout consistency.
Refactored the LoadCore method to filter out null values from the AlignedPeakPropertiesModelProperty using a Where clause. This change enhances code readability and may improve performance by preventing unnecessary processing of null values.
Introduces the AlignmentReferenceMatchedProductIonExportModel class to handle the export of alignment reference matched product ion data. Implements IAlignmentResultExportModel interface with methods for counting export files and performing synchronous/asynchronous exports. Includes functionality for loading spectra, quantifying data, and writing results to a JSON file, while managing cancellation tokens.
This commit introduces a new variable `productions`, which is an instance of `AlignmentReferenceMatchedProductIonExportModel`, to the list of export groups. The previous instance of `spectraAndReference` has been replaced with `productions`, updating the collection of export models for alignment results while maintaining the overall structure.
Introduce a new view model for exporting alignment reference matched product ions.
This includes properties for selection state and export capability using reactive programming.
Update the export logic to integrate the new view model in the existing switch statement.
Introduced a new `DataTemplate` for `AlignmentReferenceMatchedProductIonExportViewModel` featuring an `Expander` titled "Library matched product ions". This includes a `CheckBox` for JSON export, with its `IsChecked` property bound to `IsSelected.Value` for two-way data binding, along with specific styling for layout.
Removed the `ExportProductIonAbundanceResultAsync` method from `LcmsAlignmentModel.cs` and replaced it with the `AdhocExportProductIonAbundanceResultCommand` in the view model. Updated key bindings in `LcmsMainView.xaml` to reflect this change, including the removal of the `Ctrl+Shift+B` binding. The `AdhocExportProductIonQuantifactionResultCommand` was also removed from `LcmsAlignmentViewModel.cs`, indicating a shift in how product ion abundance results are managed within the application.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request introduces a comprehensive feature for visualizing MS/MS spectral similarity across samples for aligned ions, enhancing multi-sample analysis capabilities in the MSDIAL application.

Key changes include:

  • Implementation of spectral similarity mapping and grouping functionality with new ViewModels and Models
  • Addition of MS/MS data quantification algorithms and product ion abundance analysis
  • Enhanced heatmap controls with configurable value ranges for similarity visualizations

Reviewed Changes

Copilot reviewed 46 out of 46 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
SpectraGroupingViewModel.cs / SpectraSimilarityMapViewModel.cs ViewModels managing spectral grouping and similarity mapping UI logic
SpectraGroupingModel.cs / SpectraSimilarityMapModel.cs Core models implementing spectral analysis and similarity calculations
Ms2Quantifier.cs / Ms2QuantResult.cs / MzMapper.cs MS/MS quantification algorithms and m/z mapping utilities
HeatmapControl.cs Enhanced with DegreeMin/DegreeMax properties for configurable value ranges
MsScanMatchingTests.cs / MsScanMatchingBenchmark.cs Comprehensive tests and performance benchmarks for MS/MS matching
AlignmentReferenceMatchedProductIonExportModel.cs Export functionality for reference-matched product ion data
PriorityQueue.cs Refactored with improved API and support for collection initialization
Various View files UI components for spectral similarity mapping and grouping interfaces

}
}

public static double[][] GetBatchSimpleDotProduct(IReadOnlyList<IMSScanProperty?> props, double bin, double massBegin, double massEnd) {
Copy link

Copilot AI Aug 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method creates multiple large arrays and performs nested loops. Consider adding cancellation token support for long-running operations to allow graceful cancellation.

Copilot uses AI. Check for mistakes.
private int _n = 0;

public PriorityQueue(Func<T, T, int> comp): this(new List<T>(), comp) { }
public PriorityQueue(IReadOnlyList<T> data, IComparer<T> comp)
Copy link

Copilot AI Aug 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constructor sorts the entire data collection on initialization, which may be inefficient for large datasets. Consider using heapify algorithm instead.

Copilot uses AI. Check for mistakes.
…ingTests.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@YukiMatsuzawa YukiMatsuzawa merged commit 48d34ed into master Aug 20, 2025
5 checks passed
@YukiMatsuzawa YukiMatsuzawa deleted the feature/spectra-match-grouping branch August 20, 2025 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants