Histopathology finding_term binding: re-census (2026-08-18)
Re-measurement of the ontology-binding gap that motivated the open design
discussion #5140
("the boundary between phenotypes (HP) and histopathology (NCIT)"), tracked in
design-decisions.md §12.
The original triage
(histopathology_ncit_triage-2026-07-02.md)
reported 123 unbound findings across 76 files. That snapshot is six weeks
old and predates §9 (ImagingFinding) and §10 (electrophysiology), both of
which changed how the project reasons about finding-vs-phenotype boundaries.
This report re-derives the numbers and — more usefully — characterises what
kind of thing the unbound tail actually is, because the answer bears directly
on which of the issue's options A–D can work.
Regenerate every figure below with:
uv run python scripts/histopathology_binding_census.py
uv run python scripts/histopathology_binding_census.py --list-unbound # per-finding detail
Census
histopathology findings: 707 across 387 KB files
ontology-bound finding_term: 382 (54%)
unbound: 325 (46%) across 188 files
no finding_term block at all: 293
finding_term with preferred_term only: 32
bound-term vocabulary: NCIT 368, HP 14
Two things to note before reading further.
- The gap grew, and grew faster than coverage. 325 unbound against the triage's 123, across 188 files against 76. This is not regression — curation volume grew too — but binding is not keeping pace with new histopathology curation, so the decision in #5140 is not getting cheaper to defer.
- The
HP:0025461carve-out is nearly unused. 14 of 382 bound findings use it, against 368 NCIT. The narrow HP accommodation already inHistopathologyFindingTermis carrying almost no load.
The finding that reframes the options
The issue frames the gap as a vocabulary coverage problem: NCIT is sparse for
organ-specific microscopic findings, HP has the terms but is fenced off at
HP:0025461, so option B (broaden the HP root) is the coverage win. The data do
not support that framing for most of the tail.
distinct unbound labels: 324 for 325 unbound findings
post-composed labels: 190 of 325 unbound (58%) vs 77 of 382 bound (20%)
findings using an inherited post-composition slot
(located_in, modifier, laterality, spatial_extent, severity): 0 of 707
There is essentially no recurring vocabulary in the unbound tail — 324 distinct strings for 325 findings. A missing-terms problem produces repeats (the same "foot process effacement" showing up in a dozen renal entries); this does not. Spot-reading the tail shows why: the labels are rich post-compositions, not single concepts —
Interface injury with vacuolar change and necrotic keratinocytesIntratubular 2,8-DHA crystals with chronic tubulointerstitial injuryNeocortical GABAergic Interneuron Depletion and MislocalizationAtypical CD8-positive lymphomatoid infiltrate with lymphomatoid vasculitis (FUMHD)
— each bundling an entity, a quality, often a cell type, a site, and a severity or distribution modifier into one string. The unbound half is measurably different in kind from the bound half: 58% of unbound labels are compound against 20% of bound ones (median 5 words vs 3). Curators bind when the observation is one concept and fall back to prose when it is several. That is the correct instinct, and it is not a vocabulary gap.
The corollary is the actionable part: broadening the vocabulary addresses at most the ~135 single-concept unbound findings, not the ~190 post-composed ones. Even a perfect merged HP+NCIT morphology vocabulary would leave the majority of the tail unbindable, because no ontology pre-composes "2,8-DHA crystals with chronic tubulointerstitial injury".
The unused machinery
HistopathologyFindingDescriptor is_a: Descriptor, so it already inherits
located_in (UBERON), modifier, laterality, spatial_extent, and
severity — exactly the axes those compound labels are informally encoding in
prose. Not one of the 707 findings uses any of them. Every finding_term in
the KB is a bare {preferred_term, term?} pair.
This looks like a documentation gap rather than a modeling one. Compare the two
sibling classes in src/dismech/schema/dismech.yaml:
ImagingFindingDescriptor— its description explicitly says "Inherits located_in (UBERON body site), laterality, spatial_extent, and modifier from Descriptor for post-composition", and its comments tell curators where body site and distribution go.HistopathologyFindingDescriptor— says only which branchestermmay bind to. Post-composition is never mentioned, in the class, inCLAUDE.md, or in any worked example.
So curators had no signal that the compound case had a structured home, and prose was the only available answer.
What this suggests for #5140's options
Offered as input to the maintainer decision, not as a decision:
- Option B (broaden the HP root) is worth doing but is not the coverage win it looks like — it is scoped to roughly the 135 single-concept findings. Whatever root is chosen, the "NCIT vs HP" selection rule the issue asks for in question 1 still has to be written, because the two vocabularies do overlap in that single-concept space.
- A fifth option belongs on the table: head term + post-composition. Bind
the head concept (which NCIT usually does have — infiltrate, crystal
deposition, demyelination, keratinocyte necrosis) and carry site, cell type,
distribution, and severity in the inherited
Descriptorslots, instead of hunting for a pre-composed code that does not exist. This needs no schema change — only a documented convention, a worked example, and theImagingFindingDescriptor-style note on the class. It is also the option most consistent with §10's stated test, which turns on whether a term exists, not on whether a sentence does. - Question 4 (entity-level "findings" →
disease_term/subtype) remains independent of the vocabulary question and can be settled separately, as the earlier triage comment noted.
Caveats
- "Compound" is a syntactic heuristic (clause joiners, commas, slashes, or more
than four words), not a semantic judgement; it is stated in
scripts/histopathology_binding_census.pyand can be tuned there. It will misfile a genuinely single-concept term with a long name, and will miss a two-concept label written tersely. The 58%-vs-20% contrast between the unbound and bound halves is the robust signal, not the exact percentage. - The census counts binding, not binding quality. A finding bound to an over-broad NCIT term counts as bound here. Assessing whether the 382 bound terms are specific enough is separate work.
- No claim is made that any specific unbound finding has an available HP or NCIT term — testing that requires per-term ontology lookup and was out of scope for an offline census.