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