feat(associations): LOINC clinical-measurement sections (#1349) - #1356
feat(associations): LOINC clinical-measurement sections (#1349)#1356kevinschaper wants to merge 7 commits into
Conversation
Add six AssociationTypeMapping entries for the LOINC clinical-measurement
sections, built on the flexible section-matching enabler. All LOINC edges carry
the generic biolink:Association category, so each section is distinguished by
predicate + object category:
- clinical_measurement_correlated_phenotypes (correlated_with -> PhenotypicFeature)
- clinical_measurement_related_{chemicals,anatomy,organisms,proteins,cells}
(related_to -> ChemicalEntity / AnatomicalEntity / OrganismTaxon / Protein / Cell)
Each mapping also drives the reverse "Related/Correlated Clinical Measurements"
section on the counterpart pages via its object_label. Composite fragments were
verified against api-beta (e.g. correlated phenotypes = 10946, matching the edge
report). Counts-query fixtures regenerated; added a parser test proving a section
surfaces with its key and label.
Sections render via the enabler without needing biolink enum changes;
biolink:ClinicalMeasurement entity-type styling + the hierarchy widget are
separate follow-ons.
Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
Review: LOINC clinical-measurement sectionsReviewed the diff ( OverviewAdds 6 Correctness
Minor observations (non-blocking)
PerformanceEach mapping added multiplies out across all 6 count-suffix variants in SecurityNo concerns — config/data-only change, no new user input handling. Process notePR is correctly marked draft and stacked on #1355; just flagging that it shouldn't merge until the base is merged and the target is switched to Overall: well-scoped, mechanically verified (counts checked against api-beta), and leans on solid enabler infrastructure. The two minor observations above are worth a look but don't block. |
Add biolink:ClinicalMeasurement to the table-of-contents hierarchy allowlist (and a heading label) so LOINC clinical-measurement pages render their node_hierarchy (already returned by the backend) like other ontology terms. Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
…ection Remove the clinical_measurement_related_organisms mapping. Those omop2obo related_to -> OrganismTaxon edges only connect to a human-taxon node, which is not a useful relationship to surface (and is slated for removal from the ingest). Drops both the forward "Related Organisms" section and the reverse section on the organism page. Fixtures regenerated. Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
Review: LOINC clinical-measurement association sectionsOverviewAdds five Code quality / style
Potential issue: ambiguous
|
Add a knowledgeLevel.ts meta util (mirroring agentType.ts) mapping each biolink KnowledgeLevelEnum value to an icon/label/description, and render a knowledge-level icon next to the agent-type icon in the associations table actions cell. Gives an at-a-glance curated-vs-predicted signal per row (e.g. LOINC omop2obo related_to edges read as "Prediction" vs loinc2hpo's "Knowledge Assertion"). Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
ReviewReviewed the diff for PR #1356 ( OverviewAdds 5 Code quality
PR description is out of sync with the diff
Potential correctness question (not blocking, but worth double-checking)
Test coverage
Frontend
SecurityNo concerns — no user input reaches the new Solr filters (mappings are static config), and no new external data handling was introduced. Overall this is a clean, well-scoped, low-risk change that closely follows existing conventions. Main actionable item is syncing the PR description with the actual diff (dropped |
Give biolink:ClinicalMeasurement a first-class type identity: a test-tube glyph (category-clinical-measurement.svg) and a teal color in the category color map, instead of the gray "CM" initials fallback. Applies on LOINC node pages and in association-table node badges. Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
ReviewNicely scoped addition to the association-type-mapping system, and good to see fixture regeneration plus a parser test exercising the "shared 🐛 Missing mapping:
|
| key | predicate | object_category | beta count |
|---|---|---|---|
| clinical_measurement_related_organisms | related_to | OrganismTaxon | 2,591 |
...but association_type_mappings.yaml only adds five entries (phenotypes, chemicals, anatomy, proteins, cells) — there's no OrganismTaxon entry anywhere in the diff. Confirmed by grepping the regenerated association_counts_query.py fixture too: it has facet queries for PhenotypicFeature, ChemicalEntity, AnatomicalEntity, Protein, and Cell, but nothing for OrganismTaxon. Looks like the sixth mapping was dropped somewhere between drafting the description and writing the YAML — worth adding before this comes out of draft, since the "Related Organisms" section (and its reverse on OrganismTaxon pages) currently won't appear at all despite being verified against api-beta.
📝 PR description vs. diff mismatch
Two items listed under "Not in this PR (separate follow-ons)" actually are wired up in this diff:
- Per-row knowledge-level icons —
frontend/src/util/knowledgeLevel.ts(new) plus its integration intoAssociationsTable.vue's row-icon column is fully implemented and unit-tested (frontend/unit/knowledgeLevel.test.ts). This looks like solid, general-purpose work (not LOINC-specific), but it contradicts the description's claim that it's deferred. - LOINC hierarchy widget —
TheTableOfContents.vueadds"biolink:ClinicalMeasurement"to itsCATEGORIESarray, which directly flips onshowHierarchyand rendersSectionHierarchy.vuefor clinical-measurement nodes;SectionHierarchy.vue'sLABELSmap is updated to match ("Clinical measurement"). The description says this widget is explicitly out of scope.
Neither of these looks broken, but the description should be updated (or the changes should be split out) so reviewers know the actual scope. Worth double-checking that node_hierarchy.super_classes/sub_classes are actually populated for LOINC nodes in api-beta — if not, the hierarchy widget will just render an empty parents/children panel for clinical-measurement pages, which is harmless but untested per the PR notes.
Nice touches
colors.teal.darkand the newcategory-clinical-measurement.svgare wired through the existinggetCategoryIcon/getCategoryColorconvention (category-+ kebab-case category name) correctly, so the new icon/color will resolve at runtime.- Reusing the same mapping
keyto drive both the forward (clinical-measurement page) and reverse (phenotype/chemical/etc. page) sections is a clean way to avoid duplicating config, and the direction is safely disambiguated sincesubject_category(ClinicalMeasurement) and the variousobject_categoryvalues are disjoint — no risk of the two directions colliding for a single node. symmetriccorrectly defaults tofalsehere, which is right since subject (ClinicalMeasurement) and object (Phenotype/Chemical/etc.) categories aren't interchangeable, even thoughcorrelated_with/related_toare symmetric predicates at the biolink-model level.
Test coverage
Only clinical_measurement_correlated_phenotypes gets a dedicated parser test; the other four (and the still-missing organism one) rely on the same code path so risk is low, but a quick parametrized test over all six keys would make regressions in the YAML (like the missing entry above) much easier to catch automatically rather than by manual diff review.
Overall: solid mechanism, just needs the missing organism mapping added and the PR description reconciled with what's actually in the diff before merging.
Register monarch-initiative/loinc-ingest so `make fetch-docs` generates the /Sources/loinc/ page. The association "Provided By" link for LOINC edges (get_provided_by_link -> .../Sources/loinc/) currently 404s because there was no manifest entry. Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
ReviewReviewed the diff (this PR is stacked on #1355 and marked as draft, so noting a couple of things that will matter before it is marked ready). Bug: missing "Related Organisms" mapping The table in the PR description lists six mappings, including But Description vs. diff mismatch The "Not in this PR" section says the But the diff actually includes both: Neither of these looks broken — all the icon names used (circle-check, sitemap, chart-bar, equals, eye, circle-question) are already registered in Everything else looks solid
Minor/nit The YAML comment above the new mappings says these edges all carry the generic No security or performance concerns — this is config/data plus additive, low-risk frontend rendering code. |
getKnowledgeLevelMeta covers all callers (the association-row indicator); the label-only formatKnowledgeLevel had no app usage. Remove it and its test. Claude-Session: https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL
|
Note for reviewers: this PR also introduces the knowledge-level indicator (icon column on every association row, |
ReviewNice, focused PR — the mapping composite-filter approach for disambiguating LOINC's generic 🐛 Likely bug: "Related Organisms" section is missingThe PR description's table lists six mappings, including:
But 📝 PR description drifted from the diffThe "Not in this PR (separate follow-ons)" section says per-row knowledge-level icons and
Neither addition looks wrong, but they read as unrelated scope creep relative to the stated LOINC-config-only intent. Might be worth splitting into separate PRs, or just updating the description so reviewers (and the eventual changelog) aren't misled.
|
Draft — stacked on #1355 (flexible section-matching enabler); base is that branch, so this diff is just the LOINC config. Retarget to
mainonce #1355 merges.What
Six
AssociationTypeMappingentries for the LOINC clinical-measurement sections. Every LOINC edge carries the genericbiolink:Associationcategory, so each section is distinguished by predicate + object category (via the enabler):All share
category: [biolink:Association],subject_category: [biolink:ClinicalMeasurement].object_labeland thesubject_category: ClinicalMeasurementfilter that scopes the generic bucket.No biolink enum changes needed — the composite filters use raw Solr clauses.
Verification
clinical_measurement_correlated_phenotypessurfaces with its key + "Correlated Phenotypes" label. Counts-query fixtures regenerated; suite green (135).Not in this PR (separate follow-ons)
biolink:ClinicalMeasuremententity-type support (regencategory_enums.py+ frontend color/icon) — sections work without it; only the node badge styling is default.related_tolinks areprediction-level).https://claude.ai/code/session_018c9UddtKsKtm35YNrxHWuL