diff --git a/cockpit/public/fma.soa b/cockpit/public/fma.soa
index 45b0be0ee..6269c5b27 100644
Binary files a/cockpit/public/fma.soa and b/cockpit/public/fma.soa differ
diff --git a/cockpit/src/FmaGraph.tsx b/cockpit/src/FmaGraph.tsx
index bf29f1f31..22a4ce03a 100644
--- a/cockpit/src/FmaGraph.tsx
+++ b/cockpit/src/FmaGraph.tsx
@@ -3,7 +3,8 @@
// same vis-network renderer, and on click shows a node resolving to BOTH:
// · its part-of position (basin-local: organ → chamber → wall → structure)
// · its leaf-limited global TYPE (the 0xFFFF ceiling pole — cross-cutting,
-// the same "Cardiac muscle tissue" shared by every chamber).
+// e.g. one "Subdivision of cavity of cardiac chamber" or "Endothelium of
+// endocardium" shared by structures in different parts of the heart).
//
// This is the `Cascade` (ontology / part-of) reading of OGAR PR #116's HhtlMode
// FMA tier model: each node is a stack of 8:8 [container:identity] tiers —
diff --git a/crates/osint-bake/data/fma-heart.fixture.ttl b/crates/osint-bake/data/fma-heart.fixture.ttl
deleted file mode 100644
index f2814b3fc..000000000
--- a/crates/osint-bake/data/fma-heart.fixture.ttl
+++ /dev/null
@@ -1,53 +0,0 @@
-# fma-heart.fixture.ttl — FIXTURE, NOT the real FMA.
-#
-# A faithful but hand-authored heart subtree in the canonical FMA predicate
-# set. The real Foundational Model of Anatomy (266 MB fma.owl, ~1.5M triples,
-# OGIT contextId 13, dcterms:source AdaWorldAPI/MedCare-rs bioportal-ontologies)
-# hydrates through lance-graph-rdf / lance_graph_ontology::hydrate_fma at the
-# spine; this light q2 bake mirrors that shape on a subtree so /fma renders
-# without the lance/datafusion closure that bake deliberately excludes.
-#
-# Line-oriented Turtle subset: one `subject predicate object .` per line.
-# Predicates mirror the canonical hydrator set (pr-d-1-fma-owl-hydrator):
-# bfo:part_of → partonomy (drives the HHTL cascade tiers)
-# rdfs:subClassOf → cross-cutting tissue type (the is-a ceiling)
-
-@prefix fma: .
-@prefix bfo: .
-@prefix rdfs: .
-
-# ── chambers regional-part-of the heart ──
-fma:Left_atrium bfo:part_of fma:Heart .
-fma:Right_atrium bfo:part_of fma:Heart .
-fma:Left_ventricle bfo:part_of fma:Heart .
-fma:Right_ventricle bfo:part_of fma:Heart .
-
-# ── each chamber's wall layers, each a subClassOf its tissue type ──
-fma:Myocardium_of_left_atrium bfo:part_of fma:Left_atrium .
-fma:Myocardium_of_left_atrium rdfs:subClassOf fma:Cardiac_muscle_tissue .
-fma:Endocardium_of_left_atrium bfo:part_of fma:Left_atrium .
-fma:Endocardium_of_left_atrium rdfs:subClassOf fma:Endothelium .
-fma:Epicardium_of_left_atrium bfo:part_of fma:Left_atrium .
-fma:Epicardium_of_left_atrium rdfs:subClassOf fma:Mesothelium .
-
-fma:Myocardium_of_right_atrium bfo:part_of fma:Right_atrium .
-fma:Myocardium_of_right_atrium rdfs:subClassOf fma:Cardiac_muscle_tissue .
-fma:Endocardium_of_right_atrium bfo:part_of fma:Right_atrium .
-fma:Endocardium_of_right_atrium rdfs:subClassOf fma:Endothelium .
-fma:Epicardium_of_right_atrium bfo:part_of fma:Right_atrium .
-fma:Epicardium_of_right_atrium rdfs:subClassOf fma:Mesothelium .
-
-fma:Myocardium_of_left_ventricle bfo:part_of fma:Left_ventricle .
-fma:Myocardium_of_left_ventricle rdfs:subClassOf fma:Cardiac_muscle_tissue .
-fma:Endocardium_of_left_ventricle bfo:part_of fma:Left_ventricle .
-fma:Endocardium_of_left_ventricle rdfs:subClassOf fma:Endothelium .
-fma:Epicardium_of_left_ventricle bfo:part_of fma:Left_ventricle .
-fma:Epicardium_of_left_ventricle rdfs:subClassOf fma:Mesothelium .
-
-fma:Myocardium_of_right_ventricle bfo:part_of fma:Right_ventricle .
-fma:Myocardium_of_right_ventricle rdfs:subClassOf fma:Cardiac_muscle_tissue .
-fma:Endocardium_of_right_ventricle bfo:part_of fma:Right_ventricle .
-fma:Endocardium_of_right_ventricle rdfs:subClassOf fma:Endothelium .
-fma:Epicardium_of_right_ventricle bfo:part_of fma:Right_ventricle .
-fma:Epicardium_of_right_ventricle rdfs:subClassOf fma:Mesothelium .
-
diff --git a/crates/osint-bake/data/fma-heart.ttl b/crates/osint-bake/data/fma-heart.ttl
new file mode 100644
index 000000000..21493a115
--- /dev/null
+++ b/crates/osint-bake/data/fma-heart.ttl
@@ -0,0 +1,166 @@
+# fma-heart.ttl — REAL FMA heart subtree, extracted from fma.owl (FMA v5.0.0).
+# Source: BioPortal #29 / UW Structural Informatics Group, CC BY 3.0,
+# SHA-256 59465eb503c418dbf9216d362b94c7f42bc3b96b297e553ec17c7fee77979e44,
+# mirror github.com/AdaWorldAPI/q2/releases/download/fma-ontology-5.0.0/fma.owl
+# Generated by tools/extract_fma_heart.py (streaming ET; regional_part +
+# constitutional_part partonomy, BFS from FMA:Heart fma7088, depth<=4, <=80 nodes).
+# The 266 MB OWL is NOT committed; the production hydrator is the spine's
+# lance_graph_ontology::hydrate_fma. This is the real-data heart slice the
+# q2 /fma render surface hydrates.
+
+fma:Cavity_of_right_atrium bfo:part_of fma:Heart .
+fma:Cardiac_vein bfo:part_of fma:Heart .
+fma:Neural_network_of_heart bfo:part_of fma:Heart .
+fma:Coronary_sinus bfo:part_of fma:Heart .
+fma:Right_coronary_artery bfo:part_of fma:Heart .
+fma:Left_coronary_artery bfo:part_of fma:Heart .
+fma:Interatrial_septum bfo:part_of fma:Heart .
+fma:Interventricular_septum bfo:part_of fma:Heart .
+fma:Atrioventricular_septum bfo:part_of fma:Heart .
+fma:Right_side_of_heart bfo:part_of fma:Heart .
+fma:Left_side_of_heart bfo:part_of fma:Heart .
+fma:Tricuspid_valve bfo:part_of fma:Heart .
+fma:Mitral_valve bfo:part_of fma:Heart .
+fma:Aortic_valve bfo:part_of fma:Heart .
+fma:Pulmonary_valve bfo:part_of fma:Heart .
+fma:Wall_of_heart bfo:part_of fma:Heart .
+fma:Systemic_capillary_bed_of_heart bfo:part_of fma:Heart .
+fma:Lymphatic_capillary_bed_of_heart bfo:part_of fma:Heart .
+fma:Cavity_of_right_ventricle bfo:part_of fma:Heart .
+fma:Cavity_of_left_atrium bfo:part_of fma:Heart .
+fma:Cavity_of_left_ventricle bfo:part_of fma:Heart .
+fma:Fibrous_skeleton_of_heart bfo:part_of fma:Heart .
+fma:Cavity_of_inflow_part_of_right_atrium bfo:part_of fma:Cavity_of_right_atrium .
+fma:Ostium_of_superior_vena_cava bfo:part_of fma:Cavity_of_right_atrium .
+fma:Ostium_of_inferior_vena_cava bfo:part_of fma:Cavity_of_right_atrium .
+fma:Variant_branch_of_right_coronary_arterial_tree bfo:part_of fma:Right_coronary_artery .
+fma:Recurrent_atrioventricular_branch_of_right_coronary_artery bfo:part_of fma:Right_coronary_artery .
+fma:Lateral_atrial_branch_of_right_coronary_artery bfo:part_of fma:Right_coronary_artery .
+fma:Wall_of_left_coronary_artery bfo:part_of fma:Left_coronary_artery .
+fma:Lumen_of_left_coronary_artery bfo:part_of fma:Left_coronary_artery .
+fma:Trunk_of_left_coronary_artery bfo:part_of fma:Left_coronary_artery .
+fma:Membranous_part_of_interatrial_septum bfo:part_of fma:Interatrial_septum .
+fma:Fibrocollagenous_connective_tissue_of_interatrial_septum bfo:part_of fma:Interatrial_septum .
+fma:Muscular_part_of_interatrial_septum bfo:part_of fma:Interatrial_septum .
+fma:Fibrocollagenous_connective_tissue_of_interventricular_septum bfo:part_of fma:Interventricular_septum .
+fma:Muscular_part_of_interventricular_septum bfo:part_of fma:Interventricular_septum .
+fma:Membranous_part_of_interventricular_septum bfo:part_of fma:Interventricular_septum .
+fma:Endothelium_of_atrioventricular_septum bfo:part_of fma:Atrioventricular_septum .
+fma:Fibroelastic_connective_tissue_of_endocardium bfo:part_of fma:Atrioventricular_septum .
+fma:Neural_network_of_right_side_of_heart bfo:part_of fma:Right_side_of_heart .
+fma:Small_cardiac_vein bfo:part_of fma:Right_side_of_heart .
+fma:Right_marginal_vein bfo:part_of fma:Right_side_of_heart .
+fma:Neural_network_of_left_side_of_heart bfo:part_of fma:Left_side_of_heart .
+fma:Great_cardiac_vein bfo:part_of fma:Left_side_of_heart .
+fma:Left_atrium bfo:part_of fma:Left_side_of_heart .
+fma:Endothelium_of_tricuspid_valve bfo:part_of fma:Tricuspid_valve .
+fma:Anterior_leaflet_of_tricuspid_valve bfo:part_of fma:Tricuspid_valve .
+fma:Posterior_leaflet_of_tricuspid_valve bfo:part_of fma:Tricuspid_valve .
+fma:Endothelium_of_mitral_valve bfo:part_of fma:Mitral_valve .
+fma:Anterior_leaflet_of_mitral_valve bfo:part_of fma:Mitral_valve .
+fma:Posterior_leaflet_of_mitral_valve bfo:part_of fma:Mitral_valve .
+fma:Endothelium_of_aortic_valve bfo:part_of fma:Aortic_valve .
+fma:Right_posterior_cusp_of_aortic_valve bfo:part_of fma:Aortic_valve .
+fma:Anterior_cusp_of_aortic_valve bfo:part_of fma:Aortic_valve .
+fma:Left_anterior_cusp_of_pulmonary_valve bfo:part_of fma:Pulmonary_valve .
+fma:Right_anterior_cusp_of_pulmonary_valve bfo:part_of fma:Pulmonary_valve .
+fma:Posterior_cusp_of_pulmonary_valve bfo:part_of fma:Pulmonary_valve .
+fma:Endocardium bfo:part_of fma:Wall_of_heart .
+fma:Epicardium bfo:part_of fma:Wall_of_heart .
+fma:Myocardium bfo:part_of fma:Wall_of_heart .
+fma:Ostium_of_least_cardiac_vein_of_right_ventricle bfo:part_of fma:Cavity_of_right_ventricle .
+fma:Cavity_of_inflow_part_of_right_ventricle bfo:part_of fma:Cavity_of_right_ventricle .
+fma:Ostium_of_pulmonary_trunk bfo:part_of fma:Cavity_of_right_ventricle .
+fma:Cavity_of_inflow_part_of_left_atrium bfo:part_of fma:Cavity_of_left_atrium .
+fma:Cavity_proper_of_left_atrium bfo:part_of fma:Cavity_of_left_atrium .
+fma:Ostium_of_right_superior_pulmonary_vein bfo:part_of fma:Cavity_of_left_atrium .
+fma:Cavity_of_inflow_part_of_left_ventricle bfo:part_of fma:Cavity_of_left_ventricle .
+fma:Ostium_of_aorta bfo:part_of fma:Cavity_of_left_ventricle .
+fma:Cavity_of_outflow_part_of_left_ventricle bfo:part_of fma:Cavity_of_left_ventricle .
+fma:Connective_tissue_of_fibrous_skeleton_of_heart bfo:part_of fma:Fibrous_skeleton_of_heart .
+fma:Fibrocollagenous_connective_tissue_of_fibrous_skeleton_of_heart bfo:part_of fma:Fibrous_skeleton_of_heart .
+fma:Central_fibrous_body bfo:part_of fma:Fibrous_skeleton_of_heart .
+fma:Cavity_proper_of_inflow_part_of_right_atrium bfo:part_of fma:Cavity_of_inflow_part_of_right_atrium .
+fma:Ostium_of_coronary_sinus bfo:part_of fma:Cavity_of_inflow_part_of_right_atrium .
+fma:Ostium_of_least_cardiac_vein_of_right_atrium bfo:part_of fma:Cavity_of_inflow_part_of_right_atrium .
+fma:Lumen_of_trunk_of_left_coronary_artery bfo:part_of fma:Trunk_of_left_coronary_artery .
+fma:Wall_of_trunk_of_left_coronary_artery bfo:part_of fma:Trunk_of_left_coronary_artery .
+fma:Endocardium_of_interatrial_septum bfo:part_of fma:Membranous_part_of_interatrial_septum .
+fma:Fibrocollagenous_connective_tissue_of_muscular_part_of_interatrial_septum bfo:part_of fma:Muscular_part_of_interatrial_septum .
+fma:Heart rdfs:subClassOf fma:Organ_with_cavitated_organ_parts .
+fma:Cavity_of_right_atrium rdfs:subClassOf fma:Cavity_of_atrium .
+fma:Cardiac_vein rdfs:subClassOf fma:Systemic_vein .
+fma:Neural_network_of_heart rdfs:subClassOf fma:Neural_network_of_organ .
+fma:Coronary_sinus rdfs:subClassOf fma:Trunk_of_systemic_vein .
+fma:Right_coronary_artery rdfs:subClassOf fma:Coronary_artery .
+fma:Left_coronary_artery rdfs:subClassOf fma:Coronary_artery .
+fma:Interatrial_septum rdfs:subClassOf fma:Cardiac_septum .
+fma:Interventricular_septum rdfs:subClassOf fma:Cardiac_septum .
+fma:Atrioventricular_septum rdfs:subClassOf fma:Region_of_membranous_part_of_interventricular_septum .
+fma:Right_side_of_heart rdfs:subClassOf fma:Zone_of_heart .
+fma:Left_side_of_heart rdfs:subClassOf fma:Zone_of_heart .
+fma:Tricuspid_valve rdfs:subClassOf fma:Atrioventricular_valve .
+fma:Mitral_valve rdfs:subClassOf fma:Atrioventricular_valve .
+fma:Aortic_valve rdfs:subClassOf fma:Cardiac_valve .
+fma:Pulmonary_valve rdfs:subClassOf fma:Cardiac_valve .
+fma:Wall_of_heart rdfs:subClassOf fma:Wall_of_organ .
+fma:Systemic_capillary_bed_of_heart rdfs:subClassOf fma:Systemic_capillary_bed .
+fma:Lymphatic_capillary_bed_of_heart rdfs:subClassOf fma:Lymphatic_capillary_bed .
+fma:Cavity_of_right_ventricle rdfs:subClassOf fma:Cavity_of_ventricle .
+fma:Cavity_of_left_atrium rdfs:subClassOf fma:Cavity_of_atrium .
+fma:Cavity_of_left_ventricle rdfs:subClassOf fma:Cavity_of_ventricle .
+fma:Fibrous_skeleton_of_heart rdfs:subClassOf fma:Fibrous_connective_tissue .
+fma:Cavity_of_inflow_part_of_right_atrium rdfs:subClassOf fma:Subdivision_of_cavity_of_cardiac_chamber .
+fma:Ostium_of_superior_vena_cava rdfs:subClassOf fma:Orifice_of_vein .
+fma:Ostium_of_inferior_vena_cava rdfs:subClassOf fma:Orifice_of_vein .
+fma:Variant_branch_of_right_coronary_arterial_tree rdfs:subClassOf fma:Branch_of_right_coronary_artery .
+fma:Recurrent_atrioventricular_branch_of_right_coronary_artery rdfs:subClassOf fma:Branch_of_right_coronary_artery .
+fma:Lateral_atrial_branch_of_right_coronary_artery rdfs:subClassOf fma:Atrial_branch_of_right_coronary_artery .
+fma:Wall_of_left_coronary_artery rdfs:subClassOf fma:Wall_of_coronary_artery .
+fma:Lumen_of_left_coronary_artery rdfs:subClassOf fma:Lumen_of_coronary_artery .
+fma:Trunk_of_left_coronary_artery rdfs:subClassOf fma:Trunk_of_coronary_artery .
+fma:Membranous_part_of_interatrial_septum rdfs:subClassOf fma:Membranous_part_of_cardiac_septum .
+fma:Fibrocollagenous_connective_tissue_of_interatrial_septum rdfs:subClassOf fma:Fibrocollagenous_sheath_of_cardiac_muscle_tissue .
+fma:Muscular_part_of_interatrial_septum rdfs:subClassOf fma:Muscular_part_of_cardiac_septum .
+fma:Fibrocollagenous_connective_tissue_of_interventricular_septum rdfs:subClassOf fma:Fibrocollagenous_sheath_of_cardiac_muscle_tissue .
+fma:Muscular_part_of_interventricular_septum rdfs:subClassOf fma:Muscular_part_of_cardiac_septum .
+fma:Membranous_part_of_interventricular_septum rdfs:subClassOf fma:Membranous_part_of_cardiac_septum .
+fma:Endothelium_of_atrioventricular_septum rdfs:subClassOf fma:Endothelium_of_endocardium .
+fma:Fibroelastic_connective_tissue_of_endocardium rdfs:subClassOf fma:Fibroelastic_connective_tissue .
+fma:Neural_network_of_right_side_of_heart rdfs:subClassOf fma:Neural_network_of_organ_part .
+fma:Neural_network_of_left_side_of_heart rdfs:subClassOf fma:Neural_network_of_organ_part .
+fma:Left_atrium rdfs:subClassOf fma:Cardiac_atrium .
+fma:Endothelium_of_tricuspid_valve rdfs:subClassOf fma:Endothelium_of_endocardium .
+fma:Anterior_leaflet_of_tricuspid_valve rdfs:subClassOf fma:Leaflet_of_tricuspid_valve .
+fma:Posterior_leaflet_of_tricuspid_valve rdfs:subClassOf fma:Leaflet_of_tricuspid_valve .
+fma:Endothelium_of_mitral_valve rdfs:subClassOf fma:Endothelium_of_endocardium .
+fma:Anterior_leaflet_of_mitral_valve rdfs:subClassOf fma:Leaflet_of_mitral_valve .
+fma:Posterior_leaflet_of_mitral_valve rdfs:subClassOf fma:Leaflet_of_mitral_valve .
+fma:Endothelium_of_aortic_valve rdfs:subClassOf fma:Endothelium_of_endocardium .
+fma:Right_posterior_cusp_of_aortic_valve rdfs:subClassOf fma:Cusp_of_aortic_valve .
+fma:Anterior_cusp_of_aortic_valve rdfs:subClassOf fma:Cusp_of_aortic_valve .
+fma:Left_anterior_cusp_of_pulmonary_valve rdfs:subClassOf fma:Cusp_of_pulmonary_valve .
+fma:Right_anterior_cusp_of_pulmonary_valve rdfs:subClassOf fma:Cusp_of_pulmonary_valve .
+fma:Posterior_cusp_of_pulmonary_valve rdfs:subClassOf fma:Cusp_of_pulmonary_valve .
+fma:Endocardium rdfs:subClassOf fma:Tunica_intima .
+fma:Epicardium rdfs:subClassOf fma:Region_of_visceral_serous_pericardium .
+fma:Myocardium rdfs:subClassOf fma:Muscle_body .
+fma:Ostium_of_least_cardiac_vein_of_right_ventricle rdfs:subClassOf fma:Ostium_of_least_cardiac_vein .
+fma:Cavity_of_inflow_part_of_right_ventricle rdfs:subClassOf fma:Subdivision_of_cavity_of_cardiac_chamber .
+fma:Ostium_of_pulmonary_trunk rdfs:subClassOf fma:Orifice_of_artery .
+fma:Cavity_of_inflow_part_of_left_atrium rdfs:subClassOf fma:Subdivision_of_cavity_of_cardiac_chamber .
+fma:Cavity_proper_of_left_atrium rdfs:subClassOf fma:Subdivision_of_cavity_of_cardiac_chamber .
+fma:Ostium_of_right_superior_pulmonary_vein rdfs:subClassOf fma:Ostium_of_superior_pulmonary_vein .
+fma:Cavity_of_inflow_part_of_left_ventricle rdfs:subClassOf fma:Subdivision_of_cavity_of_cardiac_chamber .
+fma:Ostium_of_aorta rdfs:subClassOf fma:Orifice_of_artery .
+fma:Cavity_of_outflow_part_of_left_ventricle rdfs:subClassOf fma:Subdivision_of_cavity_of_cardiac_chamber .
+fma:Connective_tissue_of_fibrous_skeleton_of_heart rdfs:subClassOf fma:Fibroelastic_connective_tissue .
+fma:Fibrocollagenous_connective_tissue_of_fibrous_skeleton_of_heart rdfs:subClassOf fma:Fibrocollagenous_connective_tissue .
+fma:Central_fibrous_body rdfs:subClassOf fma:Subdivision_of_fibrous_skeleton_of_heart .
+fma:Cavity_proper_of_inflow_part_of_right_atrium rdfs:subClassOf fma:Subdivision_of_cavity_of_cardiac_chamber .
+fma:Ostium_of_coronary_sinus rdfs:subClassOf fma:Orifice_of_vein .
+fma:Ostium_of_least_cardiac_vein_of_right_atrium rdfs:subClassOf fma:Ostium_of_least_cardiac_vein .
+fma:Lumen_of_trunk_of_left_coronary_artery rdfs:subClassOf fma:Lumen_of_trunk_of_coronary_artery .
+fma:Wall_of_trunk_of_left_coronary_artery rdfs:subClassOf fma:Wall_of_trunk_of_coronary_artery .
+fma:Endocardium_of_interatrial_septum rdfs:subClassOf fma:Endocardium_of_cardiac_septum .
+fma:Fibrocollagenous_connective_tissue_of_muscular_part_of_interatrial_septum rdfs:subClassOf fma:Fibrocollagenous_sheath_of_cardiac_muscle_tissue .
diff --git a/crates/osint-bake/src/bin/fma.rs b/crates/osint-bake/src/bin/fma.rs
index f6bc36718..948e0f328 100644
--- a/crates/osint-bake/src/bin/fma.rs
+++ b/crates/osint-bake/src/bin/fma.rs
@@ -1,23 +1,32 @@
//! FMA anatomy slice — the "real test" of the dual-membership lattice.
//!
-//! **Hydrated from an FMA `.ttl` fixture** (`data/fma-heart.fixture.ttl`) via
+//! **Hydrated from a real FMA heart subtree** (`data/fma-heart.ttl`, extracted
+//! from the 266 MB `fma.owl` v5.0.0 by `tools/extract_fma_heart.py`) via
//! [`hydrate_fma`] — no longer hand-built. Stands up a Foundational-Model-of-
-//! Anatomy-shaped slice of the **heart** (organ → chambers → wall layers) and
-//! proves that one node resolves to BOTH addresses at once:
+//! Anatomy slice of the **heart** (organ → its 22 major subdivisions: the four
+//! chamber cavities, the four valves, the three cardiac septa, both coronary
+//! arteries, the wall's endo/epi/myocardium, the fibrous skeleton, … → their
+//! sub-parts) and proves that one node resolves to BOTH addresses at once:
//!
-//! * **part-of position** (basin-local): HEEL=[Organ:Heart], HIP=[Chamber:id],
-//! TWIG=[Wall:id] — where the node *is* in the body, read straight off the key
-//! (the partonomy walk fills the cascade; deeper tiers stay 0 until the real
-//! 75K FMA hydrates tissues/cells through the same walk).
+//! * **part-of position** (basin-local): HEEL=[Organ:Heart], HIP=[part:id],
+//! TWIG=[sub-part:id], LEAF=[deeper:id] — where the node *is* in the body, read
+//! straight off the key (the partonomy walk fills the cascade; deeper tiers
+//! stay 0 until the full 75K-term FMA hydrates tissues/cells through the same
+//! walk).
//! * **leaf-limited global type** (the CEILING pole, HEEL=HIP=TWIG=0xFFFF,
-//! LEAF=type): "cardiac muscle tissue", "endothelium" — cross-cutting types
-//! that appear in *every* chamber. The deepest sentinel run (through TWIG)
-//! makes the LEAF the sole discriminator: "limited to the leaf".
+//! LEAF=type): "Atrioventricular valve", "Endothelium of endocardium",
+//! "Cavity of ventricle" — cross-cutting FMA `subClassOf` types carried by
+//! structures in *different* parts of the heart. The deepest sentinel run
+//! (through TWIG) makes the LEAF the sole discriminator: "limited to the leaf".
//!
-//! The same `Cardiac muscle tissue` ceiling node is the `is-a` target for the
-//! myocardium tissue in all four chambers — visibly cross-cutting. Emits
-//! `cockpit/public/fma.soa` (OSO1, the cockpit's `/fma` view reads it) and
-//! prints the dual-membership proof.
+//! The proof picks the strongest real cross-cutter in the slice — the ceiling
+//! type that is the `is-a` target of the most structures (e.g. `Subdivision of
+//! cavity of cardiac chamber`, shared by the inflow/outflow cavities of all four
+//! chambers; or `Endothelium of endocardium`, shared by the valve and septum
+//! endothelia) — then a member sitting deepest in the body, and shows it
+//! resolving to both its part-of cascade and that shared global type. Emits
+//! `cockpit/public/fma.soa` (OSO1, the cockpit's `/fma` view reads it) and prints
+//! the dual-membership proof.
//!
//! ## Relation to OGAR PR #116 (the FMA canon)
//!
@@ -171,12 +180,14 @@ impl Builder {
}
}
-/// Embedded FMA heart fixture — real class names + the canonical FMA predicate
-/// set. The production path hydrates the 266 MB `fma.owl` through
-/// `lance-graph-rdf` at the spine; this light bake hydrates the fixture so
-/// `/fma` renders without the lance/datafusion closure. See
-/// `data/fma-heart.fixture.ttl`.
-const FMA_TTL: &str = include_str!("../../data/fma-heart.fixture.ttl");
+/// Embedded real FMA heart subtree — extracted from `fma.owl` (FMA v5.0.0,
+/// CC BY 3.0) by `tools/extract_fma_heart.py`: a balanced BFS of the
+/// `regional_part`/`constitutional_part` partonomy from `FMA:Heart` (depth ≤ 4,
+/// per-parent fan-out capped so no single subtree dominates). The production
+/// path hydrates the full 266 MB `fma.owl` through `lance-graph-rdf` at the
+/// spine; this light bake hydrates the committed subtree so `/fma` renders
+/// without the lance/datafusion closure. See `data/fma-heart.ttl`.
+const FMA_TTL: &str = include_str!("../../data/fma-heart.ttl");
/// Hydrate an FMA `.ttl` fragment into the bake's [`Builder`] — the light-bake
/// twin of `lance_graph_ontology::hydrate_fma`. Walk the `bfo:part_of` partonomy
@@ -321,17 +332,51 @@ fn main() {
let b = hydrate_fma(FMA_TTL);
let bytes = emit_oso1(&b);
- // dual-membership proof: a hydrated wall layer carries BOTH addresses.
- let tissue = b
- .nodes
+ // Dual-membership proof: pick the strongest real cross-cutter in the slice —
+ // the ceiling TYPE that is the `is-a` target of the most structures — then the
+ // member sitting deepest in the body. Whatever the hydrated heart slice
+ // contains, this surfaces a node that genuinely resolves to BOTH a basin-local
+ // part-of cascade and a cross-cutting global type. `tier_depth` counts the
+ // non-zero HHTL tiers: how deep into the body the part-of address runs.
+ let tier_depth = |n: usize| -> usize {
+ let k = &b.nodes[n].key;
+ [k.heel(), k.hip(), k.twig(), k.leaf(), k.family_v2()]
+ .iter()
+ .filter(|&&t| t != 0)
+ .count()
+ };
+ // group is-a edges by ceiling-type target → the members that share it.
+ let mut by_type: std::collections::BTreeMap> =
+ std::collections::BTreeMap::new();
+ for &(s, t, rel) in &b.edges {
+ if rel == REL_IS_A {
+ by_type.entry(t).or_default().push(s);
+ }
+ }
+ // strongest cross-cutter: most members, ties broken by label (deterministic).
+ let (>ype, sharers) = by_type
+ .iter()
+ .max_by(|x, y| {
+ x.1.len()
+ .cmp(&y.1.len())
+ .then_with(|| b.nodes[*y.0].label.cmp(&b.nodes[*x.0].label))
+ })
+ .expect("the slice has is-a edges");
+ // anchor: the member sitting deepest in the body (ties broken by label).
+ let &anchor = sharers
.iter()
- .position(|x| x.label == "Myocardium of left ventricle")
- .expect("LV myocardium hydrated from the fixture");
- let key = &b.nodes[tissue].key;
+ .max_by(|&&x, &&y| {
+ tier_depth(x)
+ .cmp(&tier_depth(y))
+ .then_with(|| b.nodes[y].label.cmp(&b.nodes[x].label))
+ })
+ .expect("a cross-cutting type has members");
+
+ let key = &b.nodes[anchor].key;
+ let show = |t: u16| format!("[{:02x}:{:02x}]", t >> 8, t & 0xFF);
println!("── FMA dual-membership proof ──");
- println!("node: {}", b.nodes[tissue].label);
+ println!("node: {}", b.nodes[anchor].label);
// the partonomy IS the key: each HHTL tier is an 8:8 [mixin:identity] pair.
- let show = |t: u16| format!("[{:02x}:{:02x}]", t >> 8, t & 0xFF);
println!(
" part-of address — HHTL 8:8 [mixin:identity]: HEEL {} HIP {} TWIG {} LEAF {} family {}",
show(key.heel()),
@@ -340,13 +385,7 @@ fn main() {
show(key.leaf()),
show(key.family_v2()),
);
- // its is-a edge → the leaf-limited global type (ceiling pole)
- let gtype = b
- .edges
- .iter()
- .find(|&&(s, _, rel)| s == tissue && rel == REL_IS_A)
- .map(|&(_, t, _)| t)
- .expect("tissue is-a a global type");
+ // its is-a edge → the leaf-limited global type (ceiling pole).
let gk = &b.nodes[gtype].key;
println!(
" is-a global type (ceiling): {} HEEL={:#06x} HIP={:#06x} TWIG={:#06x} LEAF={}",
@@ -356,16 +395,15 @@ fn main() {
gk.twig(),
gk.leaf()
);
- // cross-cutting: how many chambers' tissues share this one global type?
- let members = b
- .edges
- .iter()
- .filter(|&&(_, t, rel)| t == gtype && rel == REL_IS_A)
- .count();
+ // cross-cutting: how many structures across the heart share this one type?
println!(
- " '{}' is the is-a target of {members} tissues across the chambers (cross-cutting)",
- b.nodes[gtype].label
+ " '{}' is the is-a target of {} structures in different parts of the heart (cross-cutting)",
+ b.nodes[gtype].label,
+ sharers.len()
);
+ let mut shared_by: Vec<&str> = sharers.iter().map(|&m| b.nodes[m].label.as_str()).collect();
+ shared_by.sort_unstable();
+ println!(" shared by: {}", shared_by.join(", "));
let n_types = b.nodes.iter().filter(|x| x.class == C_TYPE).count();
println!(
diff --git a/crates/osint-bake/tools/extract_fma_heart.py b/crates/osint-bake/tools/extract_fma_heart.py
new file mode 100644
index 000000000..5644b5763
--- /dev/null
+++ b/crates/osint-bake/tools/extract_fma_heart.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python3
+"""Extract the FMA *heart* part-of subtree from the real fma.owl into the
+line-oriented Turtle subset the q2 light bake hydrates (osint-bake/src/fma_ttl.rs).
+
+Source (provenance): fma.owl, FMA v5.0.0, BioPortal #29 / UW Structural
+Informatics Group, CC BY 3.0, SHA-256 59465eb503c418dbf9216d362b94c7f42bc3b96b297e553ec17c7fee77979e44,
+mirrored at github.com/AdaWorldAPI/q2/releases/download/fma-ontology-5.0.0/fma.owl
+
+This is a one-off data-prep tool. The PRODUCTION hydrator is
+lance_graph_ontology::hydrate_fma (rio_xml) at the spine; this script exists so
+the light bake (no lance/datafusion closure) can carry a *real* heart subtree
+instead of a hand-authored fixture. Streaming ET.iterparse keeps memory bounded
+(only label / part / superclass maps are retained, not the 1.5M-triple graph).
+
+Usage: python3 extract_fma_heart.py
+"""
+import sys
+import xml.etree.ElementTree as ET
+
+RDF = "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}"
+RDFS = "{http://www.w3.org/2000/01/rdf-schema#}"
+OWL = "{http://www.w3.org/2002/07/owl#}"
+BASE = "http://purl.org/sig/ont/fma/"
+
+# forward "has-part" properties (whole → part); the part is a CHILD of the whole.
+PART_PROPS = {"regional_part", "constitutional_part", "systemic_part"}
+HEART = "fma7088" # FMA:Heart
+MAX_DEPTH = 4 # organ → chamber → wall → tissue
+MAX_NODES = 80 # keep the cockpit slice legible
+MAX_CHILDREN = 3 # per NON-root parent — a balanced cross-section, not a
+ # coronary-artery dump (FMA's coronary tree has ~40 named
+ # branches; uncapped BFS lets it starve every other part).
+ # The root (Heart) is exempt: all its major subdivisions
+ # — 4 chamber cavities, 4 valves, 3 septa, both coronary
+ # arteries, wall, fibrous skeleton, … — are the point.
+
+CLEAR_TAGS = {OWL + t for t in ("Class", "Axiom", "ObjectProperty",
+ "AnnotationProperty", "DatatypeProperty",
+ "NamedIndividual")} | {RDF + "Description"}
+
+
+def local(iri):
+ return iri.rsplit("/", 1)[-1] if iri else None
+
+
+def main(src, out):
+ label, children, supers = {}, {}, {}
+ for _ev, elem in ET.iterparse(src, events=("end",)):
+ if elem.tag == OWL + "Class":
+ about = elem.get(RDF + "about")
+ if about and about.startswith(BASE):
+ cid = local(about)
+ lab = elem.find(RDFS + "label")
+ if lab is not None and lab.text:
+ label[cid] = lab.text.strip()
+ for sc in elem.findall(RDFS + "subClassOf"):
+ res = sc.get(RDF + "resource")
+ if res and res.startswith(BASE): # named superclass → is-a
+ supers.setdefault(cid, []).append(local(res))
+ continue
+ restr = sc.find(OWL + "Restriction")
+ if restr is None:
+ continue
+ op = restr.find(OWL + "onProperty")
+ sv = restr.find(OWL + "someValuesFrom")
+ if op is None or sv is None:
+ continue
+ prop = local(op.get(RDF + "resource") or "")
+ tgt = sv.get(RDF + "resource")
+ if prop in PART_PROPS and tgt and tgt.startswith(BASE):
+ children.setdefault(cid, []).append(local(tgt)) # tgt is part of cid
+ if elem.tag in CLEAR_TAGS:
+ elem.clear()
+
+ # BFS the heart subtree; first whole to reach a part becomes its tree-parent
+ # (FMA part-of is a DAG; we take a spanning tree rooted at the heart). Each
+ # non-root whole contributes at most MAX_CHILDREN parts, so breadth stays
+ # balanced across the heart's subdivisions instead of draining into one
+ # deep subtree. Because every level-1 node is popped before any level-2 node
+ # (plain BFS), this caps fan-out per parent fairly across the whole level.
+ parent, depth, order = {}, {HEART: 0}, [HEART]
+ queue = [HEART]
+ while queue and len(order) < MAX_NODES:
+ n = queue.pop(0)
+ if depth[n] >= MAX_DEPTH:
+ continue
+ cap = MAX_NODES if n == HEART else MAX_CHILDREN # root keeps every major part
+ taken = 0
+ for c in sorted(set(children.get(n, []))):
+ if taken >= cap:
+ break
+ if c in depth or c not in label: # unseen + actually a labelled class
+ continue
+ parent[c], depth[c] = n, depth[n] + 1
+ order.append(c)
+ queue.append(c)
+ taken += 1
+ if len(order) >= MAX_NODES:
+ break
+
+ def tok(cid):
+ # real FMA label → a prefix:token the line-Turtle reader splits on
+ # (label_of() turns '_' back into spaces). alnum kept, else '_'.
+ lab = label.get(cid, cid)
+ t = "".join(ch if ch.isalnum() else "_" for ch in lab).strip("_")
+ while "__" in t:
+ t = t.replace("__", "_")
+ return "fma:" + t
+
+ lines = [
+ "# fma-heart.ttl — REAL FMA heart subtree, extracted from fma.owl (FMA v5.0.0).",
+ "# Source: BioPortal #29 / UW Structural Informatics Group, CC BY 3.0,",
+ "# SHA-256 59465eb503c418dbf9216d362b94c7f42bc3b96b297e553ec17c7fee77979e44,",
+ "# mirror github.com/AdaWorldAPI/q2/releases/download/fma-ontology-5.0.0/fma.owl",
+ "# Generated by tools/extract_fma_heart.py (streaming ET; regional_part +",
+ "# constitutional_part partonomy, BFS from FMA:Heart fma7088, depth<=%d, <=%d nodes)."
+ % (MAX_DEPTH, MAX_NODES),
+ "# The 266 MB OWL is NOT committed; the production hydrator is the spine's",
+ "# lance_graph_ontology::hydrate_fma. This is the real-data heart slice the",
+ "# q2 /fma render surface hydrates.",
+ "",
+ ]
+ seen_types = set()
+ for c in order:
+ if c in parent:
+ lines.append(f"{tok(c)} bfo:part_of {tok(parent[c])} .")
+ for c in order: # cross-cutting type: first named superclass
+ for s in supers.get(c, []):
+ if s in label and s not in depth: # a real category outside the part-of tree
+ lines.append(f"{tok(c)} rdfs:subClassOf {tok(s)} .")
+ seen_types.add(s)
+ break
+ open(out, "w").write("\n".join(lines) + "\n")
+
+ # inspection summary to stderr
+ print(f"heart subtree: {len(order)} nodes (<= depth {MAX_DEPTH}), "
+ f"{sum(1 for c in order if c in parent)} part-of edges, "
+ f"{len(seen_types)} cross-cutting types", file=sys.stderr)
+ for c in order[:14]:
+ print(f" depth {depth[c]} {label.get(c,c)}"
+ + (f" ⊂ {label.get(parent[c])}" if c in parent else " (root)"), file=sys.stderr)
+
+
+if __name__ == "__main__":
+ main(sys.argv[1], sys.argv[2])