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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

find_mfs-0.4.0.tar.gz (853.2 kB view details)

Uploaded Source

File details

Details for the file find_mfs-0.4.0.tar.gz.

File metadata

  • Download URL: find_mfs-0.4.0.tar.gz
  • Upload date:
  • Size: 853.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for find_mfs-0.4.0.tar.gz
Algorithm Hash digest
SHA256 ac8779a60f96ffc58649565528b158075025723d0529beb0a62972cee32ad993
MD5 237e42d0e0919ccb4d7cc29b13b282b5
BLAKE2b-256 f303b9049489fcde6e2cf419fe022aa648f876a1312fbe23bcccc50e4133672d

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.4.0 This release

1 file

0.3.0

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page