Skip to main content

mhcmatch

PyPI CI Docs Python License

Peptide–MHC presentation, cross-reactivity, and motif tools — the applied peptide–MHC layer on top of the seqtree fuzzy-search substrate. mhcmatch productionizes the reference seqtree.pmhc methodology (anchor-masked TCR-facing homology, presentation-aware E-values, allele guessing) and adds a pseudosequence-based cross-allele diffusion model that rescues rare alleles by borrowing from groove-similar frequent ones.

The mathematical/statistical theory is in appendix/mhcmatch.tex; the development plan is in ROADMAP.md.

What it does (v0)

  1. MHC restriction & presentation — rank presenting alleles for a peptide (single / set / all, human & mouse), flag non-binders, and scan a whole protein for presented peptides.
  2. Large-scale similarity search — find similar peptides across big sets / proteomes, either by same-MHC binding (presentation signature) or similar TCR recognition (anchor-masked, TCR-facing); neoantigen molecular mimicry with per-allele E-values.
  3. Anchor / TCR-facing split — decompose a peptide into anchor and TCR-facing parts (X masks).
  4. Near-exact source lookup — find the self peptide a neoantigen derives from + its parent protein / mutated position, against a reference proteome.
  5. Motif logos — per-allele information-content logos with length distributions.
  6. Pseudosequence diffusion — allele similarity, clustering, and kernel-shrinkage pooling over 34-mer groove pseudosequences (rare-allele rescue).

Install

bash setup.sh            # repo-local .venv + editable install (uses sibling ../seqtree if present)
bash setup.sh --tests    # + pytest
bash setup.sh --logo     # + logomaker/matplotlib for rendering logos

Quickstart

import mhcmatch

# build from the isalgo/pmhc_data table (full or shortlist tier)
store = mhcmatch.Store.from_pmhc("pmhc_full.tsv.gz", species="human")

store.restriction("NLVPMVATV")                  # ranked presenting alleles + binder flags
store.is_binder("NLVPMVATV", "HLA-A*02:01")
store.scan_protein(my_protein, cls="mhc1")       # presented peptides in a protein
store.decompose("NLVPMVATV", cls="mhc1")         # (tcr_facing, presentation) with X masks

# similarity at scale
mhcmatch.search.search("NLVPMVATV", big_peptide_set, mode="tcr")   # TCR-facing homologs
mhcmatch.search.find_mimics("EAAGIGILTV", self_set, bacterial_sets={...})

# near-exact source of a neoantigen
pm = mhcmatch.Proteome.from_fasta("UP000005640_9606.fasta.gz")
pm.find_source("NLVPMVATV", max_subs=1)

# pseudosequence allele similarity + rare-allele diffusion
ps = mhcmatch.Pseudoseq("mhc1")
ps.neighbors("HLA-A*02:01", candidates=store.alleles("mhc1"))

# diffusion-powered forward scorer (rescues rare alleles by borrowing from groove-neighbours)
am = store.anchor_model("mhc1")          # learned anchor weights + bounded-prior shrinkage
am.score("NLVPMVATV", "HLA-A*02:01")     # anchor log-odds; am.score(..., raw=True) disables borrowing

# footprint (which core positions) and background (the log-odds null) tune the model to the question:
store.anchor_model("mhc1", footprint="adaptive")             # anchors for rare alleles, full core otherwise
store.anchor_model("mhc1", background="proteome")            # presentation null (is it presented at all?)
store.anchor_model("mhc1", background="ligand")              # specificity null (which allele? — default)

# calibrated, cross-allele-comparable output (NetMHCpan %Rank_EL analogue + P(present) + band)
for r in store.restriction("NLVPMVATV", cls="mhc1", calibrated=True):
    print(r.allele, r.rank, r.p_present, r.band)             # e.g. HLA-A*02:01  1.6  0.98  weak

mhcmatch.logo.motif(store, "HLA-A*02:01", "mhc1")

Command line

mhcmatch decompose NLVPMVATV                                  # anchor / TCR-facing split (no data)
set -x MHCMATCH_PMHC /path/to/pmhc_data                       # or pass --pmhc to each command
mhcmatch restriction NLVPMVATV --allele 'A*02:01' --diffuse   # allele name auto-resolved; rare-aware
mhcmatch restriction NLVPMVATV --calibrated                   # + %rank, P(present), binding band
mhcmatch scan my_protein.fasta --correction bh                # presented windows, BH-FDR controlled
mhcmatch source MKTAYIAKW --proteome UP000005640_9606.fasta.gz
mhcmatch logo 'HLA-A*02:01'

Data

  • Reference ligands: isalgo/pmhc_data (full / shortlist tiers) — pass the path to Store.from_pmhc or set MHCMATCH_PMHC.
  • Pseudosequences: 34-mer groove pseudosequences vendored in src/mhcmatch/data/ (see its PROVENANCE.md).
  • Reference proteomes: not bundled — supply a UniProt reference proteome FASTA (UP000005640 human / UP000000589 mouse) to Proteome.from_fasta.

Benchmark vs NetMHCpan

A reproducible head-to-head against NetMHCpan-4.2b and NetMHCIIpan-4.3i lives in bench/compare/ (results in bench/results/compare_*.md, provenance and caveats in bench/compare/SOURCES.md). It compares the two tools on the same per-(peptide, allele) task, stratified by allele rarity, with AUROC / AUPRC / PPV@k, bootstrap CIs and paired significance. Headline results (shortlist tier, human, seed 0):

  • Allele-specificity (which allele presents a peptide — the restriction problem): mhcmatch beats NetMHCpan on MHC-I medium and frequent alleles (AUROC, AUPRC and PPV@k, p < 0.001).
  • Presented-vs-random screening (background="proteome"): mhcmatch beats NetMHCpan on MHC-I medium/frequent and NetMHCIIpan on MHC-II rare alleles. Rare MHC-I remains NetMHCpan's.
  • Speed: mhcmatch scores ~68× faster (pure Python, ~195k peptide-allele scores/s).
python bench/compare/run_compare.py --cls mhc1 --decoy-mode hard   --background ligand    # specificity
python bench/compare/run_compare.py --cls mhc1 --decoy-mode random --background proteome  # screening

Status

Beta (v0.2). See ROADMAP.md for what's next (order-k Markov / covariance null, a learned reranker for rare-allele screening, full-tier + temporal cluster sweeps, and the stability/affinity/cleavage/immunogenicity predictors).

Download files

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

Source Distribution

mhcmatch-0.2.0.tar.gz (5.1 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mhcmatch-0.2.0-py3-none-any.whl (94.7 kB view details)

Uploaded Python 3

File details

Details for the file mhcmatch-0.2.0.tar.gz.

File metadata

  • Download URL: mhcmatch-0.2.0.tar.gz
  • Upload date:
  • Size: 5.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mhcmatch-0.2.0.tar.gz
Algorithm Hash digest
SHA256 32ecc00561e6cc5a7357f321d6fc372c993ad98d944f156391bb17872ae713fc
MD5 7050a5a85853c8bf473aa0400b556791
BLAKE2b-256 41a1f0f76a8f6ae183be435d6b77342ef0f07610f555b2b5655e9e65b203e1e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for mhcmatch-0.2.0.tar.gz:

Publisher: publish.yml on antigenomics/mhcmatch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mhcmatch-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: mhcmatch-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 94.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mhcmatch-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6f70dd5c4ce5c62a642c61412bba38f4c35e373c5baa28054ef7f580bf7e377c
MD5 70cecdb7091e9d2a19c110ca483a8be7
BLAKE2b-256 46bfe750891e9a104c6cd3fee2af571d54f9d15786fe733f2acd5e3ad4592bf0

See more details on using hashes here.

Provenance

The following attestation bundles were made for mhcmatch-0.2.0-py3-none-any.whl:

Publisher: publish.yml on antigenomics/mhcmatch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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