|
14 min de lecture
|

Introduction à la terminologie FHIR : les notions de base

Résumer cet article avec :
ChatGPTPerplexityClaudeGrok

Ceci est le deuxième article de la série Introduction à la terminologie FHIR. Nous passerons en revue les concepts fondamentaux qui composent le module de terminologie FHIR. Nous verrons des exemples concrets des problèmes qu'il peut résoudre, et nous donnerons un aperçu de la façon dont les différentes pièces s'emboîtent.

Cas d'utilisation

Comme nous l'avons mentionné précédemment, nous avons observé que les nouveaux venus dans FHIR sous-utilisent les solutions de terminologie. Nous croyons que cela s'explique en partie par un manque de sensibilisation aux problèmes que ces solutions peuvent résoudre ; certaines personnes associent la terminologie à des sujets comme les normes, la conformité, la réglementation. Nous pensons donc qu'un bon point de départ consiste à présenter quelques cas d'utilisation concrets facilement mis en œuvre à l'aide d'un serveur de terminologie. En fait, tous ces exemples s'exécutent en direct contre notre instance bac à sable.

Chaque onglet présente un exemple en direct, des champs de recherche et listes déroulantes jusqu'au mappage et à la traduction ; ouvrez le tiroir au bas de la boîte pour consulter les requêtes et réponses réelles1.

Contexte

Lorsqu'un médecin écrit « crise cardiaque » et qu'un autre écrit « infarctus du myocarde », ils désignent la même chose. Mais pour un système logiciel, ou tout flux de travail à grande échelle, ce ne sont que deux chaînes de caractères différentes. La capacité à partager du sens entre les parties est primordiale pour l'interopérabilité. C'est à cela que servent les terminologies en santé. L'un des premiers exemples de terminologie en santé est la Classification internationale des maladies (CIM), adoptée en 1893 pour codifier les causes de décès. Elle est antérieure aux logiciels et est toujours utilisée aujourd'hui.

Nous travaillerons avec un ensemble de construits qui relèvent de la définition d'une terminologie : taxonomies, ontologies, nomenclatures, jeux de codes, vocabulaires, classifications. À des fins pratiques, nous les appellerons terminologies et les définirons comme un ensemble de termes dotés d'un identifiant stable lisible par machine. Ils peuvent être infinis, comporter des synonymes, des propriétés, des relations, une structure, etc. Mais la caractéristique principale dont nous aurons besoin est que chaque élément possède un identifiant stable (code) et un libellé textuel (terme/affichage).

Dans le développement web « ordinaire », les implémenteurs utilisent constamment des terminologies (même si elles ne sont pas appelées ainsi). Elles sont fréquemment mises en œuvre sous forme d'énumérations ou d'une table d'éléments avec une vue d'administration CRUD (il est très courant que les énumérations constituent leurs propres codes et que les tables d'éléments utilisent l'identifiant de base de données comme identifiant). Les exemples ci-dessus auraient très bien pu être mis en œuvre selon ces modèles.

FHIR fournit un module de terminologie conçu pour résoudre ces problèmes et d'autres. Un aspect intéressant est que les mêmes abstractions permettent d'exprimer aussi bien des ontologies standard, conformes, faisant autorité et de grande envergure que des listes locales de codes courtes ressemblant à des énumérations.

Valeurs codées

De nombreuses ressources FHIR comporteront des champs dont le domaine de valeurs possibles est tiré d'une liste (une terminologie). Leurs valeurs sont des codes attribués ailleurs qui identifient un concept défini. Par exemple :

resourceType: Patient
name:
  - given: [Jane]
    family: Doe
gender: female

Notez que, dans ce cas, name est une propriété non liée : elle peut prendre n'importe quel nom de personne, tandis que gender ne peut prendre que l'une des quatre valeurs suivantes : male, female, other, unknown. Dans ce cas, female est une valeur codée.

Une valeur codée est principalement une paire composée de « system » et de « code », où system est une URL2 qui identifie le système de codes (terminologie) définissant les codes. Cette décision a des implications importantes sur la découvrabilité des valeurs codées : au lieu de trouver une chaîne de caractères dans la nature qui ressemble à un code LOINC, les valeurs codées sont accompagnées de l'identifiant de leur système de codes. Dans le cas de « gender » ci-dessus, le système est implicite (Administrative Gender, http://hl7.org/fhir/administrative-gender) ; nous verrons pourquoi sous peu.

FHIR définit 3 types de données principaux pour représenter ces codes3 : code, Coding et CodeableConcept.

  • code : L'instance représente uniquement le code. Le système est implicite.
  • Coding : Le type de données contient un code et un système qui identifie l'origine de la définition du code.
  • CodeableConcept : Un type qui représente un concept par du texte libre et/ou un ou plusieurs éléments coding.

La plupart des éléments codés dans FHIR utilisent CodeableConcept puisqu'il offre la plus grande flexibilité. Il permet plusieurs codages et autorise le texte libre pour transmettre, par exemple, ce qu'une personne a réellement saisi ou des cas où aucun code n'est disponible. Il facilite également la transition, car vous pouvez inclure d'anciens et de nouveaux codes dans la même structure (voir l'exemple d'Observation ci-dessous).

Le type de données Coding est utilisé lorsque l'intention est de référencer un code spécifique et non d'exprimer un concept de manière générale. L'utilisation de Coding est rare car il est moins flexible que CodeableConcept et ne permet ni texte libre ni traductions.

Le type de données code apparaît généralement dans des scénarios similaires aux énumérations. Typiquement, ces éléments ont une force de liaison required, c'est-à-dire que ce code doit provenir de l'ensemble de valeurs spécifié et qu'il n'est pas nécessaire de transmettre un code alternatif. Habituellement, ces éléments peuvent être impliqués dans la logique métier, comme l'aiguillage sur une valeur, la comparaison exacte, etc. Par exemple : le statut d'une ressource, le code client pourrait ignorer les ressources retired ou n'agir que sur les ressources active.

Liaison

Dans les types de données précédents, les codes sont de type string ; la façon de restreindre l'ensemble des valeurs qu'ils peuvent prendre est via les liaisons. La spécification lie l'élément à un ensemble de valeurs, ce qui signifie qu'il ne peut prendre que des valeurs de cette liste.

Les liaisons ont deux propriétés principales : valueSet et strength. valueSet définit quels codes sont valides pour cet élément. strength indique comment la liaison doit être interprétée : required, extensible, preferred, example.

Binding example
Patient spec fragment. Notice the highlighted elements, their datatypes, binding value sets and strengths

Dans l'exemple ci-dessus, Patient.gender est lié à l'ensemble de valeurs Administrative Gender, avec une force required ; par conséquent, gender ne peut être que : male, female, other, unknown. Et maritalStatus est lié à Marital Status Codes, avec une force extensible, ce qui signifie que les codes devraient provenir de cet ensemble de valeurs à moins que le code attendu ne soit pas couvert.

Exemples de valeurs codées

resourceType: Patient
name:
  - given: [Jane]
    family: Doe
gender: female # code / AdministrativeGender (implicit)
maritalStatus: # CodeableConcept
  text: Married
  coding:
    - system: http://terminology.hl7.org/CodeSystem/v3-MaritalStatus
      code: M
      display: Married
resourceType: Location
name : South Wing Neuro OR 1
status: suspended # code / LocationStatus (implicit)
operationalStatus: # Coding
  system: http://terminology.hl7.org/CodeSystem/v2-0116
  code: H
  display: Housekeeping
type: # CodeableConcept
  coding:
    - system: http://terminology.hl7.org/CodeSystem/v3-RoleCode
      code: RNEU
      display: Neuroradiology unit
form: # CodeableConcept without codings
  text: Room
resourceType: Observation
status: final # code / ObservationStatus (implicit)
code: # CodeableConcept with local and standard codings
 coding:
   - system: http://acmelabs.org
     code: 104177
     display: "Blood culture"
   - system: http://loinc.org
     code: 600-7
     display: Bacteria identified in Blood by Culture
valueCodeableConcept: # CodeableConcept
  coding:
    - system: http://snomed.info/sct
      code: 3092008
      display: Staphylococcus aureus
interpretation:
  text: Positive
  coding:
    - system: http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation
      code: POS

Ressources

Nous examinerons maintenant brièvement les ressources FHIR impliquées dans le module de terminologie. En pratique, vous les créez rarement directement. Elles sont généralement maintenues ailleurs et chargées4 dans (ou depuis) un serveur de terminologie.

Le module de terminologie définit quatre ressources de terminologie principales : CodeSystem, ValueSet, ConceptMap et NamingSystem. Nous consacrerons un article à chacune d'elles. Pour l'instant, nous donnerons un bref aperçu de CodeSystem et de ValueSet.

CodeSystem

CodeSystem est sans doute la ressource la plus importante de la terminologie FHIR. Elle sert à décrire un système de codes, ses attributs et son contenu. Dans sa forme la plus courante, elle contient une liste de concepts, chaque concept ayant son code, ses désignations et ses propriétés.

Exemples

resourceType: CodeSystem
url: http://hl7.org/fhir/administrative-gender
version: 5.0.0
content: complete
status: active
concept:
  - code: male
    display: Male
  - code: female
    display: Female
  - code: other
    display: Other
  - code: unknown
    display: Unknown
resourceType: CodeSystem
content: supplement
supplements: http://hl7.org/fhir/administrative-gender
concept:
- code: male
  designation:
  - language: es
    value: Masculino
- code: female
  designation:
  - language: es
    value: Femenino
- code: other
  designation:
  - language: es
    value: Otro
- code: unknown
  designation:
  - language: es
    value: Desconocido
resourceType: CodeSystem
url: http://www.nlm.nih.gov/research/umls/rxnorm
version: '03022026'
publisher: National Library of Medicine
content: complete
filter:
- code: concept
  operator: [is-a, generalizes, descendent-of]
  value: comma-separated list of concept codes for direct equality testing
- code: NDC
  operator: [=,in, exists]
  value: NDC code
property:
- {code: TTY, type: string}
- {code: NDC, type: string}
- {code: RXN_STRENGTH, type: string}
- {code: dose_form_of, type: code}
- {code: has_ingredient, type: code}
- {code: has_tradename, type: code}
# ...
concept:
- code: '5640'
  display: ibuprofen
  property:
  - code: TTY
    valueString: IN
  - code: has_tradename
    valueCode: '1100067'
  - code: ingredient_of
    valueCode: '1152223'
  - code: part_of
    valueCode: '821036'
  # ...
# ...
resourceType: CodeSystem
url: http://hl7.org/fhir/sid/icd-10-cm
version: '2025'
content: complete
property:
- description: Indicator [...] transactions ("billable code")
  type: integer
  code: valid
filter:
- description: Identify valid billable codes.
  value: 0 = "header" – not valid [...]
  code: valid
  operator: ["="]
valueSet: http://hl7.org/fhir/sid/icd-10-cm/vs
concept:
- code: Chapter-1
  display: Certain infectious and parasitic diseases (A00-B99)
  concept:
  - code: Section-A00-A09
    display: Intestinal infectious diseases (A00-A09)
    concept:
    - code: A00
      display: Cholera
      concept:
      - code: A00.0
        display: Cholera due to Vibrio cholerae 01, biovar cholerae
        property:
        - code: valid
          valueInteger: 1
# ...

ValueSet

Une ressource ValueSet spécifie un ensemble de codes tirés d'un ou de plusieurs systèmes de codes.

D'après notre expérience, il s'agit de l'une des ressources les plus mal comprises de la terminologie FHIR. L'une des raisons possibles est que la différence entre les systèmes de codes et les ensembles de valeurs n'est pas toujours claire pour les implémenteurs. Le fait que, dans le noyau FHIR, la plupart des ressources CodeSystem aient un ValueSet équivalent qui inclut tous leurs codes ne facilite pas les choses. Par exemple : http://hl7.org/fhir/administrative-gender et http://hl7.org/fhir/ValueSet/administrative-gender.

La distinction principale est que les systèmes de codes contiennent la définition des concepts, leur origine, tandis que les ensembles de valeurs sélectionnent des codes à partir des systèmes de codes. Ainsi, un ensemble de valeurs peut être un sous-ensemble d'un système de codes, ou même en combiner plusieurs.

Par exemple, RxNorm est une terminologie des médicaments qui inclut des concepts pour les noms de marque, les ingrédients, les formes posologiques, etc. Nous pouvons définir un ensemble de valeurs des ingrédients dans RxNorm. Les concepts inclus seraient toujours des concepts RxNorm, mais nous n'aurions que les ingrédients.

Un autre cas d'utilisation courant pour les ensembles de valeurs consiste à ajouter une option nulle. Supposons que nous utilisions ISO 3166 (codes de pays) dans un formulaire. Il affiche correctement tous les pays et leurs codes, mais il n'existe pas de code de pays « Inconnu ». Nous pouvons définir un ensemble de valeurs qui inclut tous les codes d'ISO 3166 et le concept UNK de NullFlavor.

Exemples

resourceType: ValueSet
url: http://example.org/rxnorm-ingredients
title: RxNorm Ingredients
compose:
  include:
  - system: http://www.nlm.nih.gov/research/umls/rxnorm
    filter:
    - property: TTY
      op: =
      value: IN
resourceType: ValueSet
url: http://hl7.org/fhir/ValueSet/example
title: LOINC Codes for Cholesterol in Serum/Plasma
compose:
  include:
  - system: http://loinc.org
    concept:
    - code: 14647-2
      display: Cholesterol [Moles/Volume]
    - code: 2093-3
      display: Cholesterol [Mass/Volume]
    - code: 35200-5
      display: Cholesterol [Mass Or Moles/Volume]
    - code: 9342-7
      display: Cholesterol [Percentile]
resourceType: ValueSet
url: http://hl7.org/fhir/ValueSet/administrative-gender
status: active
compose:
  include:
  - system: http://hl7.org/fhir/administrative-gender
resourceType: ValueSet
url: http://hl7.org/fhir/ValueSet/yesnodontknow
name: YesNoDontKnow
compose:
  include:
  - valueSet: ["http://terminology.hl7.org/ValueSet/v2-0136"]
  - system: http://terminology.hl7.org/CodeSystem/data-absent-reason
    concept:
    - code: asked-unknown
      display: Don't know

Opérations

La principale façon d'interagir avec le module de terminologie et ses ressources se fait via des opérations. La spécification R6 définit 8 opérations spécifiques à la terminologie. Tout au long de cette série, nous examinerons la plupart d'entre elles en détail. Dans cet article, nous présentons $expand, celle qui alimente la plupart de nos exemples ci-dessus.

ValueSet/$expand

Étant donné un ensemble de valeurs, retourne la liste des codes qu'il définit. Cette opération est idéale pour peupler les éléments d'interface utilisateur : listes déroulantes, champs de recherche, sélecteurs de codes, etc. En plus de l'ensemble de valeurs, vous pouvez spécifier un filtre de recherche textuelle, la pagination, les propriétés et désignations à retourner, la langue de retour, parmi d'autres paramètres.

Prenons notre premier exemple : un champ de recherche par saisie semi-automatique sur les constatations cliniques de SNOMED. Supposons que nous voulions rechercher « diabetes mellitus » et obtenir 10 résultats. Voici à quoi pourrait ressembler une requête :

GET https://tx-sandbox.health-samurai.io/fhir/ValueSet/$expand
[Query]
url: http://snomed.info/sct?fhir_vs=isa/404684003
count: 10
filter: diabetes mellitus
curl -G 'https://tx-sandbox.health-samurai.io/fhir/ValueSet/$expand' \
  --data-urlencode 'url=http://snomed.info/sct?fhir_vs=isa/404684003' \
  --data-urlencode 'count=10' \
  --data-urlencode 'filter=diabetes mellitus'
ParamètreValeurExplication
urlhttp://snomed.info/sct?fhir_vs=isa/404684003URL implicite pour les concepts de constatation clinique de SNOMED5
count10Nombre de concepts à faire correspondre
filterdiabetes mellitusTexte à faire correspondre

Nous pouvons également fournir un ensemble de valeurs directement dans la requête, ce qui nous permet de concevoir des requêtes sur un système de codes via des propriétés. Par exemple, supposons que nous voulions obtenir tous les médicaments de marque contenant à la fois de la caféine et de l'acétaminophène comme ingrédients.

POST https://tx-sandbox.health-samurai.io/fhir/ValueSet/$expand
Content-Type: application/json
{
  "resourceType": "Parameters",
  "parameter": [
    {
      "name": "valueSet",
      "resource": {
        "resourceType": "ValueSet",
        "status": "active",
        "compose": {
          "include": [
            {
              "system": "http://www.nlm.nih.gov/research/umls/rxnorm",
              "filter": [
                { "property": "TTY", "op": "=", "value": "BN" },
                { "property": "tradename_of", "op": "=", "value": "CUI:161" },
                { "property": "tradename_of", "op": "=", "value": "CUI:1886" }
              ]
            }
          ]
        }
      }
    }
  ]
}
curl -X POST 'https://tx-sandbox.health-samurai.io/fhir/ValueSet/$expand' \
  -H 'Content-Type: application/json' \
  -d '{
    "resourceType": "Parameters",
    "parameter": [
      {
        "name": "valueSet",
        "resource": {
          "resourceType": "ValueSet",
          "status": "active",
          "compose": {
            "include": [
              {
                "system": "http://www.nlm.nih.gov/research/umls/rxnorm",
                "filter": [
                  { "property": "TTY", "op": "=", "value": "BN" },
                  { "property": "tradename_of", "op": "=", "value": "CUI:161" },
                  { "property": "tradename_of", "op": "=", "value": "CUI:1886" }
                ]
              }
            ]
          }
        }
      }
    ]
  }'
FiltreValeurExplication
TTYBNNoms de marque uniquement
tradename_ofCUI:161Contient de l'acétaminophène
tradename_ofCUI:1886Contient de la caféine

Prochaine étape

Dans notre prochain article, nous examinerons les canoniques. Comment les ressources de terminologie sont-elles identifiées, quelles conventions sont utilisées, comment le versionnage et la résolution fonctionnent.

Footnotes

  1. La façon la plus efficace de mettre en œuvre certains de ces exemples est d'utiliser le traitement par lots ; nous isolons les requêtes pour en faciliter l'inspection.

  2. Nous approfondirons le fonctionnement de ces URL dans un futur article sur les canoniques.

  3. La spécification définit en réalité 4 types de données (et 3 supplémentaires). Toutefois, CodeableReference est défini en termes de CodeableConcept et les types supplémentaires sont des cas particuliers. C'est pourquoi nous nous concentrons sur les trois premiers. Voir https://build.fhir.org/terminologies.html.

  4. Dans un futur article, nous examinerons un tutoriel pour configurer un serveur de terminologie afin d'alimenter une application de santé à partir de zéro.

  5. Voir https://terminology.hl7.org/en/SNOMEDCT.html pour savoir comment utiliser SNOMED avec la terminologie FHIR. Nous consacrerons un futur article à SNOMED CT.

Partager cet article
Comments
Comments
Sign in
Loading comments...
Subscribe to our blog

Get the latest articles on FHIR, interoperability, and healthcare IT.