DICOM c'est facile: Introduction à DICOM – Bien choisir son serveur d impression

Nous allons aujourd'hui diagnostiquer un problème de communication entre deux applications DICOM et, espérons-le, en trouver la cause et le résoudre. Je sais, nous n’avons même pas commencé à parler du protocole réseau DICOM, mais nous ne lirons pas ensemble ces 3 000 pages standard avant de nous salir les mains, non?
Dans ce post, nous discuterons:

  1. Entités d’application (AE) – les nœuds du réseau DICOM et leur nom – AE Title
  2. Association: session réseau entre homologues entre deux applications DICOM.
  3. Association Negotiation – La première partie de l’association dans laquelle les deux AE se mettent d’accord sur ce qui peut et ne peut pas être fait pendant l’association
  4. Le service de vérification utilisant la commande C-ECHO – une classe de service DICOM utilisée pour vérifier une connexion, sorte de «niveau d’application» au niveau de l’application.
  5. Le service de stockage utilisant la commande C-STORE – un service DICOM qui permet à un AE d'envoyer un objet DICOM à un autre AE

Les commandes C dans C-ECHO et C-STORE désignent Composite. Si vous vous en souvenez, au chapitre 4 du modèle de données DICOM, nous avons expliqué que les applications DICOM échangent des objets composites (les images DICOM que nous connaissons déjà) qui sont des composites de modules de différents IE, les IE étant les entités d’information des données DICOM normalisées. modèle.

Voici l'histoire:

Plainte 20123

Burt Simpson du Springfield Memorial Hospital a déclaré qu’il ne pouvait pas envoyer la capture d’écran au PACS. Il a continué à cliquer sur le bouton vert «Envoyer», mais il a toujours la même erreur: «Échec de l'opération!». Le fichier journal que Burt a copié à partir du système est joint.

Vous pouvez vous demander quel est l’intérêt d’analyser le journal d’une application que nous n’allons jamais utiliser? Eh bien, la vérité est que tous les journaux DICOM se ressemblent. En fait, la plupart des applications DICOM sont assez similaires car les implémentations logicielles DICOM ont des ancêtres communs. S'il s'agit d'une bibliothèque C, il peut s'agir du nœud de test DICOM, CTN. Si c’est Java, c’est peut-être dcm4che. Même s'il s'agit de PHP ou d'autres langages plus récents, les bibliothèques ont été transcrites et portées à partir des anciennes implémentations C afin que tous les journaux DICOM soient similaires.


Dans ce cas, le fichier journal, nommé DICOM-20111207-093017.log, a une longueur de 250 Mo et lorsque vous double-cliquez dessus, le bloc-notes se bloque pendant quelques minutes avant de se bloquer. Lorsque vous ouvrez le journal avec EXCEL, le même modèle se répète 100 fois, une fois pour chaque clic effectué par Burt. Après avoir isolé une répétition, vous voyez ce modèle relativement court avec exactement quatre entrées de journal que nous allons analyser ensemble.

2011-12-1022: 22: 25.906000 1508 INFO Paramètres de demande d'association:

Notre classe d'implémentation UID: 2.16.124.113543.6021.2
Notre version de mise en œuvre Nom: RZDCX_2_0_1_8
Leur UID de classe d'implémentation:
Leur nom de version d'implémentation:
Nom du contexte d'application: 1.2.840.10008.3.1.1.1
Nom de l'application appelante: RZDCX
Nom de l'application appelée: PACS
Nom de l'application qui répond: Titre de l'APP
Notre Max PDU Receive Size: 32768
Leur taille maximale de réception PDU: 0
Le contexte
ID: 1 (proposé)
Abstrait
Syntaxe: = VerificationSOPClass
Proposé
Rôle SCP / SCU: Par défaut
Accepté
Rôle SCP / SCU: Par défaut
Proposé
Syntaxe de transfert:

= LittleEndianExplicit

= BigEndianExplicit

= LittleEndianImplicit

Le contexte
ID: 3 (proposé)
Abstrait
Syntaxe: = SecondaryCaptureImageStorage
Proposé
Rôle SCP / SCU: Par défaut
Accepté
Rôle SCP / SCU: Par défaut
Transfert proposé
Syntaxe (es):

= LittleEndianExplicit

Négociation prolongée demandée: aucune
Négociation étendue acceptée: aucune
2011-12-1022: 22: 26.062000 1508 INFO Résultat de la demande d'association: Normal
Paramètres de réponse d'association:
Notre classe d'implémentation UID: 2.16.124.113543.6021.2
Notre version de mise en œuvre Nom: RZDCX_2_0_1_8
Leur classe d'implémentation UID: 1.2.826.0.1.3680043.2.60.0.1
Leur version de mise en œuvre Nom: softlink_jdt103
Nom du contexte d'application: 1.2.840.10008.3.1.1.1
Nom de l'application appelante: RZDCX
Nom de l'application appelée: PACS
Nom de l'application qui répond: PACS
Notre Max PDU Receive Size: 32768
Leur Max PDU Receive Size: 32768
Le contexte
ID: 1 (accepté)
Abstrait
Syntaxe: = VerificationSOPClass
Rôle proposé du SCP / SCU: Par défaut
Accepté
Rôle SCP / SCU: Par défaut
Accepté
Syntaxe de transfert: = LittleEndianImplicit
Le contexte
ID: 3 (Syntaxe abstraite non
Prise en charge
)
Abstrait
Syntaxe: = SecondaryCaptureImageStorage
Proposé
Rôle SCP / SCU: Par défaut
Accepté
Rôle SCP / SCU: Par défaut
Négociation prolongée demandée: aucune
Négociation étendue acceptée: aucune
2011-12-1022: 22: 31.234000 1508 INFO Impossible de stocker un objet car la classe SOP n'était pas
négocié ou non accepté par les pairs
. AMADOUER
Classe UID: 1.2.840.10008.5.1.4.1.1.7, UID Instance UID:
2.16.124.113543.6021.1.3.3727584845.5056.1323548540.2
2011-12-1022: 22: 31.234000 1508 ERREUR dans DCXREQ, Code: 520, Texte: DIMSE Non valide
ID de contexte de présentation

Le problème est clairement indiqué dans la troisième entrée du journal et marqué comme erreur dans la quatrième entrée. Cela dit que l'application homologue, celle que nous voulons envoyer à notre image, refuse de stocker ce type d'objet. Certaines boîtes à outils fournissent des informations utiles supplémentaires. Cependant, nous aurions pu deviner que ce serait déjà le problème dans la deuxième entrée du journal dans la réponse à la demande d'association, où le contexte de présentation pour la capture secondaire était marqué comme n'étant pas pris en charge par l'AE appelé.

Le journal ci-dessus provient de la courte fonction C # suivante que j’ai écrite pour cet article:

Publique vide SendSCImage (DCXOBJ o)
DCXAPP app = Nouveau DCXAPP();
app.LogLevel
= LOG_LEVEL.LOG_LEVEL_INFO;
app.StartLogging ("DICOM.log")
essayer
DCXREQ req = Nouveau DCXREQ();
req.SendObject ("RZDCX", "PACS", "localhost",
6104, o);
capture (Exception e)
Messagerie.Show (e.Message);

Avec la fonction CreateSCImage que nous avons écrit ensemble au chapitre 4, nous avons ce petit programme qui crée une image secondaire en mémoire puis tente de l’envoyer:

DCXOBJ o =
CreateSCImage ();

Avant d’analyser le journal, examinons le code de SendSCImage et assurez-vous de le comprendre.
Les trois premières lignes créent une classe DCXAPP et définissent le niveau de journalisation sur un niveau inférieur au niveau le plus élevé ("Debug"). La classe DCXAPP est utilisée pour contrôler les paramètres globaux de RZDCX. Une fois qu'il est hors de portée, les paramètres restent.
Ensuite, nous avons le bloc try-catch qui est très simple. Nous créons une classe DCXREQ et l’utilisons pour envoyer l’objet que nous avons créé à l’aide de la méthode SendObject. DCXREQ est un demandeur DICOM – une application DICOM qui initie le réseau DICOM avec une autre application et envoie des commandes DICOM. SendObject prend cinq (5) paramètres et encapsule tout le monde de la mise en réseau DICOM. L’ensemble de ce journal a été généré par cette méthode unique car il effectue tout le travail de mise en réseau DICOM pour vous et c’est exactement ce qui est unique dans RZDCX, vous n’aurez pas à traiter tous ces détails. Néanmoins, il est bon de savoir ce qui se passe à l’intérieur. Ainsi, lorsque la situation se gâte, vous avez une idée de ce qui pourrait mal tourner.
Comme toutes les autres méthodes de mise en réseau de DCXREQ, les quatre (4) premiers paramètres de SendObject sont utilisés pour établir la connexion réseau DICOM avec l'application DICOM distante.
Le premier paramètre est notre titre d'entité d'application. Dans le réseau DICOM, chaque nœud est une entité d'application (AE) et son nom est AE Title. Vous vous demandez peut-être pourquoi nous avons besoin d'un titre AE si nous avons un nom de serveur ou une adresse IP et que la réponse est qu'un titre AE est en quelque sorte un alias pour la combinaison adresse IP et numéro de port. Nous pouvons exécuter de nombreuses applications DICOM sur un seul serveur. Je peux exécuter deux instances de mon PACS sur le même ordinateur, une sur le port 104, qui est le port TCP / IP standard réservé aux communications DICOM, et une autre sur le port 1104. Chaque application peut être complètement indépendante de l'autre. Je peux exécuter autant d'applications DICOM que je le souhaite, toutes ayant la même adresse IP.
En passant, DICOM est presque toujours utilisé dans un environnement de réseau local et je déconseille fortement à quiconque d’utiliser DICOM dans un environnement de réseau étendu, même si je sais que certaines personnes le font, mais ce n’est vraiment pas une bonne idée. Le protocole DICOM est interne, privé, sur votre réseau local, de préférence dans son propre sous-réseau dédié.
Les titres AE sont sensibles à la casse, 16 caractères maximum.
Le second paramètre est le titre AE de l'application à laquelle nous souhaitons nous connecter. Nous l'appelons parfois l'application cible ou appelé titre AE ou AE répondant ou simplement l'homologue.
Le troisième paramètre est le nom du serveur (ou l'adresse IP) du serveur sur lequel l'AE appelé est exécuté.
Le quatrième paramètre est le numéro de port écouté par l'AE appelé.
Ceci conclut les paramètres communs à toutes les méthodes réseau DCXREQ. Avec ces paramètres, nous pouvons commencer une ‘Association’ avec l’AE appelé.
Le nouveau terme qui nous intéresse ici est Association. Qu'est-ce que c'est? C’est comme une session réseau. C’est un cadre dans lequel la conversation avec l’appelant appelé va avoir lieu.
Nous pouvons diviser la communication réseau DICOM en deux parties. La première partie configure l'association et la seconde échange des commandes DICOM.

99% des difficultés liées à la mise en réseau DICOM sont liées à la première partie – la négociation d’association.

Même si cette étape est passée et que nous commençons à échanger des commandes, il est probable que les problèmes proviennent de fautes dans la première partie.


Le cinquième paramètre est l'objet que nous aimerions envoyer.
SendObject effectue les opérations suivantes:

  1. Démarrer une connexion TCP / IP
  2. Négocie les paramètres d'association pour convenir de ce qui peut être fait pendant l'association
  3. Envoyer l'objet DICOM
  4. Fermer l'association
  5. Fermer la connexion TCP / IP

Revenons au journal et examinons maintenant la première partie du journal. C'est ici:

2011-12-1022: 22: 25.906000 1508 paramètres de demande d'association INFO:
Notre classe d'implémentation UID: 2.16.124.113543.6021.2
Notre version de mise en œuvre Nom: RZDCX_2_0_1_8
Leur UID de classe d'implémentation:
Leur nom de version d'implémentation:
Nom du contexte d'application: 1.2.840.10008.3.1.1.1
Nom de l'application appelante: RZDCX
Nom de l'application appelée: PACS
Nom de l'application qui répond: Titre de l'APP
Notre Max PDU Receive Size: 32768
Leur taille maximale de réception PDU: 0

Cette partie du journal est une sauvegarde textuelle de la première information envoyée à l'AE appelé et appelée Demande d'association. C’est un ensemble de paramètres décrivant notre application, ses capacités et ses intentions au cours de cette session.
Chaque entrée de journal dans le journal RZDCX commence par un horodatage, un ID de thread (1508 dans ce cas) et le niveau de journal de l'entrée (INFO dans ce cas). Dans le journal complet ci-dessus, j'ai mis en évidence les horodatages au début de chaque entrée du journal.
Le premier élément de la demande d’association identifie notre implémentation DICOM.

Notre classe d'implémentation UID: 2.16.124.113543.6021.2
Notre version de mise en œuvre Nom: RZDCX_2_0_1_8

Dans ce cas, il s’agit de l’UID RZDCX et du numéro de version. C’est toujours intéressant, car les boîtes à outils et les systèmes DICOM ont leurs propres petits problèmes. Par conséquent, si vous savez que certains systèmes ont un problème que vous avez déjà identifié et que vous voyez que vous utilisez la même mise en œuvre, vous savez comment le résoudre. Lors de la communication avec l’autre fournisseur d’applications, il est également important de signaler la version de l’application.
Dans le vidage de demandes, nous ne voyons que nos informations d'implémentation, mais plus loin dans le journal du vidage de réponses, nous verrons l'identification de l'AE appelé.
Ensuite, nous avons le nom du contexte de l'application. Il s'agit d'un UID réservé à DICOM. C'est toujours la meme chose.

Nom du contexte d'application: 1.2.840.10008.3.1.1.1


Nous avons ensuite les titres AE: le titre AE appelant et le titre AE appelé.



Nom de l'application appelante: RZDCX
Nom de l'application appelée: PACS

Notez qu’il s’agit simplement de la demande et que ce sont les valeurs que nous avons transmises à SendObject. Dans la réponse, nous aurons également ce qu'ils nous ont renvoyé. Habituellement, l'application qui répond à la demande d'association doit vérifier que l'AE appelé correspond à son propre AE et que l'AE appelant est quelque chose qui se trouve dans son fichier de configuration ou sa base de données. Si cela ne correspond pas, l'AE appelé peut rejeter l'association.
Ensuite, nous avons la taille maximale de PDU. PDU est un ‘paquet’ au niveau de l’application qui indique quelle est la taille de la mémoire tampon que nous sommes disposés à utiliser pour chaque demande.

Notre Max PDU Receive Size: 32768

Dans ce cas, nous ne proposons pas plus de 32K. Un problème connu est que certaines applications envoient une demande d’association si grosse que l’AE appelé ne peut pas consommer. Nous verrons dans une minute pourquoi ils le font et comment l’éviter.
Le bloc suivant du journal fait toujours partie de la première entrée du journal. La demande d'association comprend une liste de services DICOM. Les éléments de cette liste sont appelés contextes de présentation:

Le contexte
ID: 1 (proposé)
Abstrait
Syntaxe: = VerificationSOPClass
Proposé
Rôle SCP / SCU: Par défaut
Rôle SCP / SCU accepté: par défaut
Proposé
Syntaxe de transfert:

= LittleEndianExplicit

= BigEndianExplicit

= LittleEndianImplicit

Le contexte
ID: 3 (proposé)
Abstrait
Syntaxe: = SecondaryCaptureImageStorage
Proposé
Rôle SCP / SCU: Par défaut
Accepté
Rôle SCP / SCU: Par défaut
Proposé
Syntaxe de transfert:

= LittleEndianExplicit

Négociation prolongée demandée: aucune
Négociation étendue acceptée: aucune

Nous avons envoyé une liste avec deux éléments. Chaque élément est un contexte de présentation et identifie un service DICOM que nous souhaitons utiliser lors de cette association. Les contextes de présentation sont étrangement numérotés. Le premier est 1, le second est 3 et un troisième aurait été 5. Pourquoi? Je ne sais pas. C'est comme ça. Comme je l'ai dit, ils sont étrangement numérotés.
Le premier service que nous avons demandé est la vérification. Cette opération est effectuée à l'aide de la commande DICOM C-ECHO. Dans le journal, nous voyons ceci:

Syntaxe abstraite:
= VerificationSOPClass

Chaque service a un UID. Dans le fichier journal, les UID connus sont remplacés par leur nom. Le service de vérification est une sorte de ping de haut niveau. C-ECHO est une commande DICOM qui indique qu’une fois envoyé, l’homologue doit répondre avec un statut de réussite. Notez que nous n'avons pas encore envoyé de commande C-ECHO. Nous venons de demander à l'AE appelé dans notre demande d'association de l'utiliser dans la deuxième partie. Nous n’avons pas non plus dit que nous enverrions un C-ECHO. Une application DICOM qui écoute sur un port et attend les connexions entrantes doit toujours implémenter le service de vérification. Notre petite application n'écoute pas encore de port. À ce stade, nous jouons uniquement le rôle de client ici et nous nous connectons à une autre application. En tant que client, c’est toujours une bonne habitude de demander le service de vérification. Si nous ne le demandons pas et que l’application à laquelle nous nous connectons ne prend en charge aucun des autres services que nous demandons, elle nous le raccrochera. En ajoutant la vérification à notre demande, nous obligeons le serveur à dire oui pour au moins une chose que nous demandons.

Le deuxième service que nous avons demandé est le stockage secondaire d’images de capture:

Syntaxe abstraite:
= SecondaryCaptureImageStorage

Si vous vous en souvenez, lorsque nous avons parlé de SOP Class UID au chapitre 4, j’ai dit que SOP est une paire de services et de définition d’objet. Nous avons donc cette combinaison. Nous demandons à l'application homologue de stocker un objet que nous allons envoyer et nous lui dirons qu'il s'agira d'une image de capture secondaire. Si nous avions également un autre type d'objet, par exemple une image CT, nous aurions dû demander un troisième contexte de présentation. L'AE appelé peut autoriser ou interdire chacun des services. Il est donc possible de créer une application qui accepte des types d’objets spécifiques. Par exemple, si nous écrivons un poste de travail de reconstruction 3D pour les tomodensitogrammes, nous ne pouvons accepter que les images CT et obliger ainsi l’application d’envoi à nous envoyer ce type d’objets. Cependant, ce n’est pas une très bonne idée car les applications envoient généralement des études complètes et il peut y avoir dans une étude des images de différentes classes, par exemple une série avec un scanner, une autre avec un rapport et une autre avec un rayonnement. rapport de dose et si nous limitons notre poste de travail à accepter uniquement les images CT, l'application implémentée pour envoyer des études complètes conservera les échecs de rapport car ils ne peuvent pas envoyer les autres objets même si les images CT dont nous avions besoin sont arrivées. Une meilleure conception consisterait à autoriser tous les types d’objets et à ignorer ceux dont nous n’avons pas besoin.

Ce mécanisme de négociation de chaque type d’objet a conduit certains vendeurs à la très mauvaise habitude de simplement demander tous les objets possibles qu’ils connaissent. Cela peut entraîner une requête d'association longue de 50 Ko et si l'implémentation AE appelée ne peut lire que des requêtes de 32 Ko, elle peut facilement planter sur le bogue de débordement de mémoire tampon le plus simple. En outre, l'envoi d'une demande d'association 50K à chaque fois que vous souhaitez simplement vérifier une connexion à l'aide d'une commande C-ECHO est une pure perte de temps.

SendObject de RZDCX ne négocie que les UID de classe SOP requis. La méthode d'envoi DCXREQ envoie un ensemble de fichiers DICOM. Tout d'abord, il passe en revue tous les fichiers, crée une liste de toutes leurs classes SOP, puis négocie cette liste avec le AE appelé.

Ceci conclut notre demande d'association. Nous nous sommes identifiés et avons déclaré ce que nous appelons. Voyons maintenant ce que l’AE appelé va dire. Après l'envoi de la demande d'association, l'AE appelé lit la demande et renvoie une réponse d'association. C'est presque identique à la demande. L’appelant AE remplit simplement le formulaire que nous avons envoyé. La deuxième entrée de ce journal est un vidage de cette réponse.

2011-12-1022: 22: 26.062000 1508 INFO Résultat de la demande d'association: Ordinaire
Paramètres de réponse d'association:
Notre classe d'implémentation UID: 2.16.124.113543.6021.2
Notre version de mise en œuvre Nom: RZDCX_2_0_1_8
Leur UID de classe d'implémentation: 1.2.826.0.1.3680043.2.60.0.1
Leur nom de version d'implémentation: softlink_jdt103
Nom du contexte d'application: 1.2.840.10008.3.1.1.1
Nom de l'application appelante: RZDCX
Nom de l'application appelée: PACS
Nom de l'application qui répond: PACS
Notre Max PDU Receive Size: 32768
Leur taille maximale de réception PDU: 32768
Le contexte
ID: 1 (Accepté)
Abstrait
Syntaxe: = VerificationSOPClass
Proposé
Rôle SCP / SCU: Par défaut
Accepté
Rôle SCP / SCU: Par défaut
Accepté
Syntaxe de transfert: = LittleEndianImplicit
Le contexte
ID: 3 (Syntaxe abstraite non prise en charge)
Abstrait
Syntaxe: = SecondaryCaptureImageStorage
Proposé
Rôle SCP / SCU: Par défaut
Accepté
Rôle SCP / SCU: Par défaut
Négociation prolongée demandée: aucune
Négociation étendue acceptée: aucune

D'après l'horodatage, vous pouvez voir qu'il est revenu juste un dixième de seconde après l'envoi de la demande et que l'état de la réponse est Normal (j'ai mis en surbrillance les paramètres qui étaient vides ou qui ont changé auparavant). Vous pouvez également voir que leur identification d'implémentation est maintenant renseignée avec la valeur softlink_jdt103, qui identifie un package utilitaire Java très pratique de Tiani. Leur titre AE est bien «PACS» et ils ont accepté notre demande d'association. Il y a quelques cas ici. Un cas est qu'ils ne répondent tout simplement pas. Dans ce cas, notre demande expirera sans obtenir de réponse. Un autre cas est ce que nous avons ici, c'est-à-dire que la demande d'association a été acceptée et que nous sommes maintenant connectés à l'AE appelé. Le troisième cas est que l’appelant appelé décide qu’il ne veut pas nous parler et envoie une réponse de rejet d’association. Par exemple, si son titre AE n'est pas «PACS», le message «Mauvais titre AE appelé» apparaît alors. Le motif du rejet est codé dans le statut de la réponse et comporte parfois une explication textuelle supplémentaire.
Nous avons également reçu la liste des services. La vérification a été acceptée, mais pas le stockage de capture secondaire. Cela signifie que si nous le souhaitons, nous pouvons envoyer une commande C-ECHO mais nous ne pouvons pas envoyer notre image de capture secondaire à l’aide d’un C-STORE. Parce que c’est ce que nous voulions faire dans cette association, vous voyez les deux prochaines entrées du journal:

2011-12-1022: 22: 31.234000 1508 INFO Impossible de stocker un objet car la classe d'opération n'a pas été négociée ou acceptée
par les pairs
. SID de classe UID:
1.2.840.10008.5.1.4.1.1.7, UID d’instance SOP:
2.16.124.113543.6021.1.3.3727584845.5056.1323548540.2
2011-12-1022: 22: 31.234000 ERREUR 1508 dans DCXREQ, Code: 520, Texte: DIMSE Aucune présentation valide
ID de contexte

Cela signifie que nous ne pouvons pas stocker l’objet car l’homologue ne prend pas en charge ce service. Yippy! Nous pourrions en fait comprendre ce qui ne va pas ha?! Maintenant, Burt peut aller voir l’administrateur du PACS et lui demander pourquoi son PACS ne peut pas stocker les captures secondaires et l’administrateur du PACS va probablement demander à Burt sur quel serveur il a essayé de se connecter et sur quel port, puis indiquer que le port 6104 est le gestionnaire de listes de travail. qui servent les demandes de liste de travail de modalité et d’étapes de procédure effectuées (qui sont des services DICOM, nous en apprendrons plus tard) et que si nous voulons envoyer quelque chose au PACS, nous devons essayer de vous connecter au port 104. Cas résolu.
OK, renouvelons cette opération et connectez-vous cette fois au port 104. C’est une bonne idée de pouvoir configurer le titre, l’adresse IP et le numéro de port de l’AE appelé dans notre application afin que nous n’ayons pas à compiler à chaque fois. La plupart des applications DICOM ont une telle configuration. Il s’agit généralement d’une table avec au moins les colonnes: Titre AE, hôte et port et éventuellement un identifiant et un commentaire. Voici le journal d’un envoi réussi. Cette fois, le niveau de journalisation a été défini sur Debug.

2011-12-1512: 22: 51.000000 Association 4296 INFO
Paramètres de demande:
Notre classe d'implémentation UID: 2.16.124.113543.6021.2
Notre version de mise en œuvre Nom: RZDCX_2_0_1_8
Leur UID de classe d'implémentation:
Leur nom de version d'implémentation:
Nom du contexte d'application: 1.2.840.10008.3.1.1.1
Nom de l'application appelante: RZDCX
Nom de l'application appelée: PACS
Nom de l'application qui répond: Titre de l'APP
Notre Max PDU Receive Size: 32768
Leur taille maximale de réception PDU: 0
Le contexte
ID: 1 (proposé)
Abstrait
Syntaxe: = VerificationSOPClass
Rôle proposé du SCP / SCU: Par défaut
Accepté
Rôle SCP / SCU: Par défaut
Proposé
Syntaxe de transfert:

= LittleEndianExplicit

= BigEndianExplicit

= LittleEndianImplicit

Le contexte
ID: 3 (proposé)
Abstrait
Syntaxe: = SecondaryCaptureImageStorage
Proposé
Rôle SCP / SCU: Par défaut
Accepté
Rôle SCP / SCU: Par défaut
Proposé
Syntaxe de transfert:

= LittleEndianExplicit

Négociation prolongée demandée: aucune
Négociation étendue acceptée: aucune
2011-12-1512: 22: 51.000000 4296 PDU RQ d'associé de construction DEBUG
2011-12-1512: 22: 51.000000 4296 DEBUG WriteToConnection, longueur: 310, octets écrits:
310, numéro de boucle: 1
2011-12-1512: 22: 51.015000 4296 Type de PDU DEBUG: accepteur de partenariat, longueur de PDU: 216 +
En-tête PDU 6 octets
02 00
00 00 00 d8 00
01 00 00
50 41 43
53 20 20
20 20
20 20 20 20 20
20 20 20
52 5a 44
43 58 20
20 20
20 20 20 20 20
20 20 20
00 00 00
00 00 00
00 00
00 00 00 00 00
00 00 00
00 00 00
00 00 00
00 00
00 00 00 00 00
00 00 00
10 00 00
15 31 2e
32 2e
38 34 30 2e 31
30 30 30
38 2e 33
2e 31 2e
31 2e
31 21 00 00 19
01 00 00
00 40 00
00 11 31
2e 32
2e 38 34 30 2e
31 30 30
30 38 2e
31 2e 32
21 00
00 1b 03
00 00 00
40 00 00
13 31 2e
32 2e
38 34
30 2e 31 30 30
30 38 2e
31 2e 32
2e 31 50
00 00
3b 51 00 00 04
00 00 80
00 52 00
00 1c 31
2e 32
2e 38 32 36 2e
30 2e 31
2e 33 36
38 30 30
34 33
2e 32 2e
36 30 2e
30 2e 31
55 00 00
0f 73
6f 66
74 6c 69 6e 6b
5f 6a 64
74 31 30 33
2011-12-1512: 22: 51.015000 4296 INFO Résultat de la demande d'association: Normal
Paramètres de réponse d'association:
Notre classe d'implémentation UID: 2.16.124.113543.6021.2
Notre version de mise en œuvre Nom: RZDCX_2_0_1_8
Leur classe d'implémentation UID: 1.2.826.0.1.3680043.2.60.0.1
Leur version de mise en œuvre Nom: softlink_jdt103
Nom du contexte d'application: 1.2.840.10008.3.1.1.1
Nom de l'application appelante: RZDCX
Nom de l'application appelée: PACS
Nom de l'application qui répond: PACS
Notre Max PDU Receive Size: 32768
Leur Max PDU Receive Size: 32768
Le contexte
ID: 1 (Accepté)
Abstrait
Syntaxe: =VérificationSOPClass
Proposé
Rôle SCP / SCU: Par défaut
Accepté
Rôle SCP / SCU: Par défaut
Accepté
Syntaxe de transfert: = LittleEndianImplicit
Le contexte
ID: 3 (Accepté)
Abstrait
Syntaxe: =SecondaryCaptureImageStorage
Proposé
Rôle SCP / SCU: Par défaut
Accepté
Rôle SCP / SCU: Par défaut
Accepté
Syntaxe de transfert: = LittleEndianExplicit
Négociation prolongée demandée: aucune
Négociation étendue acceptée: aucune
2011-12-1512: 22: 51.031000 4296 DEBUG DIMSE Commande à envoyer:
# Used TransferSyntax: UnknownTransferSyntax
(0000,0000) UL 0 # 4, 1 CommandGroupLength
(0000,0002) UI = SecondaryCaptureImageStorage #
26, 1 AffectedSOPClassUID
(0000,0100) US 1 n ° 2, 1 CommandField
(0000,0110) US 1 # 2, 1 MessageID
(0000,0700) US 0 # 2, 1 priorité
(0000,0800) US 1 # 2, 1 DataSetType
(0000,1000) UI [2.16.124.113543.6021.1.3.3727584845.720.1323944568.6]
# 52, 1 AffectedSOPInstanceUID
2011-12-1512: 22: 51.031000 4296 DEBUG DIMSE sendDcmDataset: envoi de 146 octets
2011-12-1512: 22: 51.031000 4296 DEBUG WriteToConnection, longueur: 12, octets écrits:
12, boucle no: 1
2011-12-1512: 22: 51.031000 4296 DEBUG WriteToConnection, longueur: 146, octets écrits:
146, numéro de boucle: 1
2011-12-1512: 22: 51.031000 4296 DEBUG DIMSE sendDcmDataset: envoi de 7894 octets
2011-12-1512: 22: 51.031000 4296 DEBUG WriteToConnection, longueur: 12, octets écrits:
12, boucle no: 1
2011-12-1512: 22: 51.031000 4296 DEBUG WriteToConnection, longueur: 7894, octets
écrit: 7894, boucle no: 1
2011-12-1512: 22: 51.046000 4296 INFO DIMSE receiveCommand
2011-12-1512: 22: 51.062000 4296 INFO DIMSE receiveCommand: 1 pdv (178 octets),
presID = 3
2011-12-1512: 22: 51.062000 4296 Commande DEBUG DIMSE reçue:
# Used TransferSyntax: LittleEndianImplicit
(0000,0002) UI = SecondaryCaptureImageStorage #
26, 1 AffectedSOPClassUID
(0000,0100) US 32769 N ° 2, 1 CommandField
(0000,0120) US 1 # 2, 1 MessageIDBeingRespondedTo
(0000,0800) US 257 N ° 2, 1 DataSetType
(0000,0900)
US 45056
# 2, 1 Statut
(0000,0902)
LO [set InstanceNumber to 0]
# 24, 1 ErrorComment
(0000,1000) UI
[2.16.124.113543.6021.1.3.3727584845.720.1323944568.6] # 52, 1 AffectedSOPInstanceUID
2011-12-1512: 22: 51.062000 4296 DEBUG WriteToConnection, longueur: 10, octets écrits:
10, numéro de boucle: 1

La commande de stockage a réussi, mais nous avons récupéré un statut d'avertissement (45056 = 0xB000) au lieu de succès (0x0000). Nous avons également reçu un commentaire d’avertissement indiquant que l’appelant appelé avait changé l’élément numéro d’instance de null à 0, peut-être afin de l’indexer correctement dans sa base de données.

Nous aurions dû parler de syntaxes de transfert, mais ceci est déjà un long post, je vais donc laisser les syntaxes de transfert pour une autre fois.

Résumons ce que nous avons couvert dans cet article.

  1. Les nœuds du réseau DICOM sont appelés entités d'application (AE) et sont identifiés à l'aide d'un nom respectant la casse, appelé titre AE.
  2. La communication DICOM se fait toujours entre deux AE, c’est-à-dire qu’elle est peer-to-peer.
  3. La «session» DICOM s’appelle Association
  4. L'association est divisée en deux étapes. La première étape s'appelle la négociation d'association. Dans la deuxième étape, les commandes DICOM échangées par les deux AE
  5. Dans la négociation d'association, l'AE demandeur envoie une liste de contextes de présentation identifiant les services DICOM qu'il souhaite utiliser, et l'AE répondant renvoie la même liste marquée des services acceptés et utilisables et des services qu'il a refusés et ne peuvent pas être utilisés. utilisé dans cette association.
  6. Le service de vérification est un service de niveau application utilisé pour vérifier la communication entre deux AE.
  7. Le service de stockage est utilisé pour transférer des objets DICOM entre AE. Le service de stockage est négocié séparément pour chaque classe SOP. Par exemple, une application peut autoriser le stockage d’images CT et interdire le stockage d’images MR. Ce n'est pas un bon design cependant.

C'est tout. J'espère que vous me croyez toujours que DICOM est facile. Comme toujours, les commentaires sont les bienvenus.

DICOM c'est facile: Introduction à DICOM – Bien choisir son serveur d impression
4.9 (98%) 32 votes