Skip to main content

find-mfs: Accurate mass ➜ Molecular Formulae

CI PyPI version Python 3.10+ License: GPL v3

find-mfs is a simple Python package for finding molecular formulae candidates which fit some given mass (+/- an error window). It implements Böcker & Lipták's algorithm for efficient formula finding, as used in SIRIUS.

find-mfs also implements other methods for filtering the MF candidate lists:

  • Octet rule
  • Ring/double bond equivalents (RDBE's)
  • Predicted isotope envelopes, generated using Łącki and Startek's algorithm as implemented in IsoSpecPy
  • Bayesian candidate ranking, scoring formula plausibility using a database (COCONUT pre-bundled)

Motivation:

I needed to perform mass decomposition and, shockingly, I could not find a Python library for it (despite being a routine process). find-mfs is intended to be used by anyone looking to incorporate molecular formula finding into their Python project.

Installation

pip install find-mfs

Example Usage:

Simple queries

# For simple queries, one can use this convenience function
from find_mfs import find_chnops

find_chnops(
    mass=613.2391,         # Novobiocin [M+H]+ ion; C31H37N2O11+
    charge=1,              # Charge should be specified - electron mass matters
    error_ppm=5.0,         # Can also specify error_da instead
                           # --- FORMULA FILTERS ----
    check_octet=True,      # Candidates must obey the octet rule
    filter_rdbe=(0, 20),   # Candidates must have 0 to 20 ring/double-bond equivalents
    max_counts='C*H*N*O*P0S2'      # Element constraints: unlimited C/H/N/O,
                                   # No phosphorous atoms, up to two sulfurs.
)

Output:

FormulaSearchResults(query_mass=613.2391, n_results=38)

Formula                   Error (ppm)     Error (Da)      RDBE
----------------------------------------------------------------------
[C6H25N30O4S]+                     -0.12       0.000073       9.5
[C31H37N2O11]+                      0.14       0.000086      14.5
[C14H29N24OS2]+                     0.18       0.000110      12.5
[C16H41N10O11S2]+                   0.20       0.000121       1.5
[C29H33N12S2]+                     -0.64       0.000392      19.5
... and 33 more

Batch Queries

# If processing many masses, it's better to instantiate a FormulaFinder object
from find_mfs import FormulaFinder

finder = FormulaFinder()
finder.find_formulae(
    mass=613.2391,         # Novobiocin [M+H]+ ion; C31H37N2O11+
    charge=1,              
    error_ppm=5.0,         
    # ... etc
)

Including Isotope Envelope Information

If an isotope envelope is available, the candidate list can be dramatically reduced.

import numpy as np

# STEP 1: Retrieve isotope envelope from experimental data
observed_envelope = np.array(
    [  #  m/z    , relative intsy.
        [613.2397,    1.00],
        [614.2429,    0.35],
        [615.2456,    0.10],
    ]
)

# STEP 2: define isotope matching parameters
from find_mfs import IsotopeMatchConfig
iso_config = IsotopeMatchConfig(
    envelope=observed_envelope,  # np.ndarray with an m/z column and an intensity column
    mz_tolerance_da=0.1,         # Tolerance for aligning isotope signals. Should be very generous. Can also use mz_tolerance_ppm
    minimum_rmse=0.05,           # Default is 0.05, i.e. instrument reproduces isotope envelope w/ 5% fidelity
)

# STEP 3: include isotope matching parameters when performing a search
from find_mfs import FormulaFinder
finder = FormulaFinder()
finder.find_formulae(
    mass=613.2391,         # Novobiocin [M+H]+ ion; C31H37N2O11+
    charge=1,              # Charge should be specified - electron mass matters
    error_ppm=3.0,         # Can also specify error_da instead
                           # --- FORMULA FILTERS ----
    check_octet=True,      # Candidates must obey the octet rule
    filter_rdbe=(0, 20),   # Candidates must have 0 to 20 ring/double-bond equivalents
    max_counts={
        'P': 0,            # Candidates must not have any phosophorous atoms
        'S': 2,            # Candidates can have up to two sulfur atoms
    },
    isotope_match=iso_config,
)

Output:

FormulaSearchResults(query_mass=613.2391, n_results=5)

Formula                   Error (ppm)     Error (Da)      RDBE       Iso. Matches   Iso. RMSE 
------------------------------------------------------------------------------------------------------
[C31H37N2O11]+                      0.14       0.000086      14.5           3/3    0.0121
[C23H41N4O13S]+                    -0.92       0.000565       5.5           3/3    0.0478
[C24H37N8O9S]+                      1.26       0.000772      10.5           3/3    0.0311
[C32H33N6O7]+                       2.32       0.001424      19.5           3/3    0.0230
[C25H33N12O5S]+                     3.44       0.002110      15.5           3/3    0.0146

Ranking Candidates by Plausibility

Even after filtering, the candidate list often includes chemically unintuitive MF candidates. This package includes a method for scoring formula plausiblity. This is done in the form of a Bayesian prior - a Gaussian Mixture Model. By default, find-mfs bundles a GMM trained on the COCONUT natural-products database.

The prior can be combined with mass error (and isotope RMSE, if available) to re-rank formula candidates by the overall best fit.

from find_mfs import FormulaFinder, FormulaPrior

finder = FormulaFinder()
results = finder.find_formulae(
    mass=613.2391, charge=1, error_ppm=5.0,
    check_octet=True, filter_rdbe=(0, 20),
    max_counts='C*H*N*O*P0S2',
)

# Score with the bundled COCONUT-trained prior, then rank by posterior
prior = FormulaPrior.default()          # no corpus or fitting needed
prior.score_results(
  results,
  mass_sigma_ppm=2.0,  # Expected mass error of instrument
  isotope_sigma=0.05,  # Expected isotope fidelity of instrument (5%)
)

ranked = results.sort_by_posterior()
print(ranked.to_table())

Output:

Formula                       Error (ppm)      Error (Da)       RDBE      Prior
-------------------------------------------------------------------------------
[C31H37N2O11]+                       0.14        0.000086       14.5      33.49
[C32H33N6O7]+                        2.32        0.001424       19.5      31.59
[C27H33N8O9]+                       -4.24       -0.002599       15.5      31.58
[C32H41N2O6S2]+                      1.56        0.000956       13.5      18.75
[C19H41N4O18]+                       3.16        0.001937        1.5      18.71
... and 18 more

The true formula (novobiocin, C31H37N2O11) now ranks first.

Want a prior tuned to your own chemistry? Train one on any corpus of formula strings with FormulaPrior().fit(my_formulae). Use sort_by_prior() to rank by the prior alone, ignoring mass error.

Jupyter Notebook:

See this Jupyter notebook for more thorough examples/demonstrations


If you use this package, make sure to cite:

Contributing

Contributions are welcome. Here's a list of features I feel should be implemented eventually. The bold items are what I'm currently working on.

  • Statistics-based isotope envelope fitting
  • Fragmentation constraints
  • Bayesian formula candidate ranking
  • Spectrum parsing (in progress)
  • Element ratio constraints
  • GUI app

License

This project is distributed under the GPL-3 license.

Metadata

Release files for find-mfs 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for find-mfs 0.4.0
File Size Uploaded
find_mfs-0.4.0.tar.gz 853.2 kB Details

Release files / find_mfs-0.4.0.tar.gz

Download URL find_mfs-0.4.0.tar.gz
Size 853.2 kB
Tags Source
SHA-256 checksum
How to use checksums
ac8779a60f96ffc58649565528b158075025723d0529beb0a62972cee32ad993
BLAKE2b-256 checksum
How to use checksums
f303b9049489fcde6e2cf419fe022aa648f876a1312fbe23bcccc50e4133672d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.14

Release history Release notifications | RSS feed

This release

0.4.0 This release

1 release file

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page