<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.2900.2627" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT face=Arial size=2>2eme partie (sinon ca passait pas...)</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>>> 
--------------------------------------------------------------------------<BR>>> 
Maintenant voici mes remarques :<BR>>> - le File (dérivé du Document) fait 
déjà une bonne partie de ce que tu<BR>>> veux faire. Je pense qu'en effet, 
il est bien de garder cette structure qui<BR>>> convient 
parfaitement.<BR>> <BR>> c'est le terme parfaitement qui me fais sursaute. 
Aller je me lance dans <BR>> une autre de mes idee ;-P:<BR>> Un truc que 
j'adore en c++ c'est le polymorphisme, tu peux par exemple <BR>> manipler une 
classe via des fonction virtuelles sans te rendre compte <BR>> que tu 
manipule un instance d'une sous classes...ainsi j'aimerais que <BR>> 
gdcm.File soit en fait:<BR>> 
<BR>>                       
gdcm.Writer<BR>>              
|           
|             
|             
|<BR>>      gdcm.DICOMV3  
gdcm.Libido   (gdcm.ACR-NEMA) (gdcm.Papyrus)<BR>> <BR>> je veux 
pas d'une classes fourre tout ou tu fais du code pour ACRNEMA du <BR>> 
DICOMV3 et du papyrus justeaucasou ... c'est horrible !</DIV>
<DIV><FONT face=Arial size=2>Voila une bonne idée toute belle qui me plait 
bien... </FONT></DIV>
<DIV><FONT face=Arial size=2>Mais la question etait sur la donnée 
Document.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial><BR><FONT size=2></FONT></FONT> </DIV>
<DIV><FONT face=Arial size=2>>> - le DicomDir (dérivé de Document), tu 
n'en parles pas. Etant donné<BR>>> qu'il n'a pas besoin de la complexité 
interne du Document, garde-t-on<BR>>> cette dérivation ? (elle est à 
l'heure actuelle utile car le Document <BR>>> contient<BR>>> toute 
la partie Reader/Writer, mais je pense qu'on peut s'en abstraire<BR>>> 
pour la structure que tu proposes).<BR>> <BR>> <BR>> C'est la ou le bas 
blesse, je n'ai pas du tout de connaissance sur le <BR>> sujet. Est-ce que ca 
peut rentrer dans mon archi:<BR>> 
<BR>>                         
gdcm.Writer<BR>>                             
|<BR>>                        
gdcm.DICOMDIR</FONT></DIV>
<DIV><FONT face=Arial size=2>Oui, ca y rentre, car le DicomDir est ecrit comme 
les autres. </FONT></DIV>
<DIV><FONT face=Arial size=2>Mais ma question portait plutot sur la 
structure interne du DicomDir au</FONT></DIV>
<DIV><FONT face=Arial size=2>sens Data (la sortie du Writer)</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial><BR><FONT size=2></FONT></FONT> </DIV>
<DIV><FONT face=Arial size=2>>> - Dans la création d'un Element du 
Document... comment on<BR>>> différencie les ValEntry, BinEntry et 
SeqEntry ? A l'heure actuelle,<BR>>> on fait cette différenciation à la 
création de l'élément en fonction de <BR>>> son VR.<BR>>> De plus, 
un Element (ou DocEntry à l'heure actuelle) est rataché à un <BR>>> 
DictEntry.<BR>> <BR>> <BR>> Faux -IMHO- c'est le gdcm.Document qui a 
connaissance du dict. Mais un <BR>> element est rattache a un 
Document.<BR>> D'ailleurs au passage je ne comprends que deux type d'el un 
BinEntry et <BR>> un ValEntry. Pour moi un SeqEntry c'est un Document ... je 
sais pas bien <BR>> encore comment representer ca.</FONT></DIV>
<DIV><FONT face=Arial size=2>Un SeqEntry contient des SQItem qui sont eux des 
pseudo Document...</FONT></DIV>
<DIV><FONT face=Arial size=2>En fait, dans la structure actuelle, un SQItem et 
un Document derivent de </FONT></DIV>
<DIV><FONT face=Arial size=2>ElementSet. Deux points les différencie 
:</FONT></DIV>
<DIV><FONT face=Arial size=2> - dans le Document, on stoque les entry dans 
une map (pour des questions</FONT></DIV>
<DIV><FONT face=Arial size=2>de rapidité) et dans les SQItem on y stoque dans 
une liste (car moins gourmande</FONT></DIV>
<DIV><FONT face=Arial size=2>en place).</FONT></DIV>
<DIV><FONT face=Arial size=2> - dans un Document (ou plutot un File), on a 
des méthodes supplémentaires</FONT></DIV>
<DIV><FONT face=Arial size=2>pour acceder aux caractéristiques du 
Document.</FONT></DIV>
<DIV><FONT face=Arial size=2> </DIV>
<DIV> </DIV>
<DIV><BR>> Au passage, pourquoi la distinction BinEntry / ValEntry ? Pour moi 
tu <BR>> lis un petit bout de fichier tu stocke ca dans un ostringstream et 
<BR>> basta. Un ValEntry c'est juste que tu 'tautorize a interpreter le flux 
<BR>> binarie en chaine de caractere... </DIV>
<DIV>La distinction BinEntry / ValEntry se fait en fonction de la VR. Pour un 
BinEntry,</DIV>
<DIV>par exemple les pixels de l'image ou d'autres données, y stoquer dans une 
stream</DIV>
<DIV>n'aurait pas vraiment de sens... et quel en serait reelement l'intérêt 
?</DIV>
<DIV> </DIV>
<DIV>> d'ailleurs :<BR>> QUESTION: comment on sait qu'un element est une 
ValEntry dans le cas <BR>> d'un shadow dict. Est-ce qu'on ne pourrait pas 
tout lire en BinEntry et <BR>> unquiquement lorsqu'on sait ce qu'on fais on 
dynamic_cast en ValEntry -> <BR>> interprete la chaine de caractere et la 
on peut effectivement essayer de <BR>> lire par exemple le spacing.<BR>> 
<BR>> Tout ca pour dire je voudrais pouvoir lire un DICOM plus vite, il y a 
<BR>> beaucoup de temps passer a je lis un petit bout de DICOM, a tiens c'est 
<BR>> un ValEntry, je fais un new ValEntry, je copie les valeurs, je passe au 
<BR>> suivant tiens c'est un BinEntry je fais new ValEntry ... c'est vraiment 
<BR>> long et je me rend pas bien compte de ce que ca apporte.</DIV>
<DIV>Moui, c'est une excuse tout à fait valable... A étudier. Mais ca ne 
resoudrait pas </DIV>
<DIV>le problème des SeqEntry. Il faudra de toute manière faire le travail pour 
lui.</DIV>
<DIV>Par contre, il est clair que la transformation en chaine du ValEntry est un 
peu</DIV>
<DIV>lourde. Je pense qu'il manquerait meme une classe qui genere les 
NumberEntry</DIV>
<DIV>Ainsi on supprimerait les parsing de chaine de caractères pour au final 
obtenir les</DIV>
<DIV>nombres. Les transformation number->string et string->number sont a 
mon avis</DIV>
<DIV>plutot couteuses en temps.</DIV>
<DIV> </DIV>
<DIV>On pourrait avoir une structure de DocEntry comme suit :</DIV>
<DIV><FONT face="Courier New">DocEntry (existe deja)</FONT></DIV>
<DIV><FONT face="Courier New"> - SeqEntry (existe deja)</FONT></DIV>
<DIV><FONT face="Courier New"> - ContentEntry (existe deja)</FONT></DIV>
<DIV><FONT face="Courier New">    - ValEtnry (pour tout ce qui 
est chaine)</FONT></DIV>
<DIV><FONT face="Courier New">    - BinEntry (pour tout ce qui 
est donnée non interpretable)</FONT></DIV>
<DIV><FONT face="Courier New">    - NumberEntry (pour tout ce qui 
est nombre)</FONT></DIV>
<DIV>mais ca ne résout pas le problème de passage d'un BinEntry lorsqu'on a un 
ShadowDict</DIV>
<DIV>et qu'on est en ImplicitVR (car pour le ExplicitVR, on n'a pas de 
problèmes).</DIV>
<DIV>Mais avec les ShadowDict, il reste le problème du SeqEntry... car il se 
peut qu'on ne</DIV>
<DIV>sache pas qu'on a une SeqEntry à un moment (car son groupe est privé)... ce 
qui </DIV>
<DIV>d'ailleurs m'interpelle un peu, car l'élément suivant d'un SeqEntry serait 
un SQItem... et </DIV>
<DIV>on devrait pouvoir le repérer lui... na ? JPR, toi qui connait tout de 
Dicom, qu'en penses tu ?</DIV>
<DIV><BR> </DIV>
<DIV>>> Tu fais ce rattachement à quel moment ? De plus lorsque le 
dictionnaire <BR>>> publique<BR>>> ne contient pas le tuple (group, 
element, VR) il en crée un nouveau <BR>>> sauvegardé<BR>>> dans une 
zone tampon... garde-t-on cela qui n'est pas tres propre ? ou <BR>>> 
place-t-on<BR>>> le VR de l'Element dans l'Element ? <BR>> <BR>> 
Pourquoi exactement on a besoin d'en creer un nouveau ? Un element est <BR>> 
rattacher a un gdcm.Document et le gdcm.Document peut tout moment <BR>> 
changer de dictionaire (Siemens, Philips, ...). Donc la VR c'est jamais <BR>> 
stocker dans l'element, non ?</DIV>
<DIV>En ExplicitVR, on peut avoir des Entry dont la VR diffère de la VR du 
dictonnaire.</DIV>
<DIV>C'est dans la norme Dicom ca (enfin a verifer avec JPR)</DIV>
<DIV><BR> </DIV>
<DIV>> Dans mon idee c'est le gdcm.Document qui a l'ensemble des dictionaires 
<BR>> autorises. Donc a partir d'un element+group il doit etre capable de 
<BR>> renvoyer toutes les informations necessaires correct ? Et comme c'est 
<BR>> une std::map l'access est en O(1). Le seul probleme dans mon approche 
<BR>> c'est qu'un group+element n'est pas unique, par ex qu'il soit present 
<BR>> dans le dict public et le dict prive. Mais  meme dans ce cas je 
vois pas <BR>> comment vous pourriez le gerer.</DIV>
<DIV>Mais cela va ralentir lors de la recherche du nom appartenant une 
Entry...</DIV>
<DIV>certes le parsing sera plus rapide, les Entry plus petits. C'est à 
discuter.</DIV>
<DIV>Pour moi je laisse le sujet en suspend pour l'instant.</DIV>
<DIV><BR> </DIV>
<DIV>>>  Ce qui nous donnerait :<BR>>> <BR>>> newel = 
gdcm.Element("OB")    // La VR est affecté au moment de la 
<BR>>> création de l'objet<BR>> pourquoi on a besoin de la VR ?</DIV>
<DIV>Savoir si on est en BinEntry, ValEntry, NumberEntry, SeqEntry</DIV>
<DIV><BR> </DIV>
<DIV>>> newel.Set(0x1234,0x5678)       // On 
va rechercher le DictEntry <BR>>> correspondant... mais dans quel Dict 
?</DIV>
<DIV>> Ceux attacher au gdcm.Document...</DIV>
<DIV>Mais comment savoir lors de la lecture d'un fichier à quel constructeur 
il</DIV>
<DIV>appartient pour ensuite prendre le bon ShadowDict...</DIV>
<DIV><BR> </DIV>
<DIV>>> 
newel.SetValue("foobar")          
// Et pour une valeur binaire ou une <BR>>> séquence, que fait-on 
?<BR>> J'aime pas la notion de sequence ca reste pour moi qu'un 
gdcm.Document. <BR>> Mais sinon "foobar" est une valeur valide pour une 
entree binaire, non ? <BR>> Ou est la difference entre BinEntry et ValEntry 
que je ne vois toujours <BR>> pas ?</DIV>
<DIV>une BinEntry, c'est une VR = 'OB' ou 'OW'</DIV>
<DIV>une SeqEntry, c'est une VR = 'SQ'</DIV>
<DIV>une ValEntry, c'est tout le reste</DIV>
<DIV>(sauf erreur de ma part)</DIV>
<DIV><BR> </DIV>
<DIV>>> Mais ceci ne résoudrait pas le problème de création de l'élément 
en <BR>>> fonction de sa VR.<BR>>> Car avec ce choix, l'utilisateur 
peut créer un Element de VR "SQ" et <BR>>> mettre des données<BR>>> 
textuelles dedans. Une solution serait de mettre le constructeur en <BR>>> 
protected<BR>>> et d'avoir un New avec une création de l'objet en fonction 
de la VR...<BR>> <BR>>> - Concernant l'écriture des series, tu 
considères avoir en entrée une <BR>>> liste de Document<BR>>> ou un 
seul Document contenant une image 3D ? Pour moi, la liste de 
Document<BR>>> et nettement plus adaptée car d'un Document à l'autre, de 
nombreux <BR>>> champs de<BR>>> l'entete peuvent varier.<BR>> Le 
probleme est parfaitement souligner: je ne sais pas ce que j'ai en <BR>> 
entree ! Si je recois une image 4D, je eux pouvoir l'ecrire en serie <BR>> 
d'image 3D temporelle OU une serie 2D variant en Z direction et en temps 
<BR>> ! et je vois pas ou est le probleme d'archi la dedans.<BR>> Il faut 
garder en tete que c'est une archie que je propose, si le <BR>> programmeur 
ne sait pas faire il met un 'abort()' dans le code et il <BR>> attends qu'un 
utilisateur lui envoi le patch pour pouvoir le faire. Je <BR>> ne veux pas 
avoir de limitation d'entree de jeux.<BR>> <BR>>> - Une question qui ne 
peut se déduire du code python : la création des <BR>>> objets<BR>>> 
se ferait par quelle méthode ? une méthode New comme en VTK, ou un 
new<BR>>> habituel comme on fait actuellement ?<BR>> <BR>> Reponse: 
new. le ::New VTK c'est pour des compilos que gdcm ne <BR>> supporte(ra) pas, 
faut pas deconner qd meme !</DIV>
<DIV>Le New/Delete de VTK sert aussi a proteger l'accès au constructeur et 
destructeur</DIV>
<DIV>car ce dernier utilise le reference counting... ca n'a rien a voir avec des 
compilos !</DIV>
<DIV><BR> </DIV>
<DIV>>> - Concernant les Series, tu fais un SerieReader... qui 
remplacerait <BR>>> surement<BR>>> le SerieHelper actuel... je ne 
suis pas sur qu'il s'agisse d'une bonne <BR>>> solution<BR>>> 
(d'après ce que j'ai compris de l'intérêt du SerieHelper). Le <BR>>> 
SerieHelper a pour<BR>>> but d'ordonner les différents fichiers d'une meme 
série. Or <BR>>> l'utilisateur pourrait<BR>>> très bien vouloir lire 
ses différents fichiers d'une part, puis les <BR>>> trier... or s'il 
passe<BR>>> dans un SerieReader, il va de nouveau relire ces fichiers. Il 
serait <BR>>> mieux d'avoir<BR>>> un SerieOrder qui prend en entrée 
une liste de Document (donc les <BR>>> fichiers sont<BR>>> déjà lus) 
et ce process ne ferai qu'ordonner cette liste (suivant les <BR>>> 
critères actuels<BR>>> du SerieHelper).<BR>> <BR>> Parfaitement 
raisonne ! Et le SerieOrder est utiliser soit lors de la <BR>> lecture soit 
lors de l'ecriture (reutilisation de code plutot que <BR>> 
duplication).</DIV>
<DIV>Au moins on est d'accord sur un truc...</DIV>
<DIV> </DIV>
<DIV><BR> </DIV>
<DIV>>> - Pour la classe Image, je n'ai pas très bien compris comment elle 
<BR>>> fonctionne.<BR>>> A-t-elle une sortie ? et quel type de 
sortie ? ... simplement un tableau <BR>>> de données comme<BR>>> le 
fait le FileHelper actuel lorsque tu appelle la méthode GetImage ?<BR>>> 
Et lorsque l'utilisateur demande un sous-volume englobant le volume <BR>>> 
précédement lu,<BR>>> réutilise-t-on le volume précédemment lu 
?<BR>>> <BR>>> image = gdcm.Image()<BR>>> image.SetInput( 
reader.GetOutput())<BR>>> image.SetSubVolume(512,512,1,3)  # SetVOI / 
SetExtent<BR>>> image.Construct()<BR>>> 
image.SetSubVolume(512,512,0,10)  # SetVOI / SetExtent englobant le VOI 
<BR>>> precedent.<BR>>> image.Construct()<BR>> <BR>> Ok je 
reconnais le nom gdcm.Image n'est pas correct. Que pense tu de <BR>> 
gdcm.Decompress. Dans ce cas gdcm.Decompress repart de zero a chaque <BR>> 
fois: relecture du fichier / seek / contruire une nouvelle image.<BR>> C'est 
sans doute dommage niveau efficacite mais pour moi je vise le cas <BR>> du 
thesard qui fais sa registration et il sait quel sous volume <BR>> utiliser. 
Dans son rep il a une image de 3 Gig il sait qu'il doit <BR>> recaller la 
partie 0-100 x 0-100 x 0-100 s'il se trompe ben il part du <BR>> principe que 
ca va prendre un peu de temps a relire la bonne partie du <BR>> 
fichier.</DIV>
<DIV>Ca me convient. Decompress, ca serait plutot le traitement de 
décompression.</DIV>
<DIV>Mais la donnée en sortie de ce traitement ? Image ou Document avec quelque 
chose</DIV>
<DIV>en + ?</DIV>
<DIV> </DIV>
<DIV><BR> </DIV>
<DIV>>> - Pour l'ecriture des images créées from scratch. Comment cela se 
<BR>>> passerait-il ?<BR>>> Tu as dit que l'Image replacerait les 
champs du Document, ce qui veut <BR>>> dire qu'il<BR>>> faut passer 
à la fois une Image et un Document au Writer ? Sur ce point, <BR>>> je 
crois qu'il<BR>>> manque un exemple d'utilisation. J'ai aussi beaucoup de 
mal à voir ce <BR>>> que tu appelles<BR>>> Image...<BR>> 
Est-qu'on peut faire un gdcm.Document contient un gdcm.ElementSet (le <BR>> 
header) et contiendrait aussi un gdcm.Image. Donc dans le cas d'un <BR>> 
fichier DICOM raw si on force la lecture meme des element > 4096 en <BR>> 
taille et que l'utilisateur demande une gdcm.Image de la totalite alors <BR>> 
oui il aura deux fois l'image en memoire. Et non on ne pourra pas etre <BR>> 
malin en passant le meme pointeur sur l'image.</DIV>
<DIV>Et cela repondrait a ma question precedente sur la sortie du 
Decompress</DIV>
<DIV> </DIV>
<DIV><BR> </DIV>
<DIV>>> Voila, les remarques sont finies. Certaines rentrent déjà dans 
<BR>>> l'implémentation, j'espere<BR>>> donc que je ne les pose pas 
trop tot. Je crois sinon que j'ai fait le <BR>>> tour du 
sujet.<BR>>> Sinon, moi aussi je ne vais pas avoir beaucoup de temps à 
investir dans <BR>>> le développement<BR>>> de cette nouvelle 
mouture de gdcm... mais ce sera un problème à voir <BR>>> lorsqu'on 
aura<BR>>> défini la structure finale de gdcm !<BR>>> Je pense que 
cette fois ci, il ne faut pas commencer à développer avant <BR>>> d'avoir 
la structure<BR>>> finale de la librairie et d'avoir vérifié que les 
exemples créés <BR>>> conviennent à tout ce<BR>>> dont on a 
besoin.<BR>> <BR>> Si on fait le tour des cas d'utilisation on ne peut 
rien manquer par <BR>> definition. C"est pour ca qu'il faut passer pas mal de 
temps a reflechir <BR>> a tout les cas d'utilisation. De mon experience j'ai 
eu pas mal de <BR>> feedback depuis ITK, vous de votre cote vous devrier 
avoir du feedback <BR>> de CREATIS directement.</DIV>
<DIV>Euhhh... a creatis, gdcm n'est pas trop utilisé directement. Les 
utilisateurs</DIV>
<DIV>sont soit resté sur Libido (tres ancienne version de gdcm dont ils se 
contentent</DIV>
<DIV>car ils veulent po passer a mieux...) soit en utilisant DaVaW qui vient 
tout juste</DIV>
<DIV>de passer à la nouvelle version de gdcm :-)... c'etait pas trop tot.</DIV>
<DIV>Le seul non informaticien de creatis a utiliser gdcm (sauf erreur 
de ma part) est</DIV>
<DIV>Edouardo avec Maracas. Et les plus gros problèmes qu'on a eu, c'est :</DIV>
<DIV> - creer un DicomDir à partir d'une liste d'images deja lus (d'ou les 
convertisseurs</DIV>
<DIV>   Document2DicomDirImage... meme si c'est encore a revoir 
ca...)</DIV>
<DIV> - les SerieHelper qui relisent obligatoirement les fichiers (ce qui 
serait resolu par </DIV>
<DIV>   le SerieOrder)</DIV>
<DIV><BR> </DIV>
<DIV>>> Désolé pour la longueur du mail. J'ai essayé d'etre le plus 
constructif <BR>>> possible, et<BR>>> ca prend de la place. J'espere 
que vous serez arrivé jusqu'ici<BR>> J'aime les longues histoires avec plein 
de rebondissements :)</DIV>
<DIV>Tu vas etre content, j'en ai fait plein.</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>>> PS : Mathieu, tes exemples sont une très bonne idée. Je pense 
qu'il faut <BR>>> continuer à les<BR>>> faire et les compléter au 
fur et à mesure... afin d'avoir l'utilisation <BR>>> complète et 
finale<BR>>> de la librairie.<BR>> Merci infiniment et merci a toi 
d'avoir pris le temps de me repondre, <BR>> c'est extremement apprecie (si si 
!).</DIV>
<DIV>C'est la partie du travail que je prefere dans la programmation :-)</DIV>
<DIV> </DIV>
<DIV>Benoit</DIV></FONT></FONT></BODY></HTML>