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