Skip to content

Examine the unexamined providers against MATLAB; port what differed (#11 item 2) - #16

Merged
stevevanhooser merged 2 commits into
mainfrom
claude/pensive-galileo-j24fio
Oct 21, 2026
Merged

stevevanhooser merged 2 commits into
mainfrom
claude/pensive-galileo-j24fio

Conversation

@stevevanhooser

@stevevanhooser stevevanhooser commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Addresses item 2 of #11. EMPTY is item 3, which merged separately as #14, and is untouched here.

Summary

I read every provider the bridge marked NOT EXAMINED against its MATLAB source, plus the parts of OM and NCBITaxon that were still unexamined, and ported what differed. The bridge now records each one as examined, with what changed.

Changes

Shared OLS path

This affects CL, CHEBI, PATO, EFO, SNOMED, Uberon, NCIT, STATO, MICRO, MCO, OBI, ZECO, WBls, and OM's fallback.

Each of these MATLAB classes sets only a prefix and an OLS ontology id, then defers to three helpers in ontology.m. Those helpers are now ported on OLSProvider under their MATLAB names: preprocessLookupInput, searchOLSAndPerformIRILookup and performIriLookup. A lookup is now MATLAB's two requests: an OLS search that must name exactly one term, then that term's own record, fetched by its IRI from OLS's term API.

Before (Python) Now (as MATLAB)
Took the first hit when several labels matched A non-unique match raises (NotUnique)
Read fields from the search result, so synonyms were always empty Reads the term record: obo_synonym names, the first non-empty description, and MATLAB's id rules
Swallowed every error into "not found" API errors raise, with the cause chained through lookup()
A numeric OM term searched OLS for the digits Rejected, as MATLAB's OM branch does

NCIT is the one OLS class that differs from the template. NCIT.m runs preprocessLookupInput, then always does an exact obo_id search for 'NCIT:' + search_query. #15 added an override for this, which called the old _search_ols. That call would have crashed after this PR, and git doesn't flag it, so the override is rebuilt on the ported helpers. Codes like C3262 resolve; names don't, as in MATLAB.

Other providers

  • NCIm:
    • a name with several matches raises instead of taking the first
    • the search uses include=minimal, as MATLAB does
    • the id is the CUI asked for
    • errors raise
  • PubChem:
    • a name matching several CIDs raises
    • synonyms are no longer cut to 10
    • a failed title request no longer fails the lookup, and the name falls back to the first synonym
    • errors raise
  • RRID:
    • errors raise
    • the RRID is URL-encoded, as MATLAB's urlencode does
    • synonyms given as a struct are kept
    • lookupSpecies, a public MATLAB method, is now ported
  • NCBITaxon:
    • errors raise
    • an empty search counts as "not found" only when NCBI says so; anything else raises

lookup()

Behaviour changes callers may notice

  • Errors raise where they used to look like "not found." lookup() already raised in both cases, but a transport failure now comes with its real cause attached.
  • Ambiguous names raise in OLS, NCIm and PubChem, instead of silently returning the first match.
  • PubChem:cid:962 now raises, as it does in MATLAB, which accepts only digits after cid. cid 962 and 962 still work. The same rule means neither language can look up a compound whose name starts with "cid", such as cidofovir; that's an upstream question.
  • OLS synonyms are now populated for every OLS-backed ontology.

Upstream MATLAB bug, mirrored rather than fixed on one side

NCBITaxon.m's esearch regex spans the whole <IdList>, so it only ever captures the first id, and its NameNotUnique branch can never fire. Python keeps "first id" for parity, and the bridge records it.

Tests

  • I rewrote the OLS tests against a small fake OLS that answers both the search and the term API. They cover:
    • which queries are sent
    • the IRI encoded twice
    • exact-match rules (one exact label among several hits, several exact labels raising, an id search needing exactly one hit)
    • id extraction from obo_id and short_form
    • errors raising
    • the OM branch
    • NCIT: a code, a name, and the prefixed and numeric forms
  • New tests for NCIm, PubChem, RRID and NCBITaxon cover not-found, ambiguous and error paths, plus lookupSpecies.
  • On the old code, 26 of the rewritten or new tests fail. After merging main, black, ruff and the offline suite pass: 195 passed, 3 skipped.
  • The live shared-case job passes on the merged head. That includes the new NCIT, EFO and SNOMED rows from ndi-ontology-matlab 36d7814, run through the ported two-request path. EBI, NCI EVS, PubChem and SciCrunch are all blocked from the sandbox this was written in, so CI is the live check. All 18 OM cases also pass locally against the real OM file.

Generated by Claude Code

#11 item 2)

Shared OLS path (CL, CHEBI, PATO, EFO, SNOMED, Uberon, NCIT, STATO,
MICRO, MCO, OBI, ZECO, WBls, and OM's fallback): port ontology.m's
preprocessLookupInput, searchOLSAndPerformIRILookup and performIriLookup
under their MATLAB names. A lookup is now MATLAB's two requests: a
search that must name exactly one term, then that term's own record by
IRI. Python took the first hit where MATLAB requires a unique one, read
its fields from the search result (so synonyms were always empty), and
swallowed every error into "not found".

NCIm, PubChem: a name matching several concepts/CIDs raises rather than
taking the first; errors raise; NCIm keeps the CUI asked for; PubChem
keeps all synonyms, tolerates a failed title request and, as MATLAB
does, rejects 'cid:962'. RRID: errors raise, the RRID is URL-encoded,
and lookupSpecies is ported. NCBITaxon: errors raise; an esearch with no
ids is "not found" only when NCBI says so.

lookup() trims the prefix and remainder, as getOntologyNameFromPrefix
does. The bridge records each provider as examined, with what changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017iFBFMQmEZaz21d9ZFJbiH
…ed helpers

main brought #14 (EMPTY), #15 (NCIT codes by obo_id), #17 (lookup
trimming, the same fix as this branch's) and #18 (known_gaps).

#15's NCITProvider.lookup_term called OLSProvider._search_ols, which this
branch replaces; git merged it cleanly, and every NCIT lookup would have
raised AttributeError. It now does what NCIT.m does on the ported
helpers: preprocessLookupInput, then searchOLSAndPerformIRILookup on
obo_id for ['NCIT:', search_query]. Its tests move to FakeOLS, plus one
for the prefixed and numeric forms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017iFBFMQmEZaz21d9ZFJbiH
@stevevanhooser
stevevanhooser merged commit 1538c5a into main Oct 21, 2026
6 checks passed
@stevevanhooser
stevevanhooser deleted the claude/pensive-galileo-j24fio branch October 21, 2026 17:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants