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