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