IsoSpec
IsoSpec is a fine-structure isotopic distribution calculator for chemical formulas — given a molecule, it computes the masses and probabilities of its isotopologues. It is fast enough to handle large molecules (proteins, oligonucleotides) where the full distribution has astronomically many configurations, and it returns provably-optimal subsets that cover a chosen fraction of the total probability mass.
IsoSpec is primarily used as a library by mass spectrometry software. It is implemented in C++ (src/IsoSpec++/) and shipped with first-class bindings for Python (IsoSpecPy, on PyPI), R (IsoSpecR, on CRAN) and Rust (isospec, the crate in rust/).
Installation
Python
pip install IsoSpecPy
The wheel bundles the C++ library — no separate native install required. Compatible with CPython and PyPy on Linux, macOS, Windows, and Cygwin/MinGW. Python ≥ 3.10.
To build from source: pip install . from a checkout. A C++20 compiler is required.
R
install.packages("IsoSpecR")
From source: cd src && R CMD build IsoSpecR && R CMD INSTALL IsoSpecR_*.tar.gz.
Rust
cargo add isospec
or, in Cargo.toml:
[dependencies]
isospec = "0.2"
The crate (crates.io, API documentation on docs.rs) carries the C++ sources and compiles them in its build script; a C++20 compiler is all that is needed. See rust/README.md.
C++ library
cd src/IsoSpec++
make # produces libIsoSpec++.so
Or via CMake from the repo root:
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
sudo cmake --install build
Requires a C++20 compiler. CMake produces both shared and static libraries and installs headers under ${CMAKE_INSTALL_INCLUDEDIR}/IsoSpec++.
Quick start
The most common usage is IsoTotalProb: ask for the smallest set of isotopologues whose summed probability covers a chosen fraction of the spectrum (typically 0.99–0.9999). The result is a materialized envelope — arrays of masses and probabilities you can read directly.
Python
import IsoSpecPy
# Isotopologues covering at least 99.9% of the probability mass of water.
iso = IsoSpecPy.IsoTotalProb(formula="H2O1", prob_to_cover=0.999)
for mass, prob in zip(iso.masses, iso.probs):
print(mass, prob)
# From an amino-acid sequence:
iso = IsoSpecPy.IsoTotalProb(peptide_sequence="AAAPPGQAAC", prob_to_cover=0.999)
print(list(zip(iso.masses, iso.probs)))
# ...optionally carrying [UNIMOD:<id>] modification tags (the notation this
# monorepo's SAGE search-engine fork writes: [UNIMOD:<id>]-SEQUENCE prefix
# for an N-terminal mod, X[UNIMOD:<id>] inline for an internal one,
# SEQUENCE-[UNIMOD:<id>] suffix for a C-terminal one):
iso = IsoSpecPy.IsoTotalProb(peptide_sequence="PEPTC[UNIMOD:4]DEK", prob_to_cover=0.999)
print(list(zip(iso.masses, iso.probs)))
# Mind the water: peptide_sequence= yields the *residue* composition, without
# the terminal H2O of a free peptide, so the masses above are 18.0106 Da
# lighter than the neutral molecule. Add it explicitly for the real peptide
# (the C++ Iso::FromFASTAWithMods below adds it by default -- the two APIs
# differ here, and this is the older Python behaviour kept for compatibility):
iso = IsoSpecPy.IsoTotalProb(peptide_sequence="PEPTC[UNIMOD:4]DEK", formula="H2O1",
prob_to_cover=0.999)
# Or get just the composition (element -> atom count), no envelope:
composition = IsoSpecPy.ParsePeptideSequence("PEPTC[UNIMOD:4]DEK")
print(dict(composition)) # {'H': 60, 'C': 39, 'N': 10, 'O': 16, 'S': 1}
Resolves against a table of ~980 Unimod entries embedded in the library (isotope-labelled and glycan/derivatization "brick" modifications are excluded -- they aren't representable as a pure elemental delta). Pass unimod_db_path="/path/to/table.csv" to either function to resolve against a different table instead (same id,name,mono_mass,composition CSV shape as the embedded default).
See Examples/Python/ for radiolabelling, custom elements, binned spectra, and FASTA/Unimod modifications.
C++
#include "IsoSpec++/isoSpec++.h"
#include "IsoSpec++/fixedEnvelopes.h"
using namespace IsoSpec;
int main() {
FixedEnvelope iso = FixedEnvelope::FromTotalProb("H2O1", 0.999, true, true);
for (size_t i = 0; i < iso.confs_no(); ++i) {
std::cout << iso.mass(i) << '\t' << iso.prob(i) << '\n';
}
}
From a peptide sequence, optionally carrying [UNIMOD:<id>] modification tags (fasta_mods.h; same notation as the Python/R examples above):
#include "IsoSpec++/isoSpec++.h"
#include "IsoSpec++/fasta_mods.h"
#include "IsoSpec++/fixedEnvelopes.h"
using namespace IsoSpec;
int main() {
FixedEnvelope iso = FixedEnvelope::FromTotalProb(
Iso::FromFASTAWithMods("PEPTC[UNIMOD:4]DEK"), 0.999, true, true);
for (size_t i = 0; i < iso.confs_no(); ++i) {
std::cout << iso.mass(i) << '\t' << iso.prob(i) << '\n';
}
}
Iso::FromFASTAWithMods takes an optional trailing unimod_db_path argument to resolve against a different Unimod table instead of the one embedded at compile time. For just the composition, no envelope, call parse_fasta_with_mods/parse_fasta_with_mods_full directly (or the allocation-free _into forms, for a hot loop over many sequences) — see fasta_mods.h.
Quickest way to build:
clang++ -std=c++20 water.cpp src/IsoSpec++/unity-build.cpp -o water
(unity-build.cpp is a single translation unit that #includes every source file — see Examples/C++/COMPILING.)
Rust
use isospec::{Iso, PeptideOptions};
fn main() -> Result<(), isospec::Error> {
let iso = Iso::from_formula("H2O1")?;
for (mass, prob) in iso.envelope().total_prob(0.999)?.iter() {
println!("{mass}\t{prob}");
}
// A modified peptide; unlike Python's peptide_sequence=, the default
// here includes the terminal water.
let peptide = Iso::from_peptide("PEPTC[UNIMOD:4]DEK", &PeptideOptions::default())?;
println!("{}", peptide.monoisotopic_mass());
Ok(())
}
See rust/examples/ for binned spectra, generators with configurations, and labelled elements.
R
library(IsoSpecR)
water <- c(H = 2, O = 1)
IsoSpecify(molecule = water, stopCondition = 0.999)
IsoSpecify only ever takes a raw named-integer-vector molecule -- it has no sequence-string parameter -- so a [UNIMOD:<id>]-annotated peptide sequence takes two calls instead of one: RParsePeptideSequence() to resolve the sequence into a composition, then IsoSpecify() as above.
composition <- RParsePeptideSequence("PEPTC[UNIMOD:4]DEK")
print(composition) # H C N O S
# 60 39 10 16 1
IsoSpecify(molecule = composition, stopCondition = 0.999)
Like the Python ParsePeptideSequence, this returns the residue composition without a free peptide's terminal H2O -- add c(H = 2, O = 1) to it for the neutral molecule. A modification whose delta removes more atoms of an element than the bare sequence provides gives a negative count ("G[UNIMOD:11]" nets H -1, S -1); IsoSpecify rejects such a vector rather than quietly dropping those elements.
The rest of the API takes the same named vector, and treats an envelope as what IsoSpecify returns, a matrix with columns mass and prob:
insulin <- c(C = 254, H = 377, N = 65, O = 75, S = 6)
IsoProperties(insulin)$averageMass # also mono/lightest/heaviest/mode peaks, variance
IsoBinned(insulin, binWidth = 1) # unit-resolution distribution, computed directly
IsoStochastic(insulin, ionicCurrent = 1e4, seed = 1) # simulated, reproducible measurement
wassersteinDistance(IsoSpecify(insulin, 0.999), IsoSpecify(c(C = 254, H = 377, N = 65, O = 74, S = 7), 0.999))
with envelopeConvolve, envelopeLinearCombination, envelopeBin and envelopeResample for envelope arithmetic, and orientedWassersteinDistance, abyssalWassersteinDistance and wassersteinMatch beside wassersteinDistance.
See Examples/R/ for radiolabelling, full-spectrum extraction, Unimod-annotated sequences, and binned, simulated and compared envelopes.
Advanced features
- Alternative algorithms — for cases where
IsoTotalProbisn't the right shape:IsoThreshold— all isotopologues with probability above a fixed threshold.IsoStochastic— simulate a measured spectrum by sampling integer ion counts.IsoBinned— histogram-style envelope at a chosen bin width.
- FASTA/peptide-sequence support — build an
Isodirectly from an amino-acid sequence, with[UNIMOD:<id>]modification tags recognized inline; optionally include the N/C-terminal water. - Custom isotopic tables — override natural abundances per element (e.g. for radio- or stable-isotope labelling). See
Examples/*/radiolabelling.*. - Fixed-envelope arithmetic — addition, normalization, convolution, binning, resampling, Wasserstein distances.
- Reproducible sampling — stochastic envelopes and resampling take a seed (
seed=in Python and R,seeded_rng()in C++,with_seedin Rust); a seed gives the same counts on every platform and in every binding. - Nominal-mass mode — compute distributions over nucleon counts instead of real masses.
- Thread safety — the library never parallelises its own work, but independent molecules and envelopes may be used from any number of threads, and a shared molecule or envelope may be read from several at once.
- Streaming generators (for performance) — the tabulated functions above materialize the full envelope into arrays. For large molecules where that uses too much memory, or for pipelines that consume one configuration at a time (e.g. binning on the fly), use the generator classes instead:
IsoThresholdGenerator,IsoLayeredGenerator,IsoOrderedGenerator,IsoStochasticGenerator. They yield one isotopologue per call toadvanceToNextConfiguration()without ever storing the full set.IsoOrderedGeneratoradditionally streams in strict order of decreasing probability. Generators are in C++, Python and Rust; R has the materialized functions only.
Algorithmic details are in the papers cited below; the Supporting Information of each is the better starting point for implementation specifics.
Repository layout
src/IsoSpec++/ C++ core library (the algorithms live here)
src/IsoSpecPy/ Python binding, loaded via cffi
src/IsoSpecR/ R binding, via Rcpp
rust/ Rust crate (Cargo.toml at the repository root), via cxx
Examples/ Working examples in each language
tests/ C, C++, and Python test suites (R's are in src/IsoSpecR/tests, Rust's in rust/tests)
skbuild/ scikit-build-core entry point used when installing the Python wheel
Changes
CHANGELOG lists the major changes in each release (the Rust crate keeps its own, rust/CHANGELOG.md).
Citation
If IsoSpec is useful in your research, please cite:
- Łącki, M. K.; Valkenborg, D.; Startek, M. P. IsoSpec2: Ultrafast Fine Structure Calculator. Analytical Chemistry 2020, 92 (14), 9472–9475. https://doi.org/10.1021/acs.analchem.0c00959
- Łącki, M. K.; Startek, M.; Valkenborg, D.; Gambin, A. IsoSpec: Hyperfast Fine Structure Calculator. Analytical Chemistry 2017, 89 (6), 3272–3277. https://doi.org/10.1021/acs.analchem.6b01459
The Supporting Information of each paper has the algorithmic detail.
License
2-clause BSD (see LICENCE). If you need different licensing terms, contact the authors. The authors appreciate (but do not require) being told when IsoSpec is used in other software.
Metadata
Release files for IsoSpecPy 2.6.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| isospecpy-2.6.1.tar.gz | 200.9 kB | With provenance | Details for isospecpy-2.6.1.tar.gz |
Built distributions (wheels)
Total release size: 5.6 MB
Release files / isospecpy-2.6.1.tar.gz
| Download URL | isospecpy-2.6.1.tar.gz |
|---|---|
| Size | 200.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a4304f0d427c0374bf612800487eed73be270b9a48c076887d1f6edb705164c2
|
|
BLAKE2b-256 checksum How to use checksums |
a3acc03edd85d6185d91432f45a6e788c98a77a57342c8cd95a516f1b8426f0d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logRelease files / isospecpy-2.6.1-py3-none-win_arm64.whl
| Download URL | isospecpy-2.6.1-py3-none-win_arm64.whl |
|---|---|
| Size | 265.7 kB |
| Tags | Python 3 Windows ARM64 |
|
SHA-256 checksum How to use checksums |
4704a1058f8740774a1ecc21a6a2446f6a9e7e432a262e6b2bf14b0a65beb7c5
|
|
BLAKE2b-256 checksum How to use checksums |
6c04b105a21c5a361b083435b4ab6abd2771f22401967efc8049609290e7f8f0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logRelease files / isospecpy-2.6.1-py3-none-win_amd64.whl
| Download URL | isospecpy-2.6.1-py3-none-win_amd64.whl |
|---|---|
| Size | 274.4 kB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
a2a867e45c6b400908c6feaecfe79541cd29ce021332dc2a0471bc475fdeeb33
|
|
BLAKE2b-256 checksum How to use checksums |
07dbea0555ad86d480bb00d48762a7b51abb89fc8d5cceebcc34095b938ba6e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logRelease files / isospecpy-2.6.1-py3-none-win32.whl
| Download URL | isospecpy-2.6.1-py3-none-win32.whl |
|---|---|
| Size | 262.3 kB |
| Tags | Python 3 Windows x86-32 |
|
SHA-256 checksum How to use checksums |
10dc6f0b02aa834b62e5109406520aec6df1230ac19af6aceae1e64b5096cfc2
|
|
BLAKE2b-256 checksum How to use checksums |
e6381fa5bbd399453d47124877a1a27054dd277e7ab9eb6e0a2318680d01c5e8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logRelease files / isospecpy-2.6.1-py3-none-musllinux_1_2_x86_64.whl
| Download URL | isospecpy-2.6.1-py3-none-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | Linux musl 1.2+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
23ca5a9a7a6c9e2b5723f650dddec826a7172efaceb7d6fbcdece2f36f6dddff
|
|
BLAKE2b-256 checksum How to use checksums |
a649020a444b338ec761f607deeb54e5026dc17f9feeaf1ea717e8d2ecb69f7f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logRelease files / isospecpy-2.6.1-py3-none-musllinux_1_2_aarch64.whl
| Download URL | isospecpy-2.6.1-py3-none-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | Linux musl 1.2+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
66036c233df1b815a6604a48dcdd49365d56cda62704da25011d021f940c62f5
|
|
BLAKE2b-256 checksum How to use checksums |
4202279a3b17e89ed8bb11027fd0bbcec4d425a615c1e23d138f095e15e5a374
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logRelease files / isospecpy-2.6.1-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
| Download URL | isospecpy-2.6.1-py3-none-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 312.5 kB |
| Tags | Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
2b0121194860b3c7c0af4ce11ba35ff847928f0d8d823c237162e3b692faa0ef
|
|
BLAKE2b-256 checksum How to use checksums |
9601e845f1720c0652097d80c022bfb30ad6f12a45253c5261d2134616a621fc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logRelease files / isospecpy-2.6.1-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
| Download URL | isospecpy-2.6.1-py3-none-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 298.4 kB |
| Tags | Linux glibc 2.24+ ARM64 Linux glibc 2.28+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
14d794f6a79419f6233cac2431a18b92355d0e9983b839f7878b523476a18ea5
|
|
BLAKE2b-256 checksum How to use checksums |
96728865962c5ab7d7b7f62325c60e0e0c0cd74145dc9ac81491e4213b197e06
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logRelease files / isospecpy-2.6.1-py3-none-macosx_11_0_arm64.whl
| Download URL | isospecpy-2.6.1-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 642.3 kB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
d23a5b5fba3f141d4a2e6e5e74907c58d7702bd649dac2a4505e46e4e937532f
|
|
BLAKE2b-256 checksum How to use checksums |
068d829475ce42b200547825b919ae93f21a976fba89cf287fc770aa107fd63f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logRelease files / isospecpy-2.6.1-py3-none-macosx_10_9_x86_64.whl
| Download URL | isospecpy-2.6.1-py3-none-macosx_10_9_x86_64.whl |
|---|---|
| Size | 689.1 kB |
| Tags | Python 3 macOS 10.9+ x86-64 |
|
SHA-256 checksum How to use checksums |
4a4c600634fd6673250fcf71d3d4bab353f9e54bc088758c2cb7819343f8364a
|
|
BLAKE2b-256 checksum How to use checksums |
2521fed7bb4722d524939b441da36142f62a12949cb99daa3cfd5e7a3b3f000a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logSecurity for IsoSpecPy 2.6.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 10 files in this release have been uploaded with provenance metadata.
Attestation for isospecpy-2.6.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.