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