]> Creatis software - creaBruker.git/blob - lib/src1/bruker2dicom2.cxx
df045995c45c964e31018ee99821f94f4f08e2c1
[creaBruker.git] / lib / src1 / bruker2dicom2.cxx
1 #include "bruker2dicom2.h"
2 #include "brukerexception.h"
3
4 #include <gdcmAttribute.h>
5 #include <boost/filesystem.hpp>
6 #include <boost/algorithm/string.hpp>
7
8
9 #ifndef PATH_MAX // If not defined yet : do it 
10    #define PATH_MAX 2048
11 #endif 
12
13         bool Bruker2Dicom::Execute()
14         {
15             
16             //--- first, Test the system----//
17              bool bigEndian = gdcm::ByteSwap<uint16_t>::SystemIsBigEndian();
18             gdcm::SwapCode sc = gdcm::SwapCode::Unknown;
19             if ( gdcm::ByteSwap<uint16_t>::SystemIsBigEndian() )
20             {
21                 sc = gdcm::SwapCode::BigEndian;
22              }
23             else if ( gdcm::ByteSwap<uint16_t>::SystemIsLittleEndian() )
24             {
25                 sc = gdcm::SwapCode::LittleEndian;
26             }
27             else // sc == gdcm::SwapCode::Unknown
28             {
29                 return 1;
30             }
31
32             // ----- Check input directory name -----
33             if ( ! boost::filesystem::is_directory(InputDirName) )
34             {
35                     std::cout << "KO : [" << InputDirName << "] is not a Directory." << std::endl;
36                     return 0;
37             }
38             else
39             {
40                 if (verbose)
41                     std::cout << "OK : [" << InputDirName << "] is a Directory." << std::endl;
42             }
43
44              // ----- Check output directory name -----
45             if ( ! boost::filesystem::is_directory(OutputDirName) )
46             {
47                 bool res=CreateDirectory(OutputDirName);
48                 if (!res) 
49                 {
50                      std::cout << "[" << OutputDirName << "] Directory creation failure " << std::endl;
51                      throw ( BrukerHopelessException ("Output directory creation failure "));
52                 }
53             }
54             else
55             {
56                 if(verbose)
57                         std::cout << "[" << OutputDirName << "] already exist " << std::endl;
58             }
59
60             // Deal with level 0
61             // Level 0  is the original directory
62             // who could contain  "1  2  3  4  5  6"  directories  and "AdjStatePerStudy  subject" files  
63             std::string strDirNamein(InputDirName);
64             boost::filesystem::directory_iterator it(InputDirName), it_end;
65             subjectFound = false;
66             acqpFound = false;
67             for(; it != it_end; ++it)
68             {
69                    if(! boost::filesystem::is_directory( (*it) ) )
70                    {
71                        if( (*it).filename() == "subject")
72                        {
73                            subjectFound = true;
74                        }
75                        if( (*it).filename() == "acqp")
76                        {
77                            acqpFound = true;
78                        }
79                    }
80             }
81
82             // 1 : if subjectFound                       : user passed a Single Study Directory
83             // 2 : if NOT subjectFound and acqpFound     : user passed a Serie Directory
84             // 3 : if NOT subjectFound and NOT acqpFound : user passed a 'non Study Directory' (Hope it's a set of Single Study Directories)
85             int type;
86             if  (subjectFound )  type = 1; // user passed a 'study
87             else if  (acqpFound) type = 2; // user passed a 'serie' 
88             else                 type = 3; // user passed a 'non study' directory; Hope it's a 'set of studies' directory!
89  
90             switch (type)
91             {
92                 case 1:  {
93                     std::string subject = InputDirName +   VALID_FILE_SEPARATOR;
94                     subject += "subject";
95                     boost::algorithm::replace_all( subject,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
96                     bool canOpen = br_subject.LoadFile(subject);
97                     if (!canOpen)
98                     {
99                         std::cout << "Hopeless! 'subject' found / cannot be open" << std::endl;
100                         throw ( BrukerHopelessException ("Hopeless! 'subject' found in root input directory / cannot be open"));
101                     }
102                     else
103                     {
104                         br_subject.FillMap();
105                         // get info for 'Study Description'  
106                         BrukerFieldData b_name=br_subject.GetFieldData("SUBJECT_name_string");
107                         subject_name = b_name.GetStringValue()[0];
108                         strPatientName = subject_name;
109                         cleanString(subject_name);
110                         DealWithSingleStudyDirectory (InputDirName, OutputDirName);
111                         }
112                     break;
113                 }
114
115                 case 2: 
116                     {
117                      subject_name = "defaultPatName";
118                          strPatientName = subject_name;
119                      DealWithSingleStudyDirectory (InputDirName,OutputDirName);
120                          break;
121                     }
122       
123
124       case 3: {
125          std::cout << " User passed a 'non study' directory; Hope it's a *non recursive* 'set of studies' directory! (recursive not yet dealt with)" << std::endl;
126 //       DealWithMultiStudyDirectory (fileNames);
127          break;
128       }
129    }
130 }
131
132 // ----------------------------------------------------------------------------------------------------------
133
134 void Bruker2Dicom::DealWithMultiStudyDirectory (gdcm::Directory::FilenamesType &dirNames,const  std::string &currentOutputDirName)
135 {
136     gdcm::Directory::FilenamesType::iterator it;
137
138    for (it = dirNames.begin();
139          it != dirNames.end();
140        ++it)
141    {
142       if ( boost::filesystem::is_directory(*it) )
143       {
144          subjectFound = false;
145          if (verbose)
146             std::cout << "in 'DealWithMultiStudyDirectory' [" << *it << "] is a directory" << std::endl;
147          
148          gdcm::Directory dirList;
149          dirList.Load(*it);
150          gdcm::Directory::FilenamesType fileNames;
151          fileNames = dirList.GetFilenames();
152
153          gdcm::Filename file(fileNames.begin()->c_str());
154          std::string path = file.GetPath();
155          std::string subject =  path +
156                                 VALID_FILE_SEPARATOR +
157                                 "subject";
158         boost::algorithm::replace_all( subject,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
159          if (! boost::filesystem::is_regular(subject) )
160          {
161             std::cout << "no [" << subject << "] file found" << std::endl;
162             continue;
163          }
164
165          bool canOpen = br_subject.LoadFile(subject);
166          if (!canOpen)
167          {
168             std::cout << "Hopeless! 'subject' found / cannot be open" << std::endl;
169             throw ( BrukerHopelessException ("Hopeless! 'subject' found in root input directory / cannot be open"));
170          }
171          else
172          {
173             br_subject.FillMap();
174             subjectFound = true; // Hope so! (full checking needed!)
175
176             BrukerFieldData b_name=br_subject.GetFieldData("SUBJECT_name_string");
177             subject_name = b_name.GetStringValue()[0];
178             strPatientName = subject_name;
179             cleanString(subject_name);   
180         
181             DealWithSingleStudyDirectory(dirList.GetDirectories().begin()->c_str(), currentOutputDirName);
182          }  
183       }
184       else
185       {
186          if (verbose)
187             std::cout << "[" << *it << "] is NOT a directory; skipped!" << std::endl; 
188       }   
189    } 
190 }
191
192 // ----------------------------------------------------------------------------------------------------------
193
194 void Bruker2Dicom::DealWithSingleStudyDirectory  (const std::string &dirname, const std::string &i_outputDir) //(gdcm::Directory::FilenamesType &fileNames)
195 {
196      bool res;   
197       // creation directory : 'nom du patient'
198      std::string output =  createDirectory(subject_name.c_str(), i_outputDir);
199
200  
201     if (subjectFound)
202     {
203        BrukerFieldData b_entry=br_subject.GetFieldData("SUBJECT_entry");
204        subject_entry = b_entry.GetStringValue()[0];
205        //cleanString(subject_entry);
206        subject_entry = subject_entry.substr(11, subject_entry.size()-11);
207   
208        BrukerFieldData b_position=br_subject.GetFieldData("SUBJECT_position");
209        subject_position = b_position.GetStringValue()[0];
210        //cleanString(subject_position);
211        subject_position = subject_position.substr(9, subject_position.size()-9);
212  
213        BrukerFieldData b_date=br_subject.GetFieldData("SUBJECT_date");
214        subject_date = b_date.GetStringValue()[0];
215        strStudyTimeDate = subject_date;
216        cleanString(subject_date);
217  
218        BrukerFieldData b_study_name=br_subject.GetFieldData("SUBJECT_study_name");
219        subject_study_name = b_study_name.GetStringValue()[0];
220        subject_study_name = subject_study_name.substr(1, subject_study_name.size()-2);
221        cleanString(subject_study_name);
222    }
223    else  // Desperate trick when file 'subject' is missing
224    {
225       subject_entry      = "HeadFirst";            // Why not?
226       subject_position   = "Supine";               // Why not?
227       strStudyTimeDate   = "06_06_06_6_June_1666"; // Why not?
228       subject_date       = "6_June_1666";          // Why not?
229       subject_study_name = "defStudyName";         // Why not? 
230    }
231     // subject_name is already in 'Patient Name' 
232     strStudyDescr = /*subject_name + "." + */ subject_study_name /*+ "." + subject_entry + "." + subject_position + "." + subject_date*/;
233
234     // creation directory : 'nom de la Study'
235     output = createDirectory(strStudyDescr, output);
236
237     gdcm::UIDGenerator uid;
238    strStudyUID     = uid.Generate();
239    serieNumber    = 0;
240    instanceNumber = 0;
241
242    // -----------------------------------------------------
243    // Iterate to ALL the objets(files/directories) found in the input directory
244    // (this is level ZERO)
245    // each Directory (name : 1, 2, 3, ...) will be a Dicom Serie
246    // -----------------------------------------------------
247       boost::filesystem::directory_iterator it(dirname), end_iter;
248           for(; it != end_iter; ++it)
249          {
250          if(boost::filesystem::is_directory(*it))
251              {
252              std::string fname = (*it).filename() ;
253               //if (fname == "AdjResult")                   continue; what's the point?
254              boost::filesystem::directory_iterator it_level((*it));
255             bool bAcqp = false;
256             std::string nextLevel;
257             std::string strAcqp;
258             std::string nameAcqp;
259             for(; it_level != end_iter; ++it_level)
260             {
261                 if( (*it_level).filename() == "acqp")
262                 {
263                     strAcqp =  (*it_level).string();
264                     nameAcqp = (*it_level).filename();
265                     boost::algorithm::replace_all( strAcqp,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
266                     bAcqp = true;
267                }
268                else if (boost::filesystem::is_directory( (*it_level) ) && nextLevel == "")
269                {
270                    nextLevel = (*it_level).string(); // Hope we found only one directory
271                }
272                else
273                {
274                    // nothing
275                }
276            }
277
278            if ( bAcqp)
279            {
280                std::string acqp_scan_name;
281                std::string acqp_method;
282                std::string acqp_protocol_location; 
283  
284                br_acqp.LoadFile(strAcqp);
285                br_acqp.FillMap();
286                BrukerFieldData b_protocol_location=br_acqp.GetFieldData("ACQ_protocol_location");
287                acqp_protocol_location = b_protocol_location.GetStringValue()[0];
288                cleanString(acqp_protocol_location);
289               
290                BrukerFieldData b_scan_name=br_acqp.GetFieldData("ACQ_scan_name");
291                acqp_scan_name = b_scan_name.GetStringValue()[0];
292               cleanString(acqp_scan_name);
293
294               BrukerFieldData b_method=br_acqp.GetFieldData("ACQ_method");
295                   b_method.PrintSelf(); // why?
296               acqp_method = b_method.GetStringValue()[0];
297               cleanString(acqp_method);
298         
299               BrukerFieldData b_list_size = br_acqp.GetFieldData("ACQ_O1_list_size");
300               nbSlices =  b_list_size.GetIntValue()[0];
301              strSerieDescr = fname
302                          + "." + acqp_scan_name
303                          + "." + acqp_method.c_str();
304
305
306          /*sprintf(outputDirName, "%s%c%s", i_outputDir.c_str(), VALID_FILE_SEPARATOR, strSerieDescr.c_str() );
307          std::string temp(outputDirName);
308          boost::algorithm::replace_all( temp,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);*/
309            output = createDirectory(strSerieDescr, output);
310         if (verbose)
311            printf ("outputDirName [%s]\n", output);
312         try {
313
314             DealWithNiveau1( (*it).string(), output);
315              }
316                 catch (BrukerHopelessException &e)
317                 {
318                  std::cout << "And Exception was thrown in DealWithNiveau1 (" << e.what() << ") " << std::endl;
319                  continue;
320                 }
321            }
322       }
323    } // end of : for (GDCM_NAME_SPACE::DirListType::iterator it
324 }
325
326 // =====================================================================
327
328 void Bruker2Dicom::DealWithNiveau1(std::string &level1Directory, std::string &currentOutputDirName) {
329 //
330 // e.g. : at level 1, in B67d1.Bp1/6
331 //
332 // acqp  fid  imnd  pdata  pulseprogram  spnam0  spnam1
333
334   
335    //gdcm::Directory dirList;
336    //dirList.Load(level1Directory);  // DON'T get recursively the list of files
337    //gdcm::Directory::FilenamesType fileNames;
338    //fileNames = dirList.GetFilenames();
339  
340    // -----------------------------------------------------
341    // Iterate to ALL the objets(files/directories) found in the input directory
342    // -----------------------------------------------------
343    bool bmethod = false;
344    //gdcm::Directory::FilenamesType::iterator it =  fileNames.begin();
345      boost::filesystem::directory_iterator it(level1Directory), it_end;
346    for(; it != it_end; it++)
347    {
348        if((*it).leaf() == "method")
349        {
350           bmethod = br_method.LoadFile((*it).string());
351           break;
352        }
353    }
354
355    // if method wasn't found or unable to load, try with imnd file
356    if(!bmethod)
357    {
358           for(; it != it_end; it++)
359           {
360                 if((*it).leaf() == "imnd")
361                  {
362                      bmethod = br_method.LoadFile((*it).string());
363                      break;
364                 }
365             }
366    }
367    if(!bmethod)
368    {
369           std::cout << "Hopeless! neither 'method' nor 'imnd' found in ["
370                           << level1Directory  << "]; we skip it!" << std::endl;
371    }
372   //  if (verbose)
373      //        std::cout << "open => [" << strMethod << "] successfully" << std::endl; 
374       /* a recuperer :
375              ##$PVM_Fov (dimension)  // ou plutot RECO_fov !
376           */
377   /*
378           dans method (pour perfusion  seulement?) :
379           ##$PVM_ObjOrderList=( 8 )
380           0 2 4 6 1 3 5 7
381           ##$PVM_NSPacks=2
382           ##$PVM_SPackArrNSlices=( 2 )
383           7 1  
384   */  
385     br_method.FillMap();
386    
387     try
388     {
389        boost::filesystem::directory_iterator itDir(level1Directory), it_end;
390        for(; itDir != it_end; ++itDir)
391        {
392            if ( boost::filesystem::is_directory(*itDir) && (*itDir).leaf() == "pdata")
393            {
394                std::string output = createDirectory( (*itDir).leaf() , currentOutputDirName);
395                  // will be always "pdata" ...
396                boost::filesystem::directory_iterator itDirInside(*itDir), it_inside_end;
397                 for(; itDirInside != it_end; ++it)
398                 {
399                     // we take the first and hope that we have only one!
400                     if ( boost::filesystem::is_directory(*itDirInside))
401                     {
402                                  output = createDirectory( (*itDirInside).leaf() , output);
403                                 DealWithNiveau2( (*itDirInside).string(), output);
404                     }
405                 }
406             }
407          }
408     }
409        catch(BrukerHopelessException &e)
410          {
411             std::cout << "And Exception was thrown in DealWithNiveau2 (" << e.what() << ") " << std::endl;
412          }
413   
414 }
415
416 // =====================================================================
417
418 void Bruker2Dicom::DealWithNiveau2(std::string &level2Directory, std::string &currentOutputDirName) {
419
420 // e.g. : at level 2 in B67d1.Bp1/6/pdata
421 //
422 // acqp  fid  imnd  pdata  pulseprogram  spnam0  spnam1
423 //
424     std::string output = currentOutputDirName;
425
426     bool bisa = false;
427     boost::filesystem::directory_iterator it(level2Directory), it_end;
428     for(; it != it_end; ++it)
429     {
430         if((*it).leaf() == "isa")
431         {
432             bisa =  br_isa.LoadFile((*it).string());
433           if (bisa)
434           {
435              br_isa.FillMap();
436              BrukerFieldData b_isa_func_name = br_isa.GetFieldData("ISA_func_name");
437     
438              std::string  str_isa_func_name = b_isa_func_name.GetStringValue()[0];
439              cleanString(str_isa_func_name);
440              output = createDirectory(str_isa_func_name, currentOutputDirName);
441             
442           }
443           break;
444         }
445     }
446           try {
447              DealWithNiveau3(level2Directory, output);
448           }
449           catch (BrukerHopelessException &e)
450           {
451              std::cout << "And Exception was thrown in DealWithNiveau3 (" << e.what() << "); " 
452                        << " We skip [" << level2Directory << "]" << std::endl;
453          
454           }
455           catch (BrukerInitException &e)
456           {
457              std::cout << "And Init Exception was thrown in DealWithNiveau3 (" << e.what() << "); " 
458                        << " We skip [" << level2Directory << "]" << std::endl;
459          
460           }          
461    
462 }
463
464 //
465 // =====================================================================
466 //
467
468 void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &currentOutputDirName){
469
470 //
471 // e.g. at level 3, in
472
473    // just to be able to go on checking // JP
474     gdcm::Filename file;
475
476    bool res;
477
478  
479
480    gdcm::Directory dirList;
481    dirList.Load(level3Directory); // DON'T get recursively the list of files
482    gdcm::Directory::FilenamesType::iterator it;
483    gdcm::Directory::FilenamesType fileNames = dirList.GetFilenames();
484
485    char original2dseqName       [(unsigned int) PATH_MAX+2];
486    char original2dseqName_XXX   [(unsigned int) PATH_MAX+2];   
487    char currentOutputMhdDirName [(unsigned int) PATH_MAX+2];
488
489    char outputMhdFileName       [(unsigned int) PATH_MAX+2];
490    char output2dseqSliceFileName[(unsigned int) PATH_MAX+6]; // think about extra '.dcm'
491    char output2dseqName         [(unsigned int) PATH_MAX+6];
492    char output2dseqCartoName    [(unsigned int) PATH_MAX+6];
493
494    char copyFile[PATH_MAX + PATH_MAX + 5]; // Should be enough!
495    std::string temp;
496    bool canOpen;
497
498    //-------------- try d3proc;
499      
500    canOpen = br_d3proc.LoadFile(findFile( level3Directory,"d3proc"));
501
502    if (!canOpen)
503    {
504       std::cout << "Hopeless! no 'd3proc' found" << std::endl;
505       throw ( BrukerHopelessException ("Hopeless! no 'd3proc' found"));
506       //exit(0);  /// \TODO throw an exception ! 
507    }
508    else
509    {
510         canOpen = br_d3proc.FillMap();
511         if (!canOpen)
512         {
513             std::cout << "Hopeless! FillMap failed on 'd3proc'" << std::endl;
514             throw ( BrukerHopelessException ("Hopeless! FillMap failed on 'd3proc'"));      
515         }
516    }
517
518    //-------------- end try d3proc;
519
520
521  // -------------------try reco
522
523    
524    std::string str_reco = level3Directory + VALID_FILE_SEPARATOR + "reco";
525    canOpen = br_reco.LoadFile(findFile( level3Directory, "reco"));
526    if (!canOpen)
527       {
528          std::cout << "Hopeless! cannot find 'reco' in [" << str_reco << "]"  << std::endl;      
529          throw ( BrukerHopelessException ("Hopeless! cannot find 'reco'"));  
530          //exit(0);  /// \TODO throw an exception !    
531       }
532  
533  else {
534       if (verbose)
535          std::cout << "[" << str_reco << "] successfully Loaded " << std::endl;
536        canOpen = br_reco.FillMap();
537         if (!canOpen)
538         {
539             std::cout << "Hopeless! FillMap failed on [" << str_reco << "]" << std::endl;
540             throw ( BrukerHopelessException ("Hopeless! FillMap failed on 'reco'"));  
541       
542         } 
543         else {
544             if (verbose)
545                 std::cout << "[" << str_reco << "] successfully Mapped" << std::endl;
546         }
547  }
548
549    //std::cout << "------------------------------------------------------------------------------------------------" << std::cout;
550    // br_reco.PrintSelf();
551    // std::cout << "------------------------------------------------------------------------------------------------" << std::cout;
552    // -------------------end try reco
553
554
555    BrukerFieldData bX = br_d3proc.GetFieldData("IM_SIX");
556    int NX = bX.GetIntValue()[0];
557
558    if (verbose)
559       std::cout << "IM_SIX " << NX << std::endl;
560    BrukerFieldData bY=br_d3proc.GetFieldData("IM_SIY"); 
561    int NY = bY.GetIntValue()[0];
562
563    if (verbose)
564          std::cout << "IM_SIY " << NY << std::endl;
565    /// \todo : check if there are actually 3 dimensions or only 2
566
567    BrukerFieldData bZ= br_d3proc.GetFieldData("IM_SIZ");
568    int nbFrames = bZ.GetIntValue()[0]; 
569    if (verbose)
570          std::cout << "IM_SIZ " << nbFrames << std::endl;
571
572         // WARNING DATTYPE is, either in {ip_short, ip_int, ip_char, ...}, or in {1, 2, 3, ...}
573
574    BrukerFieldData bDPT = br_d3proc.GetFieldData("DATTYPE");
575
576    std::string mhdDataPixelType;
577    int pixelSize;
578    getImhDataType(bDPT, mhdDataPixelType, pixelSize);
579
580
581  /*
582
583  // See mail Denis : 
584  // En regle generale il vaut mieux que l'on passe par RECO_* 
585  // pour extraire les parametres de l'image
586  //
587
588    BrukerFieldData fov = br_method.GetFieldData("PVM_Fov");
589    double fovX = fov.GetDoubleValue()[0];
590    double fovY = fov.GetDoubleValue()[1];
591    if (verbose)
592       std::cout << "FOV (ds method) " << fovX << " " << fovY << std::endl;
593
594    BrukerFieldData spatResol = br_method.GetFieldData("PVM_SpatResol");
595    double spatResolX = spatResol.GetDoubleValue()[0];
596    double spatResolY = spatResol.GetDoubleValue()[1];
597    if (verbose)
598       std::cout << "SpatResol (ds method) " << spatResolX << " " << spatResolY << std::endl;
599      
600 */
601
602 /* ------  */
603 // Better we use 'get' accessors from BrukerImage class, as Denis wrote them
604
605    BrukerFieldData fov = br_reco.GetFieldData("RECO_fov");
606    double fovX = fov.GetDoubleValue()[0];
607    double fovY = fov.GetDoubleValue()[1];
608    if (verbose)
609       std::cout << "FOV (ds reco) " << fovX << " " << fovY << std::endl;
610
611    BrukerFieldData size = br_reco.GetFieldData("RECO_size");
612    double sizeX = size.GetDoubleValue()[0];
613    double sizeY = size.GetDoubleValue()[1];
614
615    if (verbose)
616       std::cout << "SIZE (ds reco) " << sizeX << " " << sizeY << std::endl;
617
618    double spatResolX = fovX / sizeX;
619    double spatResolY = fovY / sizeY;
620
621    if (verbose)
622       std::cout << "spatResol (ds reco : fov/size) " << spatResolX << " " << spatResolY << std::endl;
623
624 /* ------  */
625
626    /// \TODO probabely a more sophisticated accessor will be necessary :
627    ///  (cf : non contiguous slices, overlapping, slice thickness, space between slices, etc)
628
629    BrukerFieldData bsliceDistance = br_method.GetFieldData("PVM_SPackArrSliceDistance");
630    double sliceDistance = bsliceDistance.GetDoubleValue()[0];
631
632    if (verbose)
633       std::cout << "SPackArrSliceDistance (ds method) " << sliceDistance << std::endl;   
634
635 // ----------------------------------------------------------------------------------------
636
637    if (mhd)
638    {
639       sprintf(currentOutputMhdDirName, "%s%c%s", currentOutputDirName.c_str(),
640                               VALID_FILE_SEPARATOR, "MhdFiles");
641       std::string temp(currentOutputMhdDirName);
642        boost::algorithm::replace_all( temp,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
643        sprintf(currentOutputMhdDirName, "%s", temp);
644       std::string strCurrentOutputMhdDirName(currentOutputMhdDirName);
645       res = CreateDirectory( strCurrentOutputMhdDirName );
646       if (!res) {
647          std::cout << "[" << currentOutputDirName << "] Directory creation failure " << std::endl;
648          throw ( BrukerHopelessException ("Hopeless!FillMap failed on 'reco'"));  
649          //exit (0);
650       } 
651
652       if (verbose)
653          std::cout << "Directory creation [" <<  currentOutputDirName << "]" << std::endl;
654    }  // end if mhd
655
656    if (verbose)
657          std::cout << "nbFrames " << nbFrames << std::endl;
658    if (verbose)
659          std::cout << "nbSlices " << nbSlices << std::endl;
660    int k;
661    int nbInstants = nbFrames/nbSlices;
662    if (verbose)
663          std::cout << "nbInstants (deduced)" << nbInstants << std::endl;    
664    int instantNb;
665    int sliceNb; 
666    FILE *fp;  // for MHD files
667
668    sprintf( original2dseqName, "%s%c%s", level3Directory.c_str(),VALID_FILE_SEPARATOR, "2dseq");
669    temp = level3Directory + VALID_FILE_SEPARATOR + "2dseq" ;
670    boost::algorithm::replace_all( temp,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
671    sprintf(original2dseqName, "%s", temp);
672
673 /**/   
674   // \TODO : tenir compte du bazar precedent 
675
676     // load 2dseq in memory
677    
678    fp = fopen(temp.c_str(), "rb");
679    if (!fp) 
680    {
681       // try 2dseq_Angio2D ?!?
682        temp = original2dseqName_XXX;
683       sprintf( original2dseqName_XXX, "%s%s", original2dseqName, "_Angio2D");
684       sprintf(original2dseqName_XXX, "%s", temp);
685       fp = fopen(original2dseqName_XXX, "rb");
686       if (!fp)
687       {
688          std::cout << "Cannot open [" << original2dseqName << "] nor [" <<  original2dseqName_XXX << "] for reading" << std::endl;
689          fclose(fp);     
690          throw ( BrukerHopelessException ("Hopeless! Cannot open '2dseq'"));
691          //exit (0);
692       }
693    }
694
695    unsigned char *buffer_2dseq = new unsigned char[NX*NY*pixelSize*nbSlices*nbInstants];   
696    ///\ TODO : find a safer way to be sure to read everything!
697    size_t lgr = fread(buffer_2dseq, 1, NX*NY*pixelSize*nbSlices*nbInstants, fp);
698
699    // This one will be important!
700    // ---------------------------
701    try {
702       imageSet = CreateImageSet ( );
703    }
704    catch (BrukerInitException& e)
705    {
706       if (verbose)
707          std::cout <<  "an Init Exception was thrown in CreateImageSet ( ); " << e.what() 
708                    <<  "catched in DealWithNiveau3" << std::endl;
709       //return;
710       throw (e);
711    }
712
713    serieNumber++;
714    gdcm::UIDGenerator uid;
715    strSerieUID     = uid.Generate();
716   
717    if (nbInstants==1) // creer un seul fichier .mhd  pour toutes les Slices! (images natives)
718    {
719        if (verbose)
720           std::cout << "Single instant : do not split" << std::endl;
721        if (mhd)
722        {
723              sprintf(outputMhdFileName, "%s%cMhdData_All_the_Slices.mhd", currentOutputMhdDirName,
724                                         VALID_FILE_SEPARATOR);
725              temp = currentOutputDirName +                              VALID_FILE_SEPARATOR + "MhdFiles" + VALID_FILE_SEPARATOR +"MhdData_All_the_Slices.mhd";
726              boost::algorithm::replace_all( temp,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
727              sprintf(outputMhdFileName,"%s", temp);
728              fp=fopen(temp.c_str(), "w");
729              if (!fp)
730              {
731                 std::cout << "Cannot open [" << outputMhdFileName << "] for writting" << std::endl;
732                 throw ( BrukerHopelessException ("Hopeless! Cannot open  mhd file for writting"));
733                 //exit(0);
734              }
735              else
736              {
737                fprintf(fp, "ObjectType = Image\n");
738                fprintf(fp, "NDims = 3\n" );
739                fprintf(fp, "BinaryData = True \n" );
740                fprintf(fp, "BinaryDataByteOrderMSB = False\n" );
741                fprintf(fp, "DimSize = %d %d %d\n", NX, NY, nbSlices );
742                fprintf(fp, "HeaderSize = %d\n", 0);
743                //fprintf(fp, "ElementSpacing = %lf %lf %lf\n",fovX/NY, fovY/NY, sliceDistance );
744                fprintf(fp, "ElementSpacing = %lf %lf %lf\n", spatResolX, spatResolY, sliceDistance );
745                fprintf(fp, "Position = 0 0 %d\n", 0 );
746                fprintf(fp, "Offset = 0 0 0\n" );
747                fprintf(fp, "CenterOfRotation = 0 0 0\n" );
748                fprintf(fp, "ElementNumberOfChannels = 1\n" );
749                fprintf(fp, "ElementType = %s\n", mhdDataPixelType.c_str() );  
750                fprintf(fp, "ElementDataFile = %s\n", "../2dseq_All_the_Slices" );
751                fclose(fp);     
752              }
753              sprintf(output2dseqSliceFileName, "%s%c2dseq_All_the_Slices", 
754                                        currentOutputDirName.c_str(), VALID_FILE_SEPARATOR);
755              temp =  currentOutputDirName +  VALID_FILE_SEPARATOR + "2dseq_All_the_Slices";
756              boost::algorithm::replace_all( temp,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
757              sprintf(output2dseqSliceFileName,"%s",temp);
758              fp=fopen(temp.c_str(), "wb");
759              if (!fp)
760              {
761                 std::cout << "Cannot open [" << output2dseqSliceFileName << "] for writting" << std::endl;
762                 throw ( BrukerHopelessException ("Hopeless! Cannot open 2dseq file for writting"));             
763              }
764              else
765              {
766                 fwrite( buffer_2dseq, NX*NY*pixelSize, nbSlices, fp);     
767              }
768              fclose(fp);
769              serieNumber ++;
770              gdcm::UIDGenerator uid;
771             strSerieUID     = uid.Generate();
772              
773        }  // end if mhd
774        if (dicom)
775        {
776              sprintf(output2dseqSliceFileName, "%s%c2dseq_All_the_Slices.dcm", 
777                                       VALID_FILE_SEPARATOR);
778              temp = currentOutputDirName + VALID_FILE_SEPARATOR + "2dseq_All_the_Slices.dcm";
779              boost::algorithm::replace_all( temp,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
780              sprintf(output2dseqSliceFileName, "%s", temp);
781
782             /* ----------- Write Dicom Image  ---------------*/
783              MakeDicomImage(buffer_2dseq,
784                NX,
785                NY,
786                nbFrames,
787                pixelSize,
788                //fovX/NY, fovY/NY, sliceDistance,
789                spatResolX, spatResolY, sliceDistance,
790                temp.c_str(),
791                subject_name,
792                day,
793                strStudyUID,
794                strSerieUID,
795                strStudyDescr,
796                strSerieDescr,
797                strStudyTimeDate,
798                0,// index frame number
799                4 //GDCM_NAME_SPACE::UNMODIFIED_PIXELS_IMAGE
800              );
801        }  // end if dicom
802    }  // end if nbInstants = 1
803
804    else  // more than ONE instant
805    {
806           // Interleaved !
807           // it's (slice1,slide2, ...)t1 ; (slice1,slide2, ...)t2 ; ...
808          unsigned char *pixelsForCurrentSlice = new unsigned char[NX*NY*pixelSize*nbInstants];
809
810          k = 0;
811          for (sliceNb=0; sliceNb<nbSlices; sliceNb++)
812          {
813             if (mhd)
814             {
815                sprintf(outputMhdFileName, "%s%cMhdData_%03d.mhd", currentOutputMhdDirName, 
816                                         VALID_FILE_SEPARATOR, k  );
817                temp = outputMhdFileName;
818                boost::algorithm::replace_all( temp,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
819                sprintf(outputMhdFileName, "%s", temp);
820                if (verbose)
821                   std::cout << "--- Output MHD file [" << outputMhdFileName << "]" << std::endl;
822                fp=fopen(outputMhdFileName, "w");
823                if (!fp)
824                {
825                    std::cout << "Cannot open [" << outputMhdFileName << "] for writting" << std::endl;
826                    throw ( BrukerHopelessException ("Hopeless! Cannot open  mhd file for writting"));
827                    //exit(0);
828                }
829                else
830                {
831             /* ----------- Write MHD Image  ---------------*/
832                 //if (verbose)
833                 //   std::cout << "Open sucessfully[" << outputMhdFileName << "] for writting" << std::endl; 
834                    fprintf(fp, "ObjectType = Image\n");
835                    fprintf(fp, "NDims = 3\n" );  
836                    fprintf(fp, "BinaryData = True \n" );  
837                    fprintf(fp, "BinaryDataByteOrderMSB = False\n" );    
838                    fprintf(fp, "DimSize = %d %d %d\n", NX, NY, nbInstants);  
839                    fprintf(fp, "HeaderSize = %d\n", 0); 
840                    //fprintf(fp, "ElementSpacing = %lf %lf %lf\n",fovX/NY, fovY/NY, 1.0 ); // 
841                    fprintf(fp, "ElementSpacing = %lf %lf %lf\n",spatResolX, spatResolY, 1.0 ); //slice distance : no meaning for temporal serie
842                    fprintf(fp, "Position = 0 0 %d\n", sliceNb );  
843                    fprintf(fp, "Offset = 0 0 0\n" );  
844                    fprintf(fp, "CenterOfRotation = 0 0 0\n" );
845                    fprintf(fp, "ElementNumberOfChannels = 1\n" );  
846                    fprintf(fp, "ElementType = %s\n", mhdDataPixelType.c_str() );  
847                    fprintf(fp, "ElementDataFile = ..%c2dseq_Slice_%d\n", VALID_FILE_SEPARATOR, sliceNb ); 
848                    fclose(fp);
849                } // end write MHD
850
851                sprintf(output2dseqSliceFileName, "%s%c2dseq_Slice_%d", 
852                                                  currentOutputDirName.c_str(), VALID_FILE_SEPARATOR,sliceNb);
853                temp = output2dseqSliceFileName;
854                boost::algorithm::replace_all( temp,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
855                sprintf(output2dseqSliceFileName, "%s", temp);
856                fp=fopen(output2dseqSliceFileName, "wb");
857                if (!fp)
858                {     
859                    std::cout << "Cannot open [" << output2dseqSliceFileName << "] for writting" << std::endl;
860                    throw ( BrukerHopelessException ("Hopeless! Cannot open 2dseqSliceFile file for writting"));            
861                    //exit (0);
862                }
863                int frameSize = NX*NY*pixelSize;
864                for (instantNb=0; instantNb<nbInstants; instantNb++)
865                {
866 // std::cout << "------------SN " << sliceNb << " IN " << instantNb <<  " T " << nbSlices*instantNb + sliceNb << std::endl;
867                     fwrite( buffer_2dseq +(nbSlices*instantNb + sliceNb)*frameSize,
868                             frameSize,
869                             1, fp);
870                }
871                fclose(fp);
872
873 // std::cout << "end writting[" << output2dseqSliceFileName << "]" << std::endl;
874             }  // end if mhd
875    
876             if (dicom)
877             {
878                // desperate try !
879              /* 
880                sprintf(output2dseqSliceFileName, "%sdummy_buffer", 
881                                                  currentOutputDirName.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR);
882                fp=fopen(output2dseqSliceFileName, "wb");
883                if (!fp)
884                {     
885                    std::cout << "Cannot open [" << output2dseqSliceFileName << "] for writting" << std::endl;
886                    exit (0);
887                }
888                int frameSize = NX*NY*pixelSize;
889                for (instantNb=0; instantNb<nbInstants; instantNb++)
890                {
891 // std::cout << "------------SN " << sliceNb << " IN " << instantNb <<  " T " << nbSlices*instantNb + sliceNb << std::endl;
892                     fwrite( buffer_2dseq +(nbSlices*instantNb + sliceNb)*frameSize,
893                             frameSize,
894                             1, fp);
895                }
896                fclose(fp);
897
898                fp=fopen(output2dseqSliceFileName, "rb");
899                if (!fp)
900                {     
901                    std::cout << "Cannot open [" << output2dseqSliceFileName << "] for reading" << std::endl;
902                    exit (0);
903                }       
904                fread( pixelsForCurrentSlice,
905                             frameSize*nbInstants,
906                             1, fp);
907                fclose(fp);
908               // end of desperate try !
909               */
910
911                /* ----------- Write Dicom Image  ---------------*/
912
913                int frameSize = NX*NY*pixelSize;
914                for (instantNb=0; instantNb<nbInstants; instantNb++)
915                {
916                   memcpy(pixelsForCurrentSlice + frameSize*instantNb, buffer_2dseq +(nbSlices*instantNb + sliceNb)*frameSize, frameSize);
917                }
918
919                int indOfFirsImageWithinImageSet =  nbSlices*instantNb;
920                sprintf(output2dseqSliceFileName, "%s%c2dseq_Slice_%d.dcm", 
921                                                  currentOutputDirName.c_str(),  VALID_FILE_SEPARATOR, sliceNb);
922                temp= output2dseqSliceFileName;
923                boost::algorithm::replace_all( temp,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
924                sprintf(output2dseqSliceFileName, "%s", temp);
925
926                MakeDicomImage(
927                   pixelsForCurrentSlice,
928                   NX,
929                   NY,
930                   nbInstants,
931                   pixelSize,
932                   spatResolX, spatResolY, sliceDistance,
933                   //fovX/NY, fovY/NY, sliceDistance,
934                   output2dseqSliceFileName,
935                   subject_name,
936                   day,
937                   strStudyUID,
938                   strSerieUID,
939                   strStudyDescr,
940                   strSerieDescr,
941                   strStudyTimeDate,
942                   sliceNb*nbInstants,
943                   4 //GDCM_NAME_SPACE::UNMODIFIED_PIXELS_IMAGE
944                );
945                if (verbose)
946                   std::cout << "--- Output DCM file [" << output2dseqSliceFileName << "]" << std::endl;      
947
948            } // en if dicom
949
950         k++;
951         }
952         delete [] pixelsForCurrentSlice;  
953      }  // end nbInstants == 1
954    delete [] buffer_2dseq;
955 /**/
956
957
958    // -----------------------------------------------------
959    //  deal with MatLab-generated Carto file.
960    // -----------------------------------------------------
961
962    dealWithCarto(fileNames,  NX,  NY,  nbSlices, /*fovX, fovY,*/ spatResolX, spatResolY, sliceDistance,
963                    copyFile, currentOutputDirName, outputMhdFileName, output2dseqCartoName);
964 }
965
966 // ===========================================================================================
967
968 void Bruker2Dicom::dealWithCarto(gdcm::Directory::FilenamesType &fileNames, int NX, int NY, int nbSlices, 
969                                  /*double fovX, double fovY, */
970                                  double spatResolX, double spatResolY, double sliceDistance,
971                                  char *copyFile, std::string &currentOutputDirName, 
972                                  char *outputMhdFileName, char *output2dseqCartoName)
973 {
974    // -----------------------------------------------------
975    //  deal with MatLab-generated Carto file.
976    // -----------------------------------------------------
977
978    const char *code[] = { "ADC", "adc", "TTP", "ttp", "PEAK", "peak", "" };  // add more carto file name identifiers if necessary; end with ""
979    const char *separator[] =  { "_", ".", "-", "" }; //  add more, if necessary, to ckeck for 2dseq.ADC, 2dseq_ADC, 2dseq-ADC, etc; end with ""
980    int icode;
981    int iseparator; 
982   gdcm::Directory::FilenamesType::iterator it;
983    char file_name_ident[500];
984    FILE *fp;
985
986    // Iterate to ALL the objets(files/directories) found in the input directory    
987    for (it = fileNames.begin();
988         it != fileNames.end();
989       ++it)
990    {
991       if ( boost::filesystem::is_regular(*it) )
992       //if ( ! boost::filesystem::is_directory(*it) )
993       {         
994          if (verbose)
995             std::cout << "--- [" << *it << "] is a file..." << std::endl;
996
997          icode      = 0;
998          while (code[icode][0] != 0)
999          { 
1000          iseparator = 0;       
1001          while (separator[iseparator][0] != 0)
1002          {
1003             sprintf(file_name_ident, "2dseq%s%s",separator[iseparator],code[icode]); // e.g  "2dseq_ADC"
1004             //if (verbose)
1005             //   std::cout << "check name ["<<(*it) << "] for string [" << file_name_ident << "]" << std::endl;
1006             std::string::size_type loc = (*it).rfind(file_name_ident); 
1007
1008             if ( loc != std::string::npos )
1009             {
1010
1011        ///\ TODO : find a safer way to be sure to read everything!
1012               unsigned char *buffer_carto = new unsigned char[NX*NY*sizeof(double)*nbSlices];
1013               fp = fopen ( (*it).c_str(), "rb");
1014               if (!fp){
1015                  std::cout << "Cannot open [" << *it << "] for reading" << std::endl;
1016                  throw ( BrukerHopelessException ("Level 1 Unable to open 'carto' file "));
1017                }
1018                fread(buffer_carto, NX*NY*sizeof(double), nbSlices, fp);
1019
1020                     // ?!?  sprintf(copyFile, "cp %s %s%c%s", (*it).c_str() ,
1021                std::cout << "Deal with Carto file :[" <<*it << "], computed length : "
1022                          << NX*NY*sizeof(double)*nbSlices << std::endl;
1023                gdcm::Filename file ( (*it).c_str());
1024                std::string lastFileName = file.GetName();
1025                if (mhd)
1026                {
1027                   // Copy the data file in the new directory
1028                   sprintf(copyFile, "cp %s %s%c%s", (*it).c_str() ,
1029                             currentOutputDirName.c_str(),  VALID_FILE_SEPARATOR, lastFileName.c_str()); 
1030                   std::string temp(copyFile);
1031                         boost::algorithm::replace_all( temp,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
1032                     sprintf(copyFile, "%s", temp);
1033       
1034                   system(copyFile);
1035                   sprintf(outputMhdFileName, "%s%c%s%s",
1036                                          currentOutputDirName.c_str(),VALID_FILE_SEPARATOR, lastFileName.c_str(), ".mhd" );
1037                   temp = outputMhdFileName;
1038                    boost::algorithm::replace_all( temp,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
1039                   sprintf(outputMhdFileName, "%s", temp);
1040       
1041                   if (verbose)
1042                     std::cout << "--- Output Carto MHD file [" << outputMhdFileName << "]" << std::endl;
1043
1044                   FILE *fp;
1045                   fp=fopen(outputMhdFileName, "w");
1046                   if (!fp)
1047                   {
1048                      std::cout << "Cannot open [" << outputMhdFileName << "] for writting" << std::endl;
1049                   }
1050                   else
1051                   {
1052                      fprintf(fp, "ObjectType = Image\n");
1053                      fprintf(fp, "NDims = 3\n" );
1054                      fprintf(fp, "BinaryData = True \n" );
1055                      fprintf(fp, "BinaryDataByteOrderMSB = False\n" );
1056                      fprintf(fp, "DimSize = %d %d %d\n", NX, NY, nbSlices);
1057                      fprintf(fp, "HeaderSize = %d\n", 0 );
1058                      fprintf(fp, "ElementSpacing = %lf %lf %lf\n",spatResolX, spatResolY, sliceDistance );
1059                      fprintf(fp, "Position = 0 0 0\n" );
1060                      fprintf(fp, "Offset = 0 0 0\n" );
1061                      fprintf(fp, "CenterOfRotation = 0 0 0\n" );
1062                      fprintf(fp, "ElementNumberOfChannels = 1\n" );
1063                      fprintf(fp, "ElementType = %s\n", "MET_DOUBLE" );
1064                      fprintf(fp, "ElementDataFile = %s\n", lastFileName.c_str() );
1065
1066                      fclose(fp);
1067                   }
1068                   if (verbose)
1069                      std::cout << "--- end write Carto MHD file [" << outputMhdFileName << "]" << std::endl;
1070                }  // end if mhd
1071
1072             // ----------- Write Dicom Image  ---------------
1073
1074                if (dicom)
1075                {
1076                   sprintf(output2dseqCartoName, "%s%c%s%s",
1077                                        currentOutputDirName.c_str(), VALID_FILE_SEPARATOR, lastFileName.c_str(), ".dcm" );
1078                   
1079                   std::string temp(output2dseqCartoName);
1080                   boost::algorithm::replace_all( temp,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
1081                   sprintf(output2dseqCartoName,"%s", temp);
1082            
1083                   if (verbose)
1084                      std::cout << "--- end create name output2dseqCartoName file [" << output2dseqCartoName << "]" << std::endl;
1085                      gdcm::UIDGenerator uid;
1086                     strSerieUID     = uid.Generate();
1087                   
1088                     gdcm::Filename file( (*it).c_str() );
1089                     std::string strNewSerieDescr(strSerieDescr+ "_" + file.GetName()); 
1090                   MakeDicomImage(buffer_carto,
1091                      NX,
1092                      NY,
1093                      nbSlices,
1094                      8, // pixelSize
1095                      //fovX/NY, fovY/NY, sliceDistance,
1096                      spatResolX, spatResolY, sliceDistance,
1097                      output2dseqCartoName,
1098                      subject_name,
1099                      day,
1100                      strStudyUID,
1101                      strSerieUID,
1102                      strStudyDescr,
1103                      strNewSerieDescr,
1104                      strStudyTimeDate,
1105                      0,
1106                   3//   GDCM_NAME_SPACE::CREATED_IMAGE
1107                   );
1108                }  // end if dicom
1109
1110                delete [] buffer_carto;
1111                if (verbose) 
1112                   std::cout << "--- End writing Carto DICOM file [" << output2dseqCartoName << "]" << std::endl;
1113                break; // don't check for more ident on same file name!
1114
1115             }  // end deal with _ADC, -adc, etc
1116           iseparator ++;
1117           }  // end iterate speparators
1118           icode++;
1119           } // end iterate code
1120       } // end boost::filesystem::is_regular(*it)
1121    } // end iterate on all objects (files, dir, etc)
1122 } // end method
1123
1124 // ==========================================================================================================
1125
1126 int Bruker2Dicom::CheckUserDirectory(std::string &userDirName)
1127 {
1128     gdcm::Directory dirList;
1129     dirList.Load(userDirName); // DON'T get recursively the list of files
1130      
1131    gdcm::Directory::FilenamesType fileNames;
1132    fileNames = dirList.GetFilenames();
1133
1134    gdcm::Filename file( fileNames.begin()->c_str());
1135    std::string path = file.GetPath();
1136
1137    std::string subject =  path +
1138                          VALID_FILE_SEPARATOR +
1139                           "subject";
1140    boost::algorithm::replace_all( subject,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
1141     std::string acqp = path +
1142                        VALID_FILE_SEPARATOR +
1143                        "acqp";
1144     boost::algorithm::replace_all( acqp,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
1145     if ( boost::filesystem::is_regular(subject) )
1146        subjectFound = true; // user passed a 'study
1147     else
1148        subjectFound = false; // user didnt' pass a 'study 
1149
1150     if ( boost::filesystem::is_regular(acqp) )
1151        acqpFound= true; // user passes a 'serie', not a 'study' 
1152     else
1153        acqpFound = false; // user passed a 'non study' directory; Hope it's a 'set of studies' directory!
1154    
1155    int type;    
1156    if  (subjectFound )  type = 1; // user passed a 'study
1157    else if  (acqpFound) type = 2; // user passed a 'serie' 
1158    else                 type = 3; // user passed a 'non study' directory; Hope it's a 'set of studies' directory!
1159
1160    return type;   
1161 }
1162
1163 // ==========================================================================================================
1164
1165 bool Bruker2Dicom::CreateDirectory(const std::string &OutputDirName)
1166 {
1167    std::string systemCommand;
1168    
1169    if (verbose)
1170       std::cout << "Check for output directory :[" << OutputDirName << "]."
1171                 <<std::endl;
1172    boost::filesystem::directory_entry ent(OutputDirName);
1173    if ( ! boost::filesystem::is_directory(ent) )    // dirout not found
1174    {
1175       systemCommand = "mkdir " + OutputDirName;        // create it!      
1176       if (verbose)
1177          std::cout << systemCommand << std::endl;
1178       system (systemCommand.c_str());
1179   //    if ( ! boost::filesystem::is_directory(OutputDirName) ) // be sure it worked
1180   //    {
1181   //       if (verbose) 
1182   //          std::cout << "KO : not a dir : [" << OutputDirName << "] (creation failure ?)" << std::endl;
1183   //       //return 0;
1184          //throw ( BrukerHopelessException ("Level 1 output directory creation failure "));
1185   //    }
1186   //    else
1187   //    {
1188   //       if (verbose) 
1189   //         std::cout << "Directory [" << OutputDirName << "] created." << std::endl;
1190   //    }
1191    }
1192    else
1193    {
1194        if (verbose)
1195             std::cout << "Output Directory [" << OutputDirName << "] already exists; Used as is." << std::endl;
1196    }
1197    return 1;
1198 }
1199
1200 // ===========================================================================================
1201
1202 /// \TODO move cleanString to 'crea' ?
1203
1204 void Bruker2Dicom::cleanString(std::string &s)
1205 {
1206    int l = s.size();
1207    if (s[l-1] == 0x0A || s[l-1] == 0x0D ) // CR or NL
1208    {
1209       l--;
1210       s = s.substr(0, l);
1211    }
1212    if (s[l-1] == ' ' ) // blank space
1213    {
1214       l--;
1215       s = s.substr(0, l);
1216    }   
1217    
1218    if (s[0] == '<')      
1219       s= s.substr(1,l-2);
1220    std::string repChar("_");   
1221    ////boost::algorithm::replace_all(
1222    //GDCM_NAME_SPACE::Util::ReplaceSpecChar(s, repChar);
1223 }
1224
1225 // ===========================================================================================
1226
1227 void Bruker2Dicom::getImhDataType(BrukerFieldData &bDPT, std::string &mhdDataPixelType, int &pixelSize)
1228
1229    if(bDPT.GetDataType() == "string")
1230    {         
1231          std::string brukerDataPixelType = bDPT.GetStringValue()[0];
1232          if (verbose)
1233             std::cout << "DATTYPE " << brukerDataPixelType << std::endl;          
1234          //std::string brukerDataPixelType = br_d3proc.GetFieldData("DATTYPE").GetStringValue()[0];
1235          
1236          if (brukerDataPixelType ==  "ip_short") {
1237             mhdDataPixelType = "MET_USHORT";
1238             pixelSize = 2;
1239          }
1240          if (brukerDataPixelType ==  "ip_int") {
1241             mhdDataPixelType = "MET_UINT";
1242             pixelSize = 4;
1243          }
1244          if (brukerDataPixelType ==  "ip_char") {
1245              mhdDataPixelType = "MET_UCHAR";
1246              pixelSize = 1;
1247          }
1248                   /// \TODO : finish the list
1249     /*
1250     case 0 : fp << "ElementType = MET_CHAR" << std::endl;
1251       break;
1252     case 1 : fp << "ElementType = MET_UCHAR" << std::endl;
1253       break;
1254     case 2 : fp << "ElementType = MET_SHORT" << std::endl;
1255       break;
1256     case 3 : fp << "ElementType = MET_USHORT" << std::endl;
1257       break;
1258     case 4 : fp << "ElementType = MET_INT" << std::endl;
1259       break;
1260     case 5 : fp << "ElementType = MET_UINT" << std::endl;
1261       break;
1262     case 6 : fp << "ElementType = MET_FLOAT" << std::endl;
1263       break;
1264     case 7 : fp << "ElementType = MET_DOUBLE" << std::endl;  
1265     */
1266     }
1267     else
1268     {
1269          int brukerDataPixelType = bDPT.GetIntValue()[0];
1270          if (verbose)
1271             std::cout << "DATTYPE " << brukerDataPixelType << std::endl;          
1272          //std::string brukerDataPixelType = br_d3proc.GetFieldData("DATTYPE").GetStringValue()[0];
1273  
1274 // Cross your fingers !!!
1275
1276 // pb : found values : 2, 3, 5
1277
1278          if (brukerDataPixelType ==  2) {
1279             mhdDataPixelType = "MET_USHORT";
1280             pixelSize = 2;
1281          }
1282          if (brukerDataPixelType ==  3) {
1283             mhdDataPixelType = "MET_USHORT";
1284             pixelSize = 2;
1285          }    
1286          if (brukerDataPixelType ==  1) {
1287             mhdDataPixelType = "MET_UCHAR";
1288             pixelSize = 1;
1289          }     
1290     }
1291 }
1292
1293 // ===========================================================================================
1294
1295 std::vector<BrukerImage> Bruker2Dicom::CreateImageSet ( )
1296 {
1297          std::vector<BrukerImage> imageSet;      
1298          br_acqp.SetLoopStructure();
1299          std::vector<int> tempVect                      = br_acqp.GetLoopStructure() ;
1300          std::map<std::string, BrukerFieldData> map     = br_acqp.GetBrukerHeaderMap();
1301          
1302          bool result                                    = br_acqp.ObjectVaryingProperties.init(map,tempVect);
1303
1304          if (result == false)
1305          {
1306             throw ( BrukerInitException  ("ObjectVaryingProperties.init() failure in Bruker2Dicom::CreateImageSet()") );
1307          }
1308
1309          br_acqp.SetImageLoopStructure();
1310          br_acqp.SetBrukerImageList();
1311          std::vector<std::vector<int> > brukerImageList = br_acqp.GetBrukerImageList();
1312
1313          BrukerImage image(br_acqp,br_reco);
1314          image.Init(br_acqp,br_reco,1); 
1315
1316          for(int i=0;i<brukerImageList.size();i++)
1317          {
1318             image.Init(br_acqp,br_reco,i);    
1319             imageSet.push_back(image);
1320          }
1321
1322  // Just for checking
1323  /*
1324
1325          std::vector<std::vector <double> > imageOrientation;
1326          std::vector <double> imagePosition; 
1327          for(int i=0;i<brukerImageList.size();i++)
1328          {
1329            // fread(buffer_2dseq, NX*NY*pixelSize*nbSlices*nbInstants, 1, fp);   
1330
1331            imagePosition = imageSet[i].getTranslationVectorRPS2XYZ();
1332            std::cout << "Position " << imagePosition[0] << " " 
1333                      << imagePosition[1] << " "  << imagePosition[2] ;
1334            imageOrientation =  imageSet[i].getRotationMatrixRPS2XYZ();
1335            std::cout << "\t  Orientation " ;
1336            for(int i1=0; i1<3;i1++)for(int i2=0; i2<3;i2++)
1337               std::cout << imageOrientation[i1][i2] << " ";CreateImageSet
1338
1339            //std::cout << "\t  Abs Time " << imageSet[i].getAbsoluteTimePosition();
1340            std::cout << "\t  Relat Time " << imageSet[i].getRelativeTimePosition();
1341
1342            std::cout << "\t [";
1343            for (int i3=0; i3<imageSet[i].getLoopStamp().size();i3++)
1344               std::cout << " " << imageSet[i].getLoopStamp()[i3];
1345            std::cout << "]" << std::endl;       
1346          } 
1347 */
1348    return imageSet;
1349 }
1350
1351 // ===========================================================================================
1352
1353 void Bruker2Dicom::MakeDicomImage(unsigned char *tabPixels, 
1354               int X, 
1355               int Y,
1356               int nbFrames,
1357               int pixelSize,
1358               double spacingX, double spacingY, double sliceDistance, 
1359               std::string dcmImageName,
1360               const std::string &patientName,
1361               const char *day,
1362               std::string &studyUID,
1363               std::string &serieUID,
1364               std::string &studyDescr,
1365               std::string &serieDescr,
1366               std::string &strStudyTimeDate,
1367               int imgNum,
1368              int contentType
1369       )
1370 {  
1371    std::ostringstream str;
1372
1373    gdcm::File file;
1374    gdcm::DataSet ds;
1375     ds.Clear();
1376
1377
1378     // Set the image size
1379     // columns
1380     {
1381         gdcm::Attribute<0x0028,0x0011, gdcm::VR::US> at;
1382         at.SetValue(X);
1383         ds.Replace(at.GetAsDataElement());
1384     }
1385     // rows
1386     {
1387         gdcm::Attribute<0x0028,0x0010, gdcm::VR::US> at;
1388         at.SetValue(Y);
1389         ds.Replace(at.GetAsDataElement());
1390     }
1391
1392    //file.SetDataSet( createDataSet(str.str(),0x0028,0x0011,"US"));
1393   // Set the image size
1394    str.str(""); 
1395    str << X;
1396    
1397  //  file->InsertEntryString(str.str(),0x0028,0x0011,"US"); // Columns
1398    str.str("");
1399    str << Y;
1400  //  file->InsertEntryString(str.str(),0x0028,0x0010,"US"); // Rows
1401
1402    if (nbFrames != 1)
1403    {
1404         gdcm::Attribute<0x0028,0x0008, gdcm::VR::IS> at;
1405         at.SetValue(nbFrames);
1406         ds.Replace(at.GetAsDataElement());
1407      // file->InsertEntryString(str.str(),0x0028,0x0008,"IS"); // Number of Frames  
1408    }
1409
1410   // Set the pixel type
1411    // Bits allocated
1412        {
1413             gdcm::Attribute<0x0028,0x0100, gdcm::VR::US> at;
1414             at.SetValue(pixelSize*8);
1415             ds.Replace(at.GetAsDataElement());
1416         }
1417        // Bits stored
1418        {
1419             gdcm::Attribute<0x0028,0x0101, gdcm::VR::US> at;
1420             at.SetValue(pixelSize*8);
1421             ds.Replace(at.GetAsDataElement());
1422         }
1423        // High Bit
1424         {
1425             gdcm::Attribute<0x0028,0x0102, gdcm::VR::US> at;
1426             at.SetValue(pixelSize*8 -1);
1427             ds.Replace(at.GetAsDataElement());
1428         }
1429
1430         // pixel representation
1431         {
1432             gdcm::Attribute<0x0028,0x0103, gdcm::VR::US> at;
1433             at.SetValue(1);
1434             ds.Replace(at.GetAsDataElement());
1435         }
1436         // sample per pixel
1437         {
1438             gdcm::Attribute<0x0028,0x0002, gdcm::VR::US> at;
1439             at.SetValue(1);
1440             ds.Replace(at.GetAsDataElement());
1441         }
1442
1443            // pixel spacing
1444         {
1445            char temp[256];
1446            sprintf(temp,"%d%s%d",spacingX, "\\", spacingY);
1447            std::string st;
1448            st = temp;
1449              gdcm::Attribute<0x0028,0x0030, gdcm::VR::DS> at;
1450        //     at.SetValue(st);
1451             ds.Replace(at.GetAsDataElement());
1452         }
1453         //Slice Thickness 
1454         {
1455             gdcm::Attribute<0x0018,0x0050, gdcm::VR::DS> at;
1456             
1457             at.SetValue(sliceDistance);
1458             ds.Replace(at.GetAsDataElement());
1459         }
1460         // Series Number
1461         {
1462             gdcm::Attribute<0x0020,0x0011, gdcm::VR::IS> at;
1463             at.SetValue(serieNumber);
1464             ds.Replace(at.GetAsDataElement());
1465         }
1466          //Instance Number
1467         {
1468             gdcm::Attribute<0x0020,0x0013,gdcm::VR::IS> at;
1469             at.SetValue(++instanceNumber);
1470             ds.Replace(at.GetAsDataElement());
1471             
1472         }
1473           // [Media Storage SOP Class UID]
1474           {
1475         /*    
1476                str.str("");
1477                str <<  "1.2.840.10008.5.1.4.1.1.4";
1478                  gdcm::Tag tag(0x0002, 0x0002);
1479               tag.Write(str);
1480                         at.SetValue(str);
1481             ds.Replace(at.GetAsDataElement());*/
1482         }
1483             // [SOP Class UID]   
1484          {
1485          /*   gdcm::Attribute<0x0008, 0x0162gdcm::VR::UI> at;
1486             at.SetValue("1.2.840.10008.5.1.4.1.1.4");
1487             ds.Replace(at.GetAsDataElement());*/
1488         }
1489          // Patient Name
1490          {
1491             gdcm::Attribute<0x0010,0x0010, gdcm::VR::PN> at;
1492             at.SetValue(patientName);
1493             ds.Replace(at.GetAsDataElement());
1494         }
1495           // Patient's ID
1496          {
1497             gdcm::Attribute<0x0010,0x0020, gdcm::VR::LO> at;
1498             at.SetValue(patientName);
1499             ds.Replace(at.GetAsDataElement());
1500         }
1501           // study UID
1502          {
1503             gdcm::Attribute< 0x0020, 0x000d, gdcm::VR::UI> at;
1504             at.SetValue(studyUID);
1505             ds.Replace(at.GetAsDataElement());
1506         }
1507           // serieUID
1508          {
1509             gdcm::Attribute<  0x0020, 0x000e, gdcm::VR::UI> at;
1510             at.SetValue(serieUID);
1511             ds.Replace(at.GetAsDataElement());
1512         }
1513           {
1514               gdcm::Attribute<  0x0008,0x0020, gdcm::VR::DA> at;
1515             at.SetValue(strStudyTimeDate.substr(10,11).c_str());
1516             ds.Replace(at.GetAsDataElement());
1517         }
1518            {
1519             gdcm::Attribute<  0x0008,0x0030, gdcm::VR::TM> at;
1520             at.SetValue(strStudyTimeDate.substr(1,8).c_str());
1521             ds.Replace(at.GetAsDataElement());
1522         }
1523            // Study Description  
1524         {
1525             gdcm::Attribute<  0x0008,0x1030, gdcm::VR::LO> at;
1526             at.SetValue(studyDescr);
1527             ds.Replace(at.GetAsDataElement());
1528         }
1529             // Series Description  
1530         {
1531             gdcm::Attribute<  0x0008,0x103e, gdcm::VR::LO> at;
1532             at.SetValue(serieDescr);
1533             ds.Replace(at.GetAsDataElement());
1534         }
1535          // Modalirty
1536         {
1537             gdcm::Attribute<  0x0008,0x0060, gdcm::VR::CS> at;
1538             at.SetValue("MR");
1539             ds.Replace(at.GetAsDataElement());
1540         }
1541
1542
1543   //      //8, 16, 32, 64 (for double ?)
1544    str.str("");
1545    str << pixelSize*8;     
1546  //  file->InsertEntryString(str.str(),0x0028,0x0100,"US"); // Bits Allocated
1547
1548  //  file->InsertEntryString(str.str(),0x0028,0x0101,"US"); // Bits Stored
1549
1550    str.str("");
1551    str << pixelSize*8-1;     
1552   // file->InsertEntryString(str.str(),0x0028,0x0102,"US"); // High Bit
1553
1554   // Set the pixel representation // 0/1 , 0=unsigned
1555  //  file->InsertEntryString("1",0x0028,0x0103, "US"); // Pixel Representation
1556    
1557   // Set the samples per pixel // 1:Grey level, 3:RGB
1558   // file->InsertEntryString("1",0x0028,0x0002, "US"); // Samples per Pixel
1559
1560 //  0028 0030 DS 2 Pixel Spacing
1561    str.str("");
1562    str << spacingX << "\\" << spacingY;
1563  //  file->InsertEntryString(str.str(),0x0028,0x0030, "DS"); // Pixel Spacing     
1564    
1565  //   0018 0050 DS 1 Slice Thickness 
1566    str.str("");    
1567    str << sliceDistance;
1568  //  file->InsertEntryString(str.str(),0x0018,0x0050, "DS"); 
1569    
1570 //    0020 0011 IS 1 Series Number
1571    str.str("");    
1572    str << serieNumber;
1573 //   file->InsertEntryString(str.str(),0x0020,0x0011, "IS");
1574       
1575 //    0020|0013 [IS]  [Instance Number] 
1576    instanceNumber++;
1577    str.str("");    
1578    str << instanceNumber;
1579  //  file->InsertEntryString(str.str(),0x0020,0x0013, "IS");
1580      
1581   // 1.2.840.10008.5.1.4.1.1.4.1 : Enhanced MR Image Storage
1582  //  file->InsertEntryString("1.2.840.10008.5.1.4.1.1.4.1" , 0x0002, 0x0002, "UI");  // [Media Storage SOP Class UID]
1583   // file->InsertEntryString("1.2.840.10008.5.1.4.1.1.4.1" , 0x0008, 0x0016, "UI");  // [SOP Class UID]
1584
1585 // OK : MR is NOT multiframe, but I want just a quick an dirty solution
1586 //
1587 //// 1.2.840.10008.5.1.4.1.1.4         MR Image Storage
1588 //   file->InsertEntryString("1.2.840.10008.5.1.4.1.1.4" , 0x0002, 0x0002, "UI");  // [Media Storage SOP Class UID]
1589 //   file->InsertEntryString("1.2.840.10008.5.1.4.1.1.4" , 0x0008, 0x0016, "UI");  // [SOP Class UID]     
1590 //
1591 //  // if (strlen(patientName) != 0)
1592 //   file->InsertEntryString(patientName.c_str(),0x0010,0x0010, "PN"); // Patient's Name
1593 //   file->InsertEntryString(patientName.c_str(),0x0010,0x0020, "LO"); // Patient's ID
1594 //
1595 //   file->InsertEntryString(studyUID, 0x0020, 0x000d, "UI");
1596 //   file->InsertEntryString(serieUID, 0x0020, 0x000e, "UI");
1597 //   
1598 ////  0008 0020 DA 1 Study Date
1599 ////  0008 0030 TM 1 Study Time
1600 //
1601 ///// \TODO split into 2 strings!
1602 //   file->InsertEntryString(strStudyTimeDate.substr(10,11).c_str(),0x0008,0x0020, "DA");
1603 //   file->InsertEntryString(strStudyTimeDate.substr(1,8).c_str(),  0x0008,0x0030, "TM");
1604 //
1605 //   file->InsertEntryString(studyDescr, 0x0008,0x1030, "LO");  // Study Description  
1606 //   file->InsertEntryString(serieDescr, 0x0008,0x103e, "LO");  // Series Description 
1607 //
1608 ////0008|0060 [CS] [Modality] 
1609 //   file->InsertEntryString("MR",0x0008,0x0060, "CS");
1610 //
1611 // 0020 0037 DS 6 Image Orientation (Patient)
1612    char charImageOrientation[256];
1613
1614 /*
1615 std::cout << "charImageOrientation  " << 
1616                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][0] << " " <<
1617                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][1] << " " <<
1618                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][2] << " " <<
1619                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][0] << " " <<
1620                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][1] << " " <<
1621                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][2] << std::endl ;
1622 */      
1623
1624    {
1625              gdcm::Attribute<  0x0020,0x0037, gdcm::VR::DS> at;
1626               at.SetValue(  imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][0], 0);
1627               at.SetValue(  imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][1], 1);
1628               at.SetValue(  imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][2], 2);
1629               at.SetValue(   imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][0], 3);
1630               at.SetValue(  imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][1], 4);
1631               at.SetValue(  imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][2], 4);
1632             ds.Replace(at.GetAsDataElement());
1633    }
1634 //   file->InsertEntryString(charImageOrientation,0x0020,0x0037, "DS");
1635
1636    char charImagePosition[256];   
1637    sprintf(charImagePosition,"%f\\%f\\%f", 
1638                              imageSet[imgNum].getTranslationVectorRPS2XYZ()[0], 
1639                              imageSet[imgNum].getTranslationVectorRPS2XYZ()[1],
1640                              imageSet[imgNum].getTranslationVectorRPS2XYZ()[2]);
1641   
1642    //file->InsertEntryString(charImagePosition,0x0020,0x0032, "DS");  //0020 0032 DS 3 Image Position (Patient) 
1643    
1644 // 0020 0032 DS 3 Image Position (Patient) 
1645   {
1646              gdcm::Attribute<  0x0020,0x0032,gdcm::VR::DS> at;
1647               at.SetValue(  imageSet[imgNum].getTranslationVectorRPS2XYZ()[0], 0);
1648               at.SetValue(  imageSet[imgNum].getTranslationVectorRPS2XYZ()[1], 1);
1649               at.SetValue(imageSet[imgNum].getTranslationVectorRPS2XYZ()[2], 2);
1650               ds.Replace(at.GetAsDataElement());
1651   }
1652    
1653    
1654    // Private creator
1655    /*
1656    
1657 0029|0010 [LO]   [Private Creator] [CREATIS HEADER ]
1658 0029|0011 [LO]   [Private Creator] [CREATIS for BRUKER to DICOM]
1659 0029|1031 [LO]   [] [4.0.7571167 ]
1660 0029|1032 [UL]   [] [1440000] =0x(15f900)
1661
1662 > $$ Thu Jul 30 17:29:46 2009 CEST (UT+2h)  mwiart
1663 > $$ /opt/PV4.0/data/mwiart/nmr/dha80.Uw1/4/method
1664 > ##$Method=DtiEpi
1665 > ##$PVM_DwNDiffDir=3             % 3 directions
1666 > ##$PVM_DwNDiffExpEach=2         % 2 valeurs de b par direction
1667 > ##$PVM_DwAoImages=1             % 1 image pour b=0
1668 > ##$PVM_DwBvalEach=( 2 )         % Valeurs de b
1669 > 1500.000000 3000.000000
1670 >
1671 > $$ Wed Dec  2 09:56:01 2009 UTC (UT+0h)  mwiart
1672 > $$ /opt/Pv5.0/data/mwiart/nmr/ECI7.Wx1/4/method
1673 > ##$Method=DtiEpi
1674 > ##$PVM_DwNDiffDir=3             % 3 directions
1675 > ##$PVM_DwNDiffExpEach=2         % 2 valeurs de b par direction
1676 > ##$PVM_DwAoImages=1             % 1 image pour b=0
1677 > ##$PVM_DwBvalEach=( 2 )         % Valeurs de b
1678 > 1500 3000
1679 >
1680 > $$ Wed Dec  2 10:14:27 2009 UTC (UT+0h)  mwiart
1681 > $$ /opt/Pv5.0/data/mwiart/nmr/ECI7.Wx1/5/method
1682 > ##$Method=DtiStandard
1683 > ##$PVM_DwNDiffDir=1             % 1 direction
1684 > ##$PVM_DwNDiffExpEach=2         % 2 valeurs de b
1685 > ##$PVM_DwAoImages=0             % 0 image pour b=0
1686 > ##$PVM_DwBvalEach=( 2 )         % Valeurs de b
1687 > 138 1600
1688 >
1689    */
1690     //{
1691     //         gdcm::Attribute<  0x0029,0x0010, gdcm::VR::LO> at;
1692     //         at.SetValue(.SetValue(  "CREATIS HEADER");
1693     //          ds.Replace(at.GetAsDataElement());
1694     //}
1695     //{
1696     //            gdcm::Attribute<  0x0029,0x0011, gdcm::VR::LO> at;
1697     //      //    at.SetValue( "CREATIS FOR BRUKER-TO-DICOM");
1698     //          ds.Replace(at.GetAsDataElement());
1699     //}
1700
1701   // file->InsertEntryString("CREATIS HEADER", 0x0029,0x0010, "LO");
1702    //file->InsertEntryString("CREATIS FOR BRUKER-TO-DICOM", 0x0029,0x0011, "LO");
1703    
1704    BrukerFieldData brf_method            = br_method.GetFieldData("Method");
1705    const std::vector<std::string> method = brf_method.GetStringValue();
1706
1707   // std::string method = br_method.GetFieldData("Method").GetStringValue();    
1708    //{
1709    //            gdcm::Attribute<  0x0029,0x0100, gdcm::VR::LO> at;
1710    //           at.SetValue(method[0]);
1711    //           ds.Replace(at.GetAsDataElement());
1712    //}
1713    //file->InsertEntryString(method[0], 0x0029,0x0100, "LO");
1714    
1715    std::cout << " method[" << method[0]  << "]" << std::endl;
1716    if (method[0] == "DtiEpi" || method[0] == "DtiStandard")
1717    {
1718      // const std::vector<int> NDiffDir       = br_method.GetFieldData("PVM_DwNDiffDir").GetIntValue();
1719       BrukerFieldData brf_NDiffDir    = br_method.GetFieldData("PVM_DwNDiffDir");
1720       const std::vector<int> NDiffDir = brf_NDiffDir.GetIntValue();
1721       
1722       //const std::vector<int> NDiffExpEach   = br_method.GetFieldData("PVM_DwNDiffExpEach").GetIntValue();
1723       BrukerFieldData brf_NDiffExpEach      = br_method.GetFieldData("PVM_DwNDiffExpEach");
1724       const std::vector<int> NDiffExpEach   =brf_NDiffExpEach.GetIntValue();
1725       
1726 //      const std::vector<int> AoImages     = br_method.GetFieldData("PVM_DwAoImages").GetIntValue();
1727       BrukerFieldData brf_AoImages        = br_method.GetFieldData("PVM_DwAoImages");
1728       const std::vector<int> AoImages     = brf_AoImages.GetIntValue();
1729       
1730       BrukerFieldData brf_DwBvalEach       = br_method.GetFieldData("PVM_DwBvalEach");
1731       const std::vector<double> DwBvalEach = brf_DwBvalEach.GetDoubleValue();
1732       
1733  std::cout << "nb directions : " <<  NDiffDir[0] << " nb valeurs de b par direction : " << NDiffExpEach[0] 
1734            << " nb images for b=0 : " << AoImages[0] << std::endl;
1735            
1736        str.str(""); 
1737        str << NDiffDir[0];
1738          {
1739                gdcm::Attribute<  0x0029,0x0101, gdcm::VR::US> at;
1740               at.SetValue( NDiffDir[0]);
1741               ds.Replace(at.GetAsDataElement());
1742    }
1743     //   file->InsertEntryString(str.str(),0x0029,0x0101,"US"); // directions
1744        str.str(""); 
1745        str << NDiffExpEach[0];
1746         {
1747                gdcm::Attribute<  0x0029,0x0102, gdcm::VR::US> at;
1748               at.SetValue( NDiffExpEach[0]);
1749               ds.Replace(at.GetAsDataElement());
1750    }
1751    //    file->InsertEntryString(str.str(),0x0029,0x0102,"US"); // valeurs de b par direction       
1752        str.str(""); 
1753        str << AoImages[0];
1754                {
1755                gdcm::Attribute<  0x0029,0x0103, gdcm::VR::US> at;
1756               at.SetValue( AoImages[0]);
1757               ds.Replace(at.GetAsDataElement());
1758    }
1759    //    file->InsertEntryString(str.str(),0x0029,0x0103,"US"); // image pour b=0
1760
1761            {
1762              gdcm::Attribute<  0x0029,0x0104,gdcm::VR::DS> at;
1763                          for (unsigned int i=0; i<NDiffExpEach[0]; i++)
1764                       at.SetValue( DwBvalEach[i], i);
1765               ds.Replace(at.GetAsDataElement());
1766                 }
1767     //  file->InsertEntryString(str.str(),0x0029,0x0104,"DS"); // Valeurs de b          
1768    }   
1769       file.SetDataSet(ds);
1770
1771 // 0020 0x1041 DS 1 Slice Location 
1772 //        sprintf(charImagePosition,"%f",float(imgNum));
1773 //        file->InsertEntryString(charImagePosition,0x0020,0x1041, "DS");   
1774 /*
1775   // Set Rescale Intercept
1776         str.str("");
1777         str << div;  
1778         file->InsertEntryString(str.str(),0x0028,0x1052,"DS");
1779
1780   // Set Rescale Slope
1781         str.str("");
1782         str << mini;  
1783         file->InsertEntryString(str.str(),0x0028,0x1053,"DS");
1784 */
1785      // dcmImageName = "c:\\toto.dcm";
1786      boost::algorithm::replace_all( dcmImageName,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
1787
1788    //FILE *fil=fopen(dcmImageName.c_str(), "a");
1789    // fclose(fil);
1790
1791    gdcm::ImageWriter writer;
1792    writer.SetFileName(dcmImageName.c_str());
1793    writer.SetFile(file);
1794   gdcm::DataElement pixeldata( gdcm::Tag(0x7fe0,0x0010) );
1795   pixeldata.SetByteValue( (char*)tabPixels ,X*Y*nbFrames*pixelSize );
1796   gdcm::Image im;
1797   im.SetDataElement(pixeldata);
1798   writer.SetImage(im);
1799
1800 //   GDCM_NAME_SPACE::FileHelper *fileH;
1801 //   fileH = GDCM_NAME_SPACE::FileHelper::New(file);
1802 //   fileH->SetContentType(contentType);   
1803 //   
1804 //   // cast is just to avoid warnings (*no* conversion is performed)
1805 //   //fileH->SetImageData((uint8_t *)img,int(maxX*maxY)*sizeof(uint16_t)); // troubles when maxX, mayY are *actually* float!
1806 //
1807 ////std::cout << "--------------------------------  X*Y*nbFrames*pixelSize " << X << " " << Y << " " << nbFrames << " " << pixelSize << std::endl; 
1808 //
1809 //   fileH->SetImageData((uint8_t *)tabPixels, X*Y*nbFrames*pixelSize);
1810 //   fileH->SetWriteModeToRaw(); 
1811 //   fileH->SetWriteTypeToDcmExplVR();
1812 //   if( !fileH->Write(dcmImageName)) {
1813 //      std::cout << "Failed for [" << dcmImageName << "]\n"
1814 //                << "           File is unwrittable" << std::endl;             
1815 //      file->Delete();
1816 //      fileH->Delete();                
1817 //      throw ( BrukerHopelessException ("Level 1 Unable to write Dicom file "));
1818 //   }
1819 //   //if (verbose)
1820 //   //   file->Print();
1821 //
1822 //   file->Delete();
1823 //   fileH->Delete();  
1824 }
1825
1826 //////////////////////////////////////////////////////////////////////
1827 // Generic repertory creation                                                            //
1828 //////////////////////////////////////////////////////////////////////
1829 const std::string  Bruker2Dicom::createDirectory(const std::string &i_name, const std::string &i_dir)
1830 {
1831
1832  // creation directory : 'nom du patient'
1833     std::string tempString(i_dir);
1834     tempString = tempString + VALID_FILE_SEPARATOR + i_name;
1835     boost::algorithm::replace_all( tempString,       INVALID_FILE_SEPARATOR ,    VALID_FILE_SEPARATOR);
1836     if (!CreateDirectory(tempString))
1837     {
1838        std::cout << "[" << tempString << "] Directory creation failure " << std::endl;
1839        throw ( BrukerHopelessException ("Patient directory creation failure "));
1840     }
1841     return tempString.c_str();
1842 }
1843
1844  std::string Bruker2Dicom::findFile(const std::string &i_dir, const  std::string i_name)
1845 {
1846     bool bres = false;
1847     std::string file;
1848      boost::filesystem::directory_iterator it(i_dir), it_end;
1849      for(; it != it_end; ++it)
1850      {
1851          if((*it).leaf() == i_name)
1852          {
1853              file = (*it).string();
1854              bres = true;
1855              break;
1856          }
1857      }
1858
1859      if(!bres)
1860      {
1861          boost::filesystem::path pth (i_dir);
1862          boost::filesystem::directory_iterator itless(pth.branch_path()), it_end;
1863          for(; itless != it_end; ++itless)
1864         {
1865             if((*itless).leaf() == i_name)
1866            {
1867                 file = (*itless).string();
1868                 bres = true;
1869                 break;
1870             }
1871         }
1872      }
1873      return file.c_str();
1874 }
1875
1876
1877 //const gdcm::DataSet Bruker2Dicom::createDataSet(const std::string &i_val,
1878 //                                                                                            const  uint16_t &i_gr, const uint16_t &i_el,
1879 //                                                                                            const gdcm::VR &i_vr)
1880 //
1881 //{
1882 //    gdcm::Attribute<i_gr, i_el> at;
1883 //    at.SetValue(i_val.c_str());
1884 //
1885 //
1886 //    gdcm::DataElement de;
1887 //    de.Clear();
1888 //    de.SetVR(i_vr);
1889 //    de.SetTag( gdcm::Tag(i_gr, i_el) );
1890 //    
1891 //    gdcm::DataSet ds;
1892 //    ds.Clear();
1893 //    ds.Replace(at.GetAsDataElement());
1894 //   return ds;
1895 //}