Repository navigation
Incorrect HPO identifier for Macroscopic hematuria in the rare disease examples #458
Description
Problem
The Bethlem myopathy and rare-disease examples use HP:0011463 where the
phenotype is macroscopic hematuria:
HP:0011463— Childhood onsetHP:0012587— Macroscopic hematuria
Same shape as #451: a syntactically valid identifier for an unrelated concept,
so nothing in schema validation catches it.
curl -s "https://www.ebi.ac.uk/ols4/api/ontologies/hp/terms?obo_id=HP:0011463" \
| jq -r '._embedded.terms[0].label' # => Childhood onset
curl -s "https://www.ebi.ac.uk/ols4/api/ontologies/hp/terms?obo_id=HP:0012587" \
| jq -r '._embedded.terms[0].label' # => Macroscopic hematuriaNeither term carries the other's label in any synonym field.
The identifier is wrong, not the label
HP:0011463 is also used correctly in these same files, which is what makes
precision necessary here. In v2/BethlemMyopathyExample.java, five lines apart (abridged):
PhenotypicFeature motorDelay = PhenotypicFeature.newBuilder()
.setType(ontologyClass("HP:0001270", "Motor delay"))
.setOnset(TimeElement.newBuilder().setOntologyClass(
ontologyClass("HP:0011463", "Childhood onset"))) // correct
.setSeverity(mild).build();
PhenotypicFeature hematuria = PhenotypicFeature.newBuilder()
.setType(ontologyClass("HP:0011463", "Macroscopic hematuria")) // the defect
.setOnset(TimeElement.newBuilder().setAge(
Age.newBuilder().setIso8601Duration("P14Y")))
.addModifiers(ontologyClass("HP:0031796", "Recurrent"))
.addEvidence(citation).build();Four signals agree the label is right and the identifier wrong:
- the variable is named
hematuria; - the same file uses
HP:0011463correctly as an onset class five lines above; - the defective site is a
setTypecarrying its ownsetOnsetofP14Yand a
"Recurrent" modifier — and HPO definesHP:0011463as onset between 1 and 5
years, so a feature whose type is "Childhood onset" and whose onset is
age 14 is incoherent; - the example's citation is Bao M, et al., "COL6A1 mutation leading to Bethlem
myopathy with recurrent hematuria: a case report."
Scope — which occurrences change, and which must not
HP:0011463 appears 37 times across 19 files — 25 in text files and 12 in
the six binary fixtures (each .pb contains two: one defective, one correct). 16 are the defect; 21 are correct and must stay.
| Usage | Count | Action |
|---|---|---|
| paired with "Macroscopic hematuria" | 16 | → HP:0012587 |
| paired with "Childhood onset" in onset fields | 21 | leave unchanged |
The defective sites span v1/v2 BethlemMyopathyExample.java,
docs/rd-example.rst, docs/rd-example-java.rst, six
python/data/v{1,2}/*.json fixtures and the six matching .pb files.
The JSON and .pb fixtures are coupled, and must change together
python/tests/test_io.py asserts phenopacket_pb == phenopacket_json (and the
same for family and cohort, v1 and v2). The .pb files carry the defect too, so
editing the JSON without the binaries fails that test.
As far as we can see this build does not regenerate them: the protobuf plugin's
only Python output directory is python/src, and neither workflow rebuilds
python/data. But python/data/v1/README.md records that the content
corresponds to TestData.V1.comprehensive*() in phenopacket-tools as of October
2022, so there may be a regeneration path we cannot see from here.
Would you prefer we edit the fixtures directly, or regenerate them from
phenopacket-tools? Both identifiers are ten bytes, so a direct edit needs no
re-serialization — but that is your call, not ours.
Interaction with open PR #421
PR #421 (Add an example for creating a phenopacket in Python) adds four more
HP:0011463 occurrences in docs/rd-example-python.rst and
python/tests/test_rd_example.py, of which two are the defective pairing.
Worth catching there before it lands, and worth sequencing so a fix and that PR
do not collide.
Offer
Happy to open a PR correcting the 16 defective occurrences — text and binary
fixtures together so test_io.py stays green — and leaving the 21 correct ones
untouched, in the same shape as the #451 fix (#457). Just say how you would like it
sequenced against #421.
How this was found
While preparing the fix for #451 (now #457) we built the identifier/label validator suggested
there: it pairs each CURIE with its adjacent label, resolves the CURIE, and
reports mismatches. It rediscovered #451 at six sites — two beyond the four that
issue lists — and surfaced this as a second instance of the same class. Glad to
contribute it if useful; it needs only bash, python3 and network access to
OLS4.
🤖 Generated with Claude Code
Activity