Skip to main content

BLOSUM62-aware anchor-residue clustering for immunopeptides, with a Rust backend

Project description

PepCluster

BLOSUM62-aware anchor-residue clustering for immunopeptides — with a fast Rust backend.

PepCluster groups peptides by the similarity of their MHC-I anchor residues (the first 3 + last 3 amino acids) using a BLOSUM62-normalized similarity metric with double weight on the primary anchor positions P2 and PΩ. It is built for large immunopeptidomics datasets: a Rust extension does the heavy lifting (10–100× faster than pure Python), and a pure-Python fallback keeps it working everywhere.

Unlike general-purpose sequence tools (e.g. MMseqs2), PepCluster distinguishes anchor from non-anchor positions, which is what actually drives MHC-I binding specificity — producing biologically interpretable clusters on short (8–14 aa) peptides where full-length estimators break down.


Install

pip install pepcluster

Prebuilt wheels are published for Linux, macOS, and Windows, so no Rust toolchain is required for end users. If you install on a platform without a wheel, pip builds from source (needs a Rust compiler — see Building from source).


Quick start

Command line

pepcluster -i examples/peptides.fasta -o out -t 0.6

This writes cluster assignments and per-cluster FASTA files under out/ (see Output files).

Python

import pepcluster

# End-to-end: FASTA in → TSV + per-cluster FASTA out
stats = pepcluster.cluster_fasta("peptides.fasta", "out", threshold=0.6)
print(stats["n_clusters"], "clusters")

# Low-level: cluster a dict of unique 6-mer anchors → frequency
mapping, n_cmp, n_early = pepcluster.cluster_anchors(
    {"YLLAGV": 3, "YMLAGV": 1, "GYAWTK": 2}, 0.6)
# mapping: {anchor -> representative anchor}

# Optional Lloyd-style refinement on top of the greedy result
refined, refine_stats = pepcluster.refine_clusters(
    {"YLLAGV": 3, "YMLAGV": 1}, mapping, 0.6, iterations=3)

pepcluster.HAS_RUST tells you whether the compiled backend is active (cluster_anchors / refine_clusters automatically use Rust when available and fall back to identical pure-Python implementations otherwise).


CLI options

Flag Default Description
-i, --input required Input FASTA file
-o, --outdir anchor_clusters Output directory
-t, --threshold 0.6 BLOSUM similarity threshold (0.0–1.0)
--min-cluster-size 2 Min members for a per-cluster FASTA
--n-front 3 N-terminal anchor length
--n-back 3 C-terminal anchor length
--anchors "2;3" Which positions are binding anchors, as FRONT;BACK (1-based per side). See Choosing the anchors
--anchor-weight 2.0 Weight given to anchor positions (all others are 1.0)
--refinement off Apply Lloyd-style refinement after greedy clustering
--iterations 3 Max refinement passes (with --refinement)
--refine-cap 32 Max centroid comparisons per anchor in refinement reassignment (<=0 = no cap). Lower = faster
--no-merge off Skip the refinement centroid-merge step (much faster on many-cluster data)
--backend auto auto | rust | python
-q, --quiet Suppress progress output

Refinement (--refinement) is optional and can be slow on datasets with many clusters, because it widens each anchor's search to neighbouring blocks and tries to merge similar clusters. Two knobs make it fast:

  • --refine-cap N bounds how many candidate centroids each anchor is compared against during reassignment (examined own-block-first, largest-cluster-first). The default 32 is near-lossless because the best match is almost always in the same block.
  • --no-merge skips the centroid-merge step — the dominant cost when there are many clusters — at the price of leaving some greedy-split clusters separate.

Together they speed refinement up by ~90–370× on many-cluster data with essentially unchanged assignments. Example:

pepcluster -i peptides.fasta -o out -t 0.6 --refinement --refine-cap 32 --no-merge

Threshold guide:

Value Effect
0.8 Strict — mostly exact matches + very conservative substitutions
0.6 Moderate — allows 1–2 conservative substitutions (recommended)
0.4 Relaxed — broader groups for exploratory analysis

Choosing the anchors

The anchor is the peptide's first --n-front + last --n-back residues. --anchors picks which positions inside that anchor are the binding anchors: they get --anchor-weight (default 2×) in the similarity score and they define the coarse-alphabet blocking.

The format is "FRONT;BACK", where each side is a comma-separated list of 1-based indices into that side's residues. Either side may be empty.

The default "2;3" means the 2nd of the first 3 residues (P2) and the 3rd of the last 3 () — the classic MHC-I anchors.

--anchors Anchor positions (1-based, in the 6-mer) Meaning
"2;3" (default) 2, 6 P2 + PΩ — MHC-I
"2;2,3" 2, 5, 6 P2 plus the last two C-terminal residues
"1,2;3" 1, 2, 6 first two N-terminal residues plus PΩ
";3" 6 C-terminal anchor only
"2;" 2 N-terminal anchor only
# emphasise P2 and the last two residues, and weight anchors 3x
pepcluster -i peptides.fasta -o out --anchors "2;2,3" --anchor-weight 3

Anchor positions are indexed relative to --n-front / --n-back, so the two work together — e.g. a 2+2 anchor with anchors at the 2nd of each side:

pepcluster -i peptides.fasta -o out --n-front 2 --n-back 2 --anchors "2;2"

Up to 8 anchor positions are supported (they form the blocking key).


Output files

out/
├── clusters.tsv            # cluster_id, representative_anchor, representative_peptide, header, sequence, anchor (every peptide)
├── cluster_summary.tsv     # cluster_id, representative_anchor, representative_peptide, size (sorted by size)
├── summary.txt             # run statistics
└── fasta/
    ├── cluster_0.fasta     # per-cluster FASTA, ready for MSA (>= --min-cluster-size members)
    ├── cluster_1.fasta
    └── SHORT_peptides.fasta # peptides too short to form an anchor (if any)

representative_peptide is the cluster's central member — the peptide with the least average distance (highest weighted average similarity) to every other peptide in the cluster. It is computed in linear time and is always a real member sequence, so it's a good label or seed for each cluster. representative_anchor is the anchor that originally seeded the cluster.


How it works

  1. Anchor extraction. Each peptide is reduced to its anchor: the first --n-front (3) and last --n-back (3) amino acids. Peptides shorter than that are set aside in SHORT_peptides.fasta.
  2. Deduplicate. Peptides are grouped by their exact anchor, so clustering operates on unique anchors weighted by frequency.
  3. Similarity metric. Two anchors are compared position-by-position with a BLOSUM62 score normalized to sim(a,b) = B(a,b) / sqrt(B(a,a)·B(b,b)). The anchor positions (--anchors, default P2 and PΩ) carry --anchor-weight (default 2×); every other position carries 1×. The score is a weighted mean in [−…, 1].
  4. Blocking. Unique anchors are bucketed by a reduced 10-letter alphabet at the anchor positions (10ᵏ bins for k anchors — 100 by default), so only plausibly-similar anchors are ever compared. High-weight positions are checked first with early termination.
  5. Greedy clustering. Within each block, anchors are processed most-frequent-first; each joins the first centroid above threshold or becomes a new centroid.
  6. Optional refinement (--refinement). A Lloyd-style pass iterates: medoid update → cross-block reassignment → centroid merging, until stable.

The Rust backend (pepcluster._core) and the pure-Python reference (pepcluster.clustering) implement identical logic — both compute in f64 with identical, deterministic orderings — and produce bit-identical cluster assignments; the test suite asserts this parity across anchor lengths, positions and weights.


Performance

Dataset Python Rust
7K peptides <1 s <1 s
2.5M peptides ~3 min ~15 s

Speed comes from anchor deduplication, coarse-alphabet blocking, and weighted early-termination in the similarity check.


Building from source

Requires a Rust toolchain and maturin.

# one-time
pip install maturin

# build + install into the current environment (editable-ish)
maturin develop --release

# or build a wheel
maturin build --release      # wheel lands in target/wheels/

The project uses maturin's mixed layout: Rust lives in src/lib.rs (compiled to pepcluster._core), Python in python/pepcluster/.

Run the tests with:

pip install pytest
pytest

Releasing (maintainers)

Wheels are built for Linux / macOS / Windows by .github/workflows/CI.yml and published to PyPI on version tags via PyPI Trusted Publishing (OpenID Connect — no API token or stored secret).

  1. One-time: on https://pypi.org/manage/account/publishing/ add a pending publisher — Owner AmirAsgary, Repository PepCluster, Workflow CI.yml (leave the environment blank).

  2. Bump the version in pyproject.toml and Cargo.toml.

  3. Tag and push:

    git tag v0.1.0
    git push origin v0.1.0
    

The release job then builds all wheels + an sdist and uploads them to PyPI.


License

MIT © 2026 Amir Asgary


Citation

If you use PepCluster in your research, please cite this repository:

Asgary, A. PepCluster: BLOSUM62-aware anchor-residue clustering for immunopeptides. https://github.com/AmirAsgary/PepCluster

Project details


Download files

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

Source Distribution

pepcluster-0.1.2.tar.gz (32.5 kB view details)

Uploaded Source

Built Distributions

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

pepcluster-0.1.2-cp38-abi3-win_amd64.whl (178.7 kB view details)

Uploaded CPython 3.8+Windows x86-64

pepcluster-0.1.2-cp38-abi3-musllinux_1_2_x86_64.whl (523.2 kB view details)

Uploaded CPython 3.8+musllinux: musl 1.2+ x86-64

pepcluster-0.1.2-cp38-abi3-musllinux_1_2_aarch64.whl (485.7 kB view details)

Uploaded CPython 3.8+musllinux: musl 1.2+ ARM64

pepcluster-0.1.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (318.6 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

pepcluster-0.1.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (309.0 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

pepcluster-0.1.2-cp38-abi3-macosx_11_0_arm64.whl (279.8 kB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

pepcluster-0.1.2-cp38-abi3-macosx_10_12_x86_64.whl (286.7 kB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

Details for the file pepcluster-0.1.2.tar.gz.

File metadata

  • Download URL: pepcluster-0.1.2.tar.gz
  • Upload date:
  • Size: 32.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pepcluster-0.1.2.tar.gz
Algorithm Hash digest
SHA256 f9e567f71a8d9a5bbf2ef54d1c2d8f690a73a76c071d1ce692b0f991dc81b710
MD5 d69cae44a0df59eccbf3212b33b8f0cc
BLAKE2b-256 a8fc032fd083112b7a7cfa99012863066bcc9d9d4f8c568f3116bbcc5ab35578

See more details on using hashes here.

Provenance

The following attestation bundles were made for pepcluster-0.1.2.tar.gz:

Publisher: CI.yml on AmirAsgary/PepCluster

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

File details

Details for the file pepcluster-0.1.2-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: pepcluster-0.1.2-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 178.7 kB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pepcluster-0.1.2-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 3209d43c4d3434ad73404e2550e1fc0e7ae0626565ef8344db67881644ac3755
MD5 e3256647a13a25e648d9cfc8c1eec5b5
BLAKE2b-256 d818c265175d672a57522154c6ae2a58fb22ee1e52cc4a9b107436670b7bf6e8

See more details on using hashes here.

Provenance

The following attestation bundles were made for pepcluster-0.1.2-cp38-abi3-win_amd64.whl:

Publisher: CI.yml on AmirAsgary/PepCluster

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

File details

Details for the file pepcluster-0.1.2-cp38-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for pepcluster-0.1.2-cp38-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 c4d97573fe1ca3bc6d0821f5761c755b3722acc39cac0b0ad004df79edfda421
MD5 004d9b114c16a67c6cecf1787e15431f
BLAKE2b-256 4092700ebc90dcc14a951f0ba366baa3f49977f8925807e24a0004e02a53f058

See more details on using hashes here.

Provenance

The following attestation bundles were made for pepcluster-0.1.2-cp38-abi3-musllinux_1_2_x86_64.whl:

Publisher: CI.yml on AmirAsgary/PepCluster

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

File details

Details for the file pepcluster-0.1.2-cp38-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for pepcluster-0.1.2-cp38-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 e7ebfd6f2eff5b55922b8196d41579d33a9fd2a91c8aa437cd6fe1f3e4ba11c2
MD5 17b89e9f782a8da6b9a762298c7a7f0e
BLAKE2b-256 fcd6f891721609eddf967b4804a24d248dee0408458b501b052f9a0b9f6f9081

See more details on using hashes here.

Provenance

The following attestation bundles were made for pepcluster-0.1.2-cp38-abi3-musllinux_1_2_aarch64.whl:

Publisher: CI.yml on AmirAsgary/PepCluster

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

File details

Details for the file pepcluster-0.1.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pepcluster-0.1.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ea4be7d1e96359c58ea752af1cabc0f3af2ce66882053dff0bf42a159363d237
MD5 193218a8f21930f20a2ba54dc9d7645b
BLAKE2b-256 a4747c1b9ac5b2e5a6513f5ce0d637aac75351ae7d2f0b5f8124fcfa4e5e60c9

See more details on using hashes here.

Provenance

The following attestation bundles were made for pepcluster-0.1.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: CI.yml on AmirAsgary/PepCluster

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

File details

Details for the file pepcluster-0.1.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pepcluster-0.1.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 a350564659604f917e78786c6d4fddbca624daeee7f39d238e572c61b36ebe2b
MD5 eab677b5a6981593f974a0aea0297674
BLAKE2b-256 69ffce5ec6b734077b7e3aca79bd435c447c6609442e790703d31c839fb5714c

See more details on using hashes here.

Provenance

The following attestation bundles were made for pepcluster-0.1.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: CI.yml on AmirAsgary/PepCluster

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

File details

Details for the file pepcluster-0.1.2-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pepcluster-0.1.2-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8011366fccc5f3c7678597a1d5757491d181751401ccd4be44df511c8b8d6fc3
MD5 9aa3118cc4caac549a135ef506ab7cea
BLAKE2b-256 aaf7d7486effcce256bcc9a5164a0cc603ef9f96499ac76b9d7834bfa2f9731e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pepcluster-0.1.2-cp38-abi3-macosx_11_0_arm64.whl:

Publisher: CI.yml on AmirAsgary/PepCluster

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

File details

Details for the file pepcluster-0.1.2-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pepcluster-0.1.2-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 8e458e50edc08ca008b73b4c9e3366cd85b3e76c0622866e0827603a072c7a19
MD5 b7a7dcaa518caf3ab345942f9324f4eb
BLAKE2b-256 f365497c7939508dab6e59046b24cd261ea5ed8fd5accae00e8f10d3b4a9d31d

See more details on using hashes here.

Provenance

The following attestation bundles were made for pepcluster-0.1.2-cp38-abi3-macosx_10_12_x86_64.whl:

Publisher: CI.yml on AmirAsgary/PepCluster

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