Skip to content

Ontology: add Uberon, NCIT, EDAM, IAO, STATO and SchemaOrg providers #98

Closed

Description

@stevevanhooser

Part of #90 (PR #61 catch-up). Small, self-contained, no dependencies on the other items.

Current state

src/ndi/ontology/providers.py on main implements 14 providers: OLSProvider and its subclasses CL, OM, CHEBI, SNOMED, EFO, PATO, plus standalone NDIC, NCIm, NCBITaxon, WBStrain, RRID, PubChem, EMPTY.

Missing: Uberon, NCIT, EDAM, IAO, STATO, SchemaOrg. grep -rn "UBERON\|STATO" src/ndi/ontology/ returns nothing.

What it would take

Most of these are OLS-backed, so they are OLSProvider subclasses in the same shape as the existing CL/PATO/EFO entries — a few lines each. The work is:

  1. Add the provider classes to src/ndi/ontology/providers.py.
  2. Extend src/ndi/ndi_common/ontology/ontology_list.json with the corresponding registry entries.
  3. Tests per provider — lookup by id, lookup by name, and the not-found path.

Reference: PR #61 commit 31cf026 (59 lines in providers.py, 82 in ontology_list.json, 74 of test).

Two related items from the same line

  • Alphanumeric OLS ids + synonyms. PR NDI-python 2026-08 catch-up — hardening bundle + MATLAB parity + CI safety #61 commit d6bb534 fixed OLS id resolution for alphanumeric ids and made providers return synonyms. Worth checking whether main's OLSProvider handles both before adding six more subclasses on top of it.
  • Single-source the prefix map. Commit 11d1d0b derived the prefix map from ontology_list.json rather than maintaining a second copy in code. Doing that first makes step 2 above the only place a new ontology needs registering, which is the point.

Suggested order: prefix-map single-sourcing → OLS id/synonym fix → the six new providers.

Activity

  1. stevevanhooser commented on Sep 3, 2026

    @stevevanhooser
    ContributorAuthor

    Done, and closing. The work landed in ndi-ontology-python rather than here, so GitHub never linked it — closing keywords don't cross repositories.

    Where it went

    The ontology namespace was split out into Waltham-Data-Science/ndi-ontology-python, the companion to ndi-ontology-matlab (which is the source of truth — NDI-matlab has no +ndi/ontology.m). NDI-python re-exports it at src/ndi/ontology.py, so every call site here still reads from ndi.ontology import lookup and nothing downstream changed shape.

    The distribution is top-level ndi_ontology rather than ndi.ontology, because a second distribution cannot add a subpackage to a regular package — MATLAB merges the ndi namespace across path entries for free and Python does not. That divergence is recorded in the bridge contract's decision_log.

    The three items, in the order this issue suggested

    1. Single-source the prefix map — the 14-entry literal _PREFIX_MAP is gone; _load_prefix_map() reads ontology_list.json alone (22 prefixes) and raises on an empty registry. Registering an ontology is now one edit, which was the point.

    2. Alphanumeric OLS ids + synonyms — worth checking, as you suspected, and it was broken. OLSProvider was calling term.zfill(7), so CHEBI:15377 went out as CHEBI:0015377 and every CHEBI lookup-by-id returned empty. MATLAB's preprocessLookupInput (ontology.m:395) pads nothing. The id is now sent verbatim, which is also what makes alphanumeric ids work — OM:Temperature and OM:Acidity resolve live. Synonyms are carried through: OntologyResult.__slots__ is ("id", "name", "prefix", "definition", "synonyms", "short_name"), matching MATLAB's declaration order at ontology.m:125, and unpacking derives from __slots__ so the order cannot drift.

    3. The six providers — Uberon, NCIT, EDAM, IAO, STATO, SchemaOrg. Only three turned out to be OLS-backed; EDAM and IAO download and parse OWL, and SchemaOrg walks a JSON-LD @graph. PROVIDER_REGISTRY now has 19.

    Verification

    Rather than per-provider unit tests, parity is checked against ndi-ontology-matlab's own fixture — ontology_lookup_tests.json, 66 cases across 15 ontologies, each naming the exact expected_id and expected_name. The file is read directly, never vendored, so it cannot drift the way ontology_list.json had (17 registered prefixes against 22). CI checks out ndi-ontology-matlab and points NDI_ONTOLOGY_MATLAB_DIR at it.

    Latest run on main: 84 passed in 95.54s, zero skipped — including the new providers live (EDAM:1929, format:FASTA, IAO:document, schema:Person, STATO:p-value, UBERON:heart) and every should_succeed: false case.

    The fixture earned its keep. It caught six port defects, four of which had been invisible because an empty result was indistinguishable from a real answer:

    NDIC / NCIm / PubChem returned prefixed ids where MATLAB returns bare
    CHEBI the zfill above
    EMPTY a 404'd data source, whose three failure cases were passing vacuously
    the lookup cache a transient failure cached as though it were a fact

    lookup() now raises NDIOntologyLookupError instead of returning an empty result, matching MATLAB, which errors on every failure and whose own test asserts verifyError(funcToTest, ?MException). Every call site here already sat inside except Exception, and this repo's suite was unchanged across that switch.

    One thing this issue asked for that is shipped but unverified

    NCIT has no test case. It is implemented and registered, but ontology_lookup_tests.json has no NCIT entry, so it has never been checked against a real lookup in either language. The same is true of SNOMED, EFO and WBStrain, which predate this work. Filed upstream as Waltham-Data-Science/ndi-ontology-matlab#8; until cases exist there, test_case_table_covers_every_ported_provider carries them in a known_gaps set so the omission stays visible rather than silent.

    Everything else this issue named is covered by live parity cases that pass.

    Merged in ndi-ontology-python: #3 (providers + prefix registry), #4 (lookup() raises), #5 (live-test gate).


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions