]> Creatis software - creaBruker.git/blob - lib/src1/bruker2dicom.cxx
re indent
[creaBruker.git] / lib / src1 / bruker2dicom.cxx
1 #include "bruker2dicom.h"
2 #include <boost/filesystem/path.hpp>
3 #include <boost/filesystem/operations.hpp>
4 #include "brukerexception.h"
5
6 #ifndef PATH_MAX // If not defined yet : do it 
7    #define PATH_MAX 2048
8 #endif 
9
10 bool Bruker2Dicom::Execute()
11 {
12    // ----- Check input directory name -----
13
14    bool bigEndian = GDCM_NAME_SPACE::Util::IsCurrentProcessorBigEndian();
15
16    //if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(InputDirName) )
17    if ( ! boost::filesystem::is_directory(InputDirName) )
18    {
19       std::cout << "KO : [" << InputDirName << "] is not a Directory." << std::endl;
20       return 0;
21    }
22    else
23    {
24       if (verbose)
25          std::cout << "OK : [" << InputDirName << "] is a Directory." << std::endl;
26    }
27
28    // ----- Check output directory name -----
29
30    std::string strDirNameOut(OutputDirName); 
31    bool res=CreateDirectory(strDirNameOut);
32    if (!res) {
33       std::cout << "[" << OutputDirName << "] Directory creation failure " << std::endl;
34       //exit (0);
35       throw ( BrukerHopelessException ("Output directory creation failure "));
36    }
37
38 //
39 // e.g : at level 0, in : B67d1.Bp1
40 //
41 //           1  2  3  4  5  6  AdjStatePerStudy  subject
42 //
43
44    std::string strDirNamein(InputDirName);
45
46 /* */
47    GDCM_NAME_SPACE::DirList dirList(strDirNamein, false, true); // DON'T get recursively the list of files
48
49    GDCM_NAME_SPACE::DirListType fileNames;
50    fileNames = dirList.GetFilenames();
51
52    std::string path = GDCM_NAME_SPACE::Util::GetPath(*(fileNames.begin()));
53
54    std::string subject =  path +
55                           GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
56                           "subject";
57
58     std::string acqp = path +
59                        GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
60                        "acqp";
61
62     if ( boost::filesystem::is_regular(subject) )
63        subjectFound = true;
64     else
65        subjectFound = false; // user passed only a 'serie', not a 'study 
66
67     if ( boost::filesystem::is_regular(acqp) )
68        acqpFound= true;
69     else
70        acqpFound = false; // user passed a 'non study' directory; Hope it's a 'set of studies' directory!
71
72    int type;
73    if  (subjectFound )  type = 1; // user passed a 'study
74    else if  (acqpFound) type = 2; // user passed a 'serie' 
75    else                 type = 3; // user passed a 'non study' directory; Hope it's a 'set of studies' directory!
76  /* */
77
78    // 1 : if subjectFound                       : user passed a Single Study Directory
79    // 2 : if NOT subjectFound and acqpFound     : user passed a Serie Directory
80    // 3 : if NOT subjectFound and NOT acqpFound : user passed a 'non Study Directory' (Hope it's a set of Single Study Directories)
81
82    //int type = CheckUserDirectory(InputDirName);
83  
84    switch (type)
85    {
86       case 1: {   
87          bool canOpen = br_subject.LoadFile(subject);
88          if (!canOpen)
89          {
90             std::cout << "Hopeless! 'subject' found / cannot be open" << std::endl;
91             throw ( BrukerHopelessException ("Hopeless! 'subject' found in root input directory / cannot be open"));
92          }
93          else
94          {
95             br_subject.FillMap();
96
97             // get info for 'Study Description'  
98             BrukerFieldData b_name=br_subject.GetFieldData("SUBJECT_name_string");
99             subject_name = b_name.GetStringValue()[0];
100             strPatientName = subject_name;
101             cleanString(subject_name);
102             DealWithSingleStudyDirectory (fileNames);
103          }
104          break;
105       }
106
107       case 2: {
108          subject_name = "defaultPatName";
109          strPatientName = subject_name;
110          DealWithSingleStudyDirectory (fileNames);
111          break;
112       }
113
114       case 3: {
115          std::cout << " User passed a 'non study' directory; Hope it's a *non recursive* 'set of studies' directory! (recursive not yet dealt with)" << std::endl;
116          DealWithMultiStudyDirectory (fileNames);
117          break;
118       }
119    }
120 }
121
122 // ----------------------------------------------------------------------------------------------------------
123
124 void Bruker2Dicom::DealWithMultiStudyDirectory (GDCM_NAME_SPACE::DirListType &dirNames)
125 {
126    GDCM_NAME_SPACE::DirListType::iterator it;
127
128    for (it = dirNames.begin();
129          it != dirNames.end();
130        ++it)
131    {
132       if ( boost::filesystem::is_directory(*it) )
133       {
134          subjectFound = false;
135          if (verbose)
136             std::cout << "in 'DealWithMultiStudyDirectory' [" << *it << "] is a directory" << std::endl;
137
138          GDCM_NAME_SPACE::DirList dirList(*it, false, true); // DON'T get recursively the list of files
139          GDCM_NAME_SPACE::DirListType fileNames;
140          fileNames = dirList.GetFilenames();
141
142          std::string path = GDCM_NAME_SPACE::Util::GetPath(*(fileNames.begin()));
143          std::string subject =  path +
144                                 GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
145                                 "subject";
146          if (! boost::filesystem::is_regular(subject) )
147          {
148             std::cout << "no [" << subject << "] file found" << std::endl;
149             continue;
150          }
151
152          bool canOpen = br_subject.LoadFile(subject);
153          if (!canOpen)
154          {
155             std::cout << "Hopeless! 'subject' found / cannot be open" << std::endl;
156             throw ( BrukerHopelessException ("Hopeless! 'subject' found in root input directory / cannot be open"));
157          }
158          else
159          {
160             br_subject.FillMap();
161             subjectFound = true; // Hope so! (full checking needed!)
162
163             BrukerFieldData b_name=br_subject.GetFieldData("SUBJECT_name_string");
164             subject_name = b_name.GetStringValue()[0];
165             strPatientName = subject_name;
166             cleanString(subject_name);   
167             DealWithSingleStudyDirectory(fileNames);
168          }  
169       }
170       else
171       {
172          if (verbose)
173             std::cout << "[" << *it << "] is NOT a directory; skipped!" << std::endl; 
174       }   
175    } 
176 }
177
178 // ----------------------------------------------------------------------------------------------------------
179
180 void Bruker2Dicom::DealWithSingleStudyDirectory (GDCM_NAME_SPACE::DirListType &fileNames)
181 {
182      bool res;   
183     // creation directory : 'nom du patient'
184     std::string tempStringPatDir(OutputDirName);
185     tempStringPatDir = tempStringPatDir + GDCM_NAME_SPACE::GDCM_FILESEPARATOR + subject_name;
186
187     res=CreateDirectory(tempStringPatDir);
188     if (!res) {
189        std::cout << "[" << tempStringPatDir << "] Directory creation failure " << std::endl;
190        throw ( BrukerHopelessException ("Patient directory creation failure "));
191     }
192
193     if (subjectFound)
194     {
195        BrukerFieldData b_entry=br_subject.GetFieldData("SUBJECT_entry");
196        subject_entry = b_entry.GetStringValue()[0];
197        //cleanString(subject_entry);
198        subject_entry = subject_entry.substr(11, subject_entry.size()-11);
199   
200        BrukerFieldData b_position=br_subject.GetFieldData("SUBJECT_position");
201        subject_position = b_position.GetStringValue()[0];
202        //cleanString(subject_position);
203        subject_position = subject_position.substr(9, subject_position.size()-9);
204  
205        BrukerFieldData b_date=br_subject.GetFieldData("SUBJECT_date");
206        subject_date = b_date.GetStringValue()[0];
207        strStudyTimeDate = subject_date;
208        cleanString(subject_date);
209  
210        BrukerFieldData b_study_name=br_subject.GetFieldData("SUBJECT_study_name");
211        subject_study_name = b_study_name.GetStringValue()[0];
212        subject_study_name = subject_study_name.substr(1, subject_study_name.size()-2);
213        cleanString(subject_study_name);
214    }
215    else  // Desperate trick when file 'subject' is missing
216    {
217       subject_entry      = "HeadFirst";            // Why not?
218       subject_position   = "Supine";               // Why not?
219       strStudyTimeDate   = "06_06_06_6_June_1666"; // Why not?
220       subject_date       = "6_June_1666";          // Why not?
221       subject_study_name = "defStudyName";         // Why not? 
222    }
223     // subject_name is already in 'Patient Name' 
224     strStudyDescr = /*subject_name + "." + */ subject_study_name + "." + subject_entry + "." + subject_position + "." + subject_date;
225
226     // creation directory : 'nom de la Study'
227
228     std::string tempStringStudyDir(OutputDirName);
229     tempStringStudyDir = tempStringPatDir + GDCM_NAME_SPACE::GDCM_FILESEPARATOR + strStudyDescr;
230
231     res=CreateDirectory(tempStringStudyDir);
232     if (!res) {
233        std::cout << "[" << tempStringStudyDir << "] Directory creation failure " << std::endl;
234        throw ( BrukerHopelessException ("Study directory creation failure "));
235     }     
236
237    char outputDirName[(unsigned int) PATH_MAX+2];
238
239    strStudyUID    = GDCM_NAME_SPACE::Util::CreateUniqueUID();
240    serieNumber    = 0;
241    instanceNumber = 0;
242
243    // -----------------------------------------------------
244    // Iterate to ALL the objets(files/directories) found in the input directory
245    // (this is level ZERO)
246    // each Directory (name : 1, 2, 3, ...) will be a Dicom Serie
247    // -----------------------------------------------------
248
249    /// \TODO better use directory iterator, from boost! // JPR
250    GDCM_NAME_SPACE::DirListType::iterator it;
251
252    for (it = fileNames.begin();
253          it != fileNames.end();
254        ++it)
255    {
256       if ( boost::filesystem::is_directory(*it) )
257       { 
258          if (verbose)
259             std::cout << "[" << *it << "] is a directory" << std::endl;
260
261          //if((*it) == "AdjResult")  // avoid trouble with new version 'AdjResult' directory
262          if(GDCM_NAME_SPACE::Util::GetName(*it) == "AdjResult")
263             continue;
264
265          //BrukerDataSet br_acqp;
266          std::string strAcqp;
267          strAcqp = (*it) +
268                    GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
269                    "acqp";
270
271          br_acqp.LoadFile(strAcqp);
272          br_acqp.FillMap();
273
274 //std::cout << "out of br_acqp.FillMap " << std::endl;
275          std::string acqp_scan_name;
276          std::string acqp_method;
277          std::string acqp_protocol_location; 
278  
279          BrukerFieldData b_protocol_location=br_acqp.GetFieldData("ACQ_protocol_location");
280          acqp_protocol_location = b_protocol_location.GetStringValue()[0];
281          cleanString(acqp_protocol_location);
282
283 //std::cout << "out of br_acqp.FillMap 1" << std::endl;    
284          BrukerFieldData b_scan_name=br_acqp.GetFieldData("ACQ_scan_name");
285 //std::cout << "out of br_acqp.FillMap 11" << std::endl;         
286          acqp_scan_name = b_scan_name.GetStringValue()[0];
287 //std::cout << "out of br_acqp.FillMap 12 [" << acqp_scan_name << "]" << std::endl;      
288          cleanString(acqp_scan_name);
289 //std::cout << "out of br_acqp.FillMap 2" << std::endl;  
290          BrukerFieldData b_method=br_acqp.GetFieldData("ACQ_method");
291          b_method.PrintSelf();
292          acqp_method = b_method.GetStringValue()[0];
293
294          cleanString(acqp_method);
295 //std::cout << "out of br_acqp.FillMap 3" << std::endl;
296          BrukerFieldData b_list_size = br_acqp.GetFieldData("ACQ_O1_list_size");
297 //std::cout << "out of br_acqp.FillMap 4" << std::endl;        
298          //b_list_size.PrintSelf(); //JP
299
300          nbSlices =  b_list_size.GetIntValue()[0];
301 //std::cout << "out of br_acqp.FillMap 5" << std::endl;
302          strSerieDescr = GDCM_NAME_SPACE::Util::GetName(*it)
303                        /*  + "." + acqp_protocol_location */ // always the same (in each acquisition)
304                          + "." + acqp_scan_name
305                          + "." + acqp_method.c_str();
306
307          sprintf(outputDirName, "%s%c%s", tempStringStudyDir.c_str(),      //OutputDirName.c_str(), 
308                           GDCM_NAME_SPACE::GDCM_FILESEPARATOR,
309                           strSerieDescr.c_str() );
310
311          std::cout << " ================================================================================\n"
312                    << " === [" << GDCM_NAME_SPACE::Util::GetName(*it) << "] -> [" << strSerieDescr << "]\n"
313                    << " ================================================================================"
314                    << std::endl;
315         std::string strOutputDirName(outputDirName);
316         if (verbose)
317            printf ("outputDirName [%s]\n", outputDirName);
318         try {
319            DealWithNiveau1(*it, strOutputDirName);
320         }
321         catch (BrukerHopelessException &e)
322         {
323          std::cout << "And Exception was thrown in DealWithNiveau1 (" << e.what() << ") " << std::endl;
324          continue;
325         }
326       }
327    } // end of : for (GDCM_NAME_SPACE::DirListType::iterator it
328 }
329
330 // =====================================================================
331
332 void Bruker2Dicom::DealWithNiveau1(std::string &level1Directory, std::string &currentOutputDirName) {
333 //
334 // e.g. : at level 1, in B67d1.Bp1/6
335 //
336 // acqp  fid  imnd  pdata  pulseprogram  spnam0  spnam1
337
338    bool res = CreateDirectory(currentOutputDirName); 
339
340    if (!res) {
341       std::cout << "[" << currentOutputDirName << "] Directory creation failure " << std::endl;
342       throw ( BrukerHopelessException ("Level 1 output directory creation failure "));    
343      // exit (0);
344    }
345    GDCM_NAME_SPACE::DirList dirList(level1Directory, false, true); // DON'T get recursively the list of files
346    GDCM_NAME_SPACE::DirListType fileNames;
347    fileNames = dirList.GetFilenames();
348    // -----------------------------------------------------
349    // Iterate to ALL the objets(files/directories) found in the input directory
350    // -----------------------------------------------------
351    GDCM_NAME_SPACE::DirListType::iterator it;
352
353    for (it = fileNames.begin();
354         it != fileNames.end();
355       ++it)
356    {
357       if ( boost::filesystem::is_regular(*it) ) 
358       //if ( ! boost::filesystem::is_directory(*it) )
359       {
360          if (verbose)
361             std::cout << "--- [" << *it << "] is a file." << std::endl;
362       }  
363    }
364
365    char outputDirName[(unsigned int) PATH_MAX+2];
366    //std::string firstName;
367    bool canOpen;
368    for (it = fileNames.begin();
369         it != fileNames.end();
370       ++it)
371    {
372       if ( boost::filesystem::is_directory(*it) )
373       {
374          // will be always "pdata" ...
375          if (verbose)
376             std::cout << "--- [" << *it << "] is a directory" << std::endl;
377
378               /* a recuperer :
379               if (FileLine.startsWith("##$ACQ_size=")) {
380               if (FileLine.startsWith("##$NI=")) {
381               if (FileLine.startsWith("##$NR=")) {
382               if (FileLine.startsWith("##$ACQ_obj_order=")) {
383               if (FileLine.startsWith("##$ACQ_word_size=")) {
384               if (FileLine.startsWith("##$BYTORDA=")) {
385               if (FileLine.startsWith("##$PULPROG=")) {
386               */
387
388          sprintf(outputDirName, "%s%c%s", currentOutputDirName.c_str(),
389                                           GDCM_NAME_SPACE::GDCM_FILESEPARATOR,
390                                           GDCM_NAME_SPACE::Util::GetName(*it).c_str());
391          std::string strOutputDirName(outputDirName);
392          //br1.PrintSelf();
393
394           std::string strMethod;
395           //std::string firstName = *(fileNames.begin());
396
397           strMethod = GDCM_NAME_SPACE::Util::GetPath(*(fileNames.begin())) +
398                       GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
399                       "method";
400             // std::cout << "---strMethod (for method)=> [" << strMethod << "]" << std::endl;        
401           canOpen = br_method.LoadFile(strMethod);
402           if (!canOpen)
403           {
404              strMethod = GDCM_NAME_SPACE::Util::GetPath(*(fileNames.begin()))+
405                          GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
406                          "imnd";
407              //std::cout << "---strMethod (for imnd) => [" << strMethod << "]" << std::endl;
408              canOpen = br_method.LoadFile(strMethod);
409              if (!canOpen)
410              {
411                 std::cout << "Hopeless! neither 'method' nor 'imnd' found in ["
412                           << level1Directory  << "]; we skip it!" << std::endl;
413                 continue;
414                 //throw ( BrukerHopelessException ("Hopeless! neither 'method' nor 'imnd' found "));            
415                 //exit(0);  /// \TODO throw an exception !
416              }
417           }
418           if (verbose)
419              std::cout << "open => [" << strMethod << "] successfully" << std::endl; 
420           br_method.FillMap();
421
422           /* a recuperer :
423              ##$PVM_Fov (dimension)  // ou plutot RECO_fov !
424           */
425   /*
426           dans method (pour perfusion  seulement?) :
427           ##$PVM_ObjOrderList=( 8 )
428           0 2 4 6 1 3 5 7
429           ##$PVM_NSPacks=2
430           ##$PVM_SPackArrNSlices=( 2 )
431           7 1  
432   */
433          try {
434             DealWithNiveau2(*it, strOutputDirName);
435          }
436          catch (BrukerHopelessException &e)
437          {
438             std::cout << "And Exception was thrown in DealWithNiveau2 (" << e.what() << ") " << std::endl;
439             continue;
440          }
441       }
442    }
443 }
444
445 // =====================================================================
446
447 void Bruker2Dicom::DealWithNiveau2(std::string &level2Directory, std::string &currentOutputDirName) {
448
449 // e.g. : at level 2 in B67d1.Bp1/6/pdata
450 //
451 // acqp  fid  imnd  pdata  pulseprogram  spnam0  spnam1
452 //
453
454    bool res = CreateDirectory(currentOutputDirName); 
455
456    if (!res) {
457       std::cout << "[" << currentOutputDirName << "] Directory creation failure " << std::endl;
458       throw ( BrukerHopelessException ("Hopeless! Level2 output directory creation failure"));        
459       //exit (0);
460    }
461
462    GDCM_NAME_SPACE::DirList dirList(level2Directory, false, true); // DON'T get recursively the list of files
463
464    GDCM_NAME_SPACE::DirListType fileNames;
465    fileNames = dirList.GetFilenames();
466
467    char outputDirName[(unsigned int) PATH_MAX+2];
468
469    // -----------------------------------------------------
470    // Iterate to ALL the objets(files/directories) found in the input directory
471    // -----------------------------------------------------
472    GDCM_NAME_SPACE::DirListType::iterator it;
473    bool canOpen;
474
475    if (verbose)
476    for (it = fileNames.begin();
477         it != fileNames.end();
478       ++it)
479    {
480       if ( ! boost::filesystem::is_directory(*it) )
481       { 
482          std::cout << "--- --- [" << *it << "] is a file.." << std::endl;
483       }
484    }
485
486    for (it = fileNames.begin();
487          it != fileNames.end();
488        ++it)
489    {
490       if ( boost::filesystem::is_directory(*it) )
491       { 
492   
493          if (verbose)
494             std::cout << "--- --- [" << *it << "] is a directory" << std::endl;
495
496         // sprintf(outputDirName, "%s%c%s", currentOutputDirName.c_str(), 
497         //                          GDCM_NAME_SPACE::GDCM_FILESEPARATOR,
498         //                                GDCM_NAME_SPACE::Util::GetName(*it).c_str() );
499   // MUST be 'pdata'!
500
501 //
502 // (interest of previous method :
503 // If unaware user changed the pdata name, it goes on working   
504 //
505           std::string str_isa;
506           str_isa = (*it) + 
507                     GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
508                    "isa";
509
510           std::string str_isa_func_name;    
511           canOpen = br_isa.LoadFile(str_isa);
512           if (!canOpen)
513           {
514              sprintf(outputDirName, "%s%c%s", currentOutputDirName.c_str(), 
515                                           GDCM_NAME_SPACE::GDCM_FILESEPARATOR,
516                                           GDCM_NAME_SPACE::Util::GetName(*it).c_str() );        
517           }
518           else
519           {
520              br_isa.FillMap();
521              BrukerFieldData b_isa_func_name = br_isa.GetFieldData("ISA_func_name");
522     
523              str_isa_func_name = b_isa_func_name.GetStringValue()[0];
524              cleanString(str_isa_func_name);
525
526              sprintf(outputDirName, "%s%c%s.%s", currentOutputDirName.c_str(), 
527                                           GDCM_NAME_SPACE::GDCM_FILESEPARATOR,
528                                           GDCM_NAME_SPACE::Util::GetName(*it).c_str(),
529              str_isa_func_name.c_str());
530           }
531           std::string strOutputDirName(outputDirName);
532           try {
533              DealWithNiveau3(*it, strOutputDirName);
534           }
535           catch (BrukerHopelessException &e)
536           {
537              std::cout << "And Exception was thrown in DealWithNiveau3 (" << e.what() << "); " 
538                        << " We skip [" << level2Directory << "]" << std::endl;
539              continue;
540           }
541           catch (BrukerInitException &e)
542           {
543              std::cout << "And Init Exception was thrown in DealWithNiveau3 (" << e.what() << "); " 
544                        << " We skip [" << level2Directory << "]" << std::endl;
545              continue;
546           }          
547       }
548    }
549 }
550
551 //
552 // =====================================================================
553 //
554
555 void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &currentOutputDirName){
556
557 //
558 // e.g. at level 3, in
559
560    // just to be able to go on checking // JP
561    if ( GDCM_NAME_SPACE::Util::GetName(level3Directory) != "1")
562       return;
563
564    bool res = CreateDirectory(currentOutputDirName);
565
566    if (!res)
567    {
568       std::cout << "[" << currentOutputDirName << "] Directory creation failure " << std::endl;
569       throw ( BrukerHopelessException ("Hopeless! Level3 output directory creation failure"));
570       //exit (0);
571    }
572
573    GDCM_NAME_SPACE::DirList dirList(level3Directory, false, true); // DON'T get recursively the list of files
574    GDCM_NAME_SPACE::DirListType::iterator it;
575    GDCM_NAME_SPACE::DirListType fileNames;
576    fileNames = dirList.GetFilenames();
577
578    char original2dseqName       [(unsigned int) PATH_MAX+2];
579    char original2dseqName_XXX   [(unsigned int) PATH_MAX+2];   
580    char currentOutputMhdDirName [(unsigned int) PATH_MAX+2];
581
582    char outputMhdFileName       [(unsigned int) PATH_MAX+2];
583    char output2dseqSliceFileName[(unsigned int) PATH_MAX+6]; // think about extra '.dcm'
584    char output2dseqName         [(unsigned int) PATH_MAX+6];
585    char output2dseqCartoName    [(unsigned int) PATH_MAX+6];
586
587    char copyFile[PATH_MAX + PATH_MAX + 5]; // Should be enough!
588    bool canOpen;
589
590    //-------------- try d3proc;
591    char char_d3proc[(unsigned int) PATH_MAX+2];
592
593    sprintf(char_d3proc,"%s%c%s", level3Directory.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR,"d3proc" );     
594
595    if (verbose)
596       std::cout << "d3proc: --- => [" << char_d3proc << "]" << std::endl;
597    std::string str_d3proc(char_d3proc);       
598    canOpen = br_d3proc.LoadFile(str_d3proc);
599
600    if (!canOpen)
601    {
602       std::cout << "Hopeless! no 'd3proc' found" << std::endl;
603       throw ( BrukerHopelessException ("Hopeless! no 'd3proc' found"));
604       //exit(0);  /// \TODO throw an exception ! 
605    }
606
607    canOpen = br_d3proc.FillMap();
608    if (!canOpen)
609    {
610       std::cout << "Hopeless! FillMap failed on 'd3proc'" << std::endl;
611       throw ( BrukerHopelessException ("Hopeless! FillMap failed on 'd3proc'"));      
612       //exit(0);  /// \TODO throw an exception !     
613    }
614
615    //-------------- end try d3proc;
616
617
618  // -------------------try reco
619
620    char char_reco[(unsigned int) PATH_MAX+2];
621
622    sprintf(char_reco,"%s%c%s", level3Directory.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR,"reco" );     
623     //str_d3proc = GDCM_NAME_SPACE::Util::GetPath(*(fileNames.begin()))+
624     //             GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
625     //             "d3proc";
626    if (verbose)
627       std::cout << "reco: --- => [" << char_reco << "]" << std::endl;
628
629    std::string str_reco(char_reco);
630    canOpen = br_reco.LoadFile(str_reco);
631
632    if (!canOpen) // we try in directory ../1
633    {
634       if (verbose)
635          std::cout << "[" << str_reco << "] not found " << std::endl;
636       std::string lastDirName = GDCM_NAME_SPACE::Util::GetPath(level3Directory);
637       //lastDirName = GDCM_NAME_SPACE::Util::GetPath(lastDirName);
638       sprintf(char_reco,"%s%c1%c%s", lastDirName.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR,GDCM_NAME_SPACE::GDCM_FILESEPARATOR,"reco" );
639       //str_reco=char_reco;
640       canOpen = br_reco.LoadFile(str_reco);
641       if (!canOpen)
642       {
643          std::cout << "Hopeless! cannot find 'reco' in [" << str_reco << "]"  << std::endl;      
644          throw ( BrukerHopelessException ("Hopeless! cannot find 'reco'"));  
645          //exit(0);  /// \TODO throw an exception !    
646       }
647    } else {
648       if (verbose)
649          std::cout << "[" << str_reco << "] successfully Loaded " << std::endl;
650    }
651
652    canOpen = br_reco.FillMap();
653    if (!canOpen)
654    {
655       std::cout << "Hopeless! FillMap failed on [" << str_reco << "]" << std::endl;
656       throw ( BrukerHopelessException ("Hopeless! FillMap failed on 'reco'"));  
657       //exit(0);  /// \TODO throw an exception !
658    } else {
659       if (verbose)
660          std::cout << "[" << str_reco << "] successfully Mapped" << std::endl;
661    }   
662
663    //std::cout << "------------------------------------------------------------------------------------------------" << std::cout;
664    // br_reco.PrintSelf();
665    // std::cout << "------------------------------------------------------------------------------------------------" << std::cout;
666    // -------------------end try reco
667
668
669    BrukerFieldData bX = br_d3proc.GetFieldData("IM_SIX");
670    int NX = bX.GetIntValue()[0];
671
672    if (verbose)
673       std::cout << "IM_SIX " << NX << std::endl;
674    BrukerFieldData bY=br_d3proc.GetFieldData("IM_SIY"); 
675    int NY = bY.GetIntValue()[0];
676
677    if (verbose)
678          std::cout << "IM_SIY " << NY << std::endl;
679    /// \todo : check if there are actually 3 dimensions or only 2
680
681    BrukerFieldData bZ= br_d3proc.GetFieldData("IM_SIZ");
682    int nbFrames = bZ.GetIntValue()[0]; 
683    if (verbose)
684          std::cout << "IM_SIZ " << nbFrames << std::endl;
685
686         // WARNING DATTYPE is, either in {ip_short, ip_int, ip_char, ...}, or in {1, 2, 3, ...}
687
688    BrukerFieldData bDPT = br_d3proc.GetFieldData("DATTYPE");
689
690    std::string mhdDataPixelType;
691    int pixelSize;
692    getImhDataType(bDPT, mhdDataPixelType, pixelSize);
693
694
695  /*
696
697  // See mail Denis : 
698  // En regle generale il vaut mieux que l'on passe par RECO_* 
699  // pour extraire les parametres de l'image
700  //
701
702    BrukerFieldData fov = br_method.GetFieldData("PVM_Fov");
703    double fovX = fov.GetDoubleValue()[0];
704    double fovY = fov.GetDoubleValue()[1];
705    if (verbose)
706       std::cout << "FOV (ds method) " << fovX << " " << fovY << std::endl;
707
708    BrukerFieldData spatResol = br_method.GetFieldData("PVM_SpatResol");
709    double spatResolX = spatResol.GetDoubleValue()[0];
710    double spatResolY = spatResol.GetDoubleValue()[1];
711    if (verbose)
712       std::cout << "SpatResol (ds method) " << spatResolX << " " << spatResolY << std::endl;
713      
714 */
715
716 /* ------  */
717 // Better we use 'get' accessors from BrukerImage class, as Denis wrote them
718
719    BrukerFieldData fov = br_reco.GetFieldData("RECO_fov");
720    double fovX = fov.GetDoubleValue()[0];
721    double fovY = fov.GetDoubleValue()[1];
722    if (verbose)
723       std::cout << "FOV (ds reco) " << fovX << " " << fovY << std::endl;
724
725    BrukerFieldData size = br_reco.GetFieldData("RECO_size");
726    double sizeX = size.GetDoubleValue()[0];
727    double sizeY = size.GetDoubleValue()[1];
728
729    if (verbose)
730       std::cout << "SIZE (ds reco) " << sizeX << " " << sizeY << std::endl;
731
732    double spatResolX = fovX / sizeX;
733    double spatResolY = fovY / sizeY;
734
735    if (verbose)
736       std::cout << "spatResol (ds reco : fov/size) " << spatResolX << " " << spatResolY << std::endl;
737
738 /* ------  */
739
740    /// \TODO probabely a more sophisticated accessor will be necessary :
741    ///  (cf : non contiguous slices, overlapping, slice thickness, space between slices, etc)
742
743    BrukerFieldData bsliceDistance = br_method.GetFieldData("PVM_SPackArrSliceDistance");
744    double sliceDistance = bsliceDistance.GetDoubleValue()[0];
745
746    if (verbose)
747       std::cout << "SPackArrSliceDistance (ds method) " << sliceDistance << std::endl;   
748
749 // ----------------------------------------------------------------------------------------
750
751    if (mhd)
752    {
753       sprintf(currentOutputMhdDirName, "%s%c%s", currentOutputDirName.c_str(),
754                                GDCM_NAME_SPACE::GDCM_FILESEPARATOR, "MhdFiles");
755
756       std::string strCurrentOutputMhdDirName(currentOutputMhdDirName);
757       res = CreateDirectory( strCurrentOutputMhdDirName );
758       if (!res) {
759          std::cout << "[" << currentOutputDirName << "] Directory creation failure " << std::endl;
760          throw ( BrukerHopelessException ("Hopeless!FillMap failed on 'reco'"));  
761          //exit (0);
762       } 
763
764       if (verbose)
765          std::cout << "Directory creation [" <<  currentOutputDirName << "]" << std::endl;
766    }  // end if mhd
767
768    if (verbose)
769          std::cout << "nbFrames " << nbFrames << std::endl;
770    if (verbose)
771          std::cout << "nbSlices " << nbSlices << std::endl;
772    int k;
773    int nbInstants = nbFrames/nbSlices;
774    if (verbose)
775          std::cout << "nbInstants (deduced)" << nbInstants << std::endl;    
776    int instantNb;
777    int sliceNb; 
778    FILE *fp;  // for MHD files
779
780    sprintf( original2dseqName, "%s%c%s", level3Directory.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR, "2dseq");
781
782 /**/   
783   // \TODO : tenir compte du bazar precedent 
784
785     // load 2dseq in memory
786
787    fp = fopen(original2dseqName, "rb");
788    if (!fp) 
789    {
790       // try 2dseq_Angio2D ?!?
791
792       sprintf( original2dseqName_XXX, "%s%s", original2dseqName, "_Angio2D");
793       fp = fopen(original2dseqName_XXX, "rb");
794       if (!fp)
795       {
796          std::cout << "Cannot open [" << original2dseqName << "] nor [" <<  original2dseqName_XXX << "] for reading" << std::endl;
797          fclose(fp);     
798          throw ( BrukerHopelessException ("Hopeless! Cannot open '2dseq'"));
799          //exit (0);
800       }
801    }
802
803    unsigned char *buffer_2dseq = new unsigned char[NX*NY*pixelSize*nbSlices*nbInstants];   
804    ///\ TODO : find a safer way to be sure to read everything!
805    size_t lgr = fread(buffer_2dseq, 1, NX*NY*pixelSize*nbSlices*nbInstants, fp);
806
807    // This one will be important!
808    // ---------------------------
809    try {
810       imageSet = CreateImageSet ( );
811    }
812    catch (BrukerInitException& e)
813    {
814       if (verbose)
815          std::cout <<  "an Init Exception was thrown in CreateImageSet ( ); " << e.what() 
816                    <<  "catched in DealWithNiveau3" << std::endl;
817       //return;
818       throw (e);
819    }
820
821    serieNumber++;
822    strSerieUID =  GDCM_NAME_SPACE::Util::CreateUniqueUID();
823    if (nbInstants==1) // creer un seul fichier .mhd  pour toutes les Slices! (images natives)
824    {
825        if (verbose)
826           std::cout << "Single instant : do not split" << std::endl;
827        if (mhd)
828        {
829              sprintf(outputMhdFileName, "%s%cMhdData_All_the_Slices.mhd", currentOutputMhdDirName,
830                                          GDCM_NAME_SPACE::GDCM_FILESEPARATOR);
831              fp=fopen(outputMhdFileName, "w");
832              if (!fp)
833              {
834                 std::cout << "Cannot open [" << outputMhdFileName << "] for writting" << std::endl;
835                 throw ( BrukerHopelessException ("Hopeless! Cannot open  mhd file for writting"));
836                 //exit(0);
837              }
838              else
839              {
840                fprintf(fp, "ObjectType = Image\n");
841                fprintf(fp, "NDims = 3\n" );
842                fprintf(fp, "BinaryData = True \n" );
843                fprintf(fp, "BinaryDataByteOrderMSB = False\n" );
844                fprintf(fp, "DimSize = %d %d %d\n", NX, NY, nbSlices );
845                fprintf(fp, "HeaderSize = %d\n", 0);
846                //fprintf(fp, "ElementSpacing = %lf %lf %lf\n",fovX/NY, fovY/NY, sliceDistance );
847                fprintf(fp, "ElementSpacing = %lf %lf %lf\n", spatResolX, spatResolY, sliceDistance );
848                fprintf(fp, "Position = 0 0 %d\n", 0 );
849                fprintf(fp, "Offset = 0 0 0\n" );
850                fprintf(fp, "CenterOfRotation = 0 0 0\n" );
851                fprintf(fp, "ElementNumberOfChannels = 1\n" );
852                fprintf(fp, "ElementType = %s\n", mhdDataPixelType.c_str() );  
853                fprintf(fp, "ElementDataFile = %s\n", "../2dseq_All_the_Slices" );
854                fclose(fp);     
855              }
856              sprintf(output2dseqSliceFileName, "%s%c2dseq_All_the_Slices", 
857                                        currentOutputDirName.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR);
858              fp=fopen(output2dseqSliceFileName, "wb");
859              if (!fp)
860              {
861                 std::cout << "Cannot open [" << output2dseqSliceFileName << "] for writting" << std::endl;
862                 throw ( BrukerHopelessException ("Hopeless! Cannot open 2dseq file for writting"));             
863              }
864              else
865              {
866                 fwrite( buffer_2dseq, NX*NY*pixelSize, nbSlices, fp);     
867              }
868              fclose(fp);
869              serieNumber ++;
870              strSerieUID =  GDCM_NAME_SPACE::Util::CreateUniqueUID();
871        }  // end if mhd
872        if (dicom)
873        {
874              sprintf(output2dseqSliceFileName, "%s%c2dseq_All_the_Slices.dcm", 
875                                        currentOutputDirName.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR);
876
877             /* ----------- Write Dicom Image  ---------------*/
878              MakeDicomImage(buffer_2dseq,
879                NX,
880                NY,
881                nbFrames,
882                pixelSize,
883                //fovX/NY, fovY/NY, sliceDistance,
884                spatResolX, spatResolY, sliceDistance,
885                output2dseqSliceFileName,
886                subject_name,
887                day,
888                strStudyUID,
889                strSerieUID,
890                strStudyDescr,
891                strSerieDescr,
892                strStudyTimeDate,
893                0,// index frame number
894                GDCM_NAME_SPACE::UNMODIFIED_PIXELS_IMAGE
895              );
896        }  // end if dicom
897    }  // end if nbInstants = 1
898
899    else  // more than ONE instant
900    {
901           // Interleaved !
902           // it's (slice1,slide2, ...)t1 ; (slice1,slide2, ...)t2 ; ...
903          unsigned char *pixelsForCurrentSlice = new unsigned char[NX*NY*pixelSize*nbInstants];
904
905          k = 0;
906          for (sliceNb=0; sliceNb<nbSlices; sliceNb++)
907          {
908             if (mhd)
909             {
910                sprintf(outputMhdFileName, "%s%cMhdData_%03d.mhd", currentOutputMhdDirName, 
911                                         GDCM_NAME_SPACE::GDCM_FILESEPARATOR, k  );
912                if (verbose)
913                   std::cout << "--- Output MHD file [" << outputMhdFileName << "]" << std::endl;
914                fp=fopen(outputMhdFileName, "w");
915                if (!fp)
916                {
917                    std::cout << "Cannot open [" << outputMhdFileName << "] for writting" << std::endl;
918                    throw ( BrukerHopelessException ("Hopeless! Cannot open  mhd file for writting"));
919                    //exit(0);
920                }
921                else
922                {
923             /* ----------- Write MHD Image  ---------------*/
924                 //if (verbose)
925                 //   std::cout << "Open sucessfully[" << outputMhdFileName << "] for writting" << std::endl; 
926                    fprintf(fp, "ObjectType = Image\n");
927                    fprintf(fp, "NDims = 3\n" );  
928                    fprintf(fp, "BinaryData = True \n" );  
929                    fprintf(fp, "BinaryDataByteOrderMSB = False\n" );    
930                    fprintf(fp, "DimSize = %d %d %d\n", NX, NY, nbInstants);  
931                    fprintf(fp, "HeaderSize = %d\n", 0); 
932                    //fprintf(fp, "ElementSpacing = %lf %lf %lf\n",fovX/NY, fovY/NY, 1.0 ); // 
933                    fprintf(fp, "ElementSpacing = %lf %lf %lf\n",spatResolX, spatResolY, 1.0 ); //slice distance : no meaning for temporal serie
934                    fprintf(fp, "Position = 0 0 %d\n", sliceNb );  
935                    fprintf(fp, "Offset = 0 0 0\n" );  
936                    fprintf(fp, "CenterOfRotation = 0 0 0\n" );
937                    fprintf(fp, "ElementNumberOfChannels = 1\n" );  
938                    fprintf(fp, "ElementType = %s\n", mhdDataPixelType.c_str() );  
939                    fprintf(fp, "ElementDataFile = ..%c2dseq_Slice_%d\n", GDCM_NAME_SPACE::GDCM_FILESEPARATOR, sliceNb ); 
940                    fclose(fp);
941                } // end write MHD
942
943                sprintf(output2dseqSliceFileName, "%s%c2dseq_Slice_%d", 
944                                                  currentOutputDirName.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR,sliceNb);
945                fp=fopen(output2dseqSliceFileName, "wb");
946                if (!fp)
947                {     
948                    std::cout << "Cannot open [" << output2dseqSliceFileName << "] for writting" << std::endl;
949                    throw ( BrukerHopelessException ("Hopeless! Cannot open 2dseqSliceFile file for writting"));            
950                    //exit (0);
951                }
952                int frameSize = NX*NY*pixelSize;
953                for (instantNb=0; instantNb<nbInstants; instantNb++)
954                {
955 // std::cout << "------------SN " << sliceNb << " IN " << instantNb <<  " T " << nbSlices*instantNb + sliceNb << std::endl;
956                     fwrite( buffer_2dseq +(nbSlices*instantNb + sliceNb)*frameSize,
957                             frameSize,
958                             1, fp);
959                }
960                fclose(fp);
961
962 // std::cout << "end writting[" << output2dseqSliceFileName << "]" << std::endl;
963             }  // end if mhd
964    
965             if (dicom)
966             {
967                // desperate try !
968              /* 
969                sprintf(output2dseqSliceFileName, "%sdummy_buffer", 
970                                                  currentOutputDirName.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR);
971                fp=fopen(output2dseqSliceFileName, "wb");
972                if (!fp)
973                {     
974                    std::cout << "Cannot open [" << output2dseqSliceFileName << "] for writting" << std::endl;
975                    exit (0);
976                }
977                int frameSize = NX*NY*pixelSize;
978                for (instantNb=0; instantNb<nbInstants; instantNb++)
979                {
980 // std::cout << "------------SN " << sliceNb << " IN " << instantNb <<  " T " << nbSlices*instantNb + sliceNb << std::endl;
981                     fwrite( buffer_2dseq +(nbSlices*instantNb + sliceNb)*frameSize,
982                             frameSize,
983                             1, fp);
984                }
985                fclose(fp);
986
987                fp=fopen(output2dseqSliceFileName, "rb");
988                if (!fp)
989                {     
990                    std::cout << "Cannot open [" << output2dseqSliceFileName << "] for reading" << std::endl;
991                    exit (0);
992                }       
993                fread( pixelsForCurrentSlice,
994                             frameSize*nbInstants,
995                             1, fp);
996                fclose(fp);
997               // end of desperate try !
998               */
999
1000                /* ----------- Write Dicom Image  ---------------*/
1001
1002                int frameSize = NX*NY*pixelSize;
1003                for (instantNb=0; instantNb<nbInstants; instantNb++)
1004                {
1005                   memcpy(pixelsForCurrentSlice + frameSize*instantNb, buffer_2dseq +(nbSlices*instantNb + sliceNb)*frameSize, frameSize);
1006                }
1007
1008                int indOfFirsImageWithinImageSet =  nbSlices*instantNb;
1009                sprintf(output2dseqSliceFileName, "%s%c2dseq_Slice_%d.dcm", 
1010                                                  currentOutputDirName.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR, sliceNb);
1011
1012                MakeDicomImage(
1013                   pixelsForCurrentSlice,
1014                   NX,
1015                   NY,
1016                   nbInstants,
1017                   pixelSize,
1018                   spatResolX, spatResolY, sliceDistance,
1019                   //fovX/NY, fovY/NY, sliceDistance,
1020                   output2dseqSliceFileName,
1021                   subject_name,
1022                   day,
1023                   strStudyUID,
1024                   strSerieUID,
1025                   strStudyDescr,
1026                   strSerieDescr,
1027                   strStudyTimeDate,
1028                   sliceNb*nbInstants,
1029                   GDCM_NAME_SPACE::UNMODIFIED_PIXELS_IMAGE
1030                );
1031                if (verbose)
1032                   std::cout << "--- Output DCM file [" << output2dseqSliceFileName << "]" << std::endl;      
1033
1034            } // en if dicom
1035
1036         k++;
1037         }
1038         delete [] pixelsForCurrentSlice;  
1039      }  // end nbInstants == 1
1040    delete [] buffer_2dseq;
1041 /**/
1042
1043
1044    // -----------------------------------------------------
1045    //  deal with MatLab-generated Carto file.
1046    // -----------------------------------------------------
1047
1048    dealWithCarto(fileNames,  NX,  NY,  nbSlices, /*fovX, fovY,*/ spatResolX, spatResolY, sliceDistance,
1049                    copyFile, currentOutputDirName, outputMhdFileName, output2dseqCartoName);
1050 }
1051
1052 // ===========================================================================================
1053
1054 void Bruker2Dicom::dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX, int NY, int nbSlices, 
1055                                  /*double fovX, double fovY, */
1056                                  double spatResolX, double spatResolY, double sliceDistance,
1057                                  char *copyFile, std::string &currentOutputDirName, 
1058                                  char *outputMhdFileName, char *output2dseqCartoName)
1059 {
1060    // -----------------------------------------------------
1061    //  deal with MatLab-generated Carto file.
1062    // -----------------------------------------------------
1063
1064    const char *code[] = { "ADC", "adc", "TTP", "ttp", "PEAK", "peak", "" };  // add more carto file name identifiers if necessary; end with ""
1065    const char *separator[] =  { "_", ".", "-", "" }; //  add more, if necessary, to ckeck for 2dseq.ADC, 2dseq_ADC, 2dseq-ADC, etc; end with ""
1066    int icode;
1067    int iseparator; 
1068    GDCM_NAME_SPACE::DirListType::iterator it;
1069    char file_name_ident[500];
1070    FILE *fp;
1071
1072    // Iterate to ALL the objets(files/directories) found in the input directory    
1073    for (it = fileNames.begin();
1074         it != fileNames.end();
1075       ++it)
1076    {
1077       if ( boost::filesystem::is_regular(*it) )
1078       //if ( ! boost::filesystem::is_directory(*it) )
1079       {         
1080          if (verbose)
1081             std::cout << "--- [" << *it << "] is a file..." << std::endl;
1082
1083          icode      = 0;
1084          while (code[icode][0] != 0)
1085          { 
1086          iseparator = 0;       
1087          while (separator[iseparator][0] != 0)
1088          {
1089             sprintf(file_name_ident, "2dseq%s%s",separator[iseparator],code[icode]); // e.g  "2dseq_ADC"
1090             //if (verbose)
1091             //   std::cout << "check name ["<<(*it) << "] for string [" << file_name_ident << "]" << std::endl;
1092             std::string::size_type loc = (*it).rfind(file_name_ident); 
1093
1094             if ( loc != std::string::npos )
1095             {
1096
1097        ///\ TODO : find a safer way to be sure to read everything!
1098               unsigned char *buffer_carto = new unsigned char[NX*NY*sizeof(double)*nbSlices];
1099               fp = fopen ( (*it).c_str(), "rb");
1100               if (!fp){
1101                  std::cout << "Cannot open [" << *it << "] for reading" << std::endl;
1102                  throw ( BrukerHopelessException ("Level 1 Unable to open 'carto' file "));
1103                }
1104                fread(buffer_carto, NX*NY*sizeof(double), nbSlices, fp);
1105
1106                     // ?!?  sprintf(copyFile, "cp %s %s%c%s", (*it).c_str() ,
1107                std::cout << "Deal with Carto file :[" <<*it << "], computed length : "
1108                          << NX*NY*sizeof(double)*nbSlices << std::endl;
1109                std::string lastFileName = GDCM_NAME_SPACE::Util::GetName((*it).c_str());
1110                if (mhd)
1111                {
1112                   // Copy the data file in the new directory
1113                   sprintf(copyFile, "cp %s %s%c%s", (*it).c_str() ,
1114                             currentOutputDirName.c_str(),GDCM_NAME_SPACE::GDCM_FILESEPARATOR, lastFileName.c_str()); 
1115                   system(copyFile);
1116                   sprintf(outputMhdFileName, "%s%c%s%s",
1117                                          currentOutputDirName.c_str(),GDCM_NAME_SPACE::GDCM_FILESEPARATOR, lastFileName.c_str(), ".mhd" );
1118                   if (verbose)
1119                     std::cout << "--- Output Carto MHD file [" << outputMhdFileName << "]" << std::endl;
1120
1121                   FILE *fp;
1122                   fp=fopen(outputMhdFileName, "w");
1123                   if (!fp)
1124                   {
1125                      std::cout << "Cannot open [" << outputMhdFileName << "] for writting" << std::endl;
1126                   }
1127                   else
1128                   {
1129                      fprintf(fp, "ObjectType = Image\n");
1130                      fprintf(fp, "NDims = 3\n" );
1131                      fprintf(fp, "BinaryData = True \n" );
1132                      fprintf(fp, "BinaryDataByteOrderMSB = False\n" );
1133                      fprintf(fp, "DimSize = %d %d %d\n", NX, NY, nbSlices);
1134                      fprintf(fp, "HeaderSize = %d\n", 0 );
1135                      fprintf(fp, "ElementSpacing = %lf %lf %lf\n",spatResolX, spatResolY, sliceDistance );
1136                      fprintf(fp, "Position = 0 0 0\n" );
1137                      fprintf(fp, "Offset = 0 0 0\n" );
1138                      fprintf(fp, "CenterOfRotation = 0 0 0\n" );
1139                      fprintf(fp, "ElementNumberOfChannels = 1\n" );
1140                      fprintf(fp, "ElementType = %s\n", "MET_DOUBLE" );
1141                      fprintf(fp, "ElementDataFile = %s\n", lastFileName.c_str() );
1142
1143                      fclose(fp);
1144                   }
1145                   if (verbose)
1146                      std::cout << "--- end write Carto MHD file [" << outputMhdFileName << "]" << std::endl;
1147                }  // end if mhd
1148
1149             // ----------- Write Dicom Image  ---------------
1150
1151                if (dicom)
1152                {
1153                   sprintf(output2dseqCartoName, "%s%c%s%s",
1154                                        currentOutputDirName.c_str(),GDCM_NAME_SPACE::GDCM_FILESEPARATOR, lastFileName.c_str(), ".dcm" );
1155                   if (verbose)
1156                      std::cout << "--- end create name output2dseqCartoName file [" << output2dseqCartoName << "]" << std::endl;
1157
1158                   strSerieUID =  GDCM_NAME_SPACE::Util::CreateUniqueUID(); //New SerieUID for each carto.
1159                   std::string strNewSerieDescr(strSerieDescr+ "_" +GDCM_NAME_SPACE::Util::GetName((*it).c_str()));
1160                   MakeDicomImage(buffer_carto,
1161                      NX,
1162                      NY,
1163                      nbSlices,
1164                      8, // pixelSize
1165                      //fovX/NY, fovY/NY, sliceDistance,
1166                      spatResolX, spatResolY, sliceDistance,
1167                      output2dseqCartoName,
1168                      subject_name,
1169                      day,
1170                      strStudyUID,
1171                      strSerieUID,
1172                      strStudyDescr,
1173                      strNewSerieDescr,
1174                      strStudyTimeDate,
1175                      0,
1176                      GDCM_NAME_SPACE::CREATED_IMAGE
1177                   );
1178                }  // end if dicom
1179
1180                delete [] buffer_carto;
1181                if (verbose) 
1182                   std::cout << "--- End writing Carto DICOM file [" << output2dseqCartoName << "]" << std::endl;
1183                break; // don't check for more ident on same file name!
1184
1185             }  // end deal with _ADC, -adc, etc
1186           iseparator ++;
1187           }  // end iterate speparators
1188           icode++;
1189           } // end iterate code
1190       } // end boost::filesystem::is_regular(*it)
1191    } // end iterate on all objects (files, dir, etc)
1192 } // end method
1193
1194 // ==========================================================================================================
1195
1196 int Bruker2Dicom::CheckUserDirectory(std::string &userDirName)
1197 {
1198    GDCM_NAME_SPACE::DirList dirList(userDirName, false, true); // DON'T get recursively the list of files
1199      
1200    GDCM_NAME_SPACE::DirListType fileNames;
1201    fileNames = dirList.GetFilenames();
1202
1203    std::string path = GDCM_NAME_SPACE::Util::GetPath(*(fileNames.begin()));
1204
1205    std::string subject =  path +
1206                           GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
1207                           "subject";
1208
1209     std::string acqp = path +
1210                        GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
1211                        "acqp";
1212
1213     if ( boost::filesystem::is_regular(subject) )
1214        subjectFound = true; // user passed a 'study
1215     else
1216        subjectFound = false; // user didnt' pass a 'study 
1217
1218     if ( boost::filesystem::is_regular(acqp) )
1219        acqpFound= true; // user passes a 'serie', not a 'study' 
1220     else
1221        acqpFound = false; // user passed a 'non study' directory; Hope it's a 'set of studies' directory!
1222    
1223    int type;    
1224    if  (subjectFound )  type = 1; // user passed a 'study
1225    else if  (acqpFound) type = 2; // user passed a 'serie' 
1226    else                 type = 3; // user passed a 'non study' directory; Hope it's a 'set of studies' directory!
1227
1228    return type;   
1229 }
1230
1231 // ==========================================================================================================
1232
1233 bool Bruker2Dicom::CreateDirectory(std::string &OutputDirName)
1234 {
1235    std::string systemCommand;
1236    
1237    if (verbose)
1238       std::cout << "Check for output directory :[" << OutputDirName << "]."
1239                 <<std::endl;
1240    if ( ! boost::filesystem::is_directory(OutputDirName) )    // dirout not found
1241    {
1242       systemCommand = "mkdir " + OutputDirName;        // create it!      
1243       if (verbose)
1244          std::cout << systemCommand << std::endl;
1245       system (systemCommand.c_str());
1246       if ( ! boost::filesystem::is_directory(OutputDirName) ) // be sure it worked
1247       {
1248          if (verbose) 
1249             std::cout << "KO : not a dir : [" << OutputDirName << "] (creation failure ?)" << std::endl;
1250          //return 0;
1251          throw ( BrukerHopelessException ("Level 1 output directory creation failure "));
1252       }
1253       else
1254       {
1255          if (verbose) 
1256            std::cout << "Directory [" << OutputDirName << "] created." << std::endl;
1257       }
1258    }
1259    else
1260    {
1261        if (verbose)
1262             std::cout << "Output Directory [" << OutputDirName << "] already exists; Used as is." << std::endl;
1263    }
1264    return 1;
1265 }
1266
1267 // ===========================================================================================
1268
1269 /// \TODO move cleanString to 'crea' ?
1270
1271 void Bruker2Dicom::cleanString(std::string &s)
1272 {
1273    int l = s.size();
1274    if (s[l-1] == 0x0A || s[l-1] == 0x0D ) // CR or NL
1275    {
1276       l--;
1277       s = s.substr(0, l);
1278    }
1279    if (s[l-1] == ' ' ) // blank space
1280    {
1281       l--;
1282       s = s.substr(0, l);
1283    }   
1284    
1285    if (s[0] == '<')      
1286       s= s.substr(1,l-2);
1287    std::string repChar("_");   
1288    GDCM_NAME_SPACE::Util::ReplaceSpecChar(s, repChar);
1289 }
1290
1291 // ===========================================================================================
1292
1293 void Bruker2Dicom::getImhDataType(BrukerFieldData &bDPT, std::string &mhdDataPixelType, int &pixelSize)
1294
1295    if(bDPT.GetDataType() == "string")
1296    {         
1297          std::string brukerDataPixelType = bDPT.GetStringValue()[0];
1298          if (verbose)
1299             std::cout << "DATTYPE " << brukerDataPixelType << std::endl;          
1300          //std::string brukerDataPixelType = br_d3proc.GetFieldData("DATTYPE").GetStringValue()[0];
1301          
1302          if (brukerDataPixelType ==  "ip_short") {
1303             mhdDataPixelType = "MET_USHORT";
1304             pixelSize = 2;
1305          }
1306          if (brukerDataPixelType ==  "ip_int") {
1307             mhdDataPixelType = "MET_UINT";
1308             pixelSize = 4;
1309          }
1310          if (brukerDataPixelType ==  "ip_char") {
1311              mhdDataPixelType = "MET_UCHAR";
1312              pixelSize = 1;
1313          }
1314                   /// \TODO : finish the list
1315     /*
1316     case 0 : fp << "ElementType = MET_CHAR" << std::endl;
1317       break;
1318     case 1 : fp << "ElementType = MET_UCHAR" << std::endl;
1319       break;
1320     case 2 : fp << "ElementType = MET_SHORT" << std::endl;
1321       break;
1322     case 3 : fp << "ElementType = MET_USHORT" << std::endl;
1323       break;
1324     case 4 : fp << "ElementType = MET_INT" << std::endl;
1325       break;
1326     case 5 : fp << "ElementType = MET_UINT" << std::endl;
1327       break;
1328     case 6 : fp << "ElementType = MET_FLOAT" << std::endl;
1329       break;
1330     case 7 : fp << "ElementType = MET_DOUBLE" << std::endl;  
1331     */
1332     }
1333     else
1334     {
1335          int brukerDataPixelType = bDPT.GetIntValue()[0];
1336          if (verbose)
1337             std::cout << "DATTYPE " << brukerDataPixelType << std::endl;          
1338          //std::string brukerDataPixelType = br_d3proc.GetFieldData("DATTYPE").GetStringValue()[0];
1339  
1340 // Cross your fingers !!!
1341
1342 // pb : found values : 2, 3, 5
1343
1344          if (brukerDataPixelType ==  2) {
1345             mhdDataPixelType = "MET_USHORT";
1346             pixelSize = 2;
1347          }
1348          if (brukerDataPixelType ==  3) {
1349             mhdDataPixelType = "MET_USHORT";
1350             pixelSize = 2;
1351          }    
1352          if (brukerDataPixelType ==  1) {
1353             mhdDataPixelType = "MET_UCHAR";
1354             pixelSize = 1;
1355          }     
1356     }
1357 }
1358
1359 // ===========================================================================================
1360
1361 std::vector<BrukerImage> Bruker2Dicom::CreateImageSet ( )
1362 {
1363          std::vector<BrukerImage> imageSet;      
1364          br_acqp.SetLoopStructure();
1365          std::vector<int> tempVect                      = br_acqp.GetLoopStructure() ;
1366          std::map<std::string, BrukerFieldData> map     = br_acqp.GetBrukerHeaderMap();
1367          
1368          bool result                                    = br_acqp.ObjectVaryingProperties.init(map,tempVect);
1369
1370          if (result == false)
1371          {
1372             throw ( BrukerInitException  ("ObjectVaryingProperties.init() failure in Bruker2Dicom::CreateImageSet()") );
1373          }
1374
1375          br_acqp.SetImageLoopStructure();
1376          br_acqp.SetBrukerImageList();
1377          std::vector<std::vector<int> > brukerImageList = br_acqp.GetBrukerImageList();
1378
1379          BrukerImage image(br_acqp,br_reco);
1380          image.Init(br_acqp,br_reco,1); 
1381
1382          for(int i=0;i<brukerImageList.size();i++)
1383          {
1384             image.Init(br_acqp,br_reco,i);    
1385             imageSet.push_back(image);
1386          }
1387
1388  // Just for checking
1389  /*
1390
1391          std::vector<std::vector <double> > imageOrientation;
1392          std::vector <double> imagePosition; 
1393          for(int i=0;i<brukerImageList.size();i++)
1394          {
1395            // fread(buffer_2dseq, NX*NY*pixelSize*nbSlices*nbInstants, 1, fp);   
1396
1397            imagePosition = imageSet[i].getTranslationVectorRPS2XYZ();
1398            std::cout << "Position " << imagePosition[0] << " " 
1399                      << imagePosition[1] << " "  << imagePosition[2] ;
1400            imageOrientation =  imageSet[i].getRotationMatrixRPS2XYZ();
1401            std::cout << "\t  Orientation " ;
1402            for(int i1=0; i1<3;i1++)for(int i2=0; i2<3;i2++)
1403               std::cout << imageOrientation[i1][i2] << " ";CreateImageSet
1404
1405            //std::cout << "\t  Abs Time " << imageSet[i].getAbsoluteTimePosition();
1406            std::cout << "\t  Relat Time " << imageSet[i].getRelativeTimePosition();
1407
1408            std::cout << "\t [";
1409            for (int i3=0; i3<imageSet[i].getLoopStamp().size();i3++)
1410               std::cout << " " << imageSet[i].getLoopStamp()[i3];
1411            std::cout << "]" << std::endl;       
1412          } 
1413 */
1414    return imageSet;
1415 }
1416
1417 // ===========================================================================================
1418
1419 void Bruker2Dicom::MakeDicomImage(unsigned char *tabPixels, 
1420               int X, 
1421               int Y,
1422               int nbFrames,
1423               int pixelSize,
1424               double spacingX, double spacingY, double sliceDistance, 
1425               std::string dcmImageName,
1426               const std::string &patientName,
1427               const char *day,
1428               std::string &studyUID,
1429               std::string &serieUID,
1430               std::string &studyDescr,
1431               std::string &serieDescr,
1432               std::string &strStudyTimeDate,
1433               int imgNum,
1434               GDCM_NAME_SPACE::ImageContentType contentType
1435       )
1436 {  
1437    std::ostringstream str;
1438
1439    GDCM_NAME_SPACE::File *file;
1440    file = GDCM_NAME_SPACE::File::New();       
1441       
1442   // Set the image size
1443    str.str(""); 
1444    str << X;
1445    file->InsertEntryString(str.str(),0x0028,0x0011,"US"); // Columns
1446    str.str("");
1447    str << Y;
1448    file->InsertEntryString(str.str(),0x0028,0x0010,"US"); // Rows
1449
1450    if (nbFrames != 1)
1451    {
1452       str.str("");
1453       str << nbFrames;
1454       file->InsertEntryString(str.str(),0x0028,0x0008,"IS"); // Number of Frames  
1455    }
1456
1457   // Set the pixel type
1458   //      //8, 16, 32, 64 (for double ?)
1459    str.str("");
1460    str << pixelSize*8;     
1461    file->InsertEntryString(str.str(),0x0028,0x0100,"US"); // Bits Allocated
1462
1463    file->InsertEntryString(str.str(),0x0028,0x0101,"US"); // Bits Stored
1464
1465    str.str("");
1466    str << pixelSize*8-1;     
1467    file->InsertEntryString(str.str(),0x0028,0x0102,"US"); // High Bit
1468
1469   // Set the pixel representation // 0/1 , 0=unsigned
1470    file->InsertEntryString("1",0x0028,0x0103, "US"); // Pixel Representation
1471    
1472   // Set the samples per pixel // 1:Grey level, 3:RGB
1473    file->InsertEntryString("1",0x0028,0x0002, "US"); // Samples per Pixel
1474
1475 //  0028 0030 DS 2 Pixel Spacing
1476    str.str("");
1477    str << spacingX << "\\" << spacingY;
1478    file->InsertEntryString(str.str(),0x0028,0x0030, "DS"); // Pixel Spacing     
1479    
1480  //   0018 0050 DS 1 Slice Thickness 
1481    str.str("");    
1482    str << sliceDistance;
1483    file->InsertEntryString(str.str(),0x0018,0x0050, "DS"); 
1484    
1485 //    0020 0011 IS 1 Series Number
1486    str.str("");    
1487    str << serieNumber;
1488    file->InsertEntryString(str.str(),0x0020,0x0011, "IS");
1489       
1490 //    0020|0013 [IS]  [Instance Number] 
1491    instanceNumber++;
1492    str.str("");    
1493    str << instanceNumber;
1494    file->InsertEntryString(str.str(),0x0020,0x0013, "IS");
1495      
1496   // 1.2.840.10008.5.1.4.1.1.4.1 : Enhanced MR Image Storage
1497  //  file->InsertEntryString("1.2.840.10008.5.1.4.1.1.4.1" , 0x0002, 0x0002, "UI");  // [Media Storage SOP Class UID]
1498   // file->InsertEntryString("1.2.840.10008.5.1.4.1.1.4.1" , 0x0008, 0x0016, "UI");  // [SOP Class UID]
1499
1500 // OK : MR is NOT multiframe, but I want just a quick an dirty solution
1501
1502 // 1.2.840.10008.5.1.4.1.1.4         MR Image Storage
1503    file->InsertEntryString("1.2.840.10008.5.1.4.1.1.4" , 0x0002, 0x0002, "UI");  // [Media Storage SOP Class UID]
1504    file->InsertEntryString("1.2.840.10008.5.1.4.1.1.4" , 0x0008, 0x0016, "UI");  // [SOP Class UID]     
1505
1506   // if (strlen(patientName) != 0)
1507    file->InsertEntryString(patientName.c_str(),0x0010,0x0010, "PN"); // Patient's Name
1508    file->InsertEntryString(patientName.c_str(),0x0010,0x0020, "LO"); // Patient's ID
1509
1510    file->InsertEntryString(studyUID, 0x0020, 0x000d, "UI");
1511    file->InsertEntryString(serieUID, 0x0020, 0x000e, "UI");
1512    
1513 //  0008 0020 DA 1 Study Date
1514 //  0008 0030 TM 1 Study Time
1515
1516 /// \TODO split into 2 strings!
1517    file->InsertEntryString(strStudyTimeDate.substr(10,11).c_str(),0x0008,0x0020, "DA");
1518    file->InsertEntryString(strStudyTimeDate.substr(1,8).c_str(),  0x0008,0x0030, "TM");
1519
1520    file->InsertEntryString(studyDescr, 0x0008,0x1030, "LO");  // Study Description  
1521    file->InsertEntryString(serieDescr, 0x0008,0x103e, "LO");  // Series Description 
1522
1523 //0008|0060 [CS] [Modality] 
1524    file->InsertEntryString("MR",0x0008,0x0060, "CS");
1525
1526 // 0020 0037 DS 6 Image Orientation (Patient)
1527    char charImageOrientation[256];
1528
1529 /*
1530 std::cout << "charImageOrientation  " << 
1531                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][0] << " " <<
1532                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][1] << " " <<
1533                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][2] << " " <<
1534                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][0] << " " <<
1535                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][1] << " " <<
1536                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][2] << std::endl ;
1537 */      
1538    sprintf(charImageOrientation,"%f\\%f\\%f \\ %f\\%f\\%f",
1539                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][0],
1540                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][1],
1541                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][2],
1542                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][0],
1543                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][1],
1544                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][2] ) ;
1545     
1546    file->InsertEntryString(charImageOrientation,0x0020,0x0037, "DS");
1547
1548 // 0020 0032 DS 3 Image Position (Patient) 
1549
1550    char charImagePosition[256];   
1551    sprintf(charImagePosition,"%f\\%f\\%f", 
1552                              imageSet[imgNum].getTranslationVectorRPS2XYZ()[0], 
1553                              imageSet[imgNum].getTranslationVectorRPS2XYZ()[1],
1554                              imageSet[imgNum].getTranslationVectorRPS2XYZ()[2]);
1555   
1556    file->InsertEntryString(charImagePosition,0x0020,0x0032, "DS");  //0020 0032 DS 3 Image Position (Patient) 
1557    
1558    
1559    // Private creator
1560    /*
1561    
1562 0029|0010 [LO]   [Private Creator] [CREATIS HEADER ]
1563 0029|0011 [LO]   [Private Creator] [CREATIS for BRUKER to DICOM]
1564 0029|1031 [LO]   [] [4.0.7571167 ]
1565 0029|1032 [UL]   [] [1440000] =0x(15f900)
1566
1567 > $$ Thu Jul 30 17:29:46 2009 CEST (UT+2h)  mwiart
1568 > $$ /opt/PV4.0/data/mwiart/nmr/dha80.Uw1/4/method
1569 > ##$Method=DtiEpi
1570 > ##$PVM_DwNDiffDir=3             % 3 directions
1571 > ##$PVM_DwNDiffExpEach=2         % 2 valeurs de b par direction
1572 > ##$PVM_DwAoImages=1             % 1 image pour b=0
1573 > ##$PVM_DwBvalEach=( 2 )         % Valeurs de b
1574 > 1500.000000 3000.000000
1575 >
1576 > $$ Wed Dec  2 09:56:01 2009 UTC (UT+0h)  mwiart
1577 > $$ /opt/Pv5.0/data/mwiart/nmr/ECI7.Wx1/4/method
1578 > ##$Method=DtiEpi
1579 > ##$PVM_DwNDiffDir=3             % 3 directions
1580 > ##$PVM_DwNDiffExpEach=2         % 2 valeurs de b par direction
1581 > ##$PVM_DwAoImages=1             % 1 image pour b=0
1582 > ##$PVM_DwBvalEach=( 2 )         % Valeurs de b
1583 > 1500 3000
1584 >
1585 > $$ Wed Dec  2 10:14:27 2009 UTC (UT+0h)  mwiart
1586 > $$ /opt/Pv5.0/data/mwiart/nmr/ECI7.Wx1/5/method
1587 > ##$Method=DtiStandard
1588 > ##$PVM_DwNDiffDir=1             % 1 direction
1589 > ##$PVM_DwNDiffExpEach=2         % 2 valeurs de b
1590 > ##$PVM_DwAoImages=0             % 0 image pour b=0
1591 > ##$PVM_DwBvalEach=( 2 )         % Valeurs de b
1592 > 138 1600
1593 >
1594    */
1595    
1596    file->InsertEntryString("CREATIS HEADER", 0x0029,0x0010, "LO");
1597    file->InsertEntryString("CREATIS FOR BRUKER-TO-DICOM", 0x0029,0x0011, "LO");
1598    
1599    BrukerFieldData brf_method            = br_method.GetFieldData("Method");
1600    const std::vector<std::string> method = brf_method.GetStringValue();
1601
1602   // std::string method = br_method.GetFieldData("Method").GetStringValue();    
1603    file->InsertEntryString(method[0], 0x0029,0x0100, "LO");
1604    
1605    std::cout << " method[" << method[0]  << "]" << std::endl;
1606    if (method[0] == "DtiEpi" || method[0] == "DtiStandard")
1607    {
1608      // const std::vector<int> NDiffDir       = br_method.GetFieldData("PVM_DwNDiffDir").GetIntValue();
1609       BrukerFieldData brf_NDiffDir    = br_method.GetFieldData("PVM_DwNDiffDir");
1610       const std::vector<int> NDiffDir = brf_NDiffDir.GetIntValue();
1611       
1612       //const std::vector<int> NDiffExpEach   = br_method.GetFieldData("PVM_DwNDiffExpEach").GetIntValue();
1613       BrukerFieldData brf_NDiffExpEach      = br_method.GetFieldData("PVM_DwNDiffExpEach");
1614       const std::vector<int> NDiffExpEach   =brf_NDiffExpEach.GetIntValue();
1615       
1616 //      const std::vector<int> AoImages     = br_method.GetFieldData("PVM_DwAoImages").GetIntValue();
1617       BrukerFieldData brf_AoImages        = br_method.GetFieldData("PVM_DwAoImages");
1618       const std::vector<int> AoImages     = brf_AoImages.GetIntValue();
1619       
1620       BrukerFieldData brf_DwBvalEach       = br_method.GetFieldData("PVM_DwBvalEach");
1621       const std::vector<double> DwBvalEach = brf_DwBvalEach.GetDoubleValue();
1622       
1623  std::cout << "nb directions : " <<  NDiffDir[0] << " nb valeurs de b par direction : " << NDiffExpEach[0] 
1624            << " nb images for b=0 : " << AoImages[0] << std::endl;
1625            
1626        str.str(""); 
1627        str << NDiffDir[0];
1628        file->InsertEntryString(str.str(),0x0029,0x0101,"US"); // directions
1629        str.str(""); 
1630        str << NDiffExpEach[0];
1631        file->InsertEntryString(str.str(),0x0029,0x0102,"US"); // valeurs de b par direction       
1632        str.str(""); 
1633        str << AoImages[0];
1634        file->InsertEntryString(str.str(),0x0029,0x0103,"US"); // image pour b=0
1635
1636        str.str("");
1637        for (unsigned int i=0; i<NDiffExpEach[0]; i++) {
1638           str << DwBvalEach[i];
1639           if (i!=AoImages[0])
1640              str << "\\";
1641       }
1642       file->InsertEntryString(str.str(),0x0029,0x0104,"DS"); // Valeurs de b          
1643    }   
1644
1645 // 0020 0x1041 DS 1 Slice Location 
1646 //        sprintf(charImagePosition,"%f",float(imgNum));
1647 //        file->InsertEntryString(charImagePosition,0x0020,0x1041, "DS");   
1648 /*
1649   // Set Rescale Intercept
1650         str.str("");
1651         str << div;  
1652         file->InsertEntryString(str.str(),0x0028,0x1052,"DS");
1653
1654   // Set Rescale Slope
1655         str.str("");
1656         str << mini;  
1657         file->InsertEntryString(str.str(),0x0028,0x1053,"DS");
1658 */
1659
1660    GDCM_NAME_SPACE::FileHelper *fileH;
1661    fileH = GDCM_NAME_SPACE::FileHelper::New(file);
1662    fileH->SetContentType(contentType);   
1663     
1664    // cast is just to avoid warnings (*no* conversion is performed)
1665    //fileH->SetImageData((uint8_t *)img,int(maxX*maxY)*sizeof(uint16_t)); // troubles when maxX, mayY are *actually* float!
1666
1667 //std::cout << "--------------------------------  X*Y*nbFrames*pixelSize " << X << " " << Y << " " << nbFrames << " " << pixelSize << std::endl; 
1668
1669    fileH->SetImageData((uint8_t *)tabPixels, X*Y*nbFrames*pixelSize);
1670    fileH->SetWriteModeToRaw(); 
1671    fileH->SetWriteTypeToDcmExplVR();
1672    if( !fileH->Write(dcmImageName)) {
1673       std::cout << "Failed for [" << dcmImageName << "]\n"
1674                 << "           File is unwrittable" << std::endl;               
1675       file->Delete();
1676       fileH->Delete();          
1677       throw ( BrukerHopelessException ("Level 1 Unable to write Dicom file "));
1678    }
1679    //if (verbose)
1680    //   file->Print();
1681
1682    file->Delete();
1683    fileH->Delete();  
1684 }