[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