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