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