## Reading material draft ### 1. Differences between the mapping facilities in FHIR FHIR has, over time, acquired different mapping-related features to deal with various use-cases: * [ConceptMap](https://www.hl7.org/fhir/conceptmap.html): a standalone resource * `mapping` field in [every element](https://www.hl7.org/fhir/elementdefinition-definitions.html#ElementDefinition.mapping): {{render:ProfilingAcademy/mapping-element-png}} * [FHIR Mapping language](http://hl7.org/fhir/mapping-language.html): computer programming language * [StructureMap](https://www.hl7.org/fhir/structuremap.html): a standalone resource Here's a rough breakdown of them:
Concept Use this to create
ConceptMap mappings between codes in different ValueSets
mapping field in every element traceability from FHIR elements to other standards
FHIR Mapping language transformations from one data format to another
StructureMap FHIR Mapping language transformations in resource form
### 1.1 ConceptMap The [ConceptMap](https://www.hl7.org/fhir/conceptmap.html) resource defines a mapping from a set of codes (concepts) defined in a ValueSet to one or more codes defined in other ValueSets. For example, say you want to create a mapping of LOINC® codes to their equivalent SNOMED® codes - you'd use a ConceptMap for this. You could then publish your ConceptMap in an Implementation Guide (IG), use it for machine translation or codes, or include it in your FHIR mapping language transformation - see 1.2 below. ### 1.2 Mapping field in every element You might notice this field in Forge: {{render:ProfilingAcademy/mapping-element-png}} This comes from [ElementDefinition.mapping](https://www.hl7.org/fhir/elementdefinition-definitions.html#ElementDefinition.mapping), which is a free-text field that you use to create traceability to other standards within your FHIR profiles. For example, when you're mapping a national standard for prescriptions to FHIR, you'd mention the equivalent element(s) from the national standard in your `mapping` field. This field is thus not related to the ConceptMap resource. ### 1.3 FHIR Mapping language Data mapping is the process of defining how data from one data model maps to another data model, and the FHIR Mapping language is a transformation language to address that need (e.g. the conversion of HL7 version 2 or CDA to FHIR). Different technologies already exist to transform data from one data model to another - such as 3GL, XSLT - but given FHIR's unique position (open standard with XML and JSON support), none of the existing technology satisfied the requirements. To use the FHIR mapping language, you need at minimum to create a transformation map which will instruct the mapping engine on how to convert the elements in an instance of data from one model to another. That transformation map can make use of embedded ConceptMaps to transform codes within the data elements from one code to another. The FHIR mapping language is not related to the `mapping` field that's present in the profiles, as that is a free-text field you can use to provide traceability in your profiles. ### 1.4 StructureMap A FHIR Mapping language transformation map can exist in two forms - as a declarative program ("concrete syntax") or as a [StructureMap](https://www.hl7.org/fhir/structuremap.html) resource ("abstract syntax"). The StructureMap resource is thus just a resource form representation of a FHIR Mapping language transformation map. ## 2. Overview of the mapping facilities in FHIR ### 2.1 ConceptMap You can use the [ConceptMap](https://www.hl7.org/fhir/conceptmap.html) resource to define mappings between codes from different ValueSets. Use the `source` element to define the source of the concepts that you want to map. The `target` element provides the target you want to map the concepts to. The `group` element contains a list of concepts and the target concept(s) these should be mapped to. Below is an example from the mapping of the concept 'home' between HL7 version 3 and FHIR. In HL7 version 3 the code of this concept is 'H', while in FHIR the code of this concept is 'home'. In the XML code below you can see that the source concept 'home' is mapped to the target concept 'H' (both having the same display value). ``` ``` ### 2.2 Mapping field in every element The `ElementDefinition.mapping` element allows you to define a free text mapping for this element within your profile. This mapping is however harder to use when reusing profiles. The `mapping.identity` element refers to the mapping system that is used (the mapping systems should also be defined at a higher level in the `StructureDefinition.mapping` element). The `mapping.map` element defines the value that is mapped to the parent element. For example, the code below shows a mapping from the field `PasientID` to the element `Procedure.subject`. ``` ... ``` The Procedure profile contains a definition of the mapping system in the `mapping` element. The identity of the mapping system in this example is helsevest. ``` ``` In the core specification you find mappings from HL7 v3 RIM, LOINC, CDA and HL7 v2 to core FHIR resources (go to the `Mappings` tab of a resource, e.g. https://hl7.org/fhir/patient-mappings.html). ### 2.3 FHIR Mapping language The FHIR mapping language is purely declarative - this means that instead of giving concrete instructions on how to process data, you instead describe how the processed data should look like, and the engine figures out how to transform it. The FHIR mapping language addresses two very different kinds of transformations: * Structural changes between the source and target structures (skeletal mapping). This covers renaming data elements, merging elements, or creating new ones. * Differences in content and formats in string (and related) primitives contained within the structures (conceptual mapping). This covers data within the elements: trimming text, capitalizing text, and so on. FHIR Mapping language transformation maps are also uni-directional: they map from the source structure to the target structure, and no reverse map is implied. Even if the reserve mapping is simple, and happens to run losslessly, it cannot be assumed that it is correct - there might be conditions on the reverse transformation would not have been applied. #### 2.3.1 FHIR Mapping Language transformation maps The FHIR mapping language can be applied to any content that is a directed acyclic graph with metadata (DAG-M). A directed acyclic graph (DAG) is a graph that flows in one direction and no element can be a child of itself (there are no cycles). A DAG-M is a DAG with metadata (for example each element has a name, type and cardinality). The FHIR mapping language describes how one (set of) DAG-M(s) (an instance) are transformed to another (set of) DAG-M(s). The instances can be strongly typed (specifically when they have formal definitions represented as StructureDefinitions), but this is not required. A Map has 6 parts: * Metadata * Embedded ConceptMaps to translate between different code systems (optional) * References to the structures involved in the mapping (optional) * Imports: additional Maps used by this map (optional) * A series of groups, each with a list of input variables * A series of transformation rules in each group ### 4.2 Metadata The first part of the map contains a unique canonical URL to identify the map and a human readable name of the map. The syntax is as follows: ``` map "[url]" = "[name]" ``` Here below is an example of a map named exampleMap: ``` map "https://hl7.org/fhir/StructureMap/exampleMap" = exampleMap ``` #### 2.3.2 Embedded ConceptMaps You can (optionally) define a ConceptMap and embed it in your code. Note the differences with importing existing Maps as explained in paragraph 3.4 The syntax is as follows: ``` conceptmap "[name]" { prefix [x] = "[url]" prefix [y] = "[url]" x:[sourcevalue] = y:[targetvalue] x:[sourcevalue] = y:[targetvalue] } ``` For example, let's define a ConceptMap called myConceptMap that maps FHIR codes for address use to HL7 version 3 codes for address use. In this example, the FHIR value 'home' is begin mapped to the HL7 version 3 value 'H'. ``` conceptmap myConceptMap { prefix s = "http://hl7.org/fhir/ValueSet/address-use" prefix t = "http://hl7.org/fhir/ValueSet/v3-AddressUse" s:home = t:H } ``` #### 2.3.3 References to structures The next (optional) part of the map is a list of one or more StructureDefinitions that are used in the map and the way in which they are used (either as a source, target, queried or produced). The syntax is as follows: ``` uses "[url]" (alias name) as [mode] ``` For example, if you would like to list your own Patient profile (which you called myPatient) as a source and another Patient profile (suppose this one is called otherPatient) as a target, the required code would be as follows: ``` uses "https://hl7.org/fhir/StructureDefinition/myPatient" as source uses "https://hl7.org/fhir/StructureDefinition/otherPatient" as target ``` You may choose to add an alias as well for these StructureDefinitions, so you can use these in the code later on, but it is not mandatory to do so. #### 2.3.4 Import maps The next (optional) part of the map is a list of additional maps that are used in this map. The syntax is as follows: ``` imports "[url]" ``` Below is an example of the import of a StructureMap called mapA and a ConceptMap called mapB. ``` imports "https://hl7.org/fhir/StructureMap/mapA" imports "https://hl7.org/fhir/ConceptMap/mapB" ``` #### 2.3.5 Groups Each map should have at least one group of transform rules. A group is a set of related rules that share the same input and output variables defining exactly which instances are passed to mapping and by which name. The syntax is as follows: ``` group (for type) [group-name] (extends [other-group]) input [name] : [type] as [mode] //rules go here endgroup ``` For example, we can define a group called exampleGroup with input variable A and output variable B. We will show an example of how to define the rules in the next section. ``` group exampleGroup input "source" : A as source input "target" : B as target //rules go here endgroup ``` The `for type` indicates if an instance should be mapped to a specified target data type. #### 2.3.6 Transform rules Transform rules describe how source content is transformed into target content. Each rule has four main sections: * *Name* - The identity of the rule (for example for logging/debugging) * *Source Content* - One or more elements from the source that contribute to the mapping * *Target Transform* - One or more specifications of the content to create in the target model * *Dependent Rules* - Specifies which (if any) rules or groups to apply within the scope of the rule The syntax for defining transform rules is as follows: ``` name_of_rule: for src_context.field as new_variable where condition make tgt_context.field as new_variable = create([type]) then [details] ``` For example, let's say you want to keep identifier the same and copy its value from source to target without transformation. The syntax would be as follows: ``` "rule_1_copy_identifier" : for source.identifier as a make target.identifier = a ``` Let's say for maritalStatus, you have added the following category in myPatient: O = Other, but the otherPatient profile does not allow for other categories than the ones defined in the marital-status ValueSet. You need to map your category to one of the categories from the marital-status ValueSet. Although there is no mapping available that has the exact same meaning, you choose to map this category to the category UNK = Unknown. The syntax would be as follows: ``` "rule_2_transform_gender" : for source.maritalstatus as m where m="O" make target.maritalStatus = "UNK" ``` Your group is now composed of one rule that copies the value of identifier and one rule that transforms the value of maritalStatus: ``` group exampleGroup input "source" : A as source input "target" : B as target "rule_1_copy_identifier" : for source.identifier as a make target.identifier = a "rule_2_transform_gender" : for source.maritalstatus as m where m="O" make target.maritalStatus = "UNK" endgroup ``` #### 2.3.7 Learn more To learn more about the FHIR Mapping Language, have a look at the [following tutorial](https://www.hl7.org/fhir/mapping-tutorial.html). ### 2.4 StructureMap The [StructureMap](https://www.hl7.org/fhir/structuremap.html) is a Resource presentation of the FHIR mapping language. Use the `group.rule` element to define (groups of) mapping rules. Below is an example of a mapping rule where the value of the source is copied to the target destination. ``` ```