.. _tut_inlineterminology: Inline terminology ================== .. note:: A whole tutorial referenced here is available in the following Postman collection: https://documenter.getpostman.com/view/1515623/2sBXcLex64 .. note:: If running against a public sandbox.open-fhir.com, don't forget to include Authorization header of type Basic. An important aspect to successful mappings between FHIR and openEHR is a service able to translate codings, enums, terminologies from one to the other. In this specific example, within the openEHR template, ``growth_chart/body_weight/any_event:0/state_of_dress`` is coded in the archetype's ``local`` terminology with values such as ``at0013`` (Naked), ``at0011`` (Lightly clothed/underwear) or ``at0010`` (Fully clothed, including shoes) — something unknown to FHIR. The HL7 `Vital Signs with Qualifying Elements `_ IG models the state of dress on a body weight Observation as the **AssociatedSituation extension** (``http://hl7.org/fhir/us/vitals/StructureDefinition/AssociatedSituationExt``) whose ``valueCodeableConcept`` comes from the Body Weight Associated Situation value set — SNOMED CT ``248160001`` (Undressed) and Solor temporary codes for street clothes with/without shoes. This is why you need a terminology mapping from one coding to the other. A simple terminology mapping is to provide the mapping inline, within a specific model.yaml. Adding mapping of this data point (no terminology yet) ------------------------------------------------------ Mapping of the ``state_of_dress`` data point wasn't included in the original mappings. Let's add it, following a similar approach as in the previous step when we added Observation.note.text — but first without any terminology mapping, to see why one is needed. Get an ID and trigger a PUT of the body weight mapper. You need to add the following mapping within mappings: :: - name: "state of dress" with: fhir: "$resource.extension" openehr: "$archetype/data[at0002]/events[at0003]/state[at0008]" fhirCondition: targetRoot: "$resource.extension" targetAttribute: "url" operator: "one of" criteria: "http://hl7.org/fhir/us/vitals/StructureDefinition/AssociatedSituationExt" followedBy: mappings: - name: "value" with: fhir: "value" openehr: "items[at0009]" - name: "url" with: fhir: "$fhirRoot" openehr: "$archetype" manual: - name: "url" fhir: - path: "url" value: "http://hl7.org/fhir/us/vitals/StructureDefinition/AssociatedSituationExt" This will add value from ``growth_chart/body_weight/any_event/state_of_dress`` (``data[at0002]/events[at0003]/state[at0008]/items[at0009]``) to the IG's AssociatedSituation extension on the body weight Observation, and vice-versa. If you now run ``$tofhir`` with the same flat composition as before, you'll see the openEHR local code leak into FHIR untranslated — structurally valid, but not a code from the IG's value set (a profile validator flags exactly this): :: "extension": [ { "url": "http://hl7.org/fhir/us/vitals/StructureDefinition/AssociatedSituationExt", "valueCodeableConcept": { "coding": [ { "system": "local", "code": "at0013", "display": "Naked" } ], "text": "Naked" } } ] Adding the inline terminology ----------------------------- To fix that, extend the ``state of dress`` mapping with an inline terminology that translates between the archetype's local code and SNOMED CT ``248160001`` (Undressed) from the IG's Body Weight Associated Situation value set: :: - name: "state of dress" with: fhir: "$resource.extension" openehr: "$archetype/data[at0002]/events[at0003]/state[at0008]" fhirCondition: targetRoot: "$resource.extension" targetAttribute: "url" operator: "one of" criteria: "http://hl7.org/fhir/us/vitals/StructureDefinition/AssociatedSituationExt" terminology: type: "inline" mappings: - openehr: code: "at0013" system: "local" display: "Naked" fhir: system: "http://snomed.info/sct" code: "248160001" display: "Undressed" followedBy: mappings: - name: "value" with: fhir: "value" openehr: "items[at0009]" - name: "url" with: fhir: "$fhirRoot" openehr: "$archetype" manual: - name: "url" fhir: - path: "url" value: "http://hl7.org/fhir/us/vitals/StructureDefinition/AssociatedSituationExt" With the inline terminology, anything in openEHR coded as ``at0013`` in system ``local`` will be mapped to SNOMED CT ``248160001`` (Undressed) when creating a FHIR Resource. In the other direction, an AssociatedSituation extension coded as ``http://snomed.info/sct|248160001`` will result in an openEHR code of ``at0013``. Validating behavior of the inline terminology --------------------------------------------- Use the same example of openEHR as in previous steps: .. http:post:: http://localhost:8080/$tofhir?templateId=Growth chart&patient=Patient/lina-weber .. sourcecode:: http POST http://localhost:8080/$tofhir?templateId=Growth%20chart&patient=Patient/lina-weber HTTP/1.1 Content-Type: application/fhir+json Body: :download:`growth_chart_flat.json ` Within the result, you should see the extension value translated to the SNOMED CT code: :: "extension": [ { "url": "http://hl7.org/fhir/us/vitals/StructureDefinition/AssociatedSituationExt", "valueCodeableConcept": { "coding": [ { "system": "http://snomed.info/sct", "code": "248160001", "display": "Undressed" } ], "text": "Naked" } } ] Going in the other direction (``$toopenehr``), a Bundle whose AssociatedSituation extensions are coded with SNOMED CT ``248160001`` results in a properly openEHR-coded ``at0013`` in the resulting Composition: :: "growth_chart/body_weight/any_event:0/state_of_dress|code": "at0013", "growth_chart/body_weight/any_event:0/state_of_dress|terminology": "local",