En résumé
Le mapping d’un schéma dit à Linkr où se trouvent les patients, les séjours, les notes, les concepts, les événements et les médicaments d’une base. Chacun est une relation : une requête qui renvoie une liste fixe de colonnes, son contrat. Une relation se remplit par un formulaire quand une table suffit, ou s’écrit en SQL quand il faut des jointures — un contrôle vérifie alors qu’elle respecte son contrat.
Des relations, pas des tables
Les pages de Linkr n’interrogent jamais directement person ou patients. Elles interrogent des relations au nom fixe — linkr_patient, linkr_visit, linkr_event_mesures… — qui renvoient toujours les mêmes colonnes, quel que soit le modèle de la base : patient_id, birth_date, gender pour les patients ; visit_id, start_datetime, end_datetime pour les hospitalisations. Cette liste de colonnes, avec leur type, est le contrat de la relation.
Vos tables
person
death
Le modèle de la base, quel qu’il soit.
mapping →
linkr_patient
patient_id · birth_date · gender · death_datetime…
Toujours les mêmes colonnes : le contrat.
→
Linkr
Données patient, cohortes, statistiques, catalogue…
Ne lit que les relations.
Le mapping est la façon de produire chaque relation à partir de vos tables. Une base OMOP et une base MIMIC produisent les mêmes relations par des chemins différents — et le même tableau de bord fonctionne sur les deux.
L’onglet Mapping
Sur la page d’un schéma, l’onglet Mapping s’ouvre sur la vue Source, celle des formulaires ; la vue Diagramme replace les relations sur le schéma des tables. Il est en lecture seule jusqu’à ce que vous cliquiez sur Modifier, en haut à droite ; Enregistrer — ou Cmd/Ctrl + S — valide.
Les sous-onglets rangent les relations par sujet clinique, chacun avec sa couleur, la même que dans le diagramme. Tout les montre à la suite.
linkr_patientpersonLEFT JOIN death d ON d.person_id = p.person_idpatient_id*person_idbirth_datebirth_datetimebirth_yearⓘyear_of_birthgender_source_valuegender_source_valuedeath_datetimed.death_datetimeValeurs brutes de gender_source_value signifiant homme et femme.
MF—linkr_visitvisit_occurrencevisit_id*visit_occurrence_idpatient_id*person_idstart_datetime*visit_start_datetimeend_datetimevisit_end_datetimevisit_typevisit_source_valuecare_site_idcare_site_idSéjours en unité
Non mappée.
Notes cliniques
Non mappée.
linkr_concept_omopconceptconcept_id*concept_idconcept_name*concept_nameconcept_codeconcept_codeterminology_idvocabulary_idcategorydomain_idsubcategoryconcept_class_idlinkr_event_mesuresmeasurementpatient_id*person_idconcept_id*measurement_concept_idstart_datetime*measurement_datetimevisit_idvisit_occurrence_idvisit_detail_idvisit_detail_idsource_concept_idmeasurement_source_concept_idvalue_numbervalue_as_numberunitunit_source_valueomoplinkr_event_diagnosticscondition_occurrencepatient_id*person_idconcept_id*condition_concept_idstart_datetime*condition_start_datetimevisit_idvisit_occurrence_idend_datetimecondition_end_datetimeomoplinkr_drug_medicamentsdrug_exposurepatient_id*person_idconcept_id*drug_concept_idstart_datetime*drug_exposure_start_datetimevisit_idvisit_occurrence_idend_datetimedrug_exposure_end_datetimequantityquantityrouteroute_source_valuedose_source_valuedose_unit_source_valueomopadministration| Sous-onglet | Ses relations | Ce qui en dépend |
|---|---|---|
| Patient | Patients, et ses valeurs de genre | Tout. Sans relation patients, la page Données patient refuse de s’afficher. |
| Hospitalisation | Hospitalisations et Séjours en unité | Les critères de cohorte par séjour, les durées, la chronologie des admissions, les services du catalogue. |
| Notes | Notes cliniques | Le widget Notes et les critères de cohorte textuels. |
| Concepts | Un ou plusieurs dictionnaires ; le premier est celui par défaut | L’affichage des noms au lieu des codes, partout. |
| Événements | Autant de relations que nécessaire — mesures, diagnostics, actes… | La page Concepts, les critères de cohorte, la frise du patient. |
| Médicaments | Autant de relations que nécessaire, chacune avec son Type | Les mêmes usages que les événements, plus les doses, débits et durées. |
Patients, Hospitalisations, Séjours en unité et Notes cliniques sont uniques. Les dictionnaires, les événements et les médicaments s’ajoutent en mode édition — Ajouter un dictionnaire, Ajouter une relation d’événements, Ajouter une relation de médicaments — et se nomment : c’est leur Libellé, ou leur Clé pour un dictionnaire, qui donne son nom à la relation (linkr_event_mesures). La corbeille d’un bloc le retire, après confirmation — sauf le bloc Patients, qui ne se retire pas.
Remplir une relation par le formulaire
Le formulaire convient dès qu’une table porte à elle seule la relation. Un bloc vide propose Mapper depuis une table ; un bloc rempli se compose de trois parties.
- Table — le schéma et la table source. Les deux champs proposent les tables connues du DDL, sans jamais forcer la valeur : un modèle à moitié décrit reste modifiable.
- Filtre — une condition SQL sur les colonnes de cette table, pour n’en garder qu’une partie :
category = 'Signes vitaux'. C’est ce qui permet de tirer plusieurs relations d’événements d’une même table. - Colonnes — une ligne par colonne du contrat. Chacune se remplit par une Colonne de la table, ou par une Constante — une valeur fixe, comme
'Réanimation'pour un type de séjour. Les colonnes obligatoires portent un astérisque ; une colonne laissée vide revient vide (NULL).
Hors mode édition, seules les colonnes remplies s’affichent. Certaines portent un ⓘ qui explique ce que Linkr en déduit : birth_year sert de repli quand birth_date n’est pas mappée, et gender se calcule tout seul à partir de gender_source_value.
Les valeurs de genre
Le bloc Patients demande en plus les Valeurs de genre : la valeur brute de gender_source_value qui signifie homme, celle qui signifie femme, et éventuellement celle qui signifie inconnu — M et F en OMOP, 1 et 2 ailleurs. C’est avec elles que Linkr remplit gender, utilisé par les statistiques et les critères de sexe.
Le dictionnaire d’une relation d’événements
Chaque relation d’événements ou de médicaments indique quel Dictionnaire traduit ses codes en noms : Par défaut — le premier dictionnaire du sous-onglet Concepts —, un dictionnaire précis, ou Aucun (concepts nommés en clair).
« Aucun » veut dire que la colonne concept porte déjà le nom
C’est le cas d’un champ MIMIC drug qui contient « Vancomycine » et non un identifiant numérique : la colonne sert alors de nom, et aucune jointure n’est faite.
Se tromper ici ne produit pas d’erreur : la jointure se fait quand même, entre un nom de médicament et un identifiant, et ne ramène rien. C’est la première chose à vérifier quand une page Concepts reste vide.
Un dictionnaire accepte aussi, au-delà de son contrat, des colonnes supplémentaires — Ajouter une colonne —, qui prennent le préfixe extra_.
Les médicaments
Les médicaments ont leur propre sous-onglet parce qu’ils ont leurs propres colonnes. Chaque relation a un Type — Administrations, ce qui a été donné, ou Prescriptions, ce qui a été prescrit — et son contrat ajoute à celui des événements les colonnes de dose : quantité, dose, débit, concentration et durée, chacune avec son unité, et is_continuous pour une perfusion continue.
Les colonnes d’événement — valeur, unité — sont déduites des colonnes de dose quand vous ne les mappez pas. Une relation de médicaments fonctionne donc partout où fonctionne une relation d’événements.
Écrire une relation en SQL
Le formulaire ne sait lire qu’une table. Tout le reste s’écrit en SQL : une date de décès rangée dans une autre table, un code qui ne se retrouve qu’en joignant terminologie et code, ou un entrepôt entité-attribut-valeur — où une seule mesure est répartie sur plusieurs lignes qu’il faut recoller.
Le bouton SQL de chaque bloc — ou Écrire le SQL sur un bloc vide — ouvre la fenêtre de la relation. Elle s’ouvre sur le SQL généré depuis le formulaire ; dès que vous le modifiez, il est marqué Modifié, et Réinitialiser revient au SQL généré. La requête doit être un seul SELECT, qui nomme ses colonnes exactement comme le contrat (AS patient_id).
SQL — linkr_event_mesures
Généré depuis le formulaire, ou écrit à la main (Cmd+S enregistre). Le contrat à droite liste les colonnes à renvoyer.
Trois onglets :
- SQL — l’éditeur, et le Contrat à droite : les colonnes à renvoyer, les obligatoires en gras, avec le type attendu de chacune. Cmd/Ctrl + S enregistre, et relance le contrôle.
- Contrôle du contrat — sur la base choisie, Contrôler décrit ce que renvoie la requête, sans lire les données. Chaque colonne du contrat est remplie, obligatoire, absente, de mauvais type, ou non renvoyée (NULL) ; les colonnes hors contrat sont ignorées. Une colonne de mauvais type se corrige d’un
CASTdans la requête. - Aperçu — Exécuter affiche les 100 premières lignes que renvoie la relation.
Un schéma n'a pas de données : le contrôle se fait sur une base
Le contrôle et l’aperçu s’exécutent sur une base qui utilise ce schéma, choisie dans la fenêtre. S’il n’y en a encore aucune, la fenêtre le dit : installez-en une depuis ce schéma — ou créez-la avec Nouveau depuis un schéma, voir Bases de données.
Une fois le SQL enregistré, le bloc affiche Définie en SQL, suivi des colonnes que le dernier contrôle a trouvées remplies. Ces colonnes sont enregistrées avec la requête : c’est ainsi que le reste de l’application sait, par exemple, si un critère d’âge ou une valeur dans la frise est disponible. Tant qu’aucun contrôle n’a été lancé, le bloc le signale.
La fenêtre SQL enregistre directement, sans passer par Modifier, dès que vous avez le droit de modifier le schéma.
Le formulaire et le SQL ne se cumulent pas
Une relation définie en SQL ignore son formulaire. Changer le formulaire d’une telle relation régénère le SQL et supprime votre modification : Linkr le demande d’abord, avec Supprimer le SQL modifié ?
Un dernier avertissement du contrôle mérite d’être connu : une fonction de fenêtre sur toute la relation (OVER sans PARTITION BY) empêche Linkr de filtrer par patient en amont, et chaque page patient parcourt alors toute la table. Prenez plutôt une clé de la source comme identifiant, ou partitionnez la fenêtre par patient.
Un schéma, plusieurs bases
Une base copie le schéma au moment où on le lui rattache — le DDL comme le mapping — et note de quel schéma, et de quelle version, vient sa copie. Elle n’y renvoie pas.
Le schéma
OMOP CDM 5.4 — version 1.3.0
Installé une fois dans l’espace de travail.
copie
Base « Réanimation »
Copie de la version 1.2.0
SurchargéeMesures : redéfinie en SQL pour cette base
Base « MIMIC-IV démo »
Copie de la version 1.3.0
C’est ce qui rend une base robuste : elle continue de fonctionner si le schéma est modifié, supprimé, ou s’il n’a jamais été installé sur l’instance où elle arrive.
Et c’est ce qui lui permet d’avoir ses particularités. Une base peut surcharger une relation de sa copie : la redéfinir pour elle seule — par exemple parce que ses mesures sont rangées autrement —, tandis que le schéma et les autres bases restent intacts. Dans l’onglet Mapping de la base, une telle relation porte le badge Surchargée, et la fenêtre SQL y contrôle et prévisualise directement sur la base. Voir Le mapping d’une base.
Modifier un schéma ne met pas à jour les bases existantes
La correction ne se propage pas d’elle-même. Pour l’appliquer à une base, ouvrez l’onglet Mapping de cette base : quand le schéma a changé depuis la copie, un bouton Mettre à jour depuis le preset remplace la copie par la version actuelle, en conservant les surcharges de la base. Choisir un autre schéma dans Modifier, en revanche, repart de zéro : la copie est refaite et les surcharges sont abandonnées.
Symétriquement, supprimer un schéma ne casse aucune base — chacune garde sa copie. Sa carte affiche simplement « Schéma (non installé) » et cesse d’être un lien.
Quelques limites
- Une colonne qui n’existe pas ne fait pas d’erreur. Une faute de frappe dans un nom de colonne ne casse pas la relation : cette colonne revient simplement vide. Le contrôle du contrat ou l’aperçu le révèlent.
- Les jointures d’un preset restent en lecture seule dans le formulaire. Une relation installée avec une jointure — la date de décès d’OMOP, lue dans la table
death— affiche sa jointure grisée : la table, le filtre et les colonnes simples restent modifiables, la jointure elle-même se change en SQL. - Le contrôle a besoin d’une base. Sans base installée depuis le schéma, une relation SQL s’enregistre mais ne se vérifie pas.
Pour aller plus loin
- Schémas — ce qu’est un schéma, et ses deux moitiés.
- Obtenir et explorer un schéma — le catalogue, l’import, le DDL et le diagramme.
- Le mapping d’une base — surcharger une relation, et suivre les mises à jour du schéma.
- Concepts — ce que les dictionnaires rendent possible.
- Alignement de concepts — faire correspondre vos codes locaux à une terminologie standard.