Skip to main content

A Polars expression plugin that detects MHC class I chain starts at Rust speed

Project description

polars-mhci-starts

PyPI Python CI Licence: MIT

A Polars expression plugin that answers one question quickly: does this sequence contain the start of an MHC class I chain?

An MHC class I heavy (alpha) chain has a characteristic mature N-terminus — GSHSMRY, GDTRPRY and around a hundred allelic variants. This plugin tests, per row, whether any of those motifs appears in a sequence. It's a byte-level substring scan in Rust, so it runs fast enough to sweep a whole structure database in one pass.

import polars as pl
from polars_mhci_starts import has_class_i_start

df = pl.DataFrame({"seq": [
    "GSHSMRYFYTSVSRPGRGEPRFIAV",   # a class I alpha chain
    "MAVMAPRTLLLLLSGALALTQTWAGSHSMRYFYT",  # ...behind a leader peptide
    "MKWVTFISLLFLFSSAYS",          # serum albumin — not MHC
    None,
]})

df.with_columns(hit=has_class_i_start("seq"))
┌────────────────────────────────────┬───────┐
│ seq                                ┆ hit   │
│ ---                                ┆ ---   │
│ str                                ┆ bool  │
╞════════════════════════════════════╪═══════╡
│ GSHSMRYFYTSVSRPGRGEPRFIAV          ┆ true  │
│ MAVMAPRTLLLLLSGALALTQTWAGSHSMRYFYT ┆ true  │   start sits after the leader
│ MKWVTFISLLFLFSSAYS                 ┆ false │   no class I motif
│ null                               ┆ null  │   missing is unknown, not "no match"
└────────────────────────────────────┴───────┘

Install

uv add polars-mhci-starts
# or: pip install polars-mhci-starts

Wheels are published for Linux (x86_64, aarch64), macOS (x86_64, arm64) and Windows (x64), so there's nothing to compile — you don't need a Rust toolchain to use this.

Requires Python ≥ 3.14 and Polars ≥ 1.42. The wheels are abi3-py314: one wheel per platform covers 3.14 and every later 3.x.

To build from source instead, you'll need a Rust toolchain and uv:

git clone https://github.com/drchristhorpe/polars-mhci-starts
cd polars-mhci-starts
uv sync                       # fetches Python 3.14, builds the Rust extension
uv run maturin develop --release
uv run pytest

Usage

has_class_i_start takes a column name or an expression and returns a boolean expression. Use it anywhere an expression goes — select, with_columns, filter, lazy or eager:

df.filter(has_class_i_start("seq"))                     # keep only sequences with a start
df.with_columns(hit=has_class_i_start(pl.col("seq")))   # flag them instead
lf.filter(has_class_i_start("seq")).collect()           # works lazily too

There is also a .mhci namespace, if you prefer method chaining:

df.with_columns(hit=pl.col("seq").mhci.has_class_i_start())

What counts as a match

A sequence matches when any catalogued class I alpha chain-start motif appears as a substring — not only at the very beginning. In a full-length precursor the mature start sits after a signal/leader peptide, and in engineered single-chain constructs it can sit much deeper still:

  • Single-chain trimers (SCTs) — peptide–linker–β2m–linker–heavy chain fused into one polypeptide, so the heavy-chain start follows the peptide and the whole of β2m.
  • SMART-HLA — a truncated heavy chain preceded by a designed domain that replaces α3 and β2m, so the α1 start motif again sits after an engineered N-terminal segment.

A prefix test (starts_with) would miss all of these; a substring test finds the start wherever it has ended up.

To tolerate structures that are missing the first residue or two of the mature molecule, each motif is tried three ways: at full length, with its first residue dropped, and with its first two dropped. So GDTRPRY, DTRPRY and TRPRY all count as the same start.

The motif list is exposed as CLASS_I_STARTS:

from polars_mhci_starts import CLASS_I_STARTS

len(CLASS_I_STARTS)     # 118 unique motifs
CLASS_I_STARTS[0]       # 'GDTRPRY'

What it catches, and what it doesn't

The catalogue is built from real heavy chains, so it behaves sensibly on the wider MHC superfamily. A few worked examples, all verified in the test suite:

Molecule UniProt Result Why
HLA-A (classical class I) P04439 ✅ match mature start GSHSMRY
CD1a (class I-like, lipid antigen) P06126 ✅ match start EPLSFHV is catalogued
MR1 (class I-related) Q95460 ✅ match start RTHSLRY is catalogued
HLA-DRA (class II alpha) P01903 ❌ no match different N-terminus
HLA-DRB1 (class II beta) P01911 ❌ no match starts GDTRPRF

Class I and class II share a common ancestor and the same domain architecture, which makes the class II chains a genuinely hard negative control rather than an easy one — HLA-DRB1 opens GDTRPRF, a single residue away from the class I catalogue entry GDTRPRY. The final position is what tells them apart, and it does. The class I-like molecules CD1a and MR1, by contrast, carry starts that were catalogued alongside the classical alleles, so they match — which is the right answer if you're pulling class I-fold chains out of a structure database.

Behaviour worth knowing

  • Nulls propagate as null, and do not collapse to false. A missing sequence is unknown, not a non-match — so filter(has_class_i_start(...)) drops null rows, while with_columns(hit=has_class_i_start(...)) keeps them visible as null.
  • Empty and very short strings are false: the shortest needle is a 5-mer, so nothing shorter can match.
  • Non-ASCII input is rejected rather than raising. The scan is a byte-level substring search, and the motifs are pure ASCII, so no byte of a multi-byte character can be mistaken for part of a motif.

How it maps to the prior art

This packages the match_class_i_start function from an internal localpdb querying script into a reusable, vectorised Polars expression. That function looped the motif list per sequence in Python and returned the matched motif; here we answer the boolean form of the same question — is a start present? — across a whole column at Rust speed. The motif data is the same chain_starts.json.

Related

  • polars-is-peptide — the sibling plugin this is modelled on: is a string a valid peptide sequence?

Licence

MIT — see LICENSE.

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

polars_mhci_starts-0.1.0.tar.gz (41.1 kB view details)

Uploaded Source

Built Distributions

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

polars_mhci_starts-0.1.0-cp314-abi3-win_amd64.whl (3.9 MB view details)

Uploaded CPython 3.14+Windows x86-64

polars_mhci_starts-0.1.0-cp314-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.5 MB view details)

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

polars_mhci_starts-0.1.0-cp314-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.2 MB view details)

Uploaded CPython 3.14+manylinux: glibc 2.17+ ARM64

polars_mhci_starts-0.1.0-cp314-abi3-macosx_11_0_arm64.whl (3.1 MB view details)

Uploaded CPython 3.14+macOS 11.0+ ARM64

polars_mhci_starts-0.1.0-cp314-abi3-macosx_10_12_x86_64.whl (3.4 MB view details)

Uploaded CPython 3.14+macOS 10.12+ x86-64

File details

Details for the file polars_mhci_starts-0.1.0.tar.gz.

File metadata

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

File hashes

Hashes for polars_mhci_starts-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ba30178fd8cb7da77af1315d9f2705b6e5006bb87f4a7a164e756359d199fb5c
MD5 4c2dd885d8b1520ac8efe9d3398e52c4
BLAKE2b-256 49bccf2f77a2b5dd8e6d9351d4246b339d0a20eeede13a19f4bbfe8c6f184e10

See more details on using hashes here.

Provenance

The following attestation bundles were made for polars_mhci_starts-0.1.0.tar.gz:

Publisher: CI.yml on drchristhorpe/polars-mhci-starts

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

File details

Details for the file polars_mhci_starts-0.1.0-cp314-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for polars_mhci_starts-0.1.0-cp314-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 9b0ace8cd09fbb9c085d321ea4b5701d8e8216229d8f4114412aa4b15192e1af
MD5 08c781077be002abb8988f9fa97bdb86
BLAKE2b-256 9cdc7ac097eff3bd82d67d9afc40769b6c044a6da74d927ae60a80a85add20a5

See more details on using hashes here.

Provenance

The following attestation bundles were made for polars_mhci_starts-0.1.0-cp314-abi3-win_amd64.whl:

Publisher: CI.yml on drchristhorpe/polars-mhci-starts

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

File details

Details for the file polars_mhci_starts-0.1.0-cp314-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for polars_mhci_starts-0.1.0-cp314-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 35332e93ff18527a6a02eccecc9177cc23f5e163e7a68d972e9640ab6bfc2570
MD5 f6ed955ca82accd0b8b729606e143555
BLAKE2b-256 56ac37a771f81d9deb6ee71ea86e5d0f93e504c394c2539a0f90007f5a643bf1

See more details on using hashes here.

Provenance

The following attestation bundles were made for polars_mhci_starts-0.1.0-cp314-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: CI.yml on drchristhorpe/polars-mhci-starts

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

File details

Details for the file polars_mhci_starts-0.1.0-cp314-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for polars_mhci_starts-0.1.0-cp314-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 3603353f629f742585fec7714dc7a739c763f824e7d0e0e75b40ae56b76e25c0
MD5 e7436ac2673150a02007979ede7eb91d
BLAKE2b-256 300b11f18b00fee8f1f2a7a98ea4ef7a84a284a7398e8abe8b18bd6b82ecff0c

See more details on using hashes here.

Provenance

The following attestation bundles were made for polars_mhci_starts-0.1.0-cp314-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: CI.yml on drchristhorpe/polars-mhci-starts

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

File details

Details for the file polars_mhci_starts-0.1.0-cp314-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for polars_mhci_starts-0.1.0-cp314-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7a384dae0720030654be0d06875755804d17d46ac4a9822b1f8e8b11750bfe62
MD5 2e477ce75ff510217a8f68feafbac7a3
BLAKE2b-256 d264f2701c65067bacd7c103ba0ea743c2f1eeb87ec4af560563ada9d036a27c

See more details on using hashes here.

Provenance

The following attestation bundles were made for polars_mhci_starts-0.1.0-cp314-abi3-macosx_11_0_arm64.whl:

Publisher: CI.yml on drchristhorpe/polars-mhci-starts

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

File details

Details for the file polars_mhci_starts-0.1.0-cp314-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for polars_mhci_starts-0.1.0-cp314-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f5db478185b2f9bc2abdd29ccd8ccb0818146b28dddc7adb534e52dbacad5bf7
MD5 0b67a2dfe3428a01569664f1089d1a6e
BLAKE2b-256 6dbbeaa15af0ce4ea0966f24adde443d903618dd28f7716e2f18cffc0b9eaeef

See more details on using hashes here.

Provenance

The following attestation bundles were made for polars_mhci_starts-0.1.0-cp314-abi3-macosx_10_12_x86_64.whl:

Publisher: CI.yml on drchristhorpe/polars-mhci-starts

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