Repository navigation
Batch/lexical matching, OAK, SSSOM, gaps, ROBOT QC (part 4/9) - #18
Open
s28ale-maker wants to merge 7 commits into
Open
s28ale-maker wants to merge 7 commits into
s28ale-maker wants to merge 7 commits into
Conversation
…idate mappings (issue #6) - soulcap-match --batch scores every SOULCAP cell type against all CL terms in one pass; --lexical adds an independent OLS4 name-search candidate and writes a marker/lexical agreement report. - Fix scoring: required-marker conflicts now disqualify a candidate instead of just subtracting points, so shared exclusion markers can no longer outrank a term that outright contradicts a required marker. - Fix scoring: CL's "high"/"low" expression-level axioms are no longer treated as equivalent to "negative" (absent). - Add extract_marker_clauses(): SOULCAP's `(A+|B+|C-)` OR-groups were being flattened into independently-required markers instead of "at least one must hold" — this silently suppressed good matches (e.g. CL:0000043 mature basophil never scored for SOULCAP's Basophil profile). Clauses are now evaluated with proper OR semantics. - Fix OLS4 lexical search: exact label matches were buried by OLS4's default relevance ranking; now promoted to rank 1 when present in a wider pool. - Extend marker_map.py's PRO lookups (cytokines, MR1, TCR V-gene segments) via UniProt-accession-based PRO term fetch, closing most of the marker->gene mapping gaps tracked in issue #1. - Add reports/candidate_cl_mappings.md (Milestone 4 draft mappings with rationale/evidence) and log a new CL gap (missing human-specific "group 1 innate lymphoid cell" term, filed as issue #14). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- soulcap-oak-match: lexical/synonym CL search via OAK's sqlite:obo:cl adapter, an independent second opinion to soulcap-match --lexical (OLS4). Verified live: ranks exact label/synonym matches cleanly where OLS4's relevance ranking buries them behind subtype noise. - soulcap-sssom: exports the curated Milestone 4 mapping decisions as SSSOM TSV instead of writing OWL axioms directly. confidence/comment are derived automatically from whether CL directly asserts the matched marker axiom(s), only has them by inference, or has none at all — not hand-typed. - write_robot_template(): converts SSSOM rows into true logical OWL axioms (equivalentClass/subClassOf) for reasoner QC, since SSSOM's own OWL writer only emits skos:exactMatch as a non-logical annotation a reasoner ignores. - reports/gaps.tsv + .github/ISSUE_TEMPLATE/mapping_gap.yml (gap label): tracks cases with no reasonable CL match, CL/marker conflicts, CL axiom gaps, and sheet data issues, separate from the mapping table. - .github/workflows/robot-qc.yml: runs on every PR. One job audits upstream CL (cl-base.owl) standalone with robot report + robot reason (ELK); a second merges our SSSOM-derived mapping axioms into CL and re-checks, to catch problems our own proposed mappings would introduce. - New skill: soulcap-cl-matching, encoding the cross-check workflow (never trust either method's rank-1 blindly, verify via direct OLS4 lookup when uncertain). - Fix a pre-existing mypy gap in cl_match.py (_lexical_query_for_row typing). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…pings - 7 new mappings via the soulcap-cl-matching skill workflow, verified via OAK (soulcap-oak-match) after OLS4 REST search started timing out mid-run. - Eosinophil -> CL:0000771 is a strong marker-confirmed match (CD193/CCR3 directly asserted, not inferred, matching SOULCAP's defining marker). - Monocyte subset terms (CL:0000860/0000875/0002393) are lexical-only matches; CL's own markers for them are already known-incomplete per repo issue #12, cited rather than re-flagged. - Logged 4 new gaps.tsv entries: axiom gaps on the two more parent classes (Mono, B cell), and a malformed bracket shared across all four Monocyte rows' Required exclusion column (sheet data issue, not fixable here). - Extended the SSSOM curated table with the same 7 entries. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…y/naive tree) - Covers 57 of 83 remaining T cell rows via the soulcap-cl-matching skill. Marker-axiom scoring was uniformly useless across this entire branch (top candidates were consistently unrelated myeloid/NK terms); every mapping is lexical, OAK-verified directly rather than trusted from the raw batch output, which was wrong or missing for a large fraction of this branch too. - CD56+ T cell family (13 rows) ties back to repo issue #13: all Broad-match to CL:4052055, the term already flagged there for a pending rename to "CD56-positive T cell, human". - iNKT -> CL:0000814, the other term from issue #13 (pending rename to "iNKT cell"). - Several real CL gaps found and grouped in gaps.tsv: CL's CD4/CD8 vocabulary is alpha-beta-centric (no combined ab+gd, double-positive, or peripheral double-negative terms); no gamma-delta-specific or generic (non-CD4/CD8) differentiation-state terms; a likely CD8+-specific TEMRA term gap. - 26 rows have NO Full Name in the sheet at all (Conv TCRab family, Th1/2/9/17-like, Tfh, Vg9/Vd1/Vd2/Vd3, etc.) -- not mapped, since inventing a name isn't this report's call. Also found what looks like a genuine sheet data bug: Th1-like/Th2-like/Th9-like/Th17-like each appear TWICE, one copy with markers that look copy-pasted from an unrelated iNKT row. - SSSOM curated table extended with the 30 distinct (non-redundant) T cell mappings -> 80 total mappings. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…hon 3.11) and register SOULCAP: prefix in robot template David's agentic review caught a real bug I'd missed: my local dev environment runs Python 3.13, where uv.lock resolves eutils==0.6.1 (uses importlib.metadata). CI's test matrix includes Python 3.11, where uv.lock resolves the older eutils==0.6.0, which still does `import pkg_resources` at module load -- and setuptools>=81 removed pkg_resources entirely, so any import of oaklib (hence soulcap-oak-match) aborted pytest collection outright on 3.11, running 0 tests. Reproduced locally by installing Python 3.11 via uv and running the real test suite against it (matching CI's exact failure). Fixed by pinning setuptools<81 as a main dependency (not dev-only -- this also breaks the real soulcap-oak-match CLI on 3.11, not just tests) and confirmed the fix resolves cleanly under both 3.11 and the default 3.13 environment. Also found and fixed a second real CI failure while investigating (ROBOT ontology QC workflow, from actual run logs): `robot template` didn't know the SOULCAP: prefix used by write_robot_template()'s output, causing "UNKNOWN ENTITY ERROR could not interpret 'SOULCAP:NK'". Added --prefix "SOULCAP: https://soulcap.org/cell_type/" to register it, matching the CURIE_MAP already used in sssom_export.py. Could not fully dry-run the ROBOT fix locally (no Java available in this environment, and installing one hit a UAC prompt that can't be answered non-interactively) -- the setuptools/eutils fix is fully verified against a reproduced failure; the ROBOT prefix fix is a standard, well-documented fix applied directly against the real CI error, but not further dry-run. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The --prefix fix from the last commit got the merge step passing; robot report on the merged ontology then surfaced two more real, verified issues (pulled the actual merged-report.tsv artifact from the failed run rather than guessing): - ERROR duplicate_label: SOULCAP:Basophil_(PBMC) and SOULCAP:Basophil_(WB) both got the literal rdfs:label "Basophil", since build_robot_template_rows used subject_label (SOULCAP's own Full Name column, not guaranteed unique -- both preps share the same Full Name) instead of something derived from subject_id (always unique, by construction). Fixed by deriving the ROBOT template LABEL from subject_id instead. Added a regression test against the real CURATED_MAPPINGS table, not just a synthetic example. - 3x ERROR missing_ontology_title/description/license: the merged.owl ontology declaration had no dc: metadata annotations. Added a chained `robot template ... annotate ...` step setting minimal title/description/ license on the merged QC artifact. Still can't fully dry-run locally (no Java in this environment) -- pushing to let the real CI run verify, same as the last fix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… over them David flagged this as overstepping scope during review — proposing mappings for human review is this repo's job, but unilaterally asserting them as true OWL axioms and merging them into CL (even as an ephemeral CI artifact) is not. Keep only the read-only upstream-CL audit job; drop the ROBOT-template/OWL-axiom code path from sssom_export.py since nothing calls it anymore. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.
Summary
Commits
7862cc8..6005bbc(Milestone 4 / issue #6):soulcap-match --batch [--lexical]).soulcap-oak-match), SSSOM export (soulcap-sssom), and gap tracking (reports/gaps.tsvplus amapping_gapissue template).SOULCAP:prefix registration, and the remaining ROBOT failures. They're grouped so this PR never shows a red ROBOT check.Test plan
Checked in isolation with the same steps as CI (
uv sync --frozen --extra dev):uv run pytest: 396 passed, 95.0% coverageuv run ruff check .,ruff format --check ., anduv run mypy src/soulcap_cl_mappingpass🤖 Generated with Claude Code