mhcseqs

Self-contained pipeline for downloading, curating, and extracting binding grooves from MHC protein sequences.

Installation

pip install mhcseqs

For development:

git clone https://github.com/openvax/mhcseqs.git
cd mhcseqs
./develop.sh    # pip install -e ".[dev]"
./test.sh       # pytest
./lint.sh       # ruff

Requirements: Python 3.10+, mhcgnomes (installed automatically).

CLI Reference

mhcseqs build

Downloads FASTA sources (IMGT/HLA + IPD-MHC), parses alleles, selects two-field representatives, extracts binding grooves, and runs validation.

mhcseqs build [--output-dir DIR] [--data-dir DIR]
OptionDescription
--output-dirDirectory for output CSVs (default: ~/.cache/mhcseqs)
--data-dirDirectory for downloaded FASTA files (default: ~/.cache/mhcseqs/fasta)

Produces four files:

FileDescription
mhc-seqs-raw.csvEvery parsed protein entry from all sources
mhc-full-seqs.csvOne representative per two-field allele: full sequence, groove decomposition, and metadata
mhc-merge-report.txtDetails on allele group merging decisions
mhc-validation-report.txtSanity check results

mhcseqs lookup

Query built CSVs by allele name.

mhcseqs lookup "HLA-A*02:01"
mhcseqs lookup "Mamu-A1*001:01"

mhcseqs --version

Print the installed version.

Python API

Allele lookup

import mhcseqs

# Build the database (downloads FASTA sources, only needed once)
paths = mhcseqs.build()

# Look up any allele → AlleleRecord with everything
r = mhcseqs.lookup("HLA-A*02:01")
r.allele             # "HLA-A*02:01" (two-field)
r.full_allele        # "HLA-A*02:01:01:100" (full resolution)
r.sequence           # full protein (with signal peptide)
r.mature_sequence    # signal peptide removed (computed property)
r.mature_start       # signal peptide length (24)
r.groove1            # α1 domain (90 aa)
r.groove2            # α2 domain (93 aa)
r.ig_domain          # α3 Ig-fold (95 aa)
r.tail               # TM + cytoplasmic
r.species_category   # "human"

# Apply mutations (IEDB-style, e.g. "K66A")
m = mhcseqs.lookup("HLA-A*02:01", mutations=["K66A", "D77S"])

Load all sequences

import mhcseqs

# As a DataFrame (full sequence + groove decomposition + metadata)
df = mhcseqs.load_sequences_dataframe()

# Or as a list of dicts (no pandas dependency)
rows = mhcseqs.load_sequences_dict()

Species utilities

mhcseqs.normalize_species("Macaca mulatta")  # "macaque"
mhcseqs.normalize_mhc_species("macaque")      # "nhp"
mhcseqs.get_latin_name("macaque")             # "Macaca mulatta"
mhcseqs.get_canonical_prefix("macaque")       # "Mamu"

Allele utilities

mhcseqs.normalize_allele_name("A0201")  # "HLA-A*02:01"
mhcseqs.infer_gene("HLA-A*02:01")       # "A"
mhcseqs.infer_mhc_class("HLA-A*02:01")  # "I"

Output columns

mhc-seqs-raw.csv

ColumnDescription
allele_rawOriginal allele token from FASTA header
allele_normalizedFull-resolution name from mhcgnomes
two_field_alleleTruncated to two-field / "4-digit" resolution
geneGene name (e.g. A, DRB1, DQA1)
mhc_classI or II
chainalpha, beta, or B2M
speciesSpecies name (usually Latin)
species_categoryOne of: human, nhp, murine, other_mammal, bird, fish, other_vertebrate
species_prefixMHC naming prefix (HLA, Mamu, SLA, etc.)
sourceimgt, ipd_mhc, uniprot_curated, or uniprot_reference
source_idDatabase accession (HLA00001, NHP00001, P01901, etc.)
sequenceFull protein sequence
has_signal_peptideWhether a signal peptide was detected
signal_peptide_lenInferred signal peptide length
is_null, is_questionable, is_pseudogeneAllele status flags

mhc-full-seqs.csv

Shares columns with the raw CSV: two_field_allele, gene, mhc_class, chain, species, species_category, species_prefix, source, seq_len, sequence, is_null, is_questionable, is_pseudogene. Additional columns:

ColumnDescription
representative_alleleSpecific full-resolution allele chosen
protein_seq_selectionSelection method (unique, nested_longest, etc.)
mature_startOffset where mature protein begins
mature_sequenceProtein with signal peptide removed
groove1N-terminal groove half: α1 domain (class I & II alpha chains)
groove2C-terminal groove half: α2 domain (class I) or β1 domain (class II beta)
groove_seqConcatenation of groove1 + groove2
ig_domainIg support domain: α3 (class I), α2 (class II α), β2 (class II β)
tailTransmembrane + cytoplasmic region
domain_architectureTyped domain grammar, e.g. signal_peptide>g_alpha1>g_alpha2>c1_alpha3>transmembrane
domain_spansHuman-readable domain coordinates in the raw sequence
groove_statusGroove parse outcome (ok, missing_groove, fragment_fallback, etc.)
anchor_typeWhich Cys pair anchored the parse
is_functionalGroove parseable AND not null/pseudogene

Groove extraction algorithm

The parser is alignment-free and holistic. It scores signal peptide, groove, support-domain, and TM evidence together instead of anchoring the parse on one fixed mature-position constant.

Domain architecture

Class I alpha:   signal_peptide? -> g_alpha1 -> g_alpha2 -> c1_alpha3 -> TM? -> tail?
Class II alpha: signal_peptide? -> g_alpha1 -> c1_alpha2 -> TM? -> tail?
Class II beta:  signal_peptide? -> g_beta1  -> c1_beta2  -> TM? -> tail?

How it works

  1. Enumerate all plausible Cys-Cys pairs in the Ig/C-like separation range.
  2. Score each pair as G-domain or C-like using Trp41-like fold topology, Cys-flank composition, and pair separation.
  3. Enumerate candidate SP boundaries and complete domain parses, including partial-fragment parses when needed.
  4. Choose the best whole parse from combined evidence: SP grammar, groove anchor, groove boundary motifs, support-domain evidence, and TM support.

The main evidence sources are:

Groove status codes

StatusMeaning
okFull decomposition from the main structural grammar
inferred_from_alpha3Class I salvage parse using only a downstream α3 C-like anchor
beta1_only_fallbackClass II β salvage parse using only the β1 groove pair
alpha1_onlyClass-I fragment consistent with α1 / exon 2 only
alpha2_onlyClass-I fragment consistent with α2 / exon 3 only
fragment_fallbackShort fragment retained as the observable groove half
missing_grooveNo recoverable groove architecture from the available evidence
non_classicalNon-classical class-I lineage flagged post-parse
shortGroove half too short to look functionally peptide-binding
not_applicablePipeline-level non-groove row, mainly B2M in build outputs

Literature basis

Species taxonomy

Every entry is assigned a species_category from a 10-class taxonomy:

CategoryFine-grained species included
humanHomo sapiens
nhpmacaque, chimpanzee, gorilla, orangutan, baboon, other NHP
murinemouse, rat
ungulatecattle, pig, horse, sheep, goat
carnivoredog, cat
cetaceanwhale, dolphin
other_mammalrabbit, other mammals
birdchicken, other birds
fishsalmon, zebrafish, other fish
other_vertebratereptiles, amphibians

Module reference

mhcseqs.domain_parsing

Core groove extraction. Key functions:

mhcseqs.alleles

Allele name parsing via mhcgnomes:

mhcseqs.species

Species normalization:

mhcseqs.pipeline

Two-step build pipeline:

mhcseqs.validate

Post-build sanity checks:

mhcseqs.download

FASTA source downloading:


Generated by mhcseqs. Apache License 2.0.