Aligning the FAIR data principles and HL7 FHIR profiling

Tutorial for SWAT4HCLS 2024 conference in Leiden.

View the Project on GitHub IMISE/fhir4fair-swat4hcls2024

Walk through

This walk-through is intended for interested parties who have not yet worked intensively with FSH.

0. Dry run

On the left-hand side you can see the editor for FSH, on the right-hand side the editor for FHIR-JSON. You can edit in both and then transfer the changes to the other side using “Convert to”.

FSH Online provides useful templates.

That’s how it works basically. A new tab has appeared on the right-hand side; several FHIR resources can be created from one FSH file.

You can now validate the example to be sure.

There should be no errors, only some warnings.

1. Creating an empty study

Instance: firetrial
InstanceOf: ResearchStudy
Description: "Example of a research study"
Usage: #example

It generates some JSON code, but there is obviously a mistake.

error Element ResearchStudy.status has minimum cardinality 1 but occurs 0 time(s). Line: 1 - 4

The ResearchStudy has a mandatory field called status in FHIR and this is missing.

2. Adding study status (code from a controlled vocabulary)

If we look at the specification of ResearchStudy in FHIR R4, we see that the cardinality of status is 1..1.

We need to specify a value for status. The data type is code, i.e. it is a value from a predefined set. FHIR distinguishes between different degrees of strictness as to whether the value must actually be taken from the given values. This is the case with (Required). You can find out what the individual codes mean by clicking on ResearchStudyStatus.

* status = #in-review

All other elements are optional in the generic resource. Now no more errors are returned and the validation would also work.

3. Adding the study title (string)

The title of the study is a simple string.

* title = "FAIRness in FHIR"

4. Adding a description (markdown)

The description of a study is of type markdown and is assigned in the same way, except that the receiving system must be able to handle markdown syntax.

* description = "A study assessing the **FAIRness** of FHIR artifacts."

5. Adding a note (Annotation)

* note = "Study design is still unclear."

Although it was about text again, it didn’t work this time.

The data type of note is Annotation and this is not a primitive data type. An annotation can have an author and a creation date. We now want to dispense with this and only use the text element.

* note.text = "Study design is still unclear."

No problem while converting.

6. Adding the start and end date/time of a study (Period)

Adding dates is very similar to strings, except that a predefined format must be adhered to. A FHIR Period has an optional start and end of type datetime.

Therefore, not only dates are possible. Our example study starts today in the morning and ends in December.

* period.start = "2024-02-26T09:00:00+01:00"
* period.end = "2024-12"

7. Adding the study id (Identifier)

An important criterion for findability in FAIR is a persistent identifier. Interventional clinical trials must be prospectively registered in a trial registry from which they receive an identifier. For example, we register our study in the international ClinicalTrials.gov register and receive the CT.gov number NCT05487991.

The fact that this is a universal business identifier is made clear with additional information.

* identifier[0].use = #official
* identifier[=].system = "https://clinicaltrials.gov"
* identifier[=].value = "NCT05487991"

8. Adding contacts (multiple values)

Next, we would like to specify two people from the study’s environment who serve as medical and organizational contacts. The element contact must be specified multiple times for this. This is very easy to do with FSH. The first instance is given an index [0]. Further instances would then receive [1] and so on.

However, because it is often necessary to change the order later (and therefore all indices), FSH uses [=] for a further entry for the current contact and [+] for the next contact.

ResearchStudy.contact is of type ContactDetailwhich itself is composed of other data types. The deeper hierarchies are separated by a dot.

* contact[0].name = "Dr. Franziska Jauch"
* contact[=].telecom.system = #email
* contact[=].telecom.value = "fjauch@uniklinikum-ulm.de"
* contact[=].telecom.use = #work
* contact[+].name = "Wiktor Silberk"
* contact[=].telecom.system = #phone
* contact[=].telecom.value = "+49 1715 8264023"
* contact[=].telecom.use = #mobile

9. Adding the condition to be studied (Codeable Concept)

The title of a study can contain important information about what the study is about. However, medical terminology is diverse and language-dependent. For clarity and machine processability, it is better to use a community-consensus vocabulary. In the field of medicine, SNOMED CT is a good international candidate.

FHIR has three basic ways of encoding elements. We have already seen FHIR code. Here there is only the actual code, because the set from which it can be selected is implicitly fixed. FHIR Coding, on the other hand, is like a code + a system from which the code comes. A FHIR CodeableConcept can do even more: here we can even use several annotations from Code+System.

This allows the FAIR requirement for multiple relevant metadata to be met, as other systems such as ICD-10 are often used in local systems, e.g. for diagnoses in hospitals. To ensure that there is no mixture and that the study is ultimately difficult to find, we specify both values.

* condition.text = "Cholera"
* condition.coding[0] = $icd-10#A00.0
* condition.coding[=].version = "2024"
* condition.coding[+] = $sct#240349003
* condition.coding[=].version = "http://snomed.info/sct/900000000000207008/version/20230731"

What you can also see here is the version of the referenced vocabulary. As the state of knowledge about diseases changes and new ones are added (Covid-19), this is good practice.

In addition, we use the alias feature of FSH, a definition of a constant as an abbreviation for long URIs that are used several times. Aliases are placed at the beginning of the document.

Alias: $icd-10 = http://hl7.org/fhir/sid/icd-10
Alias: $sct = http://snomed.info/sct

10. Adding sponsor and PI (Reference to another named resource)

Finally, we want to add references to other FHIR resources. FHIR ResearchStudy sponsor refers to a FHIR Organization and principalInvestigator refers to a Practitioner or a PractitionerRole. Both are independent entities like ResearchStudy itself. Both can be references by other instance as well. However, they should only be created once.

In the case of principalInvestigator, you can see another peculiarity of FHIR: for some elements, several resource types are possible as values; the data modeler selects the most suitable one.

Referencing another FHIR resource instance is easy.

* sponsor = Reference(firetrial-sponsor)
* principalInvestigator = Reference(firetrial-pi)

We can also create the target resources in the same file.

Instance: firetrial-sponsor
InstanceOf: Organization
Usage: #example
* name = "Ulm University Hospital"

Instance: firetrial-pi
InstanceOf: Practitioner
Usage: #example
* name.text = "Prof. Dr. T. Ester"

FSH Online now generates three individual files, see on the far right.

Using the FHIR4FAIR Implementation Guide ResearchStudy-uv-f4f (Profile)

So far, only standard R4 resources have been used. Now a profile from the FHIR4FAIR Implementation Guide is to be used. ResearchStudy-uv-f4f is, as the name suggests, a profile from ResearchStudy. As already mentioned, profiles are, colloquially speaking, on the one hand, restrictions of values in order to obtain a certain data structure of higher quality and, on the other hand, extensions to map additional data.

First, it is declared that the instance created here should conform to the profile. This is evaluated during validation.

* meta.profile = "http://hl7.org/fhir/uv/fhir-for-fair/StructureDefinition/ResearchStudy-uv-f4f"

Meta.profile is a structure that is not defined in ResearchStudy itself, but which the Meta element inherits from its super-super-class Resource.

A license is now to be added to the study. Licenses are one of the requirements of FAIR (R1.1). While a standard R4 ResearchStudy does not have the option of referring to a license, this has been implemented in the FHIR4FAIR IG as an extension licenseCodeable.

* extension[0].url = "http://hl7.org/fhir/uv/fhir-for-fair/StructureDefinition/licenceCodeable"
* extension[=].valueCodeableConcept = http://hl7.org/fhir/spdx-license#MIT "MIT License"

Now our study is under the MIT license (whatever that means).

Download the complete example as FSH or a JSON.

Exercises

Fine-tuning and tidying up

If we now want to validate our design, we have to give the validator a hint that this is now a FHIR4FAIR study. Although it already knows this from the information in meta.profile, it naturally lacks an idea of what the profile schema should look like.

When we validate our current draft with , no errors occur, but there are some strange warnings.

No validation error issues found

Validation warnings:

  1. ResearchStudy: Constraint failed: dom-6: ‘A resource should have narrative for robust management’ (defined in http://hl7.org/fhir/StructureDefinition/DomainResource) (Best Practice Recommendation) on line 1. Jump to error.
  2. ResearchStudy.status: ValueSet http://hl7.org/fhir/ValueSet/research-study-status 4.3.0 not found on line 9. Jump to error.

Validation information:

  1. ResearchStudy.identifier[0]: This element does not match any known slice defined in the profile http://hl7.org/fhir/uv/fhir-for-fair/StructureDefinition/ResearchStudy-uv-f4f 1.0.0 (this may not be a problem, but you should check that it’s not intended to match a slice) on line 22. Jump to error.
  2. ResearchStudy.condition[0]: Reference to experimental CodeSystem http://hl7.org/fhir/sid/icd-10 2019-covid-expanded on line 51. Jump to error.
  3. ResearchStudy.extension[0].value.ofType(CodeableConcept): Reference to draft CodeSystem http://hl7.org/fhir/spdx-license 84728b7 on line 76. Jump to error.
Solution to 1. The reason for the warning is that it is a Best Practice Recommendation to have an human-readable narrative in [DomainResource.text](https://hl7.org/fhir/R4/domainresource-definitions.html#DomainResource.text). DomainResource is the superclass of ResearchStudy, so the text element is inherited. ``` * text.status = #additional * text.div = "<div xmlns=\"http://www.w3.org/1999/xhtml\">[Epic information omitted for reasons of simplicity.]</div>" ```