Skip to main content

Peptacular

Peptacular Logo

Python package codecov PyPI version DOI Python 3.12+ License: MIT

Peptacular parses ProForma 2.1 peptide sequences and calculates their masses, fragments, and isotopic distributions. It's for anyone working with peptide-level proteomics data in Python who wants exact masses and fragment ions without hand-rolling ProForma parsing and mass tables. It's built on tacular's lookup data, and its fragments export directly as mzPAF strings readable by paftacular.

Why peptacular?

  • Full ProForma 2.1 parsing into a chainable, editable ProFormaAnnotation object — or use the functional API directly on strings.
  • Mass, m/z, composition, and predicted isotopic distributions, with monoisotopic and average mass support.
  • Enzymatic digestion with missed cleavages, semi-specific, and non-specific modes.
  • Fragment ion generation for 20+ ion types, exportable straight to mzPAF strings for paftacular.
  • Batch-friendly: functional API calls on lists of sequences parallelize automatically, with per-item error collection. Pass FASTA/PEFF entries from fastatacular straight in: any object with a sequence string works.
  • Type-annotated throughout, plus optional Pyteomics, psm_utils, AlphaBase, and MCP integrations.

Install

pip install peptacular

Optional integrations install as extras:

pip install "peptacular[pyteomics]"
pip install "peptacular[psm-utils]"
pip install "peptacular[alphabase]"
pip install "peptacular[mcp]"
pip install "peptacular[numpy]"   # fragment_arrays(): ions as numpy columns

See the interoperability guide for supported conversions.

Quick example

import peptacular as pt

# Parse a sequence into a ProFormaAnnotation
peptide = pt.parse("PEM[Oxidation]TIDE")

# Calculate mass and m/z
print(peptide.mass())              # 849.3426002717299
print(peptide.mz(charge=2))        # 425.6785766024859

# Chained edits return a modified annotation
print(peptide.set_charge(2).set_peptide_name("Peptacular").serialize())
# (>Peptacular)PEM[Oxidation]TIDE/2

What else it can do

Digest a protein and generate fragment ions that round-trip through paftacular's mzPAF parser:

import peptacular as pt

peptides = pt.digest("MKVLATSAGERTIDEK", enzyme="trypsin", missed_cleavages=1)
print([seq for seq, _ in peptides])
# ['MK', 'MKVLATSAGER', 'VLATSAGER', 'VLATSAGERTIDEK', 'TIDEK']

fragments = pt.fragment("PEPTIDE", ion_types=("b", "y"), charges=[1])
print(fragments[1].to_mzpaf())  # b2{PE}

The functional API operates on lists directly, auto-parallelizing for larger batches:

import peptacular as pt

peptides = ["[Acetyl]-PEPTIDES", "<13C>ARE", "SICK/2"]
print(pt.mass(peptides))               # [928.4025574375299, 388.23835027296, 451.24535797517194]
print(pt.mz(peptides, charge=2))       # [465.20855518538593, 195.12645160310103, 225.62267898758597]

For streaming input and per-item error collection instead of a raised exception, see the streaming guide:

import peptacular as pt

results = pt.batch("mass", ["PEPTIDE", "PEP[UnknownModification]TIDE"], errors="collect")
print(results[0].value)                # 799.3599640328299
print(results[1].error.code)           # unresolved_modification

Raised errors are typed and all subclass pt.PeptacularError (a ValueError): invalid ProForma raises pt.ProFormaFormatError, an unresolved modification pt.UnknownModificationError, and so on. See the streaming guide for the full list.

Expand an ambiguous modification into its localization isomers and find the fragment ions that tell them apart. Candidate sites come from the ProForma string alone; peptacular has no built-in list of which residues a mod can sit on:

import peptacular as pt

isomers = pt.localization_isomers("PEP(ST)[Phospho]IDE")
print([a.serialize() for a in isomers])  # ['PEPS[Phospho]TIDE', 'PEPST[Phospho]IDE']
ions = pt.site_determining_ions(isomers, ion_types=("b", "y"), charges=(1,))
print([[f"{f.ion_type}{f.position}" for f in frags] for frags in ions])  # [['b4', 'y4'], ['b4', 'y4']]
Area Entry points
Digestion pt.digest, pt.semi_digest, pt.nonspecific_digest
Fragmentation pt.fragment, pt.fast_fragment
Localization pt.localization_isomers, pt.candidate_sites, pt.site_determining_ions, pt.pairwise_site_determining_ions (guide)
Isotopes pt.isotopic_distribution, pt.brain_isotopic_distribution
Tables pt.digest_records, pt.fragment_records (plain dicts for pandas or polars), pt.fragment_arrays (numpy columns)
Batch / streaming pt.batch, pt.iter_batch, pt.diagnose (read FASTA with fastatacular)
JSON interchange see the JSON serialization guide

Tables with pandas or polars

peptacular does not ship pandas or polars. pt.digest_records and pt.fragment_records return a list of plain dicts (strings, numbers, booleans, None), one per peptide or ion, which either library turns into a table. Column names are listed in pt.DIGEST_RECORD_KEYS and pt.FRAGMENT_RECORD_KEYS:

import peptacular as pt

rows = pt.digest_records("MKVLATSAGERTIDEK", "trypsin", missed_cleavages=1)
print(rows[0])  # {'peptide': 'MK', 'stripped_sequence': 'MK', 'start': 0, 'end': 2, 'missed_cleavages': 0, 'semi': False, 'accession': None}
ions = pt.fragment_records(pt.fragment("PEPTIDE/2", ion_types=("b", "y"), charges=(1, 2)))
print(ions[1]["ion_type"], ions[1]["position"], ions[1]["charge_state"], ions[1]["mzpaf"])  # b 2 1 b2{PE}
# pandas.DataFrame(rows) or polars.DataFrame(ions) gives a table

A FASTA entry's accession (or a PEFF entry's db_unique_id) is copied into each digest row.

For many peptides, pt.fragment_arrays (needs pip install "peptacular[numpy]") returns the same ions as pt.fragment as a dict of numpy columns, one row per ion, with a peptide_index column. It is about 10x faster than building a table from Fragment objects:

cols = pt.fragment_arrays(["PEPTIDE/2", "PEM[Oxidation]K"], ion_types=("b", "y"), charges=(1, 2))
print(cols["peptide_index"][:3].tolist(), cols["mz"][:3].round(4).tolist())  # [0, 0, 0] [98.06, 227.1026, 324.1554]
# polars.DataFrame(cols) or pyarrow.table(cols) takes the dict as is

See the tables guide.

Local MCP integration

Peptacular includes 12 optional MCP tools for agents to inspect annotations, calculate theoretical properties, digest protein sequences, and transform annotations. Calls accept small inline batches and return results directly, with no stored data or job setup. Install with pip install "peptacular[mcp]", then check the installation:

peptacular-mcp --check

See the local MCP guide for client setup, tool examples, and limits.

Documentation

License

MIT

Citation

Working on a JOSS submission, but in the meantime use:

https://doi.org/10.5281/zenodo.15054278

Release files for peptacular 5.0.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 peptacular 5.0.0
File Size Uploaded
peptacular-5.0.0.tar.gz 1.5 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for peptacular 5.0.0
File Interpreter ABI Platform
peptacular-5.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.8 MB

Release files / peptacular-5.0.0.tar.gz

Download URL peptacular-5.0.0.tar.gz
Size 1.5 MB
Tags Source
SHA-256 checksum
How to use checksums
c7bd59b7dcba7bb716ff8fdfd2b042743932d758f276a2fd63b065ac4d8aedc9
BLAKE2b-256 checksum
How to use checksums
28b0811d3c326bac6ed5706d0bc1f637244a4dc60311563f01646cd0937bb5ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 25, 2026.

Transparency log

Release files / peptacular-5.0.0-py3-none-any.whl

Download URL peptacular-5.0.0-py3-none-any.whl
Size 270.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
13bf9b54b4f530cf47217ce2ef6059997268e13aaf05a590af64e502b1491ee9
BLAKE2b-256 checksum
How to use checksums
dc45122e9b02c0532df8e78651fa1cbd3a6e3d9a7d080bd86359995eec25ab5f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

5.0.0 This release

2 release files

4.2.0

2 release files

4.1.0

2 release files

4.0.1

2 release files

4.0.0

2 release files

3.3.0

2 release files

3.2.0

2 release files

3.1.2

2 release files

3.1.1

2 release files

3.1.0

2 release files

3.0.0

2 release files

2.5.1

2 release files

2.5.0

2 release files

2.4.0

2 release files

2.2.1

2 release files

2.2.0

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.4

2 release files

0.0.3

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