Support un-normalizable exotic alleles (#220) - #221
Merged
Conversation
netMHCpan's -listMHC includes alleles mhcgnomes can't parse: exotic non-human alleles (H-2-Qa1, BoLA-amani.1) and HLA low/null-expression variants (HLA-A30:14L). Requesting one raised AlleleParseError during predictor construction even though netMHCpan supports it. This is the tail left over after #219 (which handled ~2,456 alleles that normalize but to a spelling netMHCpan rejects); these names don't normalize at all. Carry the predictor's own -listMHC spelling as identity for these: * add normalize_allele_name_or_raw(): normalize when possible, else fall back to a canonical raw form (strip whitespace and the '*' gene/allele separator). netMHCpan echoes a requested "HLA-A30:14L" back as "HLA-A*30:14L", so stripping '*' makes both spellings one identity. * BasePredictor.__init__ gains keep_unparseable_alleles (default False); command-line predictors pass True since they validate against the raw supported list. IEDB / in-process predictors still raise as before. * output parser (parsing.py) uses the raw fallback instead of raising on an un-normalizable echoed allele, so requested and echoed forms match in _check_results. 14 of the 21 affected names now round-trip end-to-end against netMHCpan 4.2 (11 BoLA, H-2-Qa1/Qa2, HLA-A30:14L in both spellings). The other 7 (Mamu-B12/B17/B20/B22, BoLA-T2C, H2-Qa1, H2-Qa2) are listed by netMHCpan but rejected on -a by the binary itself, so they fail at predict time with "Missing predictions" — a documented netMHCpan inconsistency mhctools can't work around. Tests: binary-free unit tests for the fallback and keep_unparseable gate (tests/test_unparseable_alleles.py, added to the public CI subset) plus a netMHCpan integration test asserting the round-trip identity. Bump version to 3.19.0. Claude-Session: https://claude.ai/code/session_01LZahFhBSCiehXTESCYQ7wG
Simplify and harden the changes from the previous commit (no behavior
change):
* _check_hla_alleles: replace the try/except in the dedup loop with a
branch on keep_unparseable. This drops a redundant second parse of
unparseable names (normalize_allele_name_or_raw re-parsed after the
try already failed) and removes the now-unused AlleleParseError import.
keep_unparseable=True -> normalize_allele_name_or_raw (parse or raw
fallback); otherwise normalize_allele_name, which still raises as before.
* normalize_allele_name_or_raw: document that un-normalizable exotic
alleles are effectively case-sensitive (parseable names are uppercased
before normalization, but the raw fallback preserves case to match the
predictor's -listMHC / output spelling), so they must be requested with
the tool's own casing.
* Add a binary-free regression test that runs an exotic allele (H-2-Qa1)
through the netMHC output parser, which previously raised on names
mhcgnomes can't parse.
Full suite: 510 passed, 38 skipped, 2 xfailed (netMHCpan 4.2).
Claude-Session: https://claude.ai/code/session_01LZahFhBSCiehXTESCYQ7wG
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #220.
Problem
netMHCpan -listMHCreports alleles that mhcgnomes can't parse, so they couldn't be requested even though netMHCpan supports them:H-2-Qa1,BoLA-amani.1, …HLA-A30:14LRequesting one raised
AlleleParseErrorduring predictor construction. This is the tail left after #219 (which made ~2,456 non-human alleles usable by round-tripping netMHCpan's own spelling — those all normalize, just to a spelling netMHCpan rejects). The names here don't normalize at all, so they have no canonical identity to key on.Fix
Carry the predictor's own
-listMHCspelling as identity for these cases.normalize_allele_name_or_raw()(new, inallele_normalization.py): normalize via mhcgnomes when possible; otherwise fall back to a canonical raw form — strip surrounding whitespace and the*gene/allele separator. netMHCpan echoes a requestedHLA-A30:14Lback asHLA-A*30:14L, so stripping*collapses both spellings to one identity.BasePredictor.__init__gainskeep_unparseable_alleles(defaultFalse). Command-line predictors passTruebecause they validate against the tool's raw supported list; IEDB / in-process predictors keep raising as before.parsing.py) uses the raw fallback instead of raising on an un-normalizable echoed allele, so the requested and echoed forms match in_check_results.Coverage of the 21 affected names
14 now round-trip end-to-end against netMHCpan 4.2 — 11 BoLA,
H-2-Qa1,H-2-Qa2, andHLA-A30:14L(bothHLA-A30:14LandHLA-A*30:14L).7 remain unusable —
Mamu-B12/B17/B20/B22,BoLA-T2C,H2-Qa1,H2-Qa2. netMHCpan lists these but rejects them on-aitself ("cannot be found in allelenames list"), so they fail at predict time withMissing predictions. This is a netMHCpan inconsistency (noted in the issue's caveat) that mhctools can't work around.Tests
tests/test_unparseable_alleles.py— binary-free unit tests for the raw fallback (parse-vs-fallback, whitespace/*stripping, request/echo identity) and thekeep_unparseablegate (default raises; kept verbatim when enabled; star-variants dedupe). Added to the public CI subset so it runs on all Python versions.test_netmhc_pan_exotic_unnormalizable_alleles— netMHCpan integration test asserting the round-trip identity forH-2-Qa1,BoLA-amani.1, and both spellings ofHLA-A30:14L.Full suite: 509 passed, 38 skipped, 2 xfailed (with the real netMHCpan 4.2 binary). Bumps version to 3.19.0.
https://claude.ai/code/session_01LZahFhBSCiehXTESCYQ7wG