[Dcmlib] converting itk,vtk or any other 3D images into dicom.
Benoit Regrain
benoit.regrain at creatis.insa-lyon.fr
Tue Nov 9 16:05:37 CET 2004
Hi all,
Petites remarques...
Partie 1
Question 1c/:
- exposer les types DocEntry, ValEntry... ne pose aucun problème en
python.
Le problème est plutot le suivant :
+ si on expose ses types (autant en C++ qu'en Python), il faut alors
protéger
le code pour que l'utilisateur ne soit pas tenté de modifier
directement les
groupes et éléments sur l'objet. S'il faisait cela, cela aurait à
l'heure actuelle
la facheuse conséquence de corrompre le dictionnaire de départ.
+ Exposer ces types (DocEntry) a pour conséquence d'empêcher
l'utilisateur de modifier
le DictEntry associé à ces DocEntry. Par contre, l'utilisateur a
plus de faciliter pour
modifier la valeur contenue dans le DocEntry.
+ Si on n'expose pas ces types, la modification sera ralentie du fait
qu'il faudra
rechercher l'Entry dans l'arborescence des sequences et group|elt...
Pour la modification
d'un champs, cela n'est surement pas trop gênant, mais s'il s'agit
d'une 10aine de champs
sur 100aine d'images à modifier (par un petit programme appelé par
exemple) alors
cela peut commencer à devenir très couteux en temps !
Benoit
----- Original Message -----
From: "Eric Boix" <Eric.Boix at creatis.insa-lyon.fr>
To: "Jean-Pierre ROUX" <jean-pierre.roux at creatis.insa-lyon.fr>
Cc: <dcmlib at tux.creatis.insa-lyon.fr>
Sent: Tuesday, November 09, 2004 3:31 PM
Subject: Re: [Dcmlib] converting itk,vtk or any other 3D images into dicom.
> Salut,
>
> Quoting Jean-Pierre ROUX <jean-pierre.roux at creatis.insa-lyon.fr>:
> Mathieu> >ReplaceOrCreateByNumber et pas ReplaceOrCreateByName.
> >
> > On pourrait attendre pour voir si le group de réflexion DICOM sur
> > l'API a une opinion sur la question, mais la sagesse serait de ne
> > *jamais* utiliser les xxxByName.
>
> Maintenant que Jean-Michel Rouet a fort gentiment essuye' les platres pour
> nous, et que Mathieu a aussi un peu souffert en voulant ecrire des
> images, je pense (comme JPR, mais a plus court terme) qu'il est en effet
> assez urgent de parler de l'API.
>
> Je pense paticulierement aux points suivants qu'il faudrait clarifier:
> 1/ l'acces au tag
> 2/ distinction des operations de modification/creation d'un tag
> 3/ definition du mode d'ecriture.
>
> Avant de lancer le[s] troll[s], je cite l'extrait suivant du commentaire
> doxygen de la definition de TagKey (typedef) dans src/Common.h:
>
> TagKey is made to old an "universal" (as in URL, Universal
> Ressource Locator) key to a DocEntry i.e. a dicom tag.
> A dicom tag allways has a group and an element, but a set of
tags
> embeded in various (optionally nested) sequences and sharing
> the same group and element all share the same (group, element)
> "identifier". Hence the (group, element) cannot be used as an
> identifier (in gdcm we shall refer to a "TagKey") of a tag.
> In order to construct a proper tag identifier (i.e. a key) we
> consider the following definition of a TagKey:
> - let Group, Element be the string representation of the
> group and element dicom tag members,
> - let ItemNumber be the string representation of the integer
> index of the considered item number of a sequence,
> Let the key of a tag embeded in a sequence, noted SeqTag, be
> the form:
> /ItemNumber#Group|Element
> where "/", "#" and "|" are characters acting as separators.
> Then the general form of a TagKey is given by:
> Group|Element<SeqTag>
> where <SeqTag> means NO or many instances of SeqTag.
> Hence the TagKey of a tag not "leaving" in a sequence is the
> string e.g.
> 0028|1201
> but the TagKey of a tag "embeded" is the first item of
> a sequence, itself nested in the third item of a sequence is
the
> string e.g.
> 0004|1220/2#0008|0082/0#0008|0090
>
> Bref, la representation interne a gdcm d'une clef de tag (appele'
pompeusement
> clef generalise'e) est un string de la forme:
> - 0028|1201 pour un tag "a plat" (pas dans une sequence).
> - 0004|1220/2#0008|0082/0#0008|0090... pour un tag de sequence
>
> Maintenant, on peut discuter (si vous le voulez bien) les differents
> points:
>
> ######################
> Point 1/ acces au tag:
> Une fois un Header parse', l'utilisateur veut legitimement acceder aux
> tags trouve's.
> Question 1a/:
> Comme le rappelait JPR le "nom" d'un tag (i.e. la designation dans
> le dictionnaire) n'est pas unique et cela pose le pb des synonymes
> et ce a deux niveaux differents:
> * Le premier est qu'un tag dont le nom est unique dans le
dictionnaire
> peut tout de meme figurer plusieurs fois dans le Header parse'
si
> jamais il apparait dans plusieurs sequences. La clef
generalise'e
> semble regler ce point.
> * le second est que des noms comme Raws ne sont pas uniques dans
le
> dictionnaire (et la clef generalise'e ne regle rien).
> D'ou la question: ne devrait-on purement et simplement supprimer
> l'acces au tag par nom ?
> Question 1b/:
> Les acces par clef (methodes de la forme *ByNumber dans
gdcmDocument.h,
> entre autres) utilisent actuellement un prototype de la forme
> *ByNumber( ..., uint16_t group, uint16_t elem, ...)
> ce qui present deux inconvenients:
> - on ne peut acceder a des tags dans des sequences (dont la clef
> generalise'e est de la forme
0004|1220/2#0008|0082/0#0008|0090...)
> - cela expose le type uint16_t:
> -- cela impose de le rendre visible dans gdcmCommon.h (a ce
sujet
> il serait bon de le mettre dans le namespace non ?).
> -- cela complique le wrappage (Python) puisque qu'il faut
definir
> la conversion entre le langage cible et le C++.
> D'ou la question: ne devrait pas choisir des prototypes de la forme
> *ByNumber( ..., TagKey key, ...)
> en substitution de
> *ByNumber( ..., uint16_t group, uint16_t
elem, ...)
> et au passage les renommer en *ByKey ?
> Si ce choix est fait, cela impose a l'API d'exposer les utilitaires
> (internes de gdcm) pour construire une clef a la vole'e:
> - DictEntry::TranslateToKey(group,element) )
> - et une version a ecrire pour la clef generalise'e
>
> Question 1c/:
> Il s'agit ici du parcours d'un Header (l'application type etant
> de presenter un Header sous forme d'un GUI, si possible avec
> les sequences "collapsables" a la e-Film: c'est une demande
> interne assez forte de nos chers utilisateurs WinDoziens).
> La structure d'un Header est recursive (pour la gestion des
sequences).
> Dans l'etat actuel de choses deux modes de parcours sont possibles:
> - "Hands-on" mode, i.e. on laisse l'utilisateur parcourir
> recursivement l'arbre d'un Header parse' i.e. l'utilisateur
> doit re-ecrire avec un squelette semblable a celui de
> Document::BuildFlatHashTableRecurse()
> - utiliser TagDocEntryHT* Document::BuildFlatHashTable()
> qui construit un std::map<> "a plat" a partir de la structure
> recursive.
> Les inconvenients/avantages des deux methodes:
> - "Hands-on":
> -- Inconvenients: 1/ cela expose les mecanismes internes (pb
> d'encapsulation). En effet un utilisateur
> recuperant un heritier d'un DocEntry, peut
> facilement casser le dictionnaire en
> faisant par exemple un DocEntry::SetVR !
> 2/ cela duplique du code
> 3/ cela fige les mecanismes internes
(puisqu'un
> utilisateur ecrit du code y faisant
reference).
> 4/ cela expose des types internes comme
> DictEntry, ValEntry... ce qui pose un pb
> en Python.
> -- Avantage: y'a rien d'autre pour l'instant !
> - BuildFlatHashTable():
> -- Inconvenient: la structure construite evolue separement du
> Header de reference. Si on modifie le Header
> le std::map<> construit ne le reflete pas.
> -- Avantages: 1/ l'utilisateur n'a pas la recursion a ecrire
> 2/ aucun type interne supplementaire n'est
expose'.
> 3/ aucun travail supplementaire pour les
wrappeurs.
> La question, la question, la question ! Bon, d'accord, voila la
> question:
> Ne peut pas ecrire un Visitor sur un Header ? Et si oui, avec
> quelle syntaxe/API ?
>
> ######################
> Point 2/ distinction des operations de modification/creation d'un tag
> Actuellement nous offrons ReplaceOrCreateByNumber(). Il serait bon,
> IMHO et meme si cela alourdi un peu le code appelant, de
> distinguer classiquement les operations de:
> - modification d'un tag existant,
> - creation d'un nouveau tag,
> - suppression d'un tag. (ajout)
> Plusieurs raisons a cela:
> * eclaircissement du code de l'appelant,
> * verification locale des contraintes d'inte'grite dans le cas
> de modification (certains tag sont "lie's" e.g. ecraser
brutalement
> le "transfert syntax" sans prendre un minimum de precautions est
> sans doute dangeureux).
> * rendre possible l'ajout/suppresion d'une sequence, ou
> l'ajout/suppresion d'un item de sequence simplement en
specialisant
> les classes ad-hoc.
>
> ######################
> Point 3/ definition du mode d'ecriture.
> Mathieu a deja propose' que l'API soit VTK-like. Il faudrait donc
> ecrire:
> gdcm::File junk;
> junk.SetWriteMode(gdcm::File::DicomImplicitVR);
> junk.Write();
> et NON pas:
> gdcm::File junk;
> junk.WriteDcmImplVR();
> // or junk.WriteDcmExplVR()
> // or junk.WriteAcr()
>
> ####################
>
> Si apres une telle incontinence verbale, y'a pas de commentaire, c'est a
> se flinguer...
>
> Eric.
> _______________________________________________
> Dcmlib mailing list
> Dcmlib at creatis.insa-lyon.fr
> http://www.creatis.insa-lyon.fr/mailman/listinfo/dcmlib
More information about the Dcmlib
mailing list