Linkr
Accueil Ressources Outils Documentation Blog Démo
EN
  • Découverte d'OMOP
  • La communauté OHDSI
  • Le modèle OMOP CDM
  • Les vocabulaires OMOP
  • L'écosystème d'outils OHDSI
  • Construire un ETL OMOP
  • SQL — Niveau débutant
  • SQL — Niveau intermédiaire
  • SQL — Niveau avancé
4/9
16 min Boris Delange · 14/05/2026

Les vocabulaires OMOP

Comment OMOP intègre les terminologies médicales dans son modèle : la table CONCEPT, les alignements vers les concepts standards, les hiérarchies pré-calculées.

En résumé

Les terminologies médicales (CIM-10, SNOMED CT, LOINC, RxNorm…) cohabitent dans OMOP au sein d’un dictionnaire unique appelé CONCEPT, où chaque code reçoit un identifiant interne stable : le concept_id. Deux autres tables font tourner l’ensemble : CONCEPT_RELATIONSHIP relie les codes entre eux et CONCEPT_ANCESTOR stocke les hiérarchies pour interroger en une requête tous les sous-types d’un concept. Ces trois tables sont le moteur qui rend les requêtes OMOP comparables d’une base à l’autre.

Ce que vous savez déjà

Dans la section Comprendre les entrepôts de données de santé, l’article Parler le même langage : les terminologies médicales a présenté les terminologies médicales en général : CIM-10, SNOMED CT, LOINC, ATC, RxNorm, leurs usages respectifs.

Si ces noms ne vous disent rien, relisez d’abord cet article : nous supposons ici que vous savez ce qu’est une terminologie standardisée et pourquoi elle est nécessaire.

L’article précédent, Le modèle OMOP CDM, a par ailleurs détaillé la dualité source/standard dans les tables d’événements (condition_concept_id vs condition_source_value vs condition_source_concept_id). Cet article expose le mécanisme qui rend cette dualité possible.

Le problème qu’OMOP résout

Chaque pays, chaque hôpital, chaque éditeur de logiciel utilise ses propres codes. OMOP doit donc faire deux choses :

  1. Rassembler tous ces vocabulaires dans un dictionnaire unique, requêtable en SQL.
  2. Aligner les codes locaux sur des concepts standards pour permettre la comparaison internationale.

Le résultat : un système où chaque code médical existe sous une forme unifiée, identifié par un concept_id, et où les liens entre codes (équivalences, hiérarchies, alignements) sont eux-mêmes des données interrogeables.

Trois niveaux à distinguer

C’est probablement le point le moins évident de tout le système OMOP, et celui qu’il vaut mieux poser avant d’aller plus loin. Quand on regarde une ligne d’événement clinique — par exemple un diagnostic dans CONDITION_OCCURRENCE — on ne voit pas deux représentations en parallèle (source et standard), comme on pourrait le croire au premier abord, mais trois niveaux distincts.

1. Code local brut

La chaîne telle qu’elle existait dans le système hospitalier. Stockée dans _source_value. Pas de concept_id, juste du texte.

2. Concept source

L’identifiant OMOP du code source s’il existe. Stocké dans _source_concept_id. Peut être issu d’un vocabulaire intégré (CIM-10, CCAM…) ou créé localement.

3. Concept standard

Le concept de référence désigné par OHDSI pour ce domaine (SNOMED CT pour les diagnostics, RxNorm pour les médicaments, LOINC pour la biologie…). Stocké dans _concept_id. Marqué standard_concept = ‘S’.

La distinction qui surprend le plus se joue entre les cas 1 et 2 (présentés ci-dessous) : être présent dans les OHDSI Vocabularies ne veut pas dire être standard. La CIM-10 est intégrée, chaque code a un concept_id officiel, mais ces concepts sont non standard — c’est SNOMED CT qui a été choisi comme vocabulaire standard pour les diagnostics. La CIM-10 sert donc à représenter le concept source, pas le concept standard.

Trois cas de figure typiques permettent de voir comment ces niveaux s’articulent en pratique. On les présente du plus simple au plus exigeant pour l’ETL.

Cas 1 — Le code source est déjà un concept standard

C’est la situation la plus simple : la source utilise directement le vocabulaire que OHDSI a désigné comme standard pour le domaine (LOINC pour la biologie, RxNorm pour les médicaments, SNOMED CT pour les diagnostics quand l’EHR le permet). L’ETL retrouve le concept dans CONCEPT et le pose à la fois en _source_concept_id et en _concept_id — les deux champs portent la même valeur, sans qu’aucun véritable alignement n’ait été nécessaire.

Exemple — une biologie LOINC, comme on en trouve dans MIMIC ou les EHR modernes

Code local brut

”8867-4”

Code LOINC Heart rate tel qu’il sort de l’EHR — déjà standard.

Concept source

3027018

Concept LOINC Heart rate. Comme LOINC est standard pour la biologie, ce concept est déjà marqué standard_concept = ‘S’.

Concept standard

3027018

Identique au concept source. Quand la source est déjà standard, les deux champs portent la même valeur.

Cas 2 — Le code source est dans un vocabulaire OHDSI mais non standard

C’est le cas le plus fréquent dans les bases européennes : la source utilise un vocabulaire intégré dans les OHDSI Vocabularies — CIM-10, CIM-10-CM, CCAM, ATC, NABM… — mais qui n’est pas standard pour ce domaine. L’ETL retrouve le concept_id officiel correspondant au code, puis suit l’alignement déjà préparé dans CONCEPT_RELATIONSHIP pour atteindre le concept standard.

Exemple — un diagnostic codé en CIM-10

Code local brut

”E11.9”

Saisi par le médecin via la nomenclature CIM-10 de l’établissement.

Concept source

45561952

Concept officiel OHDSI pour le code E11.9 de la CIM-10. Non standard (standard_concept = NULL).

Concept standard

201826

Concept SNOMED CT Type 2 diabetes mellitus. Standard (‘S’). Atteint via le Maps to fourni par OHDSI.

Cas 3 — Le code source n’est pas dans les OHDSI Vocabularies

C’est le cas le plus exigeant : le code source n’a aucun équivalent dans les vocabulaires que la communauté OHDSI maintient (nomenclature maison d’un établissement, code propriétaire d’un éditeur, libellé court d’un moniteur…). L’ETL a alors deux options.

Option A — Créer un concept custom (« 2-billionaires »). Quand le code mérite d’être tracé proprement, on lui attribue un concept_id au-delà de 2 000 000 000. OMOP réserve cette plage aux concepts locaux pour éviter tout conflit avec les identifiants officiels — d’où le surnom « 2B+ » ou « 2-billionaires ». Le concept est ajouté à un vocabulary_id dédié à l’établissement, et l’ETL doit lui-même tracer le Maps to vers le concept standard.

Exemple — un thesaurus de diagnostics maison dans un hôpital néerlandais

Code local brut

”DHD-12345”

Code interne du DHD Diagnose Thesaurus désignant un diabète de type 1, nomenclature propre à un réseau hospitalier.

Concept source (custom)

2 000 000 001

Concept créé par l’ETL local dans un vocabulary_id dédié (“DHD Diagnose Thesaurus”). Toujours non standard.

Concept standard

201254

Concept SNOMED CT Type 1 diabetes mellitus, atteint via un Maps to ajouté manuellement par l’ETL.

Option B — Laisser le concept source à 0. Quand le code source ne vaut pas la peine d’être tracé (libellé éphémère, donnée peu fiable, pas de besoin métier), l’ETL ne crée pas de concept custom. Le _source_value est conservé tel quel, mais _source_concept_id vaut 0 (« No matching concept »). Le concept standard, lui, peut toujours être renseigné si l’ETL arrive à interpréter le libellé.

Exemple — une fréquence cardiaque enregistrée par un moniteur de réanimation

Code local brut

”FC bpm”

Libellé maison du moniteur, sans code structuré.

Concept source

0

Pas de concept custom créé : OMOP utilise le concept “No matching concept”.

Concept standard

3027018

Concept LOINC Heart rate. Standard (‘S’). Décidé par l’ETL au moment de l’alignement.

Règles à respecter pour les concepts custom (≥ 2 milliards)

La documentation officielle OMOP impose plusieurs contraintes pour les concepts locaux :

  • Ils doivent appartenir à un nouveau vocabulary_id spécifique à l’établissement, jamais à un vocabulaire OHDSI existant.
  • Leur standard_concept doit rester NULL : ils ne sont jamais standard.
  • Ils ne peuvent apparaître que dans les champs _source_concept_id, jamais dans _concept_id.
  • Ils ne doivent pas être rattachés aux hiérarchies des vocabulaires OHDSI. Si l’hôpital A déclare son concept custom comme sous-type d’un concept SNOMED, une requête « tous les descendants de ce concept SNOMED » renverra des résultats différents chez l’hôpital A et l’hôpital B — la hiérarchie ne serait plus la même d’une instance à l’autre.
  • Ils doivent porter un Maps to vers un concept standard, sans quoi les données ne sont pas exploitables pour la recherche en réseau.

Qui décide ce qui est standard ?

Cette désignation « standard / non standard » n’est pas une propriété intrinsèque d’un vocabulaire : c’est une décision prise par OHDSI, vocabulaire par vocabulaire, domaine par domaine. La CIM-10 et SNOMED CT sont toutes deux des nomenclatures matures et largement utilisées pour les diagnostics, mais c’est SNOMED CT qu’OHDSI a choisi comme standard. La CIM-10 reste donc dans les OHDSI Vocabularies, parfaitement intégrée, mais cantonnée au rôle de vocabulaire source.

Un concept représentant la signification de chaque événement clinique est désigné comme le Standard. (…) Seuls ces concepts standards sont utilisés pour enregistrer les données dans les champs du CDM qui se terminent par _CONCEPT_ID.

— Book of OHDSI, chapitre 5

Le Book of OHDSI précise les critères : le choix se fait « pour chaque domaine séparément, au niveau du vocabulaire », sur la base de la qualité des concepts, de la hiérarchie disponible et de l’objectif déclaré du vocabulaire. C’est le Vocabulary Working Group d’OHDSI qui maintient ces décisions, intègre les nouveaux vocabulaires et publie les mises à jour via ATHENA.

Standards et sources : qui fait quoi

Toutes les terminologies ne jouent pas le même rôle. OMOP désigne, pour chaque domaine, un vocabulaire standard et accepte les autres comme vocabulaires sources, à aligner sur le standard.

DomaineVocabulaire standardVocabulaires sources fréquents
DiagnosticsSNOMED CTCIM-10, CIM-10-CM, Read codes
MédicamentsRxNorm + RxNorm ExtensionATC (classification), codes locaux
Biologie / mesuresLOINCCodes locaux, NABM (France)
Actes / procéduresSNOMED CT, CPT4, HCPCS, ICD10PCSCCAM (France), codes locaux
Démographie (sexe)Gender (vocabulaire OMOP)Codes ISO, codes locaux

ATC : un rôle à part

L’ATC occupe dans OMOP un rôle particulier : il n’est ni vocabulaire standard (réservé à RxNorm pour les médicaments), ni simple vocabulaire source. OHDSI le marque comme classification (standard_concept = ‘C’) : ses concepts ne peuvent pas être utilisés pour enregistrer un médicament, mais ils participent à la hiérarchie. En pratique, un médicament est enregistré via son concept RxNorm, puis on peut remonter à sa classe ATC via CONCEPT_ANCESTOR — utile pour des analyses par classe thérapeutique.

Les trois tables au cœur des vocabulaires

OMOP fait tenir tout son système de vocabulaires sur trois tables, qui se complètent :

  • CONCEPT — le dictionnaire : un identifiant unique pour chaque code de chaque vocabulaire.
  • CONCEPT_RELATIONSHIP — les liens entre concepts : équivalences, alignements, relations sémantiques.
  • CONCEPT_ANCESTOR — les hiérarchies pré-calculées, pour interroger un concept et tous ses descendants.

Nous les détaillons dans cet ordre.

CONCEPT — le dictionnaire universel

Rôle :
Dictionnaire unifié de tous les codes médicaux intégrés dans OMOP.
Une ligne par :
Concept (un code dans un vocabulaire = une ligne).
Connectée à :
Toutes les colonnes _concept_id des tables d’événements, et à elle-même via CONCEPT_RELATIONSHIP et CONCEPT_ANCESTOR.

CONCEPT est la table centrale du système. Chaque code médical de chaque vocabulaire intégré y figure comme une ligne unique, avec un identifiant interne stable : le concept_id.

ColonneContenu
concept_idIdentifiant unique OMOP du concept (à utiliser dans toutes les requêtes)
concept_nameLibellé du concept (en anglais)
domain_idDomaine (Condition, Drug, Measurement, Observation…)
vocabulary_idVocabulaire d’origine (SNOMED, ICD10, LOINC, RxNorm…)
concept_class_idClasse à l’intérieur du vocabulaire (par exemple « Clinical Finding » dans SNOMED)
standard_concept’S’ = standard, ‘C’ = classification, NULL = source non standard
concept_codeCode dans le vocabulaire d’origine
valid_start_date, valid_end_datePériode de validité

Tous les vocabulaires cohabitent dans cette même table : une recherche WHERE concept_name LIKE '%diabetes%' peut renvoyer des résultats SNOMED CT, des codes CIM-10, des codes Read britanniques, ou des concepts d’autres vocabulaires nationaux.

Aperçu de la table

Trois lignes pour le même concept clinique — le diabète de type 2 — vu sous trois angles. La première (201826) est le concept SNOMED CT standard (standard_concept = ‘S’) ; c’est elle qu’on retrouvera dans condition_concept_id. La deuxième (45561952) est le concept CIM-10 source correspondant au code E11.9 — non standard, mais reconnu par OMOP. La troisième (21600712) appartient à l’ATC, classification de classe thérapeutique : ni source brut, ni standard, mais participant à la hiérarchie.

concept_idconcept_namedomain_idvocabulary_idstandard_conceptconcept_code
201826Type 2 diabetes mellitusConditionSNOMEDS44054006
45561952Type 2 diabetes mellitus, without complicationsConditionICD10NULLE11.9
21600712DRUGS USED IN DIABETESDrugATCCA10

standard_concept = 'S' : la colonne à surveiller

Quand vous écrivez une requête, vous voulez presque toujours filtrer sur standard_concept = ‘S’. C’est ce qui garantit que vous utilisez le concept de référence et non un code source équivalent qui pourrait ne pas être reconnu par les outils ou par les autres bases du réseau OHDSI.

domain_id : où l'événement sera enregistré

La colonne domain_id indique dans quelle table d’événement un enregistrement utilisant ce concept doit être stocké. Un concept de domain_id = ‘Measurement’ sera enregistré dans MEASUREMENT, un concept de domain_id = ‘Drug’ dans DRUG_EXPOSURE, et ainsi de suite pour Condition → CONDITION_OCCURRENCE, Procedure → PROCEDURE_OCCURRENCE, Observation → OBSERVATION. Quand on cherche un concept dans ATHENA et qu’on hésite sur l’endroit où il vivra dans la base, c’est cette colonne qui tranche.

CONCEPT_RELATIONSHIP — les liens entre concepts

Rôle :
Définit les relations orientées entre deux concepts, qu’ils soient standards ou non : alignements vers le standard, relations hiérarchiques, liens question/réponse…
Une ligne par :
Relation orientée entre deux concepts, qualifiée par un relationship_id.
Connectée à :
CONCEPT via concept_id_1 et concept_id_2.

Une fois le dictionnaire en place, il faut relier les concepts entre eux. C’est le rôle de CONCEPT_RELATIONSHIP. Chaque ligne définit une relation orientée :

concept_id_1 → [relationship_id] → concept_id_2

Quelques relations parmi les plus importantes :

RelationSignification
Maps toLe concept_id_1 (source) est aligné sur le concept_id_2 (standard)
Mapped fromRelation inverse de Maps to
Is aLe concept est un sous-type de… (hiérarchie)
SubsumesRelation inverse de Is a (le concept englobe…)
Maps to valueAligne un concept pré-coordonné sur une valeur séparée
Has answerLie une question (par exemple LOINC) à ses réponses possibles

La relation « Maps to », pivot du système

C’est probablement la relation que vous croiserez le plus souvent. Elle indique qu’un concept source doit être traité comme équivalent à un concept standard : un code CIM-10 vers son équivalent SNOMED CT, un code local d’examen biologique vers LOINC, etc.

Les concepts standards sont alignés sur eux-mêmes, les concepts non standards sur des concepts standards. La plupart des concepts non standards et tous les concepts standards portent cette relation vers un concept standard.

— Book of OHDSI, section 5.3.1

Concrètement, si vous avez un code source CIM-10 E11.9 (diabète sucré de type 2 sans complication) dans condition_source_value, son condition_source_concept_id pointera vers le concept OMOP 45561952 qui représente ce code. Ce concept est non standard, mais il a une relation Maps to vers le concept SNOMED CT standard 201826 — qui est ce qu’on retrouvera dans condition_concept_id.

Aperçu de la table

Trois relations autour du diabète de type 2. La première dit que le code CIM-10 E11.9 est aligné sur le concept SNOMED CT standard. La deuxième est la relation inverse (un même lien est représenté dans les deux sens). La troisième est une relation hiérarchique : le diabète de type 2 est un sous-type de « Diabetes mellitus » dans SNOMED.

concept_id_1concept_id_2relationship_id
45561952 (ICD10 E11.9)201826 (SNOMED T2 diabetes)Maps to
201826 (SNOMED T2 diabetes)45561952 (ICD10 E11.9)Mapped from
201826 (SNOMED T2 diabetes)201820 (SNOMED Diabetes mellitus)Is a

Et si l'alignement n'est pas parfait ?

L’alignement sur SNOMED CT n’est pas toujours 1-pour-1. Le Book of OHDSI mentionne explicitement les « up-hill mappings » : quand un code source n’a pas d’équivalent exact, il est aligné sur un concept SNOMED légèrement plus large. L’exemple donné est éloquent : ICD10CM W61.51 « Bitten by goose » (mordu par une oie) n’a pas d’équivalent exact, il est donc aligné sur SNOMED 217716004 « Peck by bird » — on perd l’information de l’oie. La communauté accepte ces imperfections quand la perte d’information est jugée négligeable pour la recherche, et encourage les retours pour améliorer les alignements.

CONCEPT_ANCESTOR — les hiérarchies pré-calculées

Rôle :
Pré-calcule la fermeture transitive des hiérarchies : pour chaque concept ancêtre, liste tous ses descendants à toutes les profondeurs.
Une ligne par :
Couple ancêtre/descendant (un même concept apparaît plusieurs fois selon sa position dans la hiérarchie).
Connectée à :
CONCEPT via ancestor_concept_id et descendant_concept_id. Construite automatiquement à partir de CONCEPT_RELATIONSHIP.

Les vocabulaires médicaux sont hiérarchiques : Diabète de type 2 est un enfant de Diabète, qui est un enfant de Maladie endocrinienne. Quand on veut tous les patients ayant un diabète quel qu’il soit, on ne veut pas lister tous les sous-types manuellement.

CONCEPT_ANCESTOR résout ce problème en stockant à l’avance toutes les paires ancêtre/descendant, à toutes les profondeurs de la hiérarchie.

ColonneContenu
ancestor_concept_idConcept parent
descendant_concept_idConcept enfant (à n’importe quel niveau)
min_levels_of_separationDistance minimale entre les deux
max_levels_of_separationDistance maximale (un concept peut avoir plusieurs chemins)

Aperçu de la table — descendants de « Diabetes mellitus » (201820)

Quatre lignes parmi les descendants du concept SNOMED CT Diabetes mellitus. La première (min_levels = 0) est le concept lui-même : un concept est toujours son propre ancêtre, ce qui simplifie les requêtes IN (SELECT descendant_concept_id …). Les suivantes descendent dans la hiérarchie : type 1, type 2, puis le diabète gestationnel à deux niveaux de profondeur (sous-type de diabète, distinct du type 1 et du type 2).

ancestor_concept_iddescendant_concept_idmin_levels_of_separationmax_levels_of_separation
201820201820 (Diabetes mellitus)00
201820201254 (T1 diabetes)11
201820201826 (T2 diabetes)11
2018204024659 (Gestational diabetes)22

Cela permet une requête comme :

SELECT *
FROM condition_occurrence c
WHERE c.condition_concept_id IN (
  SELECT descendant_concept_id
  FROM concept_ancestor
  WHERE ancestor_concept_id = 201820  -- Diabetes mellitus
)

Sans CONCEPT_ANCESTOR, il faudrait une jointure récursive sur CONCEPT_RELATIONSHIP — beaucoup plus lente et fragile.

Toutes les hiérarchies ne se valent pas

Le Book of OHDSI précise qu’une hiérarchie de haute qualité n’existe que pour deux domaines : les médicaments (via RxNorm) et les conditions (via SNOMED CT). Pour les actes, la biologie et les observations, les hiérarchies sont plus partielles ou en construction. À garder en tête quand on construit des concept sets pour ces domaines : la complétude n’est pas garantie.

DRUG_STRENGTH — la dose réelle des médicaments

Rôle :
Donne la composition de chaque produit médicamenteux : quel principe actif, en quelle quantité, dans quelle unité.
Une ligne par :
Couple produit / principe actif (un produit combiné a plusieurs lignes).
Connectée à :
CONCEPT via drug_concept_id (le produit standard RxNorm) et ingredient_concept_id (le principe actif).

Comme rappelé dans l’article précédent, DRUG_EXPOSURE ne stocke pas directement la dose reçue par le patient : la colonne quantity donne uniquement le nombre d’unités délivrées (comprimés, ampoules, millilitres…). Pour calculer la dose réelle, il faut joindre DRUG_EXPOSURE avec DRUG_STRENGTH, qui contient la concentration du principe actif pour chaque produit standard.

DRUG_STRENGTH distingue deux familles de formes galéniques via des colonnes différentes :

  • Formes solides ou unitaires (comprimé, gélule, ampoule entière) : la quantité par unité est portée par amount_value et amount_unit_concept_id.
  • Formes liquides ou de concentration (solution, perfusion, sirop, patch) : la concentration s’exprime comme un rapport numerator_value / denominator_value avec leurs unités respectives.
ColonneContenu
drug_concept_idProduit standard RxNorm (par exemple ibuprofen 200 MG Oral Tablet)
ingredient_concept_idPrincipe actif (par exemple ibuprofen)
amount_value, amount_unit_concept_idQuantité par unité de forme solide (mg par comprimé, par ampoule…)
numerator_value, numerator_unit_concept_idQuantité de principe actif au numérateur d’une concentration
denominator_value, denominator_unit_concept_idVolume / unité au dénominateur (mL pour une perfusion, etc.)
box_sizeNombre d’unités par boîte, si renseigné

Aperçu de la table — deux formes contrastées

L’ibuprofène 200 mg comprimé oral est une forme solide : amount_value = 200 mg par comprimé, les colonnes numerator/denominator restent vides. La noradrénaline injectable est une concentration : numerator_value = 0,128 mg par mL, denominator_value est laissé à NULL par convention (équivalent à 1 unité du dénominateur).

drug_concept_idingredient_concept_idamount_valuenumerator_valuedenominator_value
19078461 (ibuprofen 200 MG tab.)1177480 (ibuprofen)200 mgNULLNULL
37354531 (norepinephrine 0.128 MG/ML)1321341 (norepinephrine)NULL0,128 mg1 mL (implicite)

Un produit combiné = plusieurs lignes

Pour les médicaments à plusieurs principes actifs — par exemple paracetamol + hydrocodone — DRUG_STRENGTH stocke une ligne par ingrédient, toutes pointant vers le même drug_concept_id. Quand on calcule des doses, il faut donc systématiquement préciser à quel principe actif on s’intéresse via ingredient_concept_id.

Le détail des formules de calcul de dose (par forme galénique, avec ou sans concentration) est dans la documentation officielle OMOP sur le calcul de dose. Pour la pratique, le tutoriel SQL de niveau avancé contient des exercices dédiés (dose totale d’un comprimé, débit d’une perfusion IV).

Les autres tables de vocabulaire

CONCEPT, CONCEPT_RELATIONSHIP, CONCEPT_ANCESTOR et DRUG_STRENGTH portent l’essentiel du système. Six tables auxiliaires complètent le dispositif. On les croise rarement dans les requêtes d’analyse, mais il est utile de savoir à quoi elles servent.

TableRôle
VOCABULARYCatalogue des vocabulaires intégrés (SNOMED, ICD10, LOINC, RxNorm…) avec leur version, leur référence et leur date d’import. C’est la table qu’on regarde pour savoir quelle version d’ATHENA est utilisée dans une instance.
DOMAINCatalogue des domaines (Condition, Drug, Measurement, Observation, Procedure…) et de la table CDM associée. C’est la table de référence derrière la colonne domain_id de CONCEPT.
RELATIONSHIPCatalogue des relationship_id (Maps to, Is a, Subsumes, Has answer…) avec leur relation inverse et leur niveau hiérarchique. Utile pour comprendre la sémantique d’une relation rencontrée dans CONCEPT_RELATIONSHIP.
CONCEPT_CLASSCatalogue des classes de concepts utilisées par chaque vocabulaire (par exemple « Clinical Finding » dans SNOMED, « ATC 2nd » dans ATC). Référence pour la colonne concept_class_id de CONCEPT.
CONCEPT_SYNONYMVariantes textuelles d’un même concept : libellés alternatifs, traductions, synonymes officiels. Utile pour la recherche de concepts par libellé quand le terme exact n’est pas celui retenu par OHDSI.
SOURCE_TO_CONCEPT_MAPTable d’alignement maintenue localement par chaque ETL pour relier ses codes sources aux concepts standards. On la verra en détail dans l’article Construire un ETL OMOP.

Concept_id = 0 — le « NULL » d’OMOP

Une convention déjà rencontrée dans l’article précédent : quand un code source n’a pas d’alignement disponible, son _concept_id est mis à 0.

CONCEPT.concept_id = 0 existe vraiment dans le dictionnaire ; il porte le nom “No matching concept”. C’est un choix de design pour éviter les NULL SQL classiques et fournir un signalement explicite.

Dans les vocabulaires standardisés, on ne distingue pas pourquoi une information est absente : retrait actif par le patient, valeur manquante, valeur non définie ou non standardisée, ou absence d’enregistrement d’alignement dans CONCEPT_RELATIONSHIP. Tout concept non aligné correspond, par défaut, à un alignement vers le concept standard concept_id = 0.

— Book of OHDSI, section 5.6.10 « Flavors of NULL »

En pratique :

  • Comptez régulièrement les concept_id = 0 par table — c’est l’indicateur de qualité d’alignement le plus simple.
  • Un code source peut être présent (source_value non vide) et son source_concept_id valide, tandis que le _concept_id standard vaut 0 si le concept source n’a pas encore d’alignement.

ATHENA — explorer les vocabulaires sans SQL

ATHENA est le dictionnaire centralisé des vocabulaires OMOP, accessible via une interface graphique. On y retrouve la même information que dans les tables CONCEPT, CONCEPT_RELATIONSHIP et CONCEPT_ANCESTOR d’une base OMOP, mais sans avoir à écrire une requête SQL à chaque fois qu’on cherche un concept : recherche par libellé, filtres par domaine, vocabulaire et statut standard, navigation dans les relations et les hiérarchies en quelques clics.

Avec un compte ATHENA (gratuit), on peut télécharger un bundle de vocabulaires prêt à être importé dans sa propre base OMOP — étape obligatoire pour que CONCEPT, CONCEPT_RELATIONSHIP et CONCEPT_ANCESTOR soient peuplés dans votre instance.

ATHENA est présenté plus en détail dans l’article sur l’écosystème d’outils OHDSI.

En pratique : les concept sets

Pour les analyses cliniques, on travaille rarement avec un seul concept à la fois. On construit des concept sets : des collections de concepts standards qui représentent ensemble une même notion clinique. Par exemple, un concept set « fréquence cardiaque » regroupera tous les codes LOINC sous lesquels cette mesure peut être enregistrée (variations selon le contexte de mesure, la méthode, la position du patient…), et un concept set « créatininémie » regroupera de même les différents codes LOINC du dosage de créatinine sanguine.

Un concept set typique combine plusieurs mécanismes :

  1. Quelques concepts racines sélectionnés explicitement (par exemple le concept LOINC Heart rate).
  2. L’inclusion des descendants via CONCEPT_ANCESTOR pour récupérer tous les sous-types — utile surtout pour les conditions et les médicaments, dont les hiérarchies sont les plus complètes.
  3. L’exclusion sélective des descendants qu’on ne veut pas (par exemple, exclure une variante mesurée dans un contexte particulier).

C’est exactement ce que permet de construire ATLAS sans coder, ou ce qu’on écrit directement en SQL pour les exercices à venir. La documentation officielle d’ATLAS sur les concept sets détaille la marche à suivre, et l’INDICATE Data Dictionary propose 300+ exemples de concept sets cliniques prêts à l’emploi.

Pour aller plus loin

  • L’explorateur interactif couvre aussi les tables de vocabulaire avec leurs colonnes et clés.
  • Le chapitre 5 du Book of OHDSI est la référence officielle complète.
  • ATHENA pour explorer concrètement les concepts et leurs relations.
  • Trois niveaux à distinguer pour chaque événement clinique : le code local brut (_source_value), le concept source (_source_concept_id) et le concept standard (_concept_id).
  • Être présent dans les OHDSI Vocabularies ne veut pas dire être standard. La CIM-10 y est intégrée, mais c'est SNOMED CT qui sert de standard pour les diagnostics. Le choix « standard / non standard » est une décision du Vocabulary Working Group d'OHDSI.
  • Les vocabulaires reposent sur trois tables : CONCEPT (le dictionnaire), CONCEPT_RELATIONSHIP (les liens orientés entre concepts), CONCEPT_ANCESTOR (les hiérarchies pré-calculées).
  • La relation « Maps to » est le mécanisme central qui lie un concept source à son concept standard. Pour les sources déjà standards, le concept se mappe sur lui-même.
  • Filtrez sur standard_concept = 'S' dans vos requêtes pour ne récupérer que les concepts de référence, et utilisez domain_id pour savoir dans quelle table d'événement le concept atterrira.
  • Les hiérarchies de haute qualité n'existent que pour les médicaments et les conditions. Pour les autres domaines, attention aux concept sets construits par hiérarchie.
  • concept_id = 0 signale un code source non aligné. Les concepts custom (≥ 2 milliards) permettent de tracer un code local absent des OHDSI Vocabularies, à condition de respecter les règles : vocabulaire dédié, jamais standard, Maps to obligatoire.
  • ATHENA est le dictionnaire centralisé des vocabulaires OMOP avec interface graphique : recherche, filtres, navigation dans les relations et hiérarchies, sans écrire de SQL.
PrécédentLe modèle OMOP CDMSuivantL'écosystème d'outils OHDSI

Produit

  • Accueil
  • Démo

Ressources

  • Documentation
  • Ressources
  • Outils
  • Blog

Communauté

  • Code source Framagit
  • Code source Github

À propos

  • InterHop.org
  • Contact

2021–2026 InterHop — CC BY-NC-SA 4.0 (site) · GPLv3 (logiciel)