]> Creatis software - creaBruker.git/blobdiff - lib/src1/bruker2dicom.cxx
Added CMake configuration to enable CDash tests.
[creaBruker.git] / lib / src1 / bruker2dicom.cxx
index 05695f43927ab5da979b16a535df6c41b20dea40..32cb9b29bb75041a6674d21063d7d330abfc6e6f 100644 (file)
@@ -1,3 +1,29 @@
+/*
+       # ---------------------------------------------------------------------
+       #
+       # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image 
+       #                        pour la Santé)
+       # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
+       # Previous Authors : Laurent Guigues, Jean-Pierre Roux
+       # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
+       #
+       #  This software is governed by the CeCILL-B license under French law and 
+       #  abiding by the rules of distribution of free software. You can  use, 
+       #  modify and/ or redistribute the software under the terms of the CeCILL-B 
+       #  license as circulated by CEA, CNRS and INRIA at the following URL 
+       #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
+       #  or in the file LICENSE.txt.
+       #
+       #  As a counterpart to the access to the source code and  rights to copy,
+       #  modify and redistribute granted by the license, users are provided only
+       #  with a limited warranty  and the software's author,  the holder of the
+       #  economic rights,  and the successive licensors  have only  limited
+       #  liability. 
+       #
+       #  The fact that you are presently reading this means that you have had
+       #  knowledge of the CeCILL-B license and that you accept its terms.
+       # ------------------------------------------------------------------------
+*/
 #include "bruker2dicom.h"
 #include <boost/filesystem/path.hpp>
 #include <boost/filesystem/operations.hpp>
 
 bool Bruker2Dicom::Execute()
 {
+       int dimension = 1;
    // ----- Check input directory name -----
 
    bool bigEndian = GDCM_NAME_SPACE::Util::IsCurrentProcessorBigEndian();
+
    //if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(InputDirName) )
    if ( ! boost::filesystem::is_directory(InputDirName) )
    {
@@ -42,10 +69,10 @@ bool Bruker2Dicom::Execute()
 //
 
    std::string strDirNamein(InputDirName);
-   
+
 /* */
    GDCM_NAME_SPACE::DirList dirList(strDirNamein, false, true); // DON'T get recursively the list of files
-     
+
    GDCM_NAME_SPACE::DirListType fileNames;
    fileNames = dirList.GetFilenames();
 
@@ -68,23 +95,22 @@ bool Bruker2Dicom::Execute()
        acqpFound= true;
     else
        acqpFound = false; // user passed a 'non study' directory; Hope it's a 'set of studies' directory!
-       
-   int type;    
+
+   int type;
    if  (subjectFound )  type = 1; // user passed a 'study
    else if  (acqpFound) type = 2; // user passed a 'serie' 
    else                 type = 3; // user passed a 'non study' directory; Hope it's a 'set of studies' directory!
  /* */
 
-
    // 1 : if subjectFound                       : user passed a Single Study Directory
    // 2 : if NOT subjectFound and acqpFound     : user passed a Serie Directory
    // 3 : if NOT subjectFound and NOT acqpFound : user passed a 'non Study Directory' (Hope it's a set of Single Study Directories)
-   
+
    //int type = CheckUserDirectory(InputDirName);
  
    switch (type)
    {
-      case 1: {   
+      case 1: {
          bool canOpen = br_subject.LoadFile(subject);
          if (!canOpen)
          {
@@ -94,29 +120,27 @@ bool Bruker2Dicom::Execute()
          else
          {
             br_subject.FillMap();
-         }
-   //br_subject.PrintSelf();
 
-  // get info for 'Study Description'  
-
-         BrukerFieldData b_name=br_subject.GetFieldData("SUBJECT_name_string");
-         subject_name = b_name.GetStringValue()[0];
-         strPatientName = subject_name;
-         cleanString(subject_name);
-         DealWithSingleStudyDirectory (fileNames); 
+            // get info for 'Study Description'  
+            BrukerFieldData b_name=br_subject.GetFieldData("SUBJECT_name_string");
+            subject_name = b_name.GetStringValue()[0];
+            strPatientName = subject_name;
+            cleanString(subject_name);
+            DealWithSingleStudyDirectory (fileNames, dimension);
+        }
          break;
       }
 
-      case 2: {    
-           subject_name = "defaultPatName";
-          strPatientName = subject_name;
-           DealWithSingleStudyDirectory (fileNames);
-          break;
+      case 2: {
+         subject_name = "defaultPatName";
+        strPatientName = subject_name;
+         DealWithSingleStudyDirectory (fileNames, dimension);
+        break;
       }
-   
-      case 3: {  
-         std::cout << " user passed a 'non study' directory; Hope it's a 'set of studies' directory!, not yet dealt with" << std::endl;
-        DealWithMultiStudyDirectory (fileNames);
+
+      case 3: {
+         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;
+        DealWithMultiStudyDirectory (fileNames, dimension);
         break;
       }
    }
@@ -124,7 +148,7 @@ bool Bruker2Dicom::Execute()
 
 // ----------------------------------------------------------------------------------------------------------
 
-void Bruker2Dicom::DealWithMultiStudyDirectory (GDCM_NAME_SPACE::DirListType &dirNames)
+void Bruker2Dicom::DealWithMultiStudyDirectory (GDCM_NAME_SPACE::DirListType &dirNames, int dimension)
 {
    GDCM_NAME_SPACE::DirListType::iterator it;
 
@@ -133,14 +157,15 @@ void Bruker2Dicom::DealWithMultiStudyDirectory (GDCM_NAME_SPACE::DirListType &di
        ++it)
    {
       if ( boost::filesystem::is_directory(*it) )
-      { 
+      {
+         subjectFound = false;
          if (verbose)
-            std::cout << "[" << *it << "] is a directory" << std::endl;
+            std::cout << "in 'DealWithMultiStudyDirectory' [" << *it << "] is a directory" << std::endl;
 
          GDCM_NAME_SPACE::DirList dirList(*it, false, true); // DON'T get recursively the list of files
          GDCM_NAME_SPACE::DirListType fileNames;
          fileNames = dirList.GetFilenames();
-        
+
          std::string path = GDCM_NAME_SPACE::Util::GetPath(*(fileNames.begin()));
          std::string subject =  path +
                                 GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
@@ -150,7 +175,7 @@ void Bruker2Dicom::DealWithMultiStudyDirectory (GDCM_NAME_SPACE::DirListType &di
            std::cout << "no [" << subject << "] file found" << std::endl;
            continue;
          }
-                  
+
          bool canOpen = br_subject.LoadFile(subject);
          if (!canOpen)
          {
@@ -160,14 +185,14 @@ void Bruker2Dicom::DealWithMultiStudyDirectory (GDCM_NAME_SPACE::DirListType &di
          else
          {
             br_subject.FillMap();
-         }
-          
-         BrukerFieldData b_name=br_subject.GetFieldData("SUBJECT_name_string");
-         subject_name = b_name.GetStringValue()[0];
-         strPatientName = subject_name;
-         cleanString(subject_name);     
-         
-         DealWithSingleStudyDirectory(fileNames);   
+           subjectFound = true; // Hope so! (full checking needed!)
+
+            BrukerFieldData b_name=br_subject.GetFieldData("SUBJECT_name_string");
+            subject_name = b_name.GetStringValue()[0];
+            strPatientName = subject_name;
+            cleanString(subject_name);  
+            DealWithSingleStudyDirectory(fileNames,dimension);
+        }  
       }
       else
       {
@@ -179,13 +204,15 @@ void Bruker2Dicom::DealWithMultiStudyDirectory (GDCM_NAME_SPACE::DirListType &di
 
 // ----------------------------------------------------------------------------------------------------------
 
-void Bruker2Dicom::DealWithSingleStudyDirectory (GDCM_NAME_SPACE::DirListType &fileNames)
+void Bruker2Dicom::DealWithSingleStudyDirectory (GDCM_NAME_SPACE::DirListType &fileNames, int dimension)
 {
      bool res;  
     // creation directory : 'nom du patient'
     std::string tempStringPatDir(OutputDirName);
-    tempStringPatDir = tempStringPatDir + GDCM_NAME_SPACE::GDCM_FILESEPARATOR + subject_name;
-        
+
+    tempStringPatDir = tempStringPatDir + "/"+ subject_name;
+               //GDCM_NAME_SPACE::GDCM_FILESEPARATOR + subject_name; //FCY TO MODIFY
+
     res=CreateDirectory(tempStringPatDir);
     if (!res) {
        std::cout << "[" << tempStringPatDir << "] Directory creation failure " << std::endl;
@@ -223,19 +250,22 @@ void Bruker2Dicom::DealWithSingleStudyDirectory (GDCM_NAME_SPACE::DirListType &f
       subject_study_name = "defStudyName";         // Why not? 
    }
     // subject_name is already in 'Patient Name' 
-    strStudyDescr = /*subject_name + "." + */ subject_study_name + "." + subject_entry + "." + subject_position + "." + subject_date;
-   
+    if (0) // We don't realy need so much information for 'Study'
+       strStudyDescr = /*subject_name + "." + */ subject_study_name + "." + subject_entry + "." + subject_position + "." + subject_date;
+    else
+       strStudyDescr = /*subject_name + "." + */ subject_study_name /*+ "." + subject_entry + "." + subject_position + "." + subject_date*/;
+
     // creation directory : 'nom de la Study'
-    
+
     std::string tempStringStudyDir(OutputDirName);
     tempStringStudyDir = tempStringPatDir + GDCM_NAME_SPACE::GDCM_FILESEPARATOR + strStudyDescr;
-        
+
     res=CreateDirectory(tempStringStudyDir);
     if (!res) {
        std::cout << "[" << tempStringStudyDir << "] Directory creation failure " << std::endl;
        throw ( BrukerHopelessException ("Study directory creation failure "));
     }    
-   
+
    char outputDirName[(unsigned int) PATH_MAX+2];
 
    strStudyUID    = GDCM_NAME_SPACE::Util::CreateUniqueUID();
@@ -247,7 +277,8 @@ void Bruker2Dicom::DealWithSingleStudyDirectory (GDCM_NAME_SPACE::DirListType &f
    // (this is level ZERO)
    // each Directory (name : 1, 2, 3, ...) will be a Dicom Serie
    // -----------------------------------------------------
+
+   /// \TODO better use directory iterator, from boost! // JPR
    GDCM_NAME_SPACE::DirListType::iterator it;
 
    for (it = fileNames.begin();
@@ -259,7 +290,8 @@ void Bruker2Dicom::DealWithSingleStudyDirectory (GDCM_NAME_SPACE::DirListType &f
          if (verbose)
             std::cout << "[" << *it << "] is a directory" << std::endl;
 
-        if((*it) == "AdjStatePerStudy")  // avoid trouble with new version 'AdjStatePerStudy' directory
+        //if((*it) == "AdjResult")  // avoid trouble with new version 'AdjResult' directory
+        if(GDCM_NAME_SPACE::Util::GetName(*it) == "AdjResult")
            continue;
 
          //BrukerDataSet br_acqp;
@@ -290,13 +322,13 @@ void Bruker2Dicom::DealWithSingleStudyDirectory (GDCM_NAME_SPACE::DirListType &f
          BrukerFieldData b_method=br_acqp.GetFieldData("ACQ_method");
         b_method.PrintSelf();
          acqp_method = b_method.GetStringValue()[0];
-  
+
          cleanString(acqp_method);
 //std::cout << "out of br_acqp.FillMap 3" << std::endl;
          BrukerFieldData b_list_size = br_acqp.GetFieldData("ACQ_O1_list_size");
 //std::cout << "out of br_acqp.FillMap 4" << std::endl;        
         //b_list_size.PrintSelf(); //JP
+
          nbSlices =  b_list_size.GetIntValue()[0];
 //std::cout << "out of br_acqp.FillMap 5" << std::endl;
          strSerieDescr = GDCM_NAME_SPACE::Util::GetName(*it)
@@ -307,7 +339,7 @@ void Bruker2Dicom::DealWithSingleStudyDirectory (GDCM_NAME_SPACE::DirListType &f
          sprintf(outputDirName, "%s%c%s", tempStringStudyDir.c_str(),      //OutputDirName.c_str(), 
                           GDCM_NAME_SPACE::GDCM_FILESEPARATOR,
                           strSerieDescr.c_str() );
-  
+
          std::cout << " ================================================================================\n"
                    << " === [" << GDCM_NAME_SPACE::Util::GetName(*it) << "] -> [" << strSerieDescr << "]\n"
                    << " ================================================================================"
@@ -316,7 +348,7 @@ void Bruker2Dicom::DealWithSingleStudyDirectory (GDCM_NAME_SPACE::DirListType &f
         if (verbose)
            printf ("outputDirName [%s]\n", outputDirName);
         try {
-           DealWithNiveau1(*it, strOutputDirName);
+           DealWithNiveau1(*it, strOutputDirName, dimension);
        }
        catch (BrukerHopelessException &e)
        {
@@ -329,7 +361,7 @@ void Bruker2Dicom::DealWithSingleStudyDirectory (GDCM_NAME_SPACE::DirListType &f
 
 // =====================================================================
 
-void Bruker2Dicom::DealWithNiveau1(std::string &level1Directory, std::string &currentOutputDirName) {
+void Bruker2Dicom::DealWithNiveau1(std::string &level1Directory, std::string &currentOutputDirName, int dimension) {
 //
 // e.g. : at level 1, in B67d1.Bp1/6
 //
@@ -388,7 +420,7 @@ void Bruker2Dicom::DealWithNiveau1(std::string &level1Directory, std::string &cu
          sprintf(outputDirName, "%s%c%s", currentOutputDirName.c_str(),
                                           GDCM_NAME_SPACE::GDCM_FILESEPARATOR,
                                           GDCM_NAME_SPACE::Util::GetName(*it).c_str());
-        std::string strOutputDirName(outputDirName);
+         std::string strOutputDirName(outputDirName);
          //br1.PrintSelf();
 
           std::string strMethod;
@@ -429,9 +461,9 @@ void Bruker2Dicom::DealWithNiveau1(std::string &level1Directory, std::string &cu
           ##$PVM_NSPacks=2
           ##$PVM_SPackArrNSlices=( 2 )
           7 1  
-  */    
+  */
          try {
-            DealWithNiveau2(*it, strOutputDirName);
+            DealWithNiveau2(*it, strOutputDirName, dimension);
         }
         catch (BrukerHopelessException &e)
         {
@@ -444,7 +476,7 @@ void Bruker2Dicom::DealWithNiveau1(std::string &level1Directory, std::string &cu
 
 // =====================================================================
 
-void Bruker2Dicom::DealWithNiveau2(std::string &level2Directory, std::string &currentOutputDirName) {
+void Bruker2Dicom::DealWithNiveau2(std::string &level2Directory, std::string &currentOutputDirName, int dimension) {
 
 // e.g. : at level 2 in B67d1.Bp1/6/pdata
 //
@@ -482,38 +514,38 @@ void Bruker2Dicom::DealWithNiveau2(std::string &level2Directory, std::string &cu
          std::cout << "--- --- [" << *it << "] is a file.." << std::endl;
       }
    }
-  
+
    for (it = fileNames.begin();
          it != fileNames.end();
        ++it)
    {
       if ( boost::filesystem::is_directory(*it) )
-      { 
-  
+      {
+
          if (verbose)
             std::cout << "--- --- [" << *it << "] is a directory" << std::endl;
 
-        // sprintf(outputDirName, "%s%c%s", currentOutputDirName.c_str(), 
+        // sprintf(outputDirName, "%s%c%s", currentOutputDirName.c_str(),
         //                          GDCM_NAME_SPACE::GDCM_FILESEPARATOR,
         //                                GDCM_NAME_SPACE::Util::GetName(*it).c_str() );
   // MUST be 'pdata'!
 
 //
 // (interest of previous method :
-// If unaware user changed the pdata name, it goes on working   
+// If unaware user changed the pdata name, it goes on working
 //
           std::string str_isa;
           str_isa = (*it) + 
                     GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
                    "isa";
 
-          std::string str_isa_func_name;    
+          std::string str_isa_func_name;
           canOpen = br_isa.LoadFile(str_isa);
           if (!canOpen)
           {
              sprintf(outputDirName, "%s%c%s", currentOutputDirName.c_str(), 
                                           GDCM_NAME_SPACE::GDCM_FILESEPARATOR,
-                                          GDCM_NAME_SPACE::Util::GetName(*it).c_str() );        
+                                          GDCM_NAME_SPACE::Util::GetName(*it).c_str() );
           }
           else
           {
@@ -530,7 +562,7 @@ void Bruker2Dicom::DealWithNiveau2(std::string &level2Directory, std::string &cu
           }
          std::string strOutputDirName(outputDirName);
          try {
-             DealWithNiveau3(*it, strOutputDirName);
+             DealWithNiveau3(*it, strOutputDirName, dimension);
          }
          catch (BrukerHopelessException &e)
          {
@@ -543,7 +575,7 @@ void Bruker2Dicom::DealWithNiveau2(std::string &level2Directory, std::string &cu
             std::cout << "And Init Exception was thrown in DealWithNiveau3 (" << e.what() << "); " 
                       << " We skip [" << level2Directory << "]" << std::endl;
             continue;
-         }          
+         }
       }
    }
 }
@@ -552,7 +584,7 @@ void Bruker2Dicom::DealWithNiveau2(std::string &level2Directory, std::string &cu
 // =====================================================================
 //
 
-void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &currentOutputDirName){
+void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &currentOutputDirName, int dimension){
 
 //
 // e.g. at level 3, in
@@ -594,7 +626,7 @@ void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &cu
 
    if (verbose)
       std::cout << "d3proc: --- => [" << char_d3proc << "]" << std::endl;
-   std::string str_d3proc(char_d3proc);       
+   std::string str_d3proc(char_d3proc);     
    canOpen = br_d3proc.LoadFile(str_d3proc);
 
    if (!canOpen)
@@ -609,7 +641,7 @@ void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &cu
    {
       std::cout << "Hopeless! FillMap failed on 'd3proc'" << std::endl;
       throw ( BrukerHopelessException ("Hopeless! FillMap failed on 'd3proc'"));      
-      //exit(0);  /// \TODO throw an exception !     
+      //exit(0);  /// \TODO throw an exception !
    }
 
    //-------------- end try d3proc;
@@ -625,7 +657,7 @@ void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &cu
     //             "d3proc";
    if (verbose)
       std::cout << "reco: --- => [" << char_reco << "]" << std::endl;
-      
+
    std::string str_reco(char_reco);
    canOpen = br_reco.LoadFile(str_reco);
 
@@ -648,7 +680,7 @@ void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &cu
       if (verbose)
          std::cout << "[" << str_reco << "] successfully Loaded " << std::endl;
    }
-   
+
    canOpen = br_reco.FillMap();
    if (!canOpen)
    {
@@ -658,8 +690,8 @@ void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &cu
    } else {
       if (verbose)
          std::cout << "[" << str_reco << "] successfully Mapped" << std::endl;
-   }   
-   
+   }
+
    //std::cout << "------------------------------------------------------------------------------------------------" << std::cout;
    // br_reco.PrintSelf();
    // std::cout << "------------------------------------------------------------------------------------------------" << std::cout;
@@ -710,28 +742,39 @@ void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &cu
    double spatResolY = spatResol.GetDoubleValue()[1];
    if (verbose)
       std::cout << "SpatResol (ds method) " << spatResolX << " " << spatResolY << std::endl;
-          
+     
 */
 
 /* ------  */
 // Better we use 'get' accessors from BrukerImage class, as Denis wrote them
 
    BrukerFieldData fov = br_reco.GetFieldData("RECO_fov");
-   double fovX = fov.GetDoubleValue()[0];
-   double fovY = fov.GetDoubleValue()[1];
+
+   double fovX;
+   double fovY;
+   fovX= fov.GetDoubleValue()[0];
+   if(fov.GetDoubleValue().size() > 1)
+        fovY = fov.GetDoubleValue()[1];
    if (verbose)
       std::cout << "FOV (ds reco) " << fovX << " " << fovY << std::endl;
 
    BrukerFieldData size = br_reco.GetFieldData("RECO_size");
-   double sizeX = size.GetDoubleValue()[0];
-   double sizeY = size.GetDoubleValue()[1];
+   double sizeX;
+   double sizeY;
+   sizeX = size.GetDoubleValue()[0];
    
+   if(fov.GetDoubleValue().size() > 1)
+    sizeY = size.GetDoubleValue()[1];
+
    if (verbose)
       std::cout << "SIZE (ds reco) " << sizeX << " " << sizeY << std::endl;
-       
-   double spatResolX = fovX / sizeX;
-   double spatResolY = fovY / sizeY;
-       
+
+   double spatResolX;
+   double spatResolY;
+   spatResolX = fovX / sizeX;
+    if(fov.GetDoubleValue().size() > 1)
+    spatResolY = fovY / sizeY;
+
    if (verbose)
       std::cout << "spatResol (ds reco : fov/size) " << spatResolX << " " << spatResolY << std::endl;
 
@@ -739,10 +782,12 @@ void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &cu
 
    /// \TODO probabely a more sophisticated accessor will be necessary :
    ///  (cf : non contiguous slices, overlapping, slice thickness, space between slices, etc)
-   
+   double sliceDistance;
+   if(dimension > 1)
+   {
    BrukerFieldData bsliceDistance = br_method.GetFieldData("PVM_SPackArrSliceDistance");
-   double sliceDistance = bsliceDistance.GetDoubleValue()[0];
-   
+    sliceDistance = bsliceDistance.GetDoubleValue()[0];
+   }
    if (verbose)
       std::cout << "SPackArrSliceDistance (ds method) " << sliceDistance << std::endl;   
 
@@ -752,8 +797,8 @@ void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &cu
    {
       sprintf(currentOutputMhdDirName, "%s%c%s", currentOutputDirName.c_str(),
                                GDCM_NAME_SPACE::GDCM_FILESEPARATOR, "MhdFiles");
-      std::string strCurrentOutputMhdDirName(currentOutputMhdDirName);
 
+      std::string strCurrentOutputMhdDirName(currentOutputMhdDirName);
       res = CreateDirectory( strCurrentOutputMhdDirName );
       if (!res) {
          std::cout << "[" << currentOutputDirName << "] Directory creation failure " << std::endl;
@@ -770,6 +815,8 @@ void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &cu
    if (verbose)
          std::cout << "nbSlices " << nbSlices << std::endl;
    int k;
+   if(dimension ==1)
+          nbSlices = 1;
    int nbInstants = nbFrames/nbSlices;
    if (verbose)
          std::cout << "nbInstants (deduced)" << nbInstants << std::endl;    
@@ -807,7 +854,7 @@ void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &cu
    // This one will be important!
    // ---------------------------
    try {
-      imageSet = CreateImageSet ( );
+      imageSet = CreateImageSet ( dimension);
    }
    catch (BrukerInitException& e)
    {
@@ -844,7 +891,7 @@ void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &cu
                fprintf(fp, "DimSize = %d %d %d\n", NX, NY, nbSlices );
                fprintf(fp, "HeaderSize = %d\n", 0);
                //fprintf(fp, "ElementSpacing = %lf %lf %lf\n",fovX/NY, fovY/NY, sliceDistance );
-              fprintf(fp, "ElementSpacing = %lf %lf %lf\n", spatResolX, spatResolY, sliceDistance );
+               fprintf(fp, "ElementSpacing = %lf %lf %lf\n", spatResolX, spatResolY, sliceDistance );
                fprintf(fp, "Position = 0 0 %d\n", 0 );
                fprintf(fp, "Offset = 0 0 0\n" );
                fprintf(fp, "CenterOfRotation = 0 0 0\n" );
@@ -958,7 +1005,7 @@ void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &cu
                             1, fp);
                }
                fclose(fp);
-              
+
 // std::cout << "end writting[" << output2dseqSliceFileName << "]" << std::endl;
             }  // end if mhd
    
@@ -983,7 +1030,7 @@ void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &cu
                             1, fp);
                }
                fclose(fp);
-       
+
                fp=fopen(output2dseqSliceFileName, "rb");
                if (!fp)
                {     
@@ -998,7 +1045,7 @@ void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &cu
               */
 
                /* ----------- Write Dicom Image  ---------------*/
-       
+
                int frameSize = NX*NY*pixelSize;
                for (instantNb=0; instantNb<nbInstants; instantNb++)
                {
@@ -1049,7 +1096,6 @@ void Bruker2Dicom::DealWithNiveau3(std::string &level3Directory, std::string &cu
                    copyFile, currentOutputDirName, outputMhdFileName, output2dseqCartoName);
 }
 
-
 // ===========================================================================================
 
 void Bruker2Dicom::dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX, int NY, int nbSlices, 
@@ -1061,7 +1107,7 @@ void Bruker2Dicom::dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX
    // -----------------------------------------------------
    //  deal with MatLab-generated Carto file.
    // -----------------------------------------------------
-   
+
    const char *code[] = { "ADC", "adc", "TTP", "ttp", "PEAK", "peak", "" };  // add more carto file name identifiers if necessary; end with ""
    const char *separator[] =  { "_", ".", "-", "" }; //  add more, if necessary, to ckeck for 2dseq.ADC, 2dseq_ADC, 2dseq-ADC, etc; end with ""
    int icode;
@@ -1182,7 +1228,7 @@ void Bruker2Dicom::dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX
                if (verbose) 
                   std::cout << "--- End writing Carto DICOM file [" << output2dseqCartoName << "]" << std::endl;
                break; // don't check for more ident on same file name!
-           
+
             }  // end deal with _ADC, -adc, etc
           iseparator ++;
           }  // end iterate speparators
@@ -1192,13 +1238,12 @@ void Bruker2Dicom::dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX
    } // end iterate on all objects (files, dir, etc)
 } // end method
 
-
 // ==========================================================================================================
 
 int Bruker2Dicom::CheckUserDirectory(std::string &userDirName)
 {
    GDCM_NAME_SPACE::DirList dirList(userDirName, false, true); // DON'T get recursively the list of files
-     
+
    GDCM_NAME_SPACE::DirListType fileNames;
    fileNames = dirList.GetFilenames();
 
@@ -1221,7 +1266,7 @@ int Bruker2Dicom::CheckUserDirectory(std::string &userDirName)
        acqpFound= true; // user passes a 'serie', not a 'study' 
     else
        acqpFound = false; // user passed a 'non study' directory; Hope it's a 'set of studies' directory!
-   
+
    int type;    
    if  (subjectFound )  type = 1; // user passed a 'study
    else if  (acqpFound) type = 2; // user passed a 'serie' 
@@ -1230,9 +1275,8 @@ int Bruker2Dicom::CheckUserDirectory(std::string &userDirName)
    return type;   
 }
 
-
 // ==========================================================================================================
-  
+
 bool Bruker2Dicom::CreateDirectory(std::string &OutputDirName)
 {
    std::string systemCommand;
@@ -1267,7 +1311,6 @@ bool Bruker2Dicom::CreateDirectory(std::string &OutputDirName)
    return 1;
 }
 
-
 // ===========================================================================================
 
 /// \TODO move cleanString to 'crea' ?
@@ -1285,10 +1328,10 @@ void Bruker2Dicom::cleanString(std::string &s)
       l--;
       s = s.substr(0, l);
    }   
-   
+
    if (s[0] == '<')      
       s= s.substr(1,l-2);
-   std::string repChar("_");   
+   std::string repChar("_");
    GDCM_NAME_SPACE::Util::ReplaceSpecChar(s, repChar);
 }
 
@@ -1344,7 +1387,7 @@ void Bruker2Dicom::getImhDataType(BrukerFieldData &bDPT, std::string &mhdDataPix
 // Cross your fingers !!!
 
 // pb : found values : 2, 3, 5
-         
+
          if (brukerDataPixelType ==  2) {
             mhdDataPixelType = "MET_USHORT";
             pixelSize = 2;
@@ -1362,18 +1405,18 @@ void Bruker2Dicom::getImhDataType(BrukerFieldData &bDPT, std::string &mhdDataPix
 
 // ===========================================================================================
 
-std::vector<BrukerImage> Bruker2Dicom::CreateImageSet ( )
+std::vector<BrukerImage> Bruker2Dicom::CreateImageSet ( int dimension)
 {
          std::vector<BrukerImage> imageSet;      
-         br_acqp.SetLoopStructure();
+         br_acqp.SetLoopStructure(dimension);
          std::vector<int> tempVect                      = br_acqp.GetLoopStructure() ;
          std::map<std::string, BrukerFieldData> map     = br_acqp.GetBrukerHeaderMap();
-        
+
          bool result                                    = br_acqp.ObjectVaryingProperties.init(map,tempVect);
+
          if (result == false)
         {
-           throw ( BrukerInitException  ("ObjectVaryingProperties.init() failure in Bruker2Dicom::CreateImageSet()") );
+           throw ( BrukerInitException ("ObjectVaryingProperties.init() failure in Bruker2Dicom::CreateImageSet()") );
         }
 
          br_acqp.SetImageLoopStructure();
@@ -1382,22 +1425,22 @@ std::vector<BrukerImage> Bruker2Dicom::CreateImageSet ( )
 
          BrukerImage image(br_acqp,br_reco);
          image.Init(br_acqp,br_reco,1); 
+
          for(int i=0;i<brukerImageList.size();i++)
          {
             image.Init(br_acqp,br_reco,i);    
             imageSet.push_back(image);
          }
+
  // Just for checking
  /*
+
          std::vector<std::vector <double> > imageOrientation;
          std::vector <double> imagePosition; 
          for(int i=0;i<brukerImageList.size();i++)
          {
            // fread(buffer_2dseq, NX*NY*pixelSize*nbSlices*nbInstants, 1, fp);   
-   
+
            imagePosition = imageSet[i].getTranslationVectorRPS2XYZ();
            std::cout << "Position " << imagePosition[0] << " " 
                      << imagePosition[1] << " "  << imagePosition[2] ;
@@ -1405,7 +1448,7 @@ std::vector<BrukerImage> Bruker2Dicom::CreateImageSet ( )
            std::cout << "\t  Orientation " ;
            for(int i1=0; i1<3;i1++)for(int i2=0; i2<3;i2++)
               std::cout << imageOrientation[i1][i2] << " ";CreateImageSet
-       
+
            //std::cout << "\t  Abs Time " << imageSet[i].getAbsoluteTimePosition();
            std::cout << "\t  Relat Time " << imageSet[i].getRelativeTimePosition();
 
@@ -1435,14 +1478,14 @@ void Bruker2Dicom::MakeDicomImage(unsigned char *tabPixels,
               std::string &serieDescr,
               std::string &strStudyTimeDate,
               int imgNum,
-              GDCM_NAME_SPACE::ImageContentType contentType 
+              GDCM_NAME_SPACE::ImageContentType contentType
       )
 {  
    std::ostringstream str;
 
    GDCM_NAME_SPACE::File *file;
-   file = GDCM_NAME_SPACE::File::New();       
-      
+   file = GDCM_NAME_SPACE::File::New();
+
   // Set the image size
    str.str(""); 
    str << X;
@@ -1461,7 +1504,9 @@ void Bruker2Dicom::MakeDicomImage(unsigned char *tabPixels,
   // Set the pixel type
   //      //8, 16, 32, 64 (for double ?)
    str.str("");
-   str << pixelSize*8;     
+   str << pixelSize*8;
+
+  // Bits Allocated
    file->InsertEntryString(str.str(),0x0028,0x0100,"US"); // Bits Allocated
 
    file->InsertEntryString(str.str(),0x0028,0x0101,"US"); // Bits Stored
@@ -1472,7 +1517,7 @@ void Bruker2Dicom::MakeDicomImage(unsigned char *tabPixels,
 
   // Set the pixel representation // 0/1 , 0=unsigned
    file->InsertEntryString("1",0x0028,0x0103, "US"); // Pixel Representation
-   
+
   // Set the samples per pixel // 1:Grey level, 3:RGB
    file->InsertEntryString("1",0x0028,0x0002, "US"); // Samples per Pixel
 
@@ -1480,25 +1525,25 @@ void Bruker2Dicom::MakeDicomImage(unsigned char *tabPixels,
    str.str("");
    str << spacingX << "\\" << spacingY;
    file->InsertEntryString(str.str(),0x0028,0x0030, "DS"); // Pixel Spacing     
-   
+
  //   0018 0050 DS 1 Slice Thickness 
    str.str("");    
    str << sliceDistance;
    file->InsertEntryString(str.str(),0x0018,0x0050, "DS"); 
-   
+
 //    0020 0011 IS 1 Series Number
    str.str("");    
    str << serieNumber;
    file->InsertEntryString(str.str(),0x0020,0x0011, "IS");
-      
+
 //    0020|0013 [IS]  [Instance Number] 
    instanceNumber++;
    str.str("");    
    str << instanceNumber;
    file->InsertEntryString(str.str(),0x0020,0x0013, "IS");
-     
+
   // 1.2.840.10008.5.1.4.1.1.4.1 : Enhanced MR Image Storage
- //  file->InsertEntryString("1.2.840.10008.5.1.4.1.1.4.1" , 0x0002, 0x0002, "UI");  // [Media Storage SOP Class UID]
 //  file->InsertEntryString("1.2.840.10008.5.1.4.1.1.4.1" , 0x0002, 0x0002, "UI");  // [Media Storage SOP Class UID]
   // file->InsertEntryString("1.2.840.10008.5.1.4.1.1.4.1" , 0x0008, 0x0016, "UI");  // [SOP Class UID]
 
 // OK : MR is NOT multiframe, but I want just a quick an dirty solution
@@ -1513,7 +1558,7 @@ void Bruker2Dicom::MakeDicomImage(unsigned char *tabPixels,
 
    file->InsertEntryString(studyUID, 0x0020, 0x000d, "UI");
    file->InsertEntryString(serieUID, 0x0020, 0x000e, "UI");
-   
+
 //  0008 0020 DA 1 Study Date
 //  0008 0030 TM 1 Study Time
 
@@ -1546,7 +1591,7 @@ std::cout << "charImageOrientation  " <<
                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][0],
                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][1],
                               imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][2] ) ;
-    
+
    file->InsertEntryString(charImageOrientation,0x0020,0x0037, "DS");
 
 // 0020 0032 DS 3 Image Position (Patient) 
@@ -1556,9 +1601,95 @@ std::cout << "charImageOrientation  " <<
                              imageSet[imgNum].getTranslationVectorRPS2XYZ()[0], 
                              imageSet[imgNum].getTranslationVectorRPS2XYZ()[1],
                              imageSet[imgNum].getTranslationVectorRPS2XYZ()[2]);
-  
+
    file->InsertEntryString(charImagePosition,0x0020,0x0032, "DS");  //0020 0032 DS 3 Image Position (Patient) 
 
+   // Private creator
+   /*
+
+0029|0010 [LO]   [Private Creator] [CREATIS HEADER ]
+0029|0011 [LO]   [Private Creator] [CREATIS for BRUKER to DICOM]
+0029|1031 [LO]   [] [4.0.7571167 ]
+0029|1032 [UL]   [] [1440000] =0x(15f900)
+
+> $$ Thu Jul 30 17:29:46 2009 CEST (UT+2h)  mwiart
+> $$ /opt/PV4.0/data/mwiart/nmr/dha80.Uw1/4/method
+> ##$Method=DtiEpi
+> ##$PVM_DwNDiffDir=3             % 3 directions
+> ##$PVM_DwNDiffExpEach=2         % 2 valeurs de b par direction
+> ##$PVM_DwAoImages=1             % 1 image pour b=0
+> ##$PVM_DwBvalEach=( 2 )         % Valeurs de b
+> 1500.000000 3000.000000
+>
+> $$ Wed Dec  2 09:56:01 2009 UTC (UT+0h)  mwiart
+> $$ /opt/Pv5.0/data/mwiart/nmr/ECI7.Wx1/4/method
+> ##$Method=DtiEpi
+> ##$PVM_DwNDiffDir=3             % 3 directions
+> ##$PVM_DwNDiffExpEach=2         % 2 valeurs de b par direction
+> ##$PVM_DwAoImages=1             % 1 image pour b=0
+> ##$PVM_DwBvalEach=( 2 )         % Valeurs de b
+> 1500 3000
+>
+> $$ Wed Dec  2 10:14:27 2009 UTC (UT+0h)  mwiart
+> $$ /opt/Pv5.0/data/mwiart/nmr/ECI7.Wx1/5/method
+> ##$Method=DtiStandard
+> ##$PVM_DwNDiffDir=1             % 1 direction
+> ##$PVM_DwNDiffExpEach=2         % 2 valeurs de b
+> ##$PVM_DwAoImages=0             % 0 image pour b=0
+> ##$PVM_DwBvalEach=( 2 )         % Valeurs de b
+> 138 1600
+>
+   */
+
+   file->InsertEntryString("CREATIS HEADER", 0x0029,0x0010, "LO");
+   file->InsertEntryString("CREATIS FOR BRUKER-TO-DICOM", 0x0029,0x0011, "LO");
+
+   BrukerFieldData brf_method            = br_method.GetFieldData("Method");
+   const std::vector<std::string> method = brf_method.GetStringValue();
+
+  // std::string method = br_method.GetFieldData("Method").GetStringValue();    
+   file->InsertEntryString(method[0], 0x0029,0x0100, "LO");
+
+   std::cout << " method[" << method[0]  << "]" << std::endl;
+   if (method[0] == "DtiEpi" || method[0] == "DtiStandard")
+   {
+     // const std::vector<int> NDiffDir       = br_method.GetFieldData("PVM_DwNDiffDir").GetIntValue();
+      BrukerFieldData brf_NDiffDir    = br_method.GetFieldData("PVM_DwNDiffDir");
+      const std::vector<int> NDiffDir = brf_NDiffDir.GetIntValue();
+
+      //const std::vector<int> NDiffExpEach   = br_method.GetFieldData("PVM_DwNDiffExpEach").GetIntValue();
+      BrukerFieldData brf_NDiffExpEach      = br_method.GetFieldData("PVM_DwNDiffExpEach");
+      const std::vector<int> NDiffExpEach   =brf_NDiffExpEach.GetIntValue();
+
+//      const std::vector<int> AoImages     = br_method.GetFieldData("PVM_DwAoImages").GetIntValue();
+      BrukerFieldData brf_AoImages        = br_method.GetFieldData("PVM_DwAoImages");
+      const std::vector<int> AoImages     = brf_AoImages.GetIntValue();
+
+      BrukerFieldData brf_DwBvalEach       = br_method.GetFieldData("PVM_DwBvalEach");
+      const std::vector<double> DwBvalEach = brf_DwBvalEach.GetDoubleValue();
+
+ std::cout << "nb directions : " <<  NDiffDir[0] << " nb valeurs de b par direction : " << NDiffExpEach[0] 
+           << " nb images for b=0 : " << AoImages[0] << std::endl;
+
+       str.str(""); 
+       str << NDiffDir[0];
+       file->InsertEntryString(str.str(),0x0029,0x0101,"US"); // nb de directions
+       str.str(""); 
+       str << NDiffExpEach[0];
+       file->InsertEntryString(str.str(),0x0029,0x0102,"US"); // nb valeurs de b par direction       
+       str.str(""); 
+       str << AoImages[0];
+       file->InsertEntryString(str.str(),0x0029,0x0103,"US"); // nb images pour b=0
+
+       str.str("");
+       for (unsigned int i=0; i<NDiffExpEach[0]; i++) {
+          str << DwBvalEach[i];
+          if (i!=AoImages[0])
+             str << "\\";
+      }
+      file->InsertEntryString(str.str(),0x0029,0x0104,"DS"); // Valeurs de b
+   }   
+
 // 0020 0x1041 DS 1 Slice Location 
 //        sprintf(charImagePosition,"%f",float(imgNum));
 //        file->InsertEntryString(charImagePosition,0x0020,0x1041, "DS");   
@@ -1576,8 +1707,8 @@ std::cout << "charImageOrientation  " <<
 
    GDCM_NAME_SPACE::FileHelper *fileH;
    fileH = GDCM_NAME_SPACE::FileHelper::New(file);
-   fileH->SetContentType(contentType);   
-    
+   fileH->SetContentType(contentType);
+
    // cast is just to avoid warnings (*no* conversion is performed)
    //fileH->SetImageData((uint8_t *)img,int(maxX*maxY)*sizeof(uint16_t)); // troubles when maxX, mayY are *actually* float!