Harmonize and validate HLA typing output across multiple typers
Project description
hlaconcord
Harmonize and validate HLA typing output across multiple typers.
Ingest the raw output of N HLA typers (OptiType, arcasHLA, HLA-LA, HLA-HD, …), normalize every call to canonical IPD-IMGT/HLA nomenclature at a chosen resolution, validate each allele name against the official allele database, and emit one tidy table plus a concordance/consensus view showing where the tools agree and disagree.
The field's own best practice is to run several typers and cross-check them; today that means renaming alleles by hand and building concordance tables in a spreadsheet. hlaconcord makes that workflow reproducible — and does the one thing the manual version gets wrong, reconciling cross-database-version name skew via stable accession ids so a version difference never masquerades as a real disagreement.
See PLAN.md for the full design and rationale.
Status
M0–M5 complete — nomenclature core, all four MVP parsers, concordance/consensus engine, CLI, and packaging/CI hardening. The engine (parse → normalize → validate → reconcile → concord → emit) is implemented and tested (113 tests + an optional py-ard oracle gate).
Install
pip install -e ".[dev]" # add ",oracle" to also run the py-ard cross-check
The IPD-IMGT/HLA reference database is fetched, not bundled (only the small name/group files, never the sequences). Install a release before your first run:
hlacc db update 3.55.0 # into a local cache (XDG data dir by default)
Quickstart
hlacc run \
--inputs optitype:examples/s1/s1_result.tsv \
arcasHLA:examples/s1/s1.genotype.json \
hla-la:examples/s1/s1_bestguess_G.txt \
hla-hd:examples/s1/s1_final.result.txt \
--db 3.55.0 --gl -o out/
# sample s1 (basis=lgx)
OK A A*01:01 + A*02:01
OK B B*07:02
OK C C*07:02
OK DRB1 DRB1*15:01
Four different formats/resolutions of the same genotype — 2-field, 3-field, G-group,
and HLA--prefixed — reduce to one comparison key per allele and concord across loci.
See examples/ for the full walkthrough.
CLI
hlacc run --inputs TOOL:PATH ... [--sample S] [--compare lgx|g|p|2field]
[--consensus majority|unanimous] [--db VER] [--gl] [-o DIR]
hlacc run --samplesheet samples.csv -o out/ # batch: sample,tool,path[,db_version]
hlacc validate HLA-A*02:01 A*99:99 # classify names against a release
hlacc normalize A*0201 A*29:112N # canonical form + accession + reduction
hlacc db list | update <ver> | pin <ver> | path
run exits 0 when every locus concords, 1 if any locus is discordant, and 2 on
a configuration or database error — so it drops into a pipeline or make target.
Comparison basis (--compare) defaults to lgx — the 2-field representative of an
allele's G-group — because it collapses every resolution the MVP tools emit to one key
without turning a resolution difference into a false discordance (g is available as a
stricter ARD lens; see PLAN.md §7).
Outputs
With -o DIR, run writes:
tidy.tsv— one row per allele call, raw string kept alongside the normalized / validated / reduced values and the accession (the auditable spine).concordance.tsv— one row per sample×locus: status, consensus, per-tool agreement, and flags (discordance, singleton, null allele, resolution conflict, version-skew-resolved, invalid call).concordance.json— the same, sample-grouped and metadata-stamped, for programmatic consumers; includes each sample's consensus GL string.gl_strings.tsv— consensus GL String per sample (with--gl).
Library
The CLI is a thin layer over an importable pipeline:
from hlaconcord import db
from hlaconcord.nomenclature import InHouseNomenclature
from hlaconcord.pipeline import InputSpec, run
root = db.default_root()
nom = InHouseNomenclature(db.load_reference(root, "3.55.0"))
result = run(
[InputSpec("optitype", "s1_result.tsv"), InputSpec("arcasHLA", "s1.genotype.json")],
nom, db_version="3.55.0",
)
for locus in result.concordance:
print(locus.locus, locus.status.value, locus.consensus)
Package layout:
hlaconcord.nomenclature— allele model + parser, theNomenclaturefacade, the in-house reducer/validator (InHouseNomenclature), and the reference loaders.hlaconcord.parsers— OptiType, arcasHLA, HLA-LA, HLA-HD adapters behind a registry.hlaconcord.normalize/hlaconcord.tidy— enrich calls through the facade; tidy table.hlaconcord.concordance/hlaconcord.report/hlaconcord.gl— per sample×locus concordance and consensus, TSV/JSON/human reports, and GL-String export.hlaconcord.db— reference-release cache management.hlaconcord.pipeline/hlaconcord.cli— orchestration and the command-line surface.
Nomenclature design note
The in-house reducer is the shipped implementation. py-ard (NMDP, LGPL-3.0) is used
only as a test-time oracle to cross-check it — never a runtime dependency, so no
LGPL code ships in the distributed artifact. The M0 spike verified agreement on real
IPD-IMGT/HLA 3.55.0 data (≥99.4% at lgx; residual divergences are documented and
allow-listed). See PLAN.md §6, §12.
Development
pip install -e ".[dev]"
ruff check src tests
pytest # 113 tests; add ".[oracle]" + HLACONCORD_IMGT_DIR for the oracle gate
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hlaconcord-0.1.0.tar.gz.
File metadata
- Download URL: hlaconcord-0.1.0.tar.gz
- Upload date:
- Size: 51.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
25a98e519ed7e5854d11a213f3f168a288c93b43c92306ee32b518e0daa1012e
|
|
| MD5 |
9a1ac5d3b5e082643860edc1c5ed7348
|
|
| BLAKE2b-256 |
ea32a4b55b07daa1cbbae458ccac4dfb550e27c5dfd82dc48a00a881ed4c6bb2
|
Provenance
The following attestation bundles were made for hlaconcord-0.1.0.tar.gz:
Publisher:
release.yml on leonbzt/hlaconcord
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hlaconcord-0.1.0.tar.gz -
Subject digest:
25a98e519ed7e5854d11a213f3f168a288c93b43c92306ee32b518e0daa1012e - Sigstore transparency entry: 2170924157
- Sigstore integration time:
-
Permalink:
leonbzt/hlaconcord@c9ac66aa7c24e576eab6c518ed26a69b3fa2426f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/leonbzt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c9ac66aa7c24e576eab6c518ed26a69b3fa2426f -
Trigger Event:
push
-
Statement type:
File details
Details for the file hlaconcord-0.1.0-py3-none-any.whl.
File metadata
- Download URL: hlaconcord-0.1.0-py3-none-any.whl
- Upload date:
- Size: 35.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ada818cd34448acc19e1c61938fa6ca8b7fde670bb3267700ad7db0b934e01b5
|
|
| MD5 |
75572f239d99be44a0530015ff1d9184
|
|
| BLAKE2b-256 |
9571085e7e5e0242e852af06fca92b591144e1e0c2f5fd2037d3af91db475c7c
|
Provenance
The following attestation bundles were made for hlaconcord-0.1.0-py3-none-any.whl:
Publisher:
release.yml on leonbzt/hlaconcord
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hlaconcord-0.1.0-py3-none-any.whl -
Subject digest:
ada818cd34448acc19e1c61938fa6ca8b7fde670bb3267700ad7db0b934e01b5 - Sigstore transparency entry: 2170924162
- Sigstore integration time:
-
Permalink:
leonbzt/hlaconcord@c9ac66aa7c24e576eab6c518ed26a69b3fa2426f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/leonbzt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c9ac66aa7c24e576eab6c518ed26a69b3fa2426f -
Trigger Event:
push
-
Statement type: