Provenance and status

Two record formats for anatomic locations coexist in OIDM, and this document holds both. The first is the original schema from the anatomiclocations.org repository, read at commit 1f39fa4, which validates a curated set of 2,890 body parts keyed by RadLex identifier. The second is the format used by the anatomic-locations package inside the findingmodel repository, read at commit 75afd39 on main, which covers 2,926 records and adds classification, dual hierarchies, and explicit laterality. The build plan names the newer package and its dataset as the current anatomic data, and the older set as lineage.1 Field tables here are compiled from the schema file and the model source; the records shown are copied unchanged from the published data.

Lineage A: the anatomiclocations.org body part schema

The file data/body_parts_schema.json is a JSON Schema draft-06 document.2 It validates data/body_parts.json, which declares $version 1.0.0-rc.1 and carries 2,890 entries under bodyParts.3 Every object sets additionalProperties: false, so the field list is closed.

Container

FieldTypeRequired
$schemastringyes
$versionstringyes
bodyPartsarray of BodyPartElementyes

BodyPartElement

FieldTypeRequiredNotes
radlexIdRadlexIDyesthe entry’s own identifier
descriptionstringyesdisplay name
containedByIdRadlexIDyesthe structure that spatially contains this one
partOfIdRadlexIDnomereological parent, distinct from containment
leftIdRadlexIDnoleft variant, present on the unsided entry
rightIdRadlexIDnoright variant, present on the unsided entry
unsidedIdstringnoback-reference from a sided entry to its unsided form
sexSpecificstringnoone of Male or Female
synonymsarray of stringno
codesarray of Codeno

RadlexID is constrained to the pattern ^RID\d+(_RID\d+)*$, which admits both a plain RadLex identifier and the compound form used for sided variants. unsidedId is the one field declared as a plain string rather than as a RadlexID, so the pattern is not enforced on it. A Code is a closed object of system and code, both required, with no display name.

Across the 2,890 entries, 1,611 carry a leftId, 1,584 carry an unsidedId, 990 carry a partOfId, and 2,282 carry at least one code. The code systems present are SNOMED, FMA, UMLS, and MESH.

A real record

The entry for uterine adnexa shows containment, part-of, a laterality pair, sex specificity, a synonym, and three codes.

{
  "radlexId": "RID294",
  "description": "uterine adnexa",
  "containedById": "RID2507",
  "leftId": "RID294_RID5824",
  "rightId": "RID294_RID5825",
  "sexSpecific": "Female",
  "partOfId": "RID270",
  "synonyms": ["adnexa"],
  "codes": [
    { "system": "FMA", "code": "265256" },
    { "system": "SNOMED", "code": "23043003" },
    { "system": "UMLS", "code": "C0001575" }
  ]
}

RID5824 and RID5825 are the RadLex identifiers for left and right, which is why the sided variants are written as compound identifiers rather than as new numbers.

Lineage B: the anatomic-locations package format, current

This lineage has two representations of the same information. The curation format is the JSON file that editors change, documented in the repository’s own field reference.4 The runtime format is the AnatomicLocation Pydantic model that the package returns from its index.5

Curation format fields

The source file notebooks/data/anatomic_locations_noembed.json is a flat JSON array of 2,926 objects.6

FieldTypeRequiredNotes
_idstringyesRadLex identifier, compound for sided variants
descriptionstringyeslowercase display name
regionstringnobody region label
snomedIdstringnoSNOMED CT concept, strongly encouraged
snomedDisplaystringnoSNOMED preferred term
acrCommonIdstringnoACR Common identifier
codesarray of {system, code}noFMA, MESH, UMLS and others
containedByRef{id, display}noimmediate spatial container
containsRefsarray of {id, display}noindexed structures inside this one
partOfRef{id, display}nomereological parent
hasPartsRefsarray of {id, display}nomereological children
leftRef{id, display}noleft variant
rightRef{id, display}noright variant
unsidedRef{id, display}noback-reference to the generic entry
synonymsarray of stringnoclinical shorthand
definitionstringnobrief definition with its source in brackets

Two fields appear in the data but not in the field reference: sexSpecific, on 110 records, and anatomicLocationsId, on a single record. The field reference also lists "Spine" among the common region values, but no record in the data uses it and the runtime enumeration has no spine member. The nine region values actually present are Head (869), Upper Extremity (582), Lower Extremity (579), Neck (235), Thorax (226), Abdomen (212), Pelvis (152), Breast (46), and Body (25).

The two hierarchy relations are kept deliberately distinct, as documented in the field reference: containedByRef is spatial, meaning X is inside Y, while partOfRef is mereological, meaning X is a component of Y. See contained-by and part-of. SNOMED coding follows one rule without exception: of the Structure, Entire, and Part concepts in a SNOMED anatomy triad, always use the “Structure of” concept, because that is what SNOMED intends for finding sites and procedure sites.

Laterality is expressed as a triad. The generic entry carries leftRef and rightRef; each sided entry carries unsidedRef back to the generic. 827 distinct left-sided and 827 distinct right-sided entries are referenced, and every reference resolves to a record in the file. 1,597 records carry an unsidedRef.

A real record

The hypopharynx entry, unchanged from the data file and used as the worked example in the field reference.

{
  "_id": "RID10021",
  "acrCommonId": "4013944",
  "snomedId": "81502006",
  "snomedDisplay": "Hypopharyngeal structure",
  "description": "hypopharynx",
  "region": "Neck",
  "containedByRef": { "id": "RID7488", "display": "neck" },
  "synonyms": ["laryngopharynx"],
  "partOfRef": { "id": "RID13211", "display": "pharynx" },
  "codes": [
    { "system": "FMA", "code": "54880" },
    { "system": "MESH", "code": "A14.724.490" },
    { "system": "UMLS", "code": "C0014540" }
  ],
  "definition": "The portion of the pharynx between the inferior portion of the oropharynx and the larynx. [MeSH]"
}

Runtime model fields

AnatomicLocation is the object the package hands back. It renames the curation fields, resolves the reference objects into a lightweight AnatomicRef of id and display, and adds classification and materialized paths.

FieldTypeDefaultNotes
idstringrequiredRadLex identifier
descriptionstringrequireddisplay name
regionAnatomicRegion or nullnullHead, Neck, Thorax, Abdomen, Pelvis, Upper Extremity, Lower Extremity, Breast, Body
location_typeLocationTypestructurestructure, space, region, body_part, system, group
body_systemBodySystem or nullnullten systems, cardiovascular through special_senses
structure_typeStructureType or nullnullaround forty types, set only when location_type is structure
lateralityLateralitynonlateralgeneric, left, right, nonlateral
definitionstring or nullnull
sex_specificstring or nullnull
synonymslist of stringempty
codeslist of IndexCodeemptythe same index code type finding models use
referenceslist of WebReferenceemptyeducational and documentation links
containment_pathstring or nullnullmaterialized path from the root
containment_parentAnatomicRef or nullnull
containment_depthinteger or nullnull
containment_childrenlist of AnatomicRefempty
partof_pathstring or nullnullmaterialized path in the part-of hierarchy
partof_parentAnatomicRef or nullnull
partof_depthinteger or nullnull
partof_childrenlist of AnatomicRefempty
left_variantAnatomicRef or nullnull
right_variantAnatomicRef or nullnull
generic_variantAnatomicRef or nullnull

Two computed fields are serialized with the record: is_bilateral, true when laterality is generic, and is_lateralized, true when it is left or right. LocationType is a coarse split modeled on the top level of the Foundational Model of Anatomy, separating discrete structures from spaces, regions, macro body parts, organ systems, and named groups. StructureType is the finer classification, with members grouped as musculoskeletal, vascular, peripheral neural, brain-specific, organs, lymphatic, anatomical organization, and spatial.7

The materialized paths are what make hierarchy queries cheap. Containment ancestry, descendants, and the “is X inside Y” test all read containment_path rather than walking parent links, and the part-of hierarchy works the same way through partof_path.

A location converts to an IndexCode with system set to anatomic_locations, its RadLex identifier as the code, and its description as the display. That is the form an anatomic location takes when it is attached to a finding model.

Which is current

The anatomic-locations package format is current. It is the format the OIDM tooling reads, it carries the larger and more recently curated dataset, and it adds the classification axes and explicit laterality that the original schema left implicit. The anatomiclocations.org schema remains the published format of the original curated set and of the wrapper libraries built on it, and is documented here because that data and those libraries are still reachable.

Footnotes

  1. Knowledgebase build plan, source map and work edge ↩

  2. body_parts_schema.json, anatomiclocations.org repository ↩

  3. body_parts.json, anatomiclocations.org curated body part set ↩

  4. Anatomic Locations Source JSON field reference, findingmodel repository ↩

  5. AnatomicLocation model, anatomic-locations package, findingmodel repository ↩

  6. anatomic_locations_noembed.json, the current curated anatomic location set ↩

  7. Anatomic location enumerations, anatomic-locations package, findingmodel repository ↩