lundi 23 juillet 2018

L'encodage d'objet DICOM - Format Classique (Partie 2)

Ce billet constitue la seconde partie sur la présentation de l'encodage d'objets DICOM avec le format classique (décrit dans la partie PS3.5). Afin de comprendre la suite de cet article, il est préférable d'avoir lu la première partie qui introduit les concepts d'endianisme et du système Implicit VR.

2.2. L'encodage Explicit VR


Le système Explicit VR est très proche du système Implicit VR. Il reprend exactement le même formalisme mais en ajoutant un champ pour stocker le type de l'élément (la VR). Avec ce système, il n'y a plus de risque de non interprétation des données car la VR est incluse dans l'encodage de l'élément. En contrepartie, l'espace utilisé pour représenter un élément est un peu plus conséquent. Suivant la VR, deux codages sont possibles (voir DICOM PS3.5 section 7.1.2):
           
Pour les VR de type OB, OD, OF, OL, OW, SQ, UC, UR, UT ou UN
           
Pour les VR autres que celles listées dans la figure ci-dessus

Exemple 1 : Encodage Explicit avec une VR textuelle de type « DA »
pour encoder l'élément
(0010,0030) DA #8 [20180608] PatientBirthDate
  • Le numéro de groupe du tag est un nombre codé sur 2 octets, il faut donc appliquer l'endianisme. « 00 10 » sera donc encodé « 10 00 » ;
  • La même logique que pour le numéro de groupe s'applique au numéro d'élément. « 00 30 » sera donc encodé « 30 00 » ;
  • La VR est une donnée textuelle, elle n'est donc pas affectée par l'endianisme. Les deux caractères « DA » sont donc codés par « 44 41 » ;
  • La chaîne « 20180608 » est composée de 8 caractères. Cette longueur de 8 est représentée en hexadécimal sur 2 octets par « 00 08 ». Ce nombre étant multi-octets, l'endianisme s'applique. « 00 08 » sera donc encodé « 08 00 » ;
  • Enfin « 20180608 » est une chaîne textuelle, l'endianisme ne s'applique donc pas. La longueur du texte étant paire, il n'est donc pas nécessaire de la compléter par un caractère NULL. La chaîne finale sera donc encodée « 32 30 31 38 30 36 30 38 ».
L'élément Patient's Birth Date sera donc encodé sur 14 octets dont la valeur binaire est : « 10 00 30 00 08 00 32 30 31 38 30 36 30 38 »



Exemple 2 : Encodage Explicit avec une VR binaire de type « OB »
pour encoder l'élément
(7FE0,0010) OB #25 [pixel Value] PixelData
  • Le numéro de groupe du tag est un nombre codé sur 2 octets, il faut donc appliquer l'endianisme. « 7F E0 » sera donc encodé « E0 7F » ;
  • La même logique que pour le numéro de groupe s'applique au numéro d'élément. « 00 10 » sera donc encodé « 10 00 » ;
  • La VR est une données textuelle de type OB, elle est donc codée sur 4 octets et n'est donc pas affectée par l'endianisme. Pour les 4 octets, DICOM indique que les deux octets de poids fort (je rappelle que l'on est en Little Endian) valent « 00 00 ». Les deux caractères « OB » sont donc encodés par « 4F 42 00 00 » ;
  • Nous voulons encoder une image de 5x5 pixels avec une VR de type « OB » (1 octet par pixel), soit 5x5=25 pixels. La chaîne étant de longueur impaire, il faudra ajouter le caractère NULL pour obtenir une longueur de 26. Cette longueur de 26 est représentée en hexadécimal sur 4 octets par « 00 00 00 1A ». Ce nombre étant multi-octets, l'endianisme s'applique. « 00 00 00 1A » sera donc encodé « 1A 00 00 00 » ;
  • Supposons que la valeur des 25 pixels soit « 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 ». La VR « OB » étant codé sur 1 octet, l'endianisme ne s'applique pas. De plus, DICOM impose une longueur paire. On ajoute donc le caractère NULL binaire 0x00. On obtient donc en final la chaîne encodée suivante : « 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 00 ».

Remarque : Il n'est pas possible de mélanger des Data Element encodés en Implicit VR et en Explicit VR dans un même objet DICOM.

3. Exemple d'encodage d'un objet DICOM


Nous savons maintenant encoder des Data Element. Essayons d'encoder un objet DICOM composé des deux Data Element suivants.

(0008,0018) UI #6 [1.2.3] SOPInstanceUID
(0010,0040) CS #2 [M] PatientSex

L'encodage d'objet DICOM consiste à enchaîner les différents Data Element. Pour cet exemple, nous allons utiliser l'encodage Implicit VR. Voici le résultat de l'encodage de cet objet:
           
Exemple d'objet DICOM (Cliquer pour agrandir)

4. L'encodage des séquences


Jusqu'à présent, nous avons vu comment encoder des Data Element et des objets DICOM. Mais voilà, il existe dans le standard un type de Data Element particulier qui permet de contenir des objets DICOM, le type SQ.
Pour inclure un objet dans un autre, il faut pouvoir délimiter où commence et où se termine l'objet à imbriquer. DICOM propose deux méthodes pour marquer cette limite : la solution « Explicit Length » et la solution « Undefined Length ».
Quelque soit la méthode choisie, DICOM définit les règles d'encodages suivantes concernant un Data Element de type SQ:
  • Chaque objet DICOM contenu dans une séquence est encodé comme un Item. Une séquence peut avoir plusieurs Items ;
  • Une séquence peut utiliser l'encodage « Explicit Length » ou « Undefined length » ;
  • Un Item peut utiliser l'encodage « Explicit Length » ou « Undefined Length ».
Dans les sections suivantes, nous utiliserons l'encodage Implicit VR pour présenter les méthodes « Explicit Length » et « Undefined Length ». 

4.1. L'encodage d'une séquence en « Undefined Length »


L'encodage « Undefined Length » permet de ne pas connaître la longueur des objets (des items) à intégrer dans la séquence. Pour délimiter un objet, DICOM utilise un marqueur de début et de fin (à la manière de XML qui utilise des balises pour délimiter une valeur).
Il existe en DICOM des « marqueurs » pour délimiter une séquence et des « marqueurs » pour délimiter les /items.
Puisque qu'en DICOM tout est Data Element et que la règle générale d'encodage (Implicit VR ou Explicit VR) est que chaque Data Element est composé d'un Tag, d'une longueur et d'une valeur. Il va falloir jouer avec ces 3 champs pour créer des marqueurs.

4.1.1 Règles d'encodages


Pour représenter les marqueurs, DICOM donne des valeurs particulières aux champs « Tag », « Length » ou « Value ».
Ainsi le marqueur de début d'une séquence est définit par un Data Element qui a les spécificités suivantes :
  • Le champ « Tag » doit avoir une VR SQ ;
  • Le champ « Length » doit avoir la valeur FFFFFFFFH (indique que la taille est inconnue) ;
  • Le champ « Value » contient les différents Item.
Le marqueur de fin de séquence est définit par un Data Element se situant après le dernier item et ayant les caractéristiques suivantes:
  • Le champ « Tag » doit avoir la valeur (FFFE, E0DD) ;
  • Le champ « Length » doit avoir la valeur 00000000H ;
  • Pas de présence du champ « Value ».
           
Marqueurs de séquence (Cliquer pour agrandir)

Le marqueur de début d'item est définit par un Data Element qui a les spécificités suivantes:
  • Le champ « Tag » doit avoir la valeur (FFFE, E000) ;
  • Le champ « Length » doit avoir la valeur FFFFFFFFH ;
  • Le champ « Value » contient l'objet DICOM.

Le marqueur de fin d'item est définit par un Data Element se situant après l'objet DICOM et ayant les caractéristiques suivantes:
  • Le champ « Tag » doit avoir la valeur (FFFE, E00D) ;
  • Le champ « Length » doit avoir la valeur 00000000H ;
  • Pas de présence du champ « Value ».
Marqueur d'Item (Cliquer pour agrandir)

Remarque : Puisque les Data Element (FFFE, E000), (FFFE, E00D) et (FFFE, E0DD) n'ont pas de valeur, il n'ont pas besoin d'avoir une VR (la VR de ces 3 éléments n'existe pas).

4.1.2. Exemple d'encodage d'une séquence en « Undefined Length »


Supposons que l'on dispose de la séquence suivante à encoder en Implicit VR. Cette séquence est composée de deux Items. Le premier contient un objet de deux Data Element; le second contient un objet d'un seul Data Element

(0040,A730) SQ #-1 ContentSequence
> (FFFE,E000) #-1 Item #1
> (0008,0018) UI #6 [1.2.3] SOPInstanceUID
> (0010,0040) CS #2 [M] PatientSex
> (FFFE,E00D) #0 ItemDelimitationItem
> (FFFE,E000) #-1 Item #2
> (0008,0050) SH #4 [AN1] AccessionNumber
> (FFFE,E00D) #0 ItemDelimitationItem
(FFFE,E0DD) #0 SequenceDelimitationItem

En appliquant les règles d'encodage de séquence, d'item et de Data Element, on obtient le résultat suivant:
Exemple d'encodage en Implicit VR d'une séquence en « Undefined Length » (Cliquer pour agrandir)

4.2. L'encodage d'une Séquence en « Explicit Length »


Cette méthode d'encodage permet de savoir la taille exacte de la séquence et de l'objet contenu dans cette dernière. Cette solution est similaire à l'encodage des Data Element de type autre que SQ.

4.2.1. Règles d'encodages


L'encodage d'une séquence en « Explicit Length » se fait de la manière suivante :
  • Le champ « Tag » doit avoir une VR QS ;
  • Le champ « Length » doit avoir la longueur du champ « Value » ;.
  • Le champ « Value » contient les différents Item.
L'encodage d'un item « Explicit Length » se fait de la manière suivante:
  • Le champ « Tag » doit avoir la valeur (FFFE, E000) ;
  • Le champ « Length » doit contenir la longueur de la valeur ;
  • Le champ « Value » contient l'objet DICOM.
           
encodage d'une séquence en « Explicit Length » (Cliquer pour agrandir)

4.2.2. Exemple d'encodage de la séquence


Essayons d'encoder une séquence ayant deux Items. Le premier item contient un objet composé de deux Data Element; le second item contient un objet composé d'un seul Data Element.

(0040,A730) SQ #52 ContentSequence
> (FFFE,E000) #24 Item #1
> (0008,0018) UI #6 [1.2.3] SOPInstanceUID
> (0010,0040) CS #2 [M] PatientSex
> (FFFE,E000) #12 Item #2
> (0008,0050) SH #4 [AN1] AccessionNumber
> (FFFE,E00D) #0 ItemDelimitationItem
(FFFE,E0DD) #0 SequenceDelimitationItem

Exemple d'encodage en Implicit VR en « Explicit Length » (Cliquer pour agrandir)

4.3 « Undefined Length » versus « Explicit Length »


L'utilisation de la méthode « Undefined Length » permet de ne pas connaître la longueur d'une séquence ou d'un item. Ainsi, il n'est pas nécessaire de calculer la longueur d'un item ou d'une séquence. Ce système semble plus fiable que la solution « Explicit Length » car si une erreur est commise sur le calcul de la taille, la séquence devient illisible. D'un autre côté, l'utilisation de la méthode « Explicit Length » permet d'ignorer un Data Element SQ en allant directement au suivant en sautant du nombre d'octets de la longueur de la séquence si l'on n'est pas intéressé par cette dernière.

Nous avons vu deux méthodes pour encoder une séquence, mais rien n'empêche de mélanger les deux méthodes. Par exemple, d'utiliser la méthode « Undefined Length » pour encoder une séquence et d'utiliser la méthode « Explicit Length » pour encoder chacun des items de cette séquence. On pourrait également imaginer que certains items d'une séquence sont en « Undefined Length » et d'autres en « Explicit Length ». En fait, toutes les combinaisons sont possibles, DICOM l'autorise parfaitement.

En pratique, les éditeurs ou constructeurs ne mettent en place qu'une seule méthode pour créer des séquences. Le plus souvent la méthode « Undefined Length » qui est plus facile à implémenter et plus fiable.

Remarque: DICOM impose de savoir lire toutes les méthodes (et combinaisons possibles) pour interpréter correctement un objet. En revanche, le standard n'impose pas de savoir écrire toutes les méthodes.

lundi 9 juillet 2018

L'encodage d'objet DICOM - Format Classique (Partie 1)

Comme vu dans l'article « Les données en DICOM », le standard définit des objets pour stocker et organiser des données médicales. Cette représentation des objets est encore théorique puisque rien n'est défini pour les écrire en mémoire, sur le disque, ou pour les faire voyager sur un réseau. La prochaine étape est donc de définir un encodage de ces objets.

Encoder un objet DICOM signifie écrire un ensemble d'éléments dans un format spécifique. Cela implique d'avoir des règles pour transformer chaque Data Element dans le format désiré. Ce format peut être binaire ou textuel. Dans la version actuelle (2018) du standard, il existe trois manières d'encoder un objet DICOM.
  • L'encodage classique, format historique, qui existe depuis le début du standard ;
  • L'encodage XML apparu au début des années 2010 ;
  • Et l'encodage JSON le dernier en date.
Dans cet article, nous allons nous intéresser au format DICOM classique. D'autres billets présenteront les encodages XML et JSON.

La présentation de ce système d'encodage étant assez conséquente, nous la décomposerons en deux parties.

Le format classique


Ce système d'encodage est le premier format proposé dans le standard. Il s'agit d'un format binaire, c'est-à-dire non interprétable sous forme de texte. Ses règles d'encodage sont décrites dans la partie PS3.5 du standard. Cet encodage repose sur deux règles majeures : l'endianisme et l'encodage Implicit/Explicit.

1. L'endianisme (le boutisme)


Le sens d'écriture et de lecture diverge d'une civilisation à l'autre. De gauche à droite pour les langues européennes et de droite à gauche pour les langues sémitiques (arabe et hébreu par exemple). Tout comme pour les différentes civilisations, il existe en informatique un sens d'écriture et de lecture des octets. Cet ordre de lecture et d'écriture est appelé « Endianisme ». En informatique on parle de Big Endian et de Little Endian suivant l'écriture des octets dans un sens ou dans un autre.

Remarque : Ici, on ne s’intéresse qu'à l'endianisme à l'échelle de l'octet. L'endianisme pouvant s'appliquer à une granularité plus fine, comme le bit .

1.1. Big Endian


Indique que les octets sont positionnés de gauche à droite.  Supposons que l'on ait le nombre hexadécimal 012C (300 en décimal) à encoder en Big Endian. Ce nombre est représenté par 2 octets, 01 et 2C. Il faut positionner ces octets de gauche à droite, on obtient donc le résultat 012C en Big Endian.

1.2. Little Endian


Indique que les octets sont positionnés de droite à gauche. Supposons que l'on ait le nombre hexadécimal 012C (300 en décimal) à encoder en Little Endian. Ce nombre est représenté par 2 octets, 01 et 2C. Il faut positionner ces octets de droite à gauche. On obtient donc le résultat 2C01 en Little Endian.

1.3. L'endianisme et DICOM


DICOM se voulant universel, il doit prendre en compte les différentes architectures des machines (Intel, Motorola, Sparc, etc.). C'est pourquoi le standard inclut l'endianisme dans l'encodage classique.
DICOM applique l'endianisme au niveau de l'octet. Cela a pour conséquence de n'affecter que les données étant codées sur plus d'un octet (multi-octets). En revanche les données codées sur un seul octet ne seront pas affectées par l'endianisme. En effet, positionner un seul octet de gauche à droite ou de droite à gauche revient à la même chose.
Pour résumer:
  • Les données binaires codées sur un octet ne sont pas affectées par l'endianisme. Cela correspond aux Data Element ayant une VR de type OB ;
  • Les données textuelles en DICOM étant codées sur un octet, elles ne sont pas affectées par l'endianisme. En effet, chaque caractère est codé de manière indépendante sur 1 octet. Cela correspond aux Data Element ayant une VR de type AE, AS, CS, DA, DS, DT, IS, LO, LT, PN, SH, ST, TM, UC, UI, UN, UR et UT ;
  • Les données représentant un nombre binaire multi-octets sont affectées par l'endianisme. Cela correspond à chaque composante de l'identifiant d'un tag (codée sur 2 octets) et aux Data Element ayant une VR de type FD, FL, OD, OF, OL, OW, SL, SS, UL, US et chaque composante du type AT.
Remarque : DICOM autorisait historiquement l'utilisation de l'ordonnancement des octets en Big Endian et Little Endian. Mais depuis 2014, le standard a retiré l'utilisation du Big Endian. Seul l'ordonnancement des octets en Little Endian est maintenant autorisé.

Remarque : Si des machines ont une architecture Big Endian, alors les logiciels DICOM devront effectuer un byte swapping avant d'interpréter ou de traiter certains Data Element.

2. L'encodage Implicit/Explicit


Dans l'article « Les données en DICOM », nous avons vu qu'un objet DICOM (ou DataSet) est un ensemble de Data Element. Encoder un objet DICOM revient donc à disposer de règles pour encoder un Data Element, puis d'enchaîner l'encodage des différents Data Element les uns à la suite des autres. Chacun des Data Element est composé d'un Tag, d'un Type et d'une Valeur (qui peut être multiple). Il faut donc pouvoir encoder ces trois informations.
Pour réaliser cela, DICOM définit deux types d'encodages appelés Implicit VR et Explicit VR.

2.1. L'encodage Implicit VR


Le système Implicit VR est le système par défaut dans DICOM et utilise l’ordonnancement Little Endian. Il permet de ne pas inclure le type (la Value Représentation) des Data Element dans l'encodage. On obtient ainsi une représentation de l'objet plus petite, car moins de données encodées. Cependant le décodage de l'objet nécessite de disposer d'un dictionnaire de données. L'encodage se fait de la manière suivante:


DICOM impose que la valeur d'un élément soit de longueur paire. De ce fait, si une valeur a une longueur impaire, elle doit être complétée par un caractère. Ce caractère est un Espace (0x20) pour les valeurs de type texte (à l'exception du type UI), et un caractère Null (0x00) pour les valeurs de type binaires et de type UI.

Exemple:
pour encoder le Data Element suivant : (0010,0010) PN #11 [Dupond^Jean] PatientName
  • Le numéro de groupe du tag est un nombre codé sur 2 octets, il faut donc appliquer l'endianisme. « 00 10 » sera donc codé « 10 00 ».
  • La même logique que pour le numéro de groupe s'applique au numéro d'élément.
  • La chaîne « Dupond^Jean » est composée de 11 caractères. Il faut donc la compléter par le caractère 0x20 pour obtenir une longueur paire. Cette longueur finale de 12 caractères est représentée en hexadécimal sur 4 octets par « 00 00 00 0C ». Ce nombre étant multi-octets, l'endianisme s'applique. « 00 00 00 0C » sera donc codé « 0C 00 00 00 ».
  • Enfin « Dupond^Jean » est une chaîne textuelle, l'endianisme ne s'applique donc pas. La longueur du texte étant impaire, il faut ajouter le caractère 0x20. La chaîne finale sera alors codée « 44 75 70 6F 6E 64 5E 4A 65 61 6E 20 »
L'élément Patient's Name sera donc codé sur 20 octets dont la valeur binaire est :
« 10 00 10 00 0C 00 00 00 44 75 70 6F 6E 64 5E 4A 65 61 6E 20 »


3. Quelques mots sur le type PN


Le type PN permet de représenter le nom complet d'une personne (nom, prénoms, civilité, etc.). Afin de pouvoir stocker ces différentes informations, DICOM définit l'encodage à 5 composants suivant :

FamilyName^GivenName^MiddleName^NamePrefix^NameSuffix

Chaque composant est séparé par le caractère « ^ ».

Ce formalisme n'est pas sans rappeler celui utilisé par le type HL7 v2 XPN (qui est d'ailleurs mentionné dans le standard DICOM pour parler de la VR PN). Il est donc possible de faire un parallèle entre le type DICOM PN et le type de données HL7 XPN. En combinant les remarques du standard DICOM sur l'utilisation des champs et les contraintes sur les types de données HL7 v2.5 applicables aux profils d’intégration du cadre technique ITI dans le périmètre d'IHE France (publié par Interop'Santé), on en déduit l'utilisation des composants de la manière suivante:
  • FamilyName : contient le nom de famille ;
  • GivenName : contient le premier prénom ;
  • MiddleName : contient les prénoms autres que le premier prénom ;
  • NamePrefix : contient la civilité ;
  • NameSuffix : non utilisé dans le contexte français.
Remarque : Malheureusement, DICOM ne permet pas de spécifier le type de nom (de naissance, d'usage, pseudonyme). Il serait intéressant d'étendre l'encodage DICOM PN en ajoutant un 6ème composant « NameTypeCode » comme l'a fait HL7 en passant de la version 2.2 à 2.3 du standard en introduisant le type XPN en remplacement du type PN.

Le type PN permet aussi de prendre en compte différents systèmes d'écriture (Alphabétique(1) et Idéographique-Phonétique(2)). Pour représenter ces systèmes le type PN propose l'encodage suivant:

AlphabeticRepresentation=IdeographicRepresentation=PhoneticRepresentation

Chaque représentation d'écriture est optionnelle et séparée par le caractère « = ». Enfin, chacune des représentations est composée des 5 champs décrits ci-dessus. 
Exemple d'un nom et prénom Japonais utilisant les 3 systèmes de représentation

Yamada^Tarou=山田^太郎=やまだ^たろう

L'annexe H.3 de la partie PS3.5 donne un exemple d'encodage en binaire d'un nom Japonais.

Remarque : Dans le contexte Français, seul le système de représentation alphabétique est utilisé.
Ainsi, Lionel Droz-Bartholet est encodé en PN par « Droz-Bartholet^Lionel ». L'encodage « Droz-Bartholet^Lionel== » est également possible mais comme chacune des trois représentations est optionnelle, les deux séparateurs « = » peuvent être retirés.

(1) Les systèmes idéographiques: Dans ces systèmes, chaque signe représente un objet (on parle alors de pictogramme) ou une idée (idéogramme). L'écriture idéographique exige des milliers de signes et un long apprentissage.
(2) Les systèmes alphabétiques: Dans ces systèmes, chaque signe représente un son décomposé. Plusieurs signes sont regroupés pour représenter un son. Grâce aux multiples combinaisons possibles, une trentaine de signes maximum sont nécessaires pour rendre compte d'une langue (source: http://classes.bnf.fr/dossiecr/sys-ecri.htm).

dimanche 1 juillet 2018

Les données en DICOM

1. Les éléments DICOM


1.1 Le dictionnaire de données


Dans la partie « Généralités sur le standard DICOM », il a été dit que pour éviter des erreurs et assurer un certain degré de traçabilité, il fallait lier une image à son contexte (pour qui, par qui, pourquoi, comment, etc.).
Afin de réaliser cela, DICOM définit une liste de données contenant les éléments pouvant être utiles dans le milieu de la médecine numérique. Cette liste est exposée dans un dictionnaire de données représenté par la partie PS3.6 du standard. Dans ce dictionnaire, on peut trouver des éléments comme le nom du patient, sa date de naissance, son identifiant local, la date d'un examen d'imagerie, le type de machine ayant produit l'imagerie, son modèle, le nom du prescripteur de l'examen, le nom de la personne ayant réalisé l'examen, etc.
Le dictionnaire de données DICOM définit ainsi plus de 2000 éléments en tout genre. Chacun de ces éléments dispose d'un nom descriptif appelé « Name ».
Pour mettre de l'ordre dans une telle quantité d'éléments, DICOM a classé ces derniers par groupes. Par exemple, des éléments comme le nom du patient, sa date de naissance, son genre, son poids, sa taille, etc. ont en commun qu'ils concernent tous le patient. DICOM a donc crée un groupe « patient ». D'autres éléments comme la dimension d'une image, ses pixels, le fait qu'elle soit en couleur ou non, ont en commun qu'il s'agit de caractéristiques d'une image. DICOM a donc crée un groupe « image ». Ainsi, tous les éléments appartiennent à un groupe.
Pour continuer dans sa démarche, DICOM a attribué à chaque groupe un numéro unique. Par exemple, le groupe « patient » a le numéro 0010, le groupe « image » a le numéro 0028.
Enfin, pour identifier les éléments appartenant à un groupe, DICOM a également attribué un identifiant unique à chaque élément d'un groupe.
Ainsi, chaque élément du dictionnaire DICOM se voit attribué un identifiant unique appelé tag, qui prend la forme d'un couple (groupe-élément). Chacune des composantes de ce couple est un entier de 4 chiffres en hexadécimal (de 0 à F).
Exemples:
  • le tag (0010, 0010) correspond à l'élément dont le nom est « Patient Name » ;
  • le tag (0010, 0020) représente l'élément dont le nom est « Patient ID » ;
  • le tag (0010, 0030) indique l'élément dont le nom est « Patient's Birth Date » ;
  • le tag (0028, 0010) symbolise l'élément dont le nom est « Rows » en pixel ;
  • le tag (0028, 0011) correspond à l'élément dont le nom est « Column » en pixel ;
  • le tag (7FE0, 0010) est l'identifiant de l'élément dont le nom est « Pixel Data ».

Remarque : La composante représentant le groupe dans le dictionnaire de données DICOM est toujours un nombre pair. Les nombres impairs étant réservés aux tags propriétaires, c'est-à-dire non répertoriés par le standard et spécifiques à un constructeur ou un éditeur.

Remarque : Le groupe FFFF est réservé pour le standard et ne peut donc pas être utilisé par un éditeur ou constructeur.

Remarque : On peut se référer à un élément par son nom descriptif ou son identifiant de manière équivalente. L'identifiant (tag) étant plus court, de taille fixe et avec un format hexadécimal strict, toutes les applications l'utilisent pour se référer à un élément DICOM.

1.2 Le type de données dans DICOM (aka VR)


De par la multiplicité d'éléments que l'on peut trouver dans le dictionnaire de données, il est évident que tous ne sont pas du même type. En effet, on peut trouver :
  • des données qui expriment une distance, dont l'unité de mesure est le millimètre ;
  • des données qui représentent une durée, dont l'unité est la seconde ;
  • des données qui indiquent un point dans le temps, dont l'unité est une date ;
  • des données comme le nom du patient exprimé par une chaîne de caractères alphanumérique ;
  • etc.
Afin de représenter ces différentes catégories d'informations, le standard définit 31 types de données de base tels que:
  • le type DA pour une date: chaîne de 8 caractères sous la forme YYYYMMDD; ou YYYY correspond à une année, MM correspond à un mois de l'année (de 01 à 12) et DD correspond à un jour dans le mois (de 01 à 31). Exemple : 19930822 correspond au 22 août 1993 ;
  • le type UI pour les identifiants : chaîne de 64 caractères maximum composée uniquement de chiffres (0 à 9) et du caractère « . ». Exemple : 1.2.840.10008.1.2 ;
  • le type PN pour un nom de personne: chaîne de 64 caractères maximum sous la forme nomFamille^PremierPrénom^SecondPrénom^Prefix^Suffix, où le caractère « ^ » est le séparateur des 5 composantes du nom. Chacune des composantes peut être vide ;
  • ou encore le type OB pour indiquer un flux d'octets.
Ces types sont connus sous le nom Value Representation (VR).

Remarque : Chaque VR est désignée par un nom à 2 lettres (ex. AE, CS, DA, TM).

De manière grossière, les 31 types peuvent être répartis en 7 catégories:
  • les VR de format texte : AE, CS, LO, LT, SH, ST, UC, UI, UR, UT ;
  • les VR de format date/heure : DA, DT, TM, AS ;
  • les VR de format nombre texte : IS, DS ;
  • les VR de format binaire : FL, FD, OB, OD, OF, OL, OW, SL, SS, UL, UN, US ;
  • une VR pour les noms de personnes : PN ;
  • une VR pour les séquences : SQ ;
  • une VR pour les tags  : AT ;

1.3 La Value Multiplicity (VM)


Parmi tous les éléments du dictionnaire, certains peuvent avoir une seule valeur (un patient ne peut avoir qu'une date de naissance par exemple) ; tandis que d'autres peuvent en avoir plusieurs - un patient peut porter différents noms (un nom de naissance et un nom d'usage par exemple). Pour cette raison, DICOM a introduit la notion de Value Multiplicity (VM). Cette VM peut posséder une valeur stricte ou un plage de valeurs. Chaque élément DICOM a donc une VR qui indique si un élément peut disposer ou non de plusieurs valeurs.
Exemple :
  • le tag (0028, 0030) Pixel Spacing a une VM de 2 (une valeur pour la distance horizontale et une pour la distance verticale) ;
  • le tag (0010, 0030) Patient's Birth Date a une VM de 1 ;
  • le tag (0010, 1001) OtherPatientNames a une VM de 1-n (plusieurs noms sont possibles).
Pour résumer : DICOM définit une liste d'éléments typés (VR), identifiés (tag) de manière unique et ayant un nombre de valeurs spécifié (VM). Ces éléments sont appelés tag ou attribut ou encore DICOM element.

Extrait de quelques éléments du dictionnaire de données
Tag Name Keyword VR VM
 (0010,0020)  Patient ID Patient​ID LO 1
 (0010,0021)  Issuer of Patient ID Issuer​Of​Patient​ID LO 1
(0010,0022) Type of Patient ID Type​Of​Patient​ID CS 1
(0010,0024) Issuer of Patient ID Qualifiers Sequence Issuer​Of​Patient​ID​Qualifiers​Sequence SQ 1
(0010,0026) Source Patient Group Identification Sequence Source​Patient​Group​Identification​Sequence SQ 1
(0010,0027) Group of Patients Identification Sequence Group​Of​Patients​Identification​Sequence SQ 1
(0010,0028) Subject Relative Position in Image Subject​Relative​Position​In​Image US 3
(0010,0030) Patient's Birth Date Patient​Birth​Date DA 1
(0010,0032) Patient's Birth Time Patient​Birth​Time TM 1
(0010,0033) Patient's Birth Date in Alternative Calendar Patient​Birth​Date​In​Alternative​Calendar LO 1
(0010,0034) Patient's Death Date in Alternative Calendar Patient​Death​Date​In​Alternative​Calendar LO 1
(0010,0035) Patient's Alternative Calendar Patient​Alternative​Calendar CS 1
(0010,0040) Patient's Sex Patient​Sex CS 1

Remarque : la colonne Keyword a récemment été ajoutée au standard. Cette donnée d'un seul mot est très similaire au nom descriptif et fournit une alternative à l'identifiant (tag) pour être utilisée en XML ou HTTP.

2. Les objets DICOM


Un objet DICOM (appelé Information Object) est un ensemble d'éléments DICOM (ensemble de tags). Ces objets sont la pierre angulaire du standard DICOM.
Objet DICOM
Un objet DICOM n'est pas toujours un enchaînement linéaire d'éléments DICOM. En effet, parmi tous les types (les VR) définis par le standard, il en existe un qui est particulier. Ce type s'appelle SQ (pour SeQuence). Il permet de contenir un ou plusieurs autres objets DICOM (une séquence d'éléments DICOM) qui peuvent également être des séquences, et donc contenir à leur tour d'autres éléments DICOM.
Objet DICOM imbriqué
On obtient donc une structure imbriquée qui peut vite devenir complexe.

Remarque : Dans un objet DICOM, les éléments doivent être organisés par ordre croissant des tags (cf. PS 3.5 - section 3.10 définition de DataSet).

La définition des objets DICOM (aka IOD)


Un objet est un ensemble d'éléments DICOM. Mais avec plus de 2000 tags dans le dictionnaire de données, comment structurer tout cela ?
Il ne servirait à rien de mettre l'intégralité des éléments définis dans le dictionnaire DICOM dans un même objet, de ne remplir que ceux qui nous intéressent et de laisser les autres vides. Cela prendrait trop de place.
De plus, mélanger des éléments spécifiques à une IRM, tel que (0018, 0087) magnetic field strength, avec des éléments ne concernant que le scanner (comme le kVp dans l'élément (0018, 0060)) ne semble pas très judicieux.
Pour résoudre ce problème, DICOM définit des Information Object Definition (IOD) qui représentent la structure d'un objet DICOM (les éléments à mettre dedans).
Ces IOD sont décrits dans la partie PS3.3 du standard DICOM. Il en existe environ quatre-vingt qui permettent de spécifier :
  • les éléments DICOM à inclure dans un objet ;
  • si ces éléments sont obligatoires ou optionnels ;
  • et la valeur que ces objets peuvent prendre (au travers des VR, d'énumération de valeurs possibles ou de jeux de valeurs).

Par exemple il existe un objet :
Remarque : De manière plus strict, DICOM utilise un système un peu plus hiérarchisé pour définir des objets. Il regroupe des briques de base que sont les DICOM elements en des paquets appelés Modules. Les Modules sont eux même combinés pour former des Informations Entities (IE). Enfin, les IE sont assemblés pour former les Informations Object Définition (IOD) qui sont nos objets DICOM finaux. Il n'en reste pas moins qu'un objet DICOM est au final, un ensemble d'attributs DICOM.



3. Le Modèle hiérarchique DICOM


Que savons-nous de l'organisation des données en DICOM jusqu'à présent ?
DICOM organise les éléments de son dictionnaire en les regroupant, les identifiant et en les typant. Il spécifie également des assemblages d'éléments définis dans des IOD. Mais il reste à refléter un aspect important.
Prenons un exemple :
Un patient se rend dans un hôpital pour subir un examen d'imagerie (disons un PET-SCAN). Cet examen est composé de deux séries d'images, un PET et un SCAN. Chacune de ces séries est elle-même constituée de plusieurs images. Ce même patient, peut très bien revenir quelques temps après et faire une IRM.
Ainsi, un patient peut avoir plusieurs examens d'imagerie. Chacun de ces examens peut être composé d'une ou plusieurs séries ; qui elles-mêmes peuvent être composées d'une ou plusieurs images.
Une hiérarchie Patient-Examen-Série-Image est donc nécessaire.
Afin de représenter ce modèle hiérarchique, DICOM assigne à chacun des 4 niveaux un identifiant unique. Pour le niveau Patient, c'est l'élément « (0010,0020) Patient ID », pour le niveau Examen c'est l'élément « (0020,000D) Study Instance UID », au niveau série, l'identifiant est l'élément « (0020,000E) Series Instance UID », enfin le niveau Image a pour identifiant l'élément « (0008,0018) Series Instance UID ». Quel que soit l'objet DICOM, ces 4 identifiants sont obligatoires.

Remarque : Ce modèle hiérarchique est le point central d'un modèle DICOM plus complexe appelé Model of the Real World décrit dans la partie PS3.3 - section 7.

2.2. Exemple

Voici un exemple (non complet) d'objet DICOM. L'utilitaire dcmdump de l'API dcm4che a été utilisé pour afficher cet exemple.
(0008,0016) UI #26 [1.2.840.10008.5.1.4.1.1.7] SOPClassUID
(0008,0018) UI #10 [1.2.3.4.5] SOPInstanceUID
(0008,0020) DA #8 [20161202] StudyDate
(0008,0021) DA #8 [20161202] SeriesDate
(0008,0050) SH #10 [1002394744] AccessionNumber
(0008,0060) CS #2 [CT] Modality
(0010,0010) PN #14 [John^SMith] PatientName
(0010,0020) LO #8 [2579437] PatientID
(0010,0030) DA #8 [19331013] PatientBirthDate
(0010,0040) CS #2 [M] PatientSex
(0020,000D) UI #9 [1.2.5.6.9] StudyInstanceUID
(0020,000E) UI #11 [1.9.8.7.6.5] SeriesInstanceUID
(0028,0002) US #2 [1] SamplesPerPixel
(0028,0004) CS #12 [MONOCHROME2] PhotometricInterpretation
(0028,0010) US #2 [512] Rows
(0028,0011) US #2 [512] Columns
(0028,0100) US #2 [16] BitsAllocated
(0028,0101) US #2 [12] BitsStored
(0028,0102) US #2 [11] HighBit
(0028,0103) US #2 [0] PixelRepresentation
(7FE0,0010) OB #-1 PixelData
(FFFE,E000) #4 [0\0\0\0] Item
(FFFE,E000) #32836 [-1\-40\-1\-32\0\...
(FFFE,E0DD) #0 SequenceDelimitationItem

    Tag
    VR
    Longueur
    Valeur