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).

Aucun commentaire:

Enregistrer un commentaire