Skip to content

Improve adduct/isotope generation - #315

Closed
joewandy wants to merge 10 commits into
masterfrom
codex/review-adduct-and-isotope-implementation
Closed

Improve adduct/isotope generation#315
joewandy wants to merge 10 commits into
masterfrom
codex/review-adduct-and-isotope-implementation

Conversation

@joewandy

@joewandy joewandy commented Jan 27, 2026

Copy link
Copy Markdown
Member

Summary

This PR improves simulated isotope envelopes, adduct generation, and deisotoping/deadducting support.

The main scientific change is replacing the previous carbon-only isotope approximation with a multi-element isotope envelope approximation based on natural isotope abundances. The PR also adds configurable adduct priors/profiles and concentration controls, removes adducts we cannot currently simulate correctly, and adds OpenMS / ms-deisotope helpers plus tests to validate generated patterns.

Scientific fixes and behavior changes

Isotope generation

Isotope generation now approximates the full-formula isotope envelope by convolving per-element natural isotope distributions (NATURAL_ISOTOPES).

  • Build each element distribution relative to its monoisotope.
  • Raise each element distribution to the element count via repeated convolution.
  • Merge/prune intermediate states with mass_precision, min_prob, and max_states to keep runtime bounded.
  • Keep peaks until total_proportion is reached.
  • max_peaks now defaults to unlimited; if explicitly set too low to reach total_proportion, a warning is emitted.
  • Always preserve the zero-shift monoisotopic peak as isotopes[0], because downstream code assumes that invariant.

Implementation lives in vimms/IsotopeDistribution.py, with vimms/Chemicals.py::Isotopes kept as the public wrapper.

Adduct generation

Adduct metadata now has one shared definition table in vimms/Common.py, from which names, priors, and mass terms are derived.

  • Adduct proportions are sampled from a Dirichlet distribution with configurable priors/profiles.
  • Default positive/negative adduct sets are derived from the shared table.
  • Custom adduct names are validated, including ionisation-mode compatibility.
  • The mislabeled potassium adduct M+2K+H was replaced with M+2K-H.
  • Negative-mode adduct coverage now includes M+Cl, M+FA-H, and M+Ac-H; M+Cl uses the chloride ion mass.
  • Unsupported dimer/multimer adducts (2M+H, 2M+NH4) were removed because the old mass-term approach applies isotope envelopes incorrectly for multimer species. It is better not to simulate them than to produce scientifically wrong isotope/adduct peaks.

Deisotoping and deadducting

vimms/Deisotoping.py is added with utilities for validating and processing generated isotope/adduct patterns.

  • A lightweight deisotoper is added and tested against multi-element isotope envelopes.
  • OpenMS and ms-deisotope helper paths are added and covered by tests.
  • OpenMS deadducting support is implemented with focused helper functions for feature-map setup, adduct parsing, probability normalization, and neutral-mass reconstruction.
  • pyopenms and ms-deisotope are added as required dependencies for this PR's functionality and tests.

Validation

Added tests/test_deisotoping.py to cover:

  • multi-element isotope envelope generation,
  • monoisotope preservation under filtering,
  • warning behavior when max_peaks truncates the requested envelope,
  • removal/rejection of unsupported dimer adducts,
  • potassium replacement and chloride adduct definitions,
  • adduct metadata consistency from the shared table,
  • polarity-aware adduct validation,
  • OpenMS and ms-deisotope helper behavior,
  • end-to-end deadducting examples.

Local validation run in the vimms conda environment:

  • pytest tests/test_deisotoping.py -q -> 30 passed
  • pytest tests/test_chemical_generation.py tests/test_controllers_TopN.py -q -> 31 passed
  • pytest -q -> 144 passed, 2 existing warnings
  • Smoke simulation: generated HMDB-derived chemicals, isotope/adduct envelopes, and non-empty Top-N MS1/MS2 scans.

CI is currently green on the PR.

Limitations

  • True dimer/multimer adduct isotope envelopes are not supported in this PR. They were removed rather than approximated incorrectly.
  • The adduct prior defaults are heuristic and configurable; they are not claimed to be empirically calibrated for all instruments or sample classes.
  • Unknown chemicals remain single-peak representations. This is intentional because ROI-derived unknowns may already represent a specific isotope/adduct peak or noise, and expanding them could invent correlated signal.

@joewandy joewandy changed the title Make isotope/adduct modeling configurable and add improved deisotoper Improve adduct/isotope generation [WIP] Jan 27, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 36ddc497a3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread vimms/Chemicals.py Outdated
@joewandy joewandy changed the title Improve adduct/isotope generation [WIP] Improve adduct/isotope generation Jun 1, 2026
@joewandy joewandy closed this Jun 1, 2026
@joewandy
joewandy deleted the codex/review-adduct-and-isotope-implementation branch June 1, 2026 14:03
@joewandy

joewandy commented Jun 1, 2026

Copy link
Copy Markdown
Member Author

Branch was renamed to review-adduct-and-isotope-implementation. GitHub closed this PR when the old head ref disappeared, so the same branch/commits/body are now continued in #319: #319

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant