# Reading Material
Terminology is about the codes you can record in your data - say a doctor picking a code for cough, or setting the status of a prescription to active.
## 1. The terminology module
There are [a few resources](http://hl7.org/fhir/STU3/terminology-module.html "Terminology module") in FHIR that cover (or are related to) terminology: CodeSystem, ValueSet, coded data types, ElementDefinition, NamingSystem, ConceptMap and ExpansionProfile.
A couple of these resources and their relations are shown in the image below. The next sections will explain them in more detail.
{{render:TerminologyModule-png-2}}
A concept map
### 1.1 CodeSystem
A [CodeSystem]("https://www.hl7.org/fhir/codesystem.html") defines a set of concepts (codes) with a coherent meaning, for example [condition-clinical](https://simplifier.net/CoreCodeSystemsSTU3/condition-clinical) is a CodeSystem in the core specification for setting the clinical status of a condition.
### 1.2 ValueSet
A [ValueSet]("https://www.hl7.org/fhir/valueset.html") is a selection of codes for use in a particular context. The relation of a ValueSet to a CodeSystem is that it selects (codes from) one or more CodeSystems. The actual codes belong to the CodeSystem, while the ValueSet is composed by linking to these codes in the CodeSystem. For example, the ValueSet [condition-clinical](https://simplifier.net/core-vs-stu3/condition-clinical) includes all codes defined in the CodeSystem [condition-clinical](https://simplifier.net/CoreCodeSystemsSTU3/condition-clinical).
When the codes in the CodeSystem are updated, the ValueSet automatically contains the updated codes. The lockedDate element can be used to "freeze" the codes to a particular version of the CodeSystem.
You can also link to another ValueSet to include all codes from this ValueSet.
To compose your ValueSet, use the ``compose`` element. With the ``include`` element you can add concepts or codes from one or more CodeSystems and/or other ValueSets. You can either:
* List the codes you want to use by using the ``concept.code`` element
* Use the ``filter`` element to select a group of codes *or*
* Use the ``ValueSet`` element to refer to a ValueSet that contains a list of codes you want to include
Note that it is not possible to use both the ``concept`` and ``filter`` elements, you have to select either one of them to add codes from a CodeSystem.
You can also explicitly state that particular codes from a code system or other ValueSets should be excluded by using the ``exclude`` element.
Below are examples of the use of the ``concept`` and ``filter`` elements. In the first example, two ICD-10 codes for breast cancer are included.
**Example 1**
```xml
```
The second example is an example of a ValueSet that includes all codes from the Loinc CodeSystem where the parent property equals ``LP43571-6``.
**Example 2**
```xml
```
Besides the ``compose`` element, which is used to create the ValueSet, you may notice that there is also an element called ``expansion``. This element is used in the response of a FHIR Terminology Server when a user wants to retrieve all codes from a ValueSet by using the ``$expand`` operation.
This is also known as ValueSet expansion or ValueSet enumeration. The ``$expand`` operation is commonly used together with the ``filter`` operation to reduce the number of codes returned in an expansion. Note that this results in a reduced view of the ValueSet, not a change in the ValueSet itself
### 1.3 Coded data type
Codes in CodeSystems can have one of the following data types:
* [Code]("https://www.hl7.org/fhir/datatypes.html#code") - bound to a fixed list of codes, for example gender (male - female - other - unknown)
* [Coding]("https://www.hl7.org/fhir/datatypes.html#coding") - contains elements to capture the system, its version, the value of the code itself and a textual representation
* [CodeableConcept]("https://www.hl7.org/fhir/datatypes.html#codeableconcept") - contains one or more Codings and an optional textual representation
When you are profiling and you need to choose one of these data types, the best and safest choice will usually be the CodeableConcept. As the CodeableConcept can have one or more Codings, the profile will be more reusable this way. The use of Codings is more limited and primarily used in extensions when there's need for finer control over use of translations and text.
The relation of coded data types to the other resources in the terminology module is that they refer to a CodeSystem and conform to an ElementDefinition.
### 1.4 ElementDefinition
An [ElementDefinition]("https://www.hl7.org/fhir/elementdefinition.html") defines an element in a resource or extension. For example, the Patient resource has an element called `name`, which is the name of the patient. The ElementDefinition of `name` defines the properties of the `name` element, for example it defines that its data type is HumanName and its cardinality is 0..*. Within the terminology module, the ElementDefinition defines the (coded) data type and the ValueSet containing the codes that you can select in this element. The ElementDefinition binds a ValueSet. The binding strength is defined in the ElementDefinition as well. We will explain this in more detail in the next chapter.
For example, let's take a look at the ElementDefinition of the ``clinicalStatus`` element.
{{tree:CoreProfilesSTU3/Condition}}
The type of this element is a code and it binds the ValueSet [condition-clinical](https://simplifier.net/core-vs-stu3/condition-clinical). Below you see part of the XML code of the ElementDefinition.
**Condition.clinicalStatus element**
```xml
```
**ValueSet binding**
```xml
```
### 1.5 NamingSystem
A [NamingSystem](https://www.hl7.org/fhir/namingsystem.html) is used for the unique identification of concepts, people, devices etc. A NamingSystem can either be used to define an identifier system (e.g. a patient number) or a code system (e.g. UCUM or LOINC). The `kind` element defines the way in which the NamingSystem is used (identifier, codesystem or root). Root means that the NamingSystem is used as the root for other naming systems. Below we’ll explain the difference between the use of the NamingSystem for identifiers and its use for CodeSystems.
#### 1.5.1 NamingSystem for identifier
The most common use of the NamingSystem is to manage identifiers. For example, if you wanted to describe the Dutch BSN number (i.e. the Dutch security number) which used to uniquely identify Dutch citizens as a FHIR resource - you'd create a NamingSystem. This resource would have a description of what the BSN does, who manages it, and most importantly, it would also declare the identifier that can be used to refer to it in FHIR resources.
{{render: NictizSTU3/unnamednamingsystem2}}
#### 1.5.2 NamingSystem for CodeSystem
It is also possible to use the NamingSystem resource to define the existence of an external CodeSystem that you don’t have control over. In this case, you can use the NamingSystem to describe the CodeSystem’s use, its owner and create an identifier for it. If you are the owner of the CodeSystem resource you would of course use the CodeSystem resource itself to define it. Below is an example of the use of the NamingSystem to define a CodeSystem.
**Example**
```xml
```
### 1.6 ConceptMap
A [ConceptMap](https://build.fhir.org/conceptmap.html) defines a mapping from a set of concepts defined in a CodeSystem to one or more concepts defined in other CodeSystems. The ``source`` element refers to the original ValueSet and the ``target`` element to the destination ValueSet. The actual mappings are defined in the ``group`` element, where ``group.element.code`` is the original value from the source and ``group.element.target.code`` is the new value in the target destination.
**Example**
```xml
```
In this example, the ``home`` code in from the address-use ValueSet from HL7 FHIR version DSTU2 is mapped to ``H`` in the AddressUse ValueSet from version HL7 FHIR version STU3.
### 1.7 ExpansionProfile
An [ExpansionProfile](https://www.hl7.org/fhir/expansionprofile.html) is used to configure the behaviour of a terminology server when it processes ValueSet resources. It's not necessary to understand all its details at this point, but it's good to know that they are used for the ValueSet ``expansion`` and ``validation`` operations.
## 2. Profiling terminology
ValueSet and CodeSystem are the two most important resources covering terminology that you will be working with. To learn more about them, head over to the excellent [FHIR Drills ValueSet and CodeSystem page](https://fhir-drills.github.io/ValueSet-And-CodeSystem.html) that describes them in detail.
Read on to learn how can you profile terminology, starting with changing the binding strength.
The very first thing that you need to know is: the strength of the binding that a field has to a ValueSet. There can be four, described in detail [here](http://hl7.org/fhir/STU3/terminologies.html#strength) and summarised below:
|Binding strength|Meaning|How you can profile this|
|-
|Required|You can only select codes from this valueset and none other|You can remove codes from the valueset but you cannot add any new codes|
|Extensible|You must select codes from this valueset, but you can use other codes if the valueset doesn't have a matching code|You can add and removes codes from the valueset, but don't duplicate or replace existing ones|
|Preferred|You should select codes from the valueset, but it's not strictly necessary|You don't have to use these codes, but it's recommended that you do|
|Example|This is just an example of codes you could use|You should set this to a ValueSet of your own, or at least strengthen the binding (raise it)|
### 2.1 Changing the binding strength
The easiest type of profiling you could do with terminology, besides fixing an element to be a specific code, is to change the binding strength. Similar to how you can only constrain and not relax the cardinality of an element (make it tighter), you can only constrain the binding of of a valueset - that is, make it stricter. You can do this in [Forge](https://simplifier.net/forge/download "Download Forge") by selecting an element with a coded data type (e.g. ``Patient.maritalStatus``) and changing the strength field.
{{render:ValueSetBinding.gif}}
### 2.2 Changing the codes of the valueset
In some cases you may want to add or remove codes from an existing ValueSet. However, you can't actually edit someone else's ValueSet. In this case you will need to create your own ValueSet and define which codes you want to include. Note that you can only add codes if the binding strength is not required.
For example, let's say you want to constrain ``Patient.gender``, which currently has a required binding to ``AdministrativeGender``. For example, you want to constrain the "unknown" code out from this required ValueSet. This ValueSet is managed by HL7, so you will need to create your own ValueSet which includes all of the codes except the ones you'd like to exclude. Once you've got your ValueSet, change the ValueSet reference in the binding.
{{render:ValueSetReference.gif}}
### 2.3 Binding to multiple valuesets
A common usecase that comes up is binding a file to multiple valuesets. You can't do that directly in FHIR, but here are two solutions:
1. Create a union valueset (using [ValueSet.compose.include.valueSet](http://hl7.org/fhir/STU3/valueset-definitions.html#ValueSet.compose.include.valueSet)) that includes all the ValueSets you'd like to bind to and then bind to that. This does, however, enable users to pick from any of the codes presented.
2. If you'd like to limit codes to a particular context, you can create derived profiles that set the binding to the specific ValueSet that is appropriate for that context.