### Reading material draft (revised, VP3)
## Reading material draft
### 1. Data transformation and mapping
There are many cases in which you will need to transform data from one data model to another (e.g. the conversion of HL7 version 2 or CDA to FHIR). Data mapping is the process of defining how data from one data model maps to another data model. Different technologies exist to transform data from one data model to another (such as 3GL, XSLT and the FHIR mapping language).
#### 1.1 Mapping criteria
There's a couple of criteria that are important to take into account when creating your mapping solution and choosing which technology to use:
* Clarity/traceability - The ability to trace back the initial requirements, to keep your solution maintenable and people who use it understand what you're doing
* Expressiveness - The ability to express the transformation you need to make, the actual transformations, cardinality and structure
* Performance - The performance of your solution (e.g. amount of messages a second, capacity)
* Portability - The ability to reuse your solution in a different setting (run it somewhere else)
* Comfort/experience - The ease of use of your solution
#### 1.2 Mapping levels
There are different levels of mapping:
* Skeletal - Mapping of the structure of data models
* Notional - Mapping at the class/attribute level (data types may not match)
* Conceptual - Mapping of primititive data types
* Executional - Mapping for the full value domain, handling of all special cases and full description of construction issues
#### 1.3 Procedural versus declarative transformation
In a procedural transformation a method is followed to get the right output. A procedural mapping describes a set of methods with their conditions. In a declarative transformation a standard method is applied to get the right output. A declarative mapping describes precise relationships between data models and their conditions. Relationships are inspected to derive additional meaning.
### 2. Mapping in FHIR
The FHIR Specification version STU3 includes a [mapping language](https://www.hl7.org/fhir/mapping-language.html) to describe how one set of instances is transformed to another set of instances. FHIR has two resources that define two different types of maps: the [StructureMap](https://www.hl7.org/fhir/structuremap.html) and the [ConceptMap](https://www.hl7.org/fhir/conceptmap.html).
Maps are uni-directional: they map from the source structure to the target structure, and no reverse map is implied. Even if the mapping is simple, and loss-less, it cannot be assumed that there are no conditions that might additionally apply in the reverse direction.
Finally, it is also possible to provide a free-text mapping for elements at the Profile level, but this is harder to use when reusing profiles.
#### 2.1 The FHIR Mapping Language
The FHIR mapping language is purely declarative. The FHIR mapping language addresses two very different kinds of transformations:
* Structural changes between the source and target structures (skeletal mapping)
* Differences in content and formats in string (and related) primitives contained within the structures (conceptual mapping)
#### 2.2 StructureMap
The [StructureMap](https://www.hl7.org/fhir/structuremap.html) resource. This resource defines a detailed set of rules that describe how one Structure is related to another, and provides sufficient detail to allow for automated conversion of instances. The intention of the structure map resource is to allow a specialist in formats and interoperability to specify the full relationships between two structures (e.g. a CDA document and a set of FHIR resources), and then many different systems - both testing and production clinical systems - can leverage that to automatically transform from one format to the other.
#### 2.3 ConceptMap
The [ConceptMap](https://www.hl7.org/fhir/conceptmap.html) resource. A concept map defines a mapping from a set of concepts defined in a code system to one or more concepts defined in other code systems. Mappings between code systems are only defined in the context of the specified source and destination value sets - they are specific to a particular context of use. The mappings may be useful in other contexts, but this must be determined based on the context of use and meaning; it cannot be taken for granted automatically. Note that all code systems have value sets that include the entire code system, and these value sets can be used for mappings that are valid in all contexts.
#### 2.4 Mapping at Profile level
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. Scroll all the way down to inspect the `mapping` element.
{{render:CoreProfilesSTU3/ElementDefinition}}
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).
### 3. Using the FHIR Mapping Language
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
#### 3.1 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
```
#### 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:[sourcename] = y:[targetname]
x:[sourcename] = y:[targetname]
}
```
For example, let's define a ConceptMap called myConceptMap that maps v3 codes for address use to FHIR codes for address use.
```
conceptmap myConceptMap {
prefix s = "http://hl7.org/fhir/ValueSet/address-use"
prefix t = "http://hl7.org/fhir/ValueSet/v3-AddressUse"
s:.. = t:...
s:.. = t:...
}
```
#### 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.
#### 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"
```
#### 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.
#### 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
```
#### 3.7 Learn more
If you want to learn more about the FHIR Mapping Language you can use the following link to open a short tutorial into the FHIR mapping language: https://www.hl7.org/fhir/mapping-tutorial.html