--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+###################################
+PROJECT(creaBruker)
+###################################
+
+#==================================
+# The project version
+SET(PROJECT_MAJOR_VERSION 1)
+SET(PROJECT_MINOR_VERSION 0)
+SET(PROJECT_BUILD_VERSION 0)
+#==================================
+
+#==================================
+# Find crea (mandatory to use macros)
+SET(CREA_VERBOSE_CMAKE TRUE)
+FIND_PACKAGE(crea REQUIRED)
+IF (crea_FOUND)
+ INCLUDE(${crea_USE_FILE})
+ENDIF(crea_FOUND)
+#==================================
+
+#==================================
+# Do not allow to build inside the source tree
+CREA_PREVENT_IN_SOURCE_BUILD()
+#==================================
+
+#==================================
+# Libraries/tools used
+# Note : Set USE_CREA to ON
+# if you need to LINK against crea
+# (and not only use its macros)
+SET(USE_CREA ON)
+SET(USE_GDCM ON)
+SET(USE_GDCM_VTK OFF)
+SET(USE_GDCM2 OFF)
+SET(USE_WXWIDGETS OFF)
+SET(USE_KWWIDGETS OFF)
+SET(USE_VTK OFF)
+SET(USE_ITK OFF)
+SET(USE_BOOST ON)
+SET(USE_DOXYGEN ON)
+SET(USE_LATEX OFF)
+SET(USE_TTH OFF)
+
+CREA_FIND_AND_USE_LIBRARIES()
+#==================================
+
+#==================================
+# Where to put executables and libs
+SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
+SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
+MARK_AS_ADVANCED(
+ CMAKE_BACKWARDS_COMPATIBILITY
+ EXECUTABLE_OUTPUT_PATH
+ LIBRARY_OUTPUT_PATH
+ )
+#==================================
+
+ SET(LIBNAME $(PROJECT_NAME))
+ INCLUDE_DIRECTORIES(
+ ${PROJECT_BINARY_DIR}
+ ${PROJECT_SOURCE_DIR}/lib/src1
+ )
+#==================================
+# Subdirs
+SUBDIRS(lib)
+SUBDIRS(appli)
+
+#==================================
--- /dev/null
+
+SUBDIRS(
+# ==> mettez ici la liste des directories qui contiennent
+# ==> les fichiers sources de chacune de vos applications
+# ==> Selon que l'application utilise ou non wX, vous duppliquerez
+# ==> l'un ou l'autre des directories WithWx ou WithoutWx
+#
+# ==> Here, the list of the directories that hold
+# ==> the source files of each one of your applications
+# ==> Depending on the use or not of Wx,
+# ==> You will dupplicate WithWx or WithoutWx
+#
+ essaiDenis
+ #SimpleBrukerToMhdDcm
+ PrintParameterFile
+ #exObjectVaryingProperties
+ testBruker2Dicom
+ #appli1_WithoutWx
+ #appli2_WithWx
+
+ # some more directories, if you have more appli
+)
--- /dev/null
+
+ #----------------------------------------------------------------------------
+# SET THE NAME OF YOUR EXECUTABLE
+SET ( EXE_NAME PrintParameterFile )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# EXECUTABLE SOURCES (TO BE COMPILED)
+# EITHER LIST ALL .cxx, *.cpp, *.cc IN CURRENT DIR USING NEXT LINE:
+FILE(GLOB ${EXE_NAME}_SOURCES *.cxx *.cpp *.cc)
+# OR MANUALLY LIST YOUR FILES WITH NEXT COMMAND (WITHOUT EXTENSION)
+# SET ( ${EXE_NAME}_SOURCES
+#
+# )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# DEPENDENCIES (LIBRARIES TO LINK WITH)
+SET ( ${EXE_NAME}_LINK_LIBRARIES
+ ${crea_LIBRARIES}
+ # ${WXWIDGETS_LIBRARIES}
+ # ${KWWidgets_LIBRARIES}
+ # ${VTK_LIBRARIES}
+ # ${ITK_LIBRARIES}
+ ${GDCM_LIBRARIES}
+ ${BOOST_LIBRARIES}
+
+ creaBruker
+ )
+
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# CREATES AND INSTALLS THE EXE
+# Set to ON if your appli has a GUI (to build as a Win32 app on windows)
+SET(${EXE_NAME}_HAS_GUI OFF)
+# Set to ON if your appli has a GUI but you also want a msdos console on windows
+SET(${EXE_NAME}_CONSOLE OFF)
+CREA_ADD_EXECUTABLE( ${EXE_NAME} )
+#----------------------------------------------------------------------------
+
+
--- /dev/null
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "brukerdataset.h"
+//#include "brukerkspaceobject.h"
+
+#include "gdcmArgMgr.h"
+#include "gdcmDebug.h"
+//#include "gdcmUtil.h"
+
+
+int main(int argc, char *argv[])
+{
+ START_USAGE(usage)
+ " \n PrintParameterFile : \n ",
+ " - explores the given Bruker parameter file, ",
+ " - prints its content, ",
+ " usage: BrukerToMhd filein=rukerParameterFile ",
+ " [debug] [verbose] ",
+ " ",
+ " debug : developper wants to run the program in 'debug mode' ",
+ FINISH_USAGE
+
+// ------------ Initialize Arguments Manager ----------------
+ GDCM_NAME_SPACE::ArgMgr *am= new GDCM_NAME_SPACE::ArgMgr(argc, argv);
+
+ if (argc == 1 || am->ArgMgrDefined("usage") )
+ {
+ am->ArgMgrUsage(usage); // Display 'usage'
+ delete am;
+ return 1;
+ }
+
+ const char *fileNamein;
+ fileNamein = am->ArgMgrWantString("filein",usage);
+
+ if (am->ArgMgrDefined("debug"))
+ GDCM_NAME_SPACE::Debug::DebugOn();
+
+ /* if unused Param we give up */
+ if ( am->ArgMgrPrintUnusedLabels() )
+ {
+ am->ArgMgrUsage(usage);
+ delete am;
+ return 1;
+ }
+
+ delete am; // we don't need Argument Manager any longer
+
+ // ----------- End Arguments Manager ---------
+
+ BrukerDataSet br1;
+ //BrukerKspaceObject bro1(br1);
+ std::string file2Read(fileNamein);
+ br1.LoadFile(file2Read);
+std::cout << "=============== FillMap =================" << std::endl;
+ br1.FillMap();
+std::cout << "=============== End FillMap =================" << std::endl;
+
+ std::cout << "=============== PrintSelf =================" << std::endl;
+ br1.PrintSelf();
+ std::cout << "=============== End PrintSelf =============" << std::endl;
+
+ return EXIT_SUCCESS;
+}
--- /dev/null
+ # ==>
+ # ==> Dans ce directory : les fichiers sources qui composent l'application (sans Wx)
+ #
+ # ==> In this directory : the source files that compose the (Wx less) application
+ # ==>
+
+
--- /dev/null
+Une 'vraie' application (contrairement `a un 'exemple') est succeptible d'^etre
+r'epartie sur plusieurs fichiers sources.
+Par convention, nous consid`ererons qu'il y a un directory par application.
+Le nom de l'executable sera celui du directory qui contient les fichiers sources
+Une application ne se compile pas exactement de la meme maniere selon qu'elle utilise ou WxWidgets
+Nous avons laisse ici un squelette de programme pour chaque cas.
+
+A 'true application' (as opposed to 'examples') may be be held within more than
+one file.
+Here, we consider there is one directory per application.
+Application name will be the one of the directory holding all the application
+source files.
+An application is not compiled the same way, if it uses or not WxWidgets.
+Therefore, there are two different 'skeletons'.
--- /dev/null
+#----------------------------------------------------------------------------
+# SET THE NAME OF YOUR EXECUTABLE
+SET ( EXE_NAME essaiDenis )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# EXECUTABLE SOURCES (TO BE COMPILED)
+# EITHER LIST ALL .cxx, *.cpp, *.cc IN CURRENT DIR USING NEXT LINE:
+FILE(GLOB ${EXE_NAME}_SOURCES *.cxx *.cpp *.cc)
+# OR MANUALLY LIST YOUR FILES WITH NEXT COMMAND (WITHOUT EXTENSION)
+# SET ( ${EXE_NAME}_SOURCES
+#
+# )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# DEPENDENCIES (LIBRARIES TO LINK WITH)
+SET ( ${EXE_NAME}_LINK_LIBRARIES
+ ${crea_LIBRARIES}
+ # ${WXWIDGETS_LIBRARIES}
+ # ${KWWidgets_LIBRARIES}
+ # ${VTK_LIBRARIES}
+ # ${ITK_LIBRARIES}
+ ${GDCM_LIBRARIES}
+ ${BOOST_LIBRARIES}
+
+ creaBruker
+ )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# CREATES AND INSTALLS THE EXE
+# Set to ON if your appli has a GUI (to build as a Win32 app on windows)
+SET(${EXE_NAME}_HAS_GUI OFF)
+# Set to ON if your appli has a GUI but you also want a msdos console on windows
+SET(${EXE_NAME}_CONSOLE OFF)
+CREA_ADD_EXECUTABLE( ${EXE_NAME} )
+#----------------------------------------------------------------------------
+
+
--- /dev/null
+ # ==>
+ # ==> Dans ce directory : les fichiers sources qui composent l'application (sans Wx)
+ #
+ # ==> In this directory : the source files that compose the (Wx less) application
+ # ==>
+
+
--- /dev/null
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "brukerdataset.h"
+#include "brukerkspaceobject.h"
+#include "brukerimage.h"
+
+
+int main(int argc, char *argv[])
+{
+ BrukerDataSet acqp1, reco1;
+ std::string file2Read1("/home/denis/TestDicom/kiwidicom.QZ1/3/acqp");
+ std::string file2Read2("/home/denis/TestDicom/kiwidicom.QZ1/3/pdata/1/reco");
+ //std::string file2Read("/home/denis/TestDicom/mcao31a.pc1-exam_fabien/6/acqp");
+ //std::string file2Read("/home/denis/TestDicom/mcao31a.pc1-exam_fabien/6/pdata/1/reco");
+ //std::string file2Read("/home/denis/TestDicom/mcao31a.pc1-exam_fabien/6/acqp");
+ acqp1.LoadFile(file2Read1);
+ reco1.LoadFile(file2Read2);
+ std::cout << "=============== acqp1 FillMap =================" << std::endl;
+ acqp1.FillMap();
+ acqp1.PrintSelf();
+ std::cout << "=============== End acqp1 FillMap =================" << std::endl;
+ std::cout << "=============== reco1 FillMap =================" << std::endl;
+ reco1.FillMap();
+ reco1.PrintSelf();
+ std::cout << "=============== End reco1 FillMap =================" << std::endl;
+
+
+
+ std::cout << "=============== BuildLoopStructure =================" << std::endl;
+
+// LoopStructure is used to control the way the loops can be unrolled (in ObjectsLineList)
+ acqp1.SetLoopStructure();
+ std::vector<int> TempVect = acqp1.GetLoopStructure() ;
+ for(int i=0;i<TempVect.size();i++){
+ std::cout<<"GenericLoopStructure["<<i<<"]="<<TempVect[i]<<std::endl;
+ }
+ std::cout << "=============== End BuildLoopStructure =================" << std::endl;
+
+ std::cout << "=============== SetBrukerObjectsLineStructure =================" << std::endl;
+
+// ObjectsLineList is a matrix containing for each line acquired which was its position in the acquisition loop
+// This position do not take into account an eventual slice interleaved acquisition
+
+ acqp1.SetBrukerObjectsLineList();
+ std::vector<std::vector<int> > TempMat=acqp1.GetBrukerObjectsLineList();
+ std::map<std::string, BrukerFieldData> Map=acqp1.GetBrukerHeaderMap();
+
+//ObjectVaryingProperties is a method centralizing the access to "all" the varying properties of images like position, orientation, echo time, .....
+//It needs the BrukerHeaderMap and the LoopStructure as input
+
+ bool result=acqp1.ObjectVaryingProperties.init(Map,TempVect);
+ int Reordered,i,j,k,l;
+ std::vector<std::vector<double> > TempMat2;
+ for(int i=0;i<TempMat.size();i++){
+ std::cout<<std::endl<<"["<<i<<"] ";
+ for (int j=0;j<TempMat[0].size();j++)
+ std::cout<< "["<<TempMat[i][j]<<"] ";
+// fugly trick but sofar the eventual interleaved information applies to the slice loop =>BrukerObjectsLineList[*][2]
+ Reordered=acqp1.ObjectVaryingProperties.getAcquisitionOrder(TempMat[i][2]);
+ std::cout<<" TE = "<<acqp1.ObjectVaryingProperties.getTE(TempMat[i][0]);
+// And the Reordering applies to values "constructed" exterior to the slice loop (ie : BrukerObjectsLineList[*][>=2])
+ std::cout<<" [R,P,S]xyz = ["<<acqp1.ObjectVaryingProperties.getPositionR(Reordered);
+ std::cout<<" , "<<acqp1.ObjectVaryingProperties.getPositionP(Reordered);
+ std::cout<<" , "<<acqp1.ObjectVaryingProperties.getPositionS(Reordered)<<"] ";
+ TempMat2=acqp1.ObjectVaryingProperties.getOrientation(Reordered);
+ std::cout<<" [R,P,S]orient = [";
+ for (k=0;k<=2;k++){
+ std::cout << "[";
+ for (l=0;l<=2;l++) std::cout<< TempMat2[k][l]<<" ";
+ std::cout<<"]";
+ }
+ std::cout<<"]";
+ std::cout<<" Slice Number = "<<Reordered<<" ";
+ std::cout<<" TimePositionPerNR = "<<acqp1.ObjectVaryingProperties.getPositionTimePerNR(TempMat[i].back());
+ }
+ std::cout<<std::endl;
+ std::cout << "=============== End SetBrukerObjectsLineStructure =================" << std::endl;
+
+//Same routine as above but instead of scruting the loop structure of raw data
+//we deal with an image structure so the loops used to construct an image do not appear anymore
+//but apparently the interleaveness stand still
+
+ std::cout << "=============== Begin BrukerImageStructure=================" << std::endl;
+ acqp1.SetImageLoopStructure();
+ acqp1.SetBrukerImageList();
+ std::vector<std::vector<int> > BrukerImageList=acqp1.GetBrukerImageList();
+ std::vector<std::vector<double> > BrukerImageList2;
+ for(int i=0;i<BrukerImageList.size();i++){
+
+
+ std::cout<<std::endl<<"["<<i<<"] ";
+ for (int j=0;j<BrukerImageList[0].size();j++)
+ std::cout<< "["<<BrukerImageList[i][j]<<"] ";
+ Reordered=acqp1.ObjectVaryingProperties.getAcquisitionOrder(BrukerImageList[i][2]);
+ std::cout<<" TE = "<<acqp1.ObjectVaryingProperties.getTE(BrukerImageList[i][0]);
+ std::cout<<" [R,P,S]xyz = ["<<acqp1.ObjectVaryingProperties.getPositionR(Reordered);
+ std::cout<<" , "<<acqp1.ObjectVaryingProperties.getPositionP(Reordered);
+ std::cout<<" , "<<acqp1.ObjectVaryingProperties.getPositionS(Reordered)<<"] ";
+ BrukerImageList2=acqp1.ObjectVaryingProperties.getOrientation(Reordered);
+ std::cout<<" [R,P,S]orient = [";
+ for (k=0;k<=2;k++){
+ std::cout << "[";
+ for (l=0;l<=2;l++)
+ std::cout<< BrukerImageList2[k][l]<<" ";
+ std::cout<<"]";
+ }
+ std::cout<<"]";
+ std::cout<<" Slice Number = "<<Reordered<<" ";
+ std::cout<<" TimePositionPerNR = "<<acqp1.ObjectVaryingProperties.getPositionTimePerNR(BrukerImageList[i].back());
+ }
+ std::cout<<std::endl;
+ std::cout << "=============== End BrukerImageStructure=============" << std::endl;
+
+
+ BrukerImage Image(acqp1,reco1);
+ Image.Init(acqp1,reco1,1);
+ std::vector<BrukerImage> ImageSet;
+
+ for(int i=0;i<BrukerImageList.size();i++){
+ Image.Init(acqp1,reco1,i);
+ ImageSet.push_back(Image);
+ }
+
+ std::string fid("/home/denis/TestDicom/kiwidicom.QZ1/3/fid");
+ std::cout << "=============== Getkspace =================" << std::endl;
+ acqp1.Getkspace(fid);
+ std::cout << "=============== End Getkspace =================" << std::endl;
+ return EXIT_SUCCESS;
+}
+
--- /dev/null
+
+#----------------------------------------------------------------------------
+# SET THE NAME OF YOUR EXECUTABLE
+SET ( EXE_NAME exObjectVaryingProperties )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# EXECUTABLE SOURCES (TO BE COMPILED)
+# EITHER LIST ALL .cxx, *.cpp, *.cc IN CURRENT DIR USING NEXT LINE:
+FILE(GLOB ${EXE_NAME}_SOURCES *.cxx *.cpp *.cc)
+# OR MANUALLY LIST YOUR FILES WITH NEXT COMMAND (WITHOUT EXTENSION)
+# SET ( ${EXE_NAME}_SOURCES
+#
+# )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# DEPENDENCIES (LIBRARIES TO LINK WITH)
+SET ( ${EXE_NAME}_LINK_LIBRARIES
+ ${crea_LIBRARIES}
+ # ${WXWIDGETS_LIBRARIES}
+ # ${KWWidgets_LIBRARIES}
+ # ${VTK_LIBRARIES}
+ # ${ITK_LIBRARIES}
+ ${GDCM_LIBRARIES}
+ ${BOOST_LIBRARIES}
+ )
+
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# CREATES AND INSTALLS THE EXE
+# Set to ON if your appli has a GUI (to build as a Win32 app on windows)
+SET(${EXE_NAME}_HAS_GUI OFF)
+# Set to ON if your appli has a GUI but you also want a msdos console on windows
+SET(${EXE_NAME}_CONSOLE OFF)
+CREA_ADD_EXECUTABLE( ${EXE_NAME} )
+#----------------------------------------------------------------------------
+
+
--- /dev/null
+ # ==>
+ # ==> Dans ce directory : les fichiers sources qui composent l'application (sans Wx)
+ #
+ # ==> In this directory : the source files that compose the (Wx less) application
+ # ==>
+
+
--- /dev/null
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "brukerdataset.h"
+#include "brukerkspaceobject.h"
+#include "brukerimage.h"
+
+
+int main(int argc, char *argv[])
+{
+ BrukerDataSet acqp1, reco1;
+ std::string file2Read1("/home/denis/TestDicom/kiwidicom.QZ1/3/acqp");
+ std::string file2Read2("/home/denis/TestDicom/kiwidicom.QZ1/3/pdata/1/reco");
+ //std::string file2Read("/home/denis/TestDicom/mcao31a.pc1-exam_fabien/6/acqp");
+ //std::string file2Read("/home/denis/TestDicom/mcao31a.pc1-exam_fabien/6/pdata/1/reco");
+ //std::string file2Read("/home/denis/TestDicom/mcao31a.pc1-exam_fabien/6/acqp");
+ acqp1.LoadFile(file2Read1);
+ reco1.LoadFile(file2Read2);
+ std::cout << "=============== acqp1 FillMap =================" << std::endl;
+ acqp1.FillMap();
+ acqp1.PrintSelf();
+ std::cout << "=============== End acqp1 FillMap =================" << std::endl;
+ std::cout << "=============== reco1 FillMap =================" << std::endl;
+ reco1.FillMap();
+ reco1.PrintSelf();
+ std::cout << "=============== End reco1 FillMap =================" << std::endl;
+
+
+
+ std::cout << "=============== BuildLoopStructure =================" << std::endl;
+
+// LoopStructure is used to control the way the loops can be unrolled (in ObjectsLineList)
+ acqp1.SetLoopStructure();
+ std::vector<int> TempVect = acqp1.GetLoopStructure() ;
+ for(int i=0;i<TempVect.size();i++){
+ std::cout<<"GenericLoopStructure["<<i<<"]="<<TempVect[i]<<std::endl;
+ }
+ std::cout << "=============== End BuildLoopStructure =================" << std::endl;
+
+ std::cout << "=============== SetBrukerObjectsLineStructure =================" << std::endl;
+
+// ObjectsLineList is a matrix containing for each line acquired which was its position in the acquisition loop
+// This position do not take into account an eventual slice interleaved acquisition
+
+ acqp1.SetBrukerObjectsLineList();
+ std::vector<std::vector<int> > TempMat=acqp1.GetBrukerObjectsLineList();
+ std::map<std::string, BrukerFieldData> Map=acqp1.GetBrukerHeaderMap();
+
+//ObjectVaryingProperties is a method centralizing the access to "all" the varying properties of images like position, orientation, echo time, .....
+//It needs the BrukerHeaderMap and the LoopStructure as input
+
+ bool result=acqp1.ObjectVaryingProperties.init(Map,TempVect);
+ int Reordered,i,j,k,l;
+ std::vector<std::vector<double> > TempMat2;
+ for(int i=0;i<TempMat.size();i++){
+ std::cout<<std::endl<<"["<<i<<"] ";
+ for (int j=0;j<TempMat[0].size();j++)
+ std::cout<< "["<<TempMat[i][j]<<"] ";
+// fugly trick but sofar the eventual interleaved information applies to the slice loop =>BrukerObjectsLineList[*][2]
+ Reordered=acqp1.ObjectVaryingProperties.getAcquisitionOrder(TempMat[i][2]);
+ std::cout<<" TE = "<<acqp1.ObjectVaryingProperties.getTE(TempMat[i][0]);
+// And the Reordering applies to values "constructed" exterior to the slice loop (ie : BrukerObjectsLineList[*][>=2])
+ std::cout<<" [R,P,S]xyz = ["<<acqp1.ObjectVaryingProperties.getPositionR(Reordered);
+ std::cout<<" , "<<acqp1.ObjectVaryingProperties.getPositionP(Reordered);
+ std::cout<<" , "<<acqp1.ObjectVaryingProperties.getPositionS(Reordered)<<"] ";
+ TempMat2=acqp1.ObjectVaryingProperties.getOrientation(Reordered);
+ std::cout<<" [R,P,S]orient = [";
+ for (k=0;k<=2;k++){
+ std::cout << "[";
+ for (l=0;l<=2;l++) std::cout<< TempMat2[k][l]<<" ";
+ std::cout<<"]";
+ }
+ std::cout<<"]";
+ std::cout<<" Slice Number = "<<Reordered<<" ";
+ std::cout<<" TimePositionPerNR = "<<acqp1.ObjectVaryingProperties.getPositionTimePerNR(TempMat[i].back());
+ }
+ std::cout<<std::endl;
+ std::cout << "=============== End SetBrukerObjectsLineStructure =================" << std::endl;
+
+//Same routine as above but instead of scruting the loop structure of raw data
+//we deal with an image structure so the loops used to construct an image do not appear anymore
+//but apparently the interleaveness stand still
+
+ std::cout << "=============== Begin BrukerImageStructure=================" << std::endl;
+ acqp1.SetImageLoopStructure();
+ acqp1.SetBrukerImageList();
+ std::vector<std::vector<int> > BrukerImageList=acqp1.GetBrukerImageList();
+ std::vector<std::vector<double> > BrukerImageList2;
+ for(int i=0;i<BrukerImageList.size();i++){
+ std::cout<<std::endl<<"["<<i<<"] ";
+ for (int j=0;j<BrukerImageList[0].size();j++)
+ std::cout<< "["<<BrukerImageList[i][j]<<"] ";
+ Reordered=acqp1.ObjectVaryingProperties.getAcquisitionOrder(BrukerImageList[i][2]);
+ std::cout<<" TE = "<<acqp1.ObjectVaryingProperties.getTE(BrukerImageList[i][0]);
+ std::cout<<" [R,P,S]xyz = ["<<acqp1.ObjectVaryingProperties.getPositionR(Reordered);
+ std::cout<<" , "<<acqp1.ObjectVaryingProperties.getPositionP(Reordered);
+ std::cout<<" , "<<acqp1.ObjectVaryingProperties.getPositionS(Reordered)<<"] ";
+ BrukerImageList2=acqp1.ObjectVaryingProperties.getOrientation(Reordered);
+ std::cout<<" [R,P,S]orient = [";
+ for (k=0;k<=2;k++){
+ std::cout << "[";
+ for (l=0;l<=2;l++)
+ std::cout<< BrukerImageList2[k][l]<<" ";
+ std::cout<<"]";
+ }
+ std::cout<<"]";
+ std::cout<<" Slice Number = "<<Reordered<<" ";
+ std::cout<<" TimePositionPerNR = "<<acqp1.ObjectVaryingProperties.getPositionTimePerNR(BrukerImageList[i].back());
+ }
+ std::cout<<std::endl;
+ std::cout << "=============== End BrukerImageStructure=============" << std::endl;
+
+
+ BrukerImage Image(acqp1,reco1);
+ Image.Init(acqp1,reco1,1);
+ std::vector<BrukerImage> ImageSet;
+
+ for(int i=0;i<BrukerImageList.size();i++){
+ Image.Init(acqp1,reco1,i);
+ ImageSet.push_back(Image);
+ };
+
+ std::string fid("/home/denis/TestDicom/kiwidicom.QZ1/3/fid");
+ std::cout << "=============== Getkspace =================" << std::endl;
+ acqp1.Getkspace(fid);
+ std::cout << "=============== End Getkspace =================" << std::endl;
+ return EXIT_SUCCESS;
+}
--- /dev/null
+#----------------------------------------------------------------------------
+# SET THE NAME OF YOUR EXECUTABLE
+SET ( EXE_NAME MyExe )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# EXECUTABLE SOURCES (TO BE COMPILED)
+# EITHER LIST ALL .cxx, *.cpp, *.cc IN CURRENT DIR USING NEXT LINE:
+FILE(GLOB ${EXE_NAME}_SOURCES *.cxx *.cpp *.cc)
+# OR MANUALLY LIST YOUR FILES WITH NEXT COMMAND (WITHOUT EXTENSION)
+# SET ( ${EXE_NAME}_SOURCES
+#
+# )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# DEPENDENCIES (LIBRARIES TO LINK WITH)
+SET ( ${EXE_NAME}_LINK_LIBRARIES
+ # ${crea_LIBRARIES}
+ # ${WXWIDGETS_LIBRARIES}
+ # ${KWWidgets_LIBRARIES}
+ # ${VTK_LIBRARIES}
+ # ${ITK_LIBRARIES}
+ # ${GDCM_LIBRARIES}
+ # ${BOOST_LIBRARIES}
+ )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# CREATES AND INSTALLS THE EXE
+# Set to ON if your appli has a GUI (to build as a Win32 app on windows)
+SET(${EXE_NAME}_HAS_GUI OFF)
+# Set to ON if your appli has a GUI but you also want a msdos console on windows
+SET(${EXE_NAME}_CONSOLE OFF)
+CREA_ADD_EXECUTABLE( ${EXE_NAME} )
+#----------------------------------------------------------------------------
+
+
--- /dev/null
+#----------------------------------------------------------------------------
+# SET THE NAME OF YOUR EXECUTABLE
+SET ( EXE_NAME MyExe )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# EXECUTABLE SOURCES (TO BE COMPILED)
+# EITHER LIST ALL .cxx, *.cpp, *.cc IN CURRENT DIR USING NEXT LINE:
+FILE(GLOB ${EXE_NAME}_SOURCES *.cxx *.cpp *.cc)
+# OR MANUALLY LIST YOUR FILES WITH NEXT COMMAND (WITHOUT EXTENSION)
+# SET ( ${EXE_NAME}_SOURCES
+#
+# )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# DEPENDENCIES (LIBRARIES TO LINK WITH)
+SET ( ${EXE_NAME}_LINK_LIBRARIES
+ ${crea_LIBRARIES}
+ # ${WXWIDGETS_LIBRARIES}
+ # ${VTK_LIBRARIES}
+ # ${ITK_LIBRARIES}
+ # ${GDCM_LIBRARIES}
+ # ${BOOST_LIBRARIES}
+ )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# UNCOMMENT NEXT LINE IF YOU WANT A CONSOLE ON WINDOWS
+# NB : YOUR MAIN MUST BE ADAPTED ALSO
+# SEE THE MACRO CREA_WXMAIN_WITH_CONSOLE IN creaWx.h
+#SET(${EXE_NAME}_CONSOLE TRUE)
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# CREATES AND INSTALLS THE EXE
+CREA_ADD_WX_EXECUTABLE( ${EXE_NAME} )
+#----------------------------------------------------------------------------
+
+
--- /dev/null
+
+#----------------------------------------------------------------------------
+# SET THE NAME OF YOUR EXECUTABLE
+SET ( EXE_NAME testBruker2Dicom )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# EXECUTABLE SOURCES (TO BE COMPILED)
+# EITHER LIST ALL .cxx, *.cpp, *.cc IN CURRENT DIR USING NEXT LINE:
+FILE(GLOB ${EXE_NAME}_SOURCES *.cxx *.cpp *.cc)
+# OR MANUALLY LIST YOUR FILES WITH NEXT COMMAND (WITHOUT EXTENSION)
+# SET ( ${EXE_NAME}_SOURCES
+#
+# )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# DEPENDENCIES (LIBRARIES TO LINK WITH)
+SET ( ${EXE_NAME}_LINK_LIBRARIES
+ ${crea_LIBRARIES}
+ # ${WXWIDGETS_LIBRARIES}
+ # ${KWWidgets_LIBRARIES}
+ # ${VTK_LIBRARIES}
+ # ${ITK_LIBRARIES}
+ ${GDCM_LIBRARIES}
+ ${BOOST_LIBRARIES}
+
+ creaBruker
+ )
+
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# CREATES AND INSTALLS THE EXE
+# Set to ON if your appli has a GUI (to build as a Win32 app on windows)
+SET(${EXE_NAME}_HAS_GUI OFF)
+# Set to ON if your appli has a GUI but you also want a msdos console on windows
+SET(${EXE_NAME}_CONSOLE OFF)
+CREA_ADD_EXECUTABLE( ${EXE_NAME} )
+#----------------------------------------------------------------------------
+
+
--- /dev/null
+/*=========================================================================
+
+ Program: gdcm
+ Module: $RCSfile: testBruker2Dicom.cxx,v $
+ Language: C++
+ Date: $Date: 2009/05/13 15:37:43 $
+ Version: $Revision: 1.1 $
+
+ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+ l'Image). All rights reserved. See Doc/License.txt or
+ http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+
+/**
+ * Transform private Bruker tree structure
+ * into the equivalent, with DICOM files *and/or* MHD files.
+ *
+ */
+#include "bruker2dicom.h"
+
+#include "gdcmCommon.h"
+#include "gdcmDebug.h"
+#include "gdcmUtil.h"
+#include "gdcmDirList.h"
+
+#include "gdcmArgMgr.h"
+
+#include "bruker2dicom.h"
+
+// ===================================================================================================
+/**
+ * \brief
+ * - explores the given root directory e.g. :
+ * B67d1.Bp1
+ * subject
+ * AdjStatePerStudy
+ * 1
+ * acqp
+ * AdjStatePerScan
+ * fid
+ * imnd / method
+ * pulseprogram
+ * spnam0
+ * spnam1
+ * pdata
+ * 1 // only 'native' images
+ * 2dseq
+ * d3proc
+ * meta
+ * procs
+ * reco <--
+ * roi
+ * CreatisComputedCartoFile
+ * 2 // post processed images (if any)
+ * 2dseq
+ * d3proc
+ * isa <--
+ * meta
+ * procs
+ * roi ...
+ * roi
+ * 3 // post processed images (if any)
+ * 2dseq
+ * d3proc
+ * isa <--
+ * meta
+ * procs
+ * roi
+ * ...
+ * 2
+ * acqp
+ * fid
+ * ...
+ * pdata
+ * 3
+ * ...
+ * - fills a single level Directory with the MHD files,
+ */
+
+
+int main(int argc, char *argv[])
+{
+ START_USAGE(usage)
+ " \n testBruker2Dicom : \n ",
+ " - explores the given directory, at the 3 levels, ",
+ " - fills an equivalent Directory with the MHD files or the DICOM files ",
+ " usage: testBruker2Dicom dirin=rootDirectoryName ",
+ " dirout=outputDirectoryName ",
+ " [D] [M] ",
+ " [{b|l}] b:BigEndian,l:LittleEndian default : l ",
+ " [debug] [verbose] [listonly] ",
+ " ",
+ " D : user wants to export as DICOM ",
+ " M : user wants to export as MHD ",
+ " debug : developper wants to run the program in 'debug mode' ",
+ FINISH_USAGE
+
+ // ------------ Initialize Arguments Manager ----------------
+ GDCM_NAME_SPACE::ArgMgr *am= new GDCM_NAME_SPACE::ArgMgr(argc, argv);
+
+ if (argc == 1 || am->ArgMgrDefined("usage") )
+ {
+ am->ArgMgrUsage(usage); // Display 'usage'
+ delete am;
+ return 1;
+ }
+
+ // create the devilish object!
+ Bruker2Dicom b2d;
+
+ const char *dirNamein;
+ dirNamein = am->ArgMgrGetString("dirin",".");
+
+ const char *dirNameout;
+ dirNameout = am->ArgMgrGetString("dirout",".");
+
+// note : Big Endian / Little Endian pb not yet dealt with.
+// not a great issue, since everybody (?) works on Intell procs
+ int b = am->ArgMgrDefined("b");
+ int l = am->ArgMgrDefined("l");
+
+ if (am->ArgMgrDefined("debug"))
+ GDCM_NAME_SPACE::Debug::DebugOn();
+
+ b2d.verbose = am->ArgMgrDefined("verbose");
+ int listonly = am->ArgMgrDefined("listonly");
+
+ int dicom = am->ArgMgrDefined("D");
+ int mhd = am->ArgMgrDefined("M");
+
+ if (dicom)
+ b2d.SetConvertModeToDicom();
+ if (mhd)
+ b2d.SetConvertModeToMhd();
+
+ /* if unused Param we give up */
+ if ( am->ArgMgrPrintUnusedLabels() )
+ {
+ am->ArgMgrUsage(usage);
+ delete am;
+ return 1;
+ }
+
+// patientName : found in Bruker parameter files
+// patientName = am->ArgMgrGetString("patientname", "Patient^Name");
+
+// b2d.day : unused ...
+ b2d.day = am->ArgMgrGetString("day", "You_forget_the_Day");
+
+ delete am; // we don't need Argument Manager any longer
+
+ // ----------- End Arguments Manager ---------
+
+
+ // ----- Begin Processing -----
+
+ b2d.SetInputDirectory(dirNamein);
+ b2d.SetOutputDirectory(dirNameout);
+
+ /// \TODO : *do* use exceptions in the methods!
+
+ try {
+ b2d.Execute();
+ }
+ catch (int)
+ {
+ std::cout << "Exception was thrown :-( " << std::endl;
+ }
+
+}
+
+
--- /dev/null
+# Add a SUBDIRS command for each one of your libraries
+ SUBDIRS(src1)
--- /dev/null
+#----------------------------------------------------------------------------
+# SET THE NAME OF YOUR LIBRARY
+SET ( LIBRARY_NAME creaBruker )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# CREATES A USER OPTION IN CMAKE
+OPTION ( BUILD_${LIBRARY_NAME} "Build ${LIBRARY_NAME} library ?" ON)
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+IF ( BUILD_${LIBRARY_NAME} )
+#----------------------------------------------------------------------------
+
+ #----------------------------------------------------------------------------
+ # BUILD LIBRARY
+ #----------------------------------------------------------------------------
+
+ #----------------------------------------------------------------------------
+ # LIBRARY HEADERS (TO BE INSTALLED)
+ # EITHER LIST ALL .h IN CURRENT DIR USING NEXT LINE:
+ FILE(GLOB ${LIBRARY_NAME}_HEADERS "*.h")
+ # OR MANUALLY LIST YOUR HEADERS WITH NEXT COMMAND
+ # SET ( ${LIBRARY_NAME}_HEADERS
+ #
+ # )
+ #----------------------------------------------------------------------------
+
+ #----------------------------------------------------------------------------
+ # LIBRARY SOURCES (TO BE COMPILED)
+ # EITHER LIST ALL .cxx, *.cpp, *.cc IN CURRENT DIR USING NEXT LINE:
+ FILE(GLOB ${LIBRARY_NAME}_SOURCES *.cxx *.cpp *.cc)
+ # OR MANUALLY LIST YOUR FILES WITH NEXT COMMAND (WITHOUT EXTENSION)
+ # SET ( ${LIBRARY_NAME}_SOURCES
+ #
+ # )
+ #----------------------------------------------------------------------------
+
+ #----------------------------------------------------------------------------
+ # LIBRARY DEPENDENCIES (LIBRARIES TO LINK WITH)
+ SET ( ${LIBRARY_NAME}_LINK_LIBRARIES
+ ${crea_LIBRARIES}
+ # ${WXWIDGETS_LIBRARIES}
+ # ${VTK_LIBRARIES}
+ # ${ITK_LIBRARIES}
+ ${GDCM_LIBRARIES}
+ ${BOOST_LIBRARIES}
+ )
+ #----------------------------------------------------------------------------
+
+
+ #----------------------------------------------------------------------------
+ # MACRO WHICH DOES ALL THE JOB : BUILD AND INSTALL
+ CREA_ADD_LIBRARY( ${LIBRARY_NAME} )
+ #----------------------------------------------------------------------------
+
+
+ #---------------------------------------------------------------------------
+ENDIF ( BUILD_${LIBRARY_NAME} )
--- /dev/null
+#include "bruker2dicom.h"
+
+
+
+bool Bruker2Dicom::Execute()
+{
+ // ----- Begin Processing -----
+
+ bool bigEndian = GDCM_NAME_SPACE::Util::IsCurrentProcessorBigEndian();
+
+ if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(InputDirName) )
+ {
+ std::cout << "KO : [" << InputDirName << "] is not a Directory." << std::endl;
+ return 0;
+ }
+ else
+ {
+ if (verbose)
+ std::cout << "OK : [" << InputDirName << "] is a Directory." << std::endl;
+ }
+
+ std::string strDirNameOut(OutputDirName);
+ bool res=CreateDirectory(strDirNameOut);
+ if (!res) {
+ std::cout << "[" << OutputDirName << "] Directory creation failure " << std::endl;
+ exit (0);
+ }
+
+ std::string strDirNamein(InputDirName);
+ GDCM_NAME_SPACE::DirList dirList(strDirNamein, false, true); // DON'T get recursively the list of files
+ std::string strDirNameout(OutputDirName);
+
+/*
+ if (listonly)
+ {
+ std::cout << "------------List of found files ------------" << std::endl;
+ dirList.Print();
+ std::cout << std::endl;
+ return 1;
+ }
+*/
+
+//
+// e.g : at level 0, in : B67d1.Bp1
+//
+// 1 2 3 4 5 6 AdjStatePerStudy subject
+//
+
+ GDCM_NAME_SPACE::DirListType fileNames;
+ fileNames = dirList.GetFilenames();
+ bool canOpen;
+ std::string outputFileName;
+
+ // BrukerDataSet br_subject;
+ std::string subject;
+ subject = GDCM_NAME_SPACE::Util::GetPath(*(fileNames.begin()))+
+ GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
+ "subject";
+ if (verbose)
+ std::cout << " Subject : [" << subject << "]" << std::endl;
+ canOpen =br_subject.LoadFile(subject);
+
+ if (!canOpen)
+ {
+ std::cout << "Hopeless! no 'subject' found" << std::endl;
+ exit(0); /// \TODO throw an exception !
+ }
+ else
+ {
+ br_subject.FillMap();
+ }
+ //br_subject.PrintSelf();
+
+ // get info for 'Study Description'
+
+ /*
+ BrukerFieldData b_protocol_location=br_acqp.GetFieldData("ACQ_protocol_location");
+ acqp_protocol_location = b_protocol_location.GetStringValue()[0];
+ cleanString(acqp_protocol_location);
+*/
+ BrukerFieldData b_name=br_subject.GetFieldData("SUBJECT_name_string");
+ std::string subject_name = b_name.GetStringValue()[0];
+ strPatientName = subject_name;
+ cleanString(subject_name);
+
+ BrukerFieldData b_entry=br_subject.GetFieldData("SUBJECT_entry");
+ std::string subject_entry = b_entry.GetStringValue()[0];
+ //cleanString(subject_entry);
+ subject_entry = subject_entry.substr(11, subject_entry.size()-11);
+
+ BrukerFieldData b_position=br_subject.GetFieldData("SUBJECT_position");
+ std::string subject_position = b_position.GetStringValue()[0];
+ //cleanString(subject_position);
+ subject_position = subject_position.substr(9, subject_position.size()-9);
+
+ BrukerFieldData b_date=br_subject.GetFieldData("SUBJECT_date");
+ std::string subject_date = b_date.GetStringValue()[0];
+ strStudyTimeDate = subject_date;
+ cleanString(subject_date);
+
+ BrukerFieldData b_study_name=br_subject.GetFieldData("SUBJECT_study_name");
+ std::string subject_study_name = b_study_name.GetStringValue()[0];
+ subject_study_name = subject_study_name.substr(1, subject_study_name.size()-2);
+ cleanString(subject_date);
+
+ strStudyDescr = subject_name + "-" + subject_study_name + "-" + subject_entry + "-" + subject_position + "-" + subject_date;
+
+ char outputDirName[(unsigned int) PATH_MAX+2];
+
+ strStudyUID = GDCM_NAME_SPACE::Util::CreateUniqueUID();
+
+ // -----------------------------------------------------
+ // Iterate to ALL the objets(files/directories) found in the input directory
+ // (this is level ZERO)
+ // -----------------------------------------------------
+
+ GDCM_NAME_SPACE::DirListType::iterator it;
+
+ for (it = fileNames.begin();
+ it != fileNames.end();
+ ++it)
+ {
+ if ( GDCM_NAME_SPACE::DirList::IsDirectory(*it) )
+ {
+ if (verbose)
+ std::cout << "[" << *it << "] is a directory" << std::endl;
+
+ //BrukerDataSet br_acqp;
+ std::string strAcqp;
+ strAcqp = (*it) +
+ GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
+ "acqp";
+
+ br_acqp.LoadFile(strAcqp);
+ br_acqp.FillMap();
+
+ std::string acqp_scan_name;
+ std::string acqp_method;
+ std::string acqp_protocol_location;
+
+ BrukerFieldData b_protocol_location=br_acqp.GetFieldData("ACQ_protocol_location");
+ acqp_protocol_location = b_protocol_location.GetStringValue()[0];
+ cleanString(acqp_protocol_location);
+
+ BrukerFieldData b_scan_name=br_acqp.GetFieldData("ACQ_scan_name");
+ acqp_scan_name = b_scan_name.GetStringValue()[0];
+ cleanString(acqp_scan_name);
+
+ BrukerFieldData b_method=br_acqp.GetFieldData("ACQ_method");
+ acqp_method = b_method.GetStringValue()[0];
+ cleanString(acqp_method);
+
+ BrukerFieldData b_list_size = br_acqp.GetFieldData("ACQ_O1_list_size");
+ b_list_size.PrintSelf(); //JP
+
+ nbSlices = b_list_size.GetIntValue()[0];
+
+ strSerieDescr = GDCM_NAME_SPACE::Util::GetName(*it)
+ + "-" + acqp_protocol_location
+ + "-" + acqp_scan_name
+ + "-" + acqp_method.c_str();
+
+ sprintf(outputDirName, "%s%c%s", OutputDirName.c_str(),
+ GDCM_NAME_SPACE::GDCM_FILESEPARATOR,
+ strSerieDescr.c_str() );
+
+ std::cout << " ================================================================================\n"
+ << " ========================= [" << GDCM_NAME_SPACE::Util::GetName(*it).c_str()
+ << acqp_protocol_location.c_str()
+ << acqp_scan_name.c_str()
+ << acqp_method.c_str()
+ << "]\n"
+ << " ================================================================================"
+ << std::endl;
+
+ if (verbose)
+ printf ("outputDirName [%s]\n", outputDirName);
+
+ DealWithNiveau1(*it, outputDirName);
+ }
+ } // end of : for (GDCM_NAME_SPACE::DirListType::iterator it
+}
+
+
+// =====================================================================
+
+void Bruker2Dicom::DealWithNiveau1(std::string level1Directory, std::string currentOutputDirName) {
+//
+// e.g. : at level 1, in B67d1.Bp1/6
+//
+// acqp fid imnd pdata pulseprogram spnam0 spnam1
+
+ bool res = CreateDirectory(currentOutputDirName);
+
+ if (!res) {
+ std::cout << "[" << currentOutputDirName << "] Directory creation failure " << std::endl;
+ exit (0);
+ }
+ GDCM_NAME_SPACE::DirList dirList(level1Directory, false, true); // DON'T get recursively the list of files
+ GDCM_NAME_SPACE::DirListType fileNames;
+ fileNames = dirList.GetFilenames();
+ // -----------------------------------------------------
+ // Iterate to ALL the objets(files/directories) found in the input directory
+ // -----------------------------------------------------
+ GDCM_NAME_SPACE::DirListType::iterator it;
+
+ for (it = fileNames.begin();
+ it != fileNames.end();
+ ++it)
+ {
+ if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(*it) )
+ {
+ if (verbose)
+ std::cout << "--- [" << *it << "] is a file" << std::endl;
+ }
+ }
+
+ char outputDirName[(unsigned int) PATH_MAX+2];
+ //std::string firstName;
+ bool canOpen;
+ for (it = fileNames.begin();
+ it != fileNames.end();
+ ++it)
+ {
+ if ( GDCM_NAME_SPACE::DirList::IsDirectory(*it) )
+ {
+ // will be always "pdata" ...
+ if (verbose)
+ std::cout << "--- [" << *it << "] is a directory" << std::endl;
+
+ /* a recuperer :
+ if (FileLine.startsWith("##$ACQ_size=")) {
+ if (FileLine.startsWith("##$NI=")) {
+ if (FileLine.startsWith("##$NR=")) {
+ if (FileLine.startsWith("##$ACQ_obj_order=")) {
+ if (FileLine.startsWith("##$ACQ_word_size=")) {
+ if (FileLine.startsWith("##$BYTORDA=")) {
+ if (FileLine.startsWith("##$PULPROG=")) {
+ */
+
+ sprintf(outputDirName, "%s%c%s", currentOutputDirName.c_str(),
+ GDCM_NAME_SPACE::GDCM_FILESEPARATOR,
+ GDCM_NAME_SPACE::Util::GetName(*it).c_str());
+ //br1.PrintSelf();
+
+ std::string strMethod;
+ //std::string firstName = *(fileNames.begin());
+
+ strMethod = GDCM_NAME_SPACE::Util::GetPath(*(fileNames.begin())) +
+ GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
+ "method";
+ // std::cout << "---strMethod (for method)=> [" << strMethod << "]" << std::endl;
+ canOpen = br_method.LoadFile(strMethod);
+ if (!canOpen)
+ {
+ strMethod = GDCM_NAME_SPACE::Util::GetPath(*(fileNames.begin()))+
+ GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
+ "imnd";
+ //std::cout << "---strMethod (for imnd) => [" << strMethod << "]" << std::endl;
+ canOpen = br_method.LoadFile(strMethod);
+ if (!canOpen)
+ {
+ std::cout << "Hopeless! neither 'method' nor 'imnd' found" << std::endl;
+ exit(0); /// \TODO throw an exception !
+ }
+ }
+ if (verbose)
+ std::cout << "open => [" << strMethod << "] successfully" << std::endl;
+ br_method.FillMap();
+
+ /* a recuperer :
+ ##$PVM_Fov (dimension)
+ */
+ /*
+ dans method (pour perfusion seulement?) :
+ ##$PVM_ObjOrderList=( 8 )
+ 0 2 4 6 1 3 5 7
+ ##$PVM_NSPacks=2
+ ##$PVM_SPackArrNSlices=( 2 )
+ 7 1
+ */
+ DealWithNiveau2(*it,outputDirName );
+ }
+ }
+}
+
+// =====================================================================
+
+void Bruker2Dicom::DealWithNiveau2(std::string level2Directory, std::string currentOutputDirName) {
+
+// e.g. : at level 2 in B67d1.Bp1/6/pdata
+//
+// acqp fid imnd pdata pulseprogram spnam0 spnam1
+//
+
+ bool res = CreateDirectory(currentOutputDirName);
+
+ if (!res) {
+ std::cout << "[" << currentOutputDirName << "] Directory creation failure " << std::endl;
+ exit (0);
+ }
+
+ GDCM_NAME_SPACE::DirList dirList(level2Directory, false, true); // DON'T get recursively the list of files
+
+ GDCM_NAME_SPACE::DirListType fileNames;
+ fileNames = dirList.GetFilenames();
+
+ char outputDirName[(unsigned int) PATH_MAX+2];
+
+ // -----------------------------------------------------
+ // Iterate to ALL the objets(files/directories) found in the input directory
+ // -----------------------------------------------------
+ GDCM_NAME_SPACE::DirListType::iterator it;
+ bool canOpen;
+
+ if (verbose)
+ for (it = fileNames.begin();
+ it != fileNames.end();
+ ++it)
+ {
+ if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(*it) )
+ {
+ std::cout << "--- --- [" << *it << "] is a file" << std::endl;
+ }
+
+ }
+
+ for (it = fileNames.begin();
+ it != fileNames.end();
+ ++it)
+ {
+ if ( GDCM_NAME_SPACE::DirList::IsDirectory(*it) )
+ {
+
+ if (verbose)
+ std::cout << "--- --- [" << *it << "] is a directory" << std::endl;
+
+ // 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
+//
+ std::string str_isa;
+ str_isa = (*it) +
+ GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
+ "isa";
+
+ 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() );
+ }
+ else
+ {
+ br_isa.FillMap();
+ BrukerFieldData b_isa_func_name = br_isa.GetFieldData("ISA_func_name");
+
+ str_isa_func_name = b_isa_func_name.GetStringValue()[0];
+ cleanString(str_isa_func_name);
+
+ sprintf(outputDirName, "%s%c%s-%s", currentOutputDirName.c_str(),
+ GDCM_NAME_SPACE::GDCM_FILESEPARATOR,
+ GDCM_NAME_SPACE::Util::GetName(*it).c_str(),
+ str_isa_func_name.c_str());
+ }
+ DealWithNiveau3(*it, outputDirName);
+ }
+ }
+}
+
+
+//
+// =====================================================================
+//
+
+void Bruker2Dicom::DealWithNiveau3(std::string level3Directory, std::string currentOutputDirName){
+
+//
+// e.g. at level 3, in
+
+ // just to be able to go on checking // JP
+ if ( GDCM_NAME_SPACE::Util::GetName(level3Directory) != "1")
+ return;
+
+ bool res = CreateDirectory(currentOutputDirName);
+
+ if (!res)
+ {
+ std::cout << "[" << currentOutputDirName << "] Directory creation failure " << std::endl;
+ exit (0);
+ }
+
+ GDCM_NAME_SPACE::DirList dirList(level3Directory, false, true); // DON'T get recursively the list of files
+ GDCM_NAME_SPACE::DirListType::iterator it;
+ GDCM_NAME_SPACE::DirListType fileNames;
+ fileNames = dirList.GetFilenames();
+
+ char original2dseqName [(unsigned int) PATH_MAX+2];
+ char currentOutputMhdDirName [(unsigned int) PATH_MAX+2];
+
+ char outputMhdFileName [(unsigned int) PATH_MAX+2];
+ char output2dseqSliceFileName[(unsigned int) PATH_MAX+6]; // think about extra '.dcm'
+ char output2dseqName [(unsigned int) PATH_MAX+6];
+ char output2dseqCartoName [(unsigned int) PATH_MAX+6];
+
+ char copyFile[PATH_MAX + PATH_MAX + 5]; // Should be enough!
+ bool canOpen;
+
+ //-------------- try d3proc;
+ char char_d3proc[(unsigned int) PATH_MAX+2];
+
+ sprintf(char_d3proc,"%s%c%s", level3Directory.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR,"d3proc" );
+
+ if (verbose)
+ std::cout << "--- => [" << char_d3proc << "]" << std::endl;
+ std::string str_d3proc(char_d3proc);
+ canOpen = br_d3proc.LoadFile(str_d3proc);
+
+ if (!canOpen)
+ {
+ std::cout << "Hopeless! no 'd3proc' found" << std::endl;
+ exit(0); /// \TODO throw an exception !
+ }
+
+ canOpen = br_d3proc.FillMap();
+ if (!canOpen)
+ {
+ std::cout << "Hopeless! FillMap failed on 'd3proc'" << std::endl;
+ exit(0); /// \TODO throw an exception !
+ }
+
+ //-------------- end try d3proc;
+
+
+ // -------------------try reco
+
+ char char_reco[(unsigned int) PATH_MAX+2];
+
+ sprintf(char_reco,"%s%c%s", level3Directory.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR,"reco" );
+ //str_d3proc = GDCM_NAME_SPACE::Util::GetPath(*(fileNames.begin()))+
+ // GDCM_NAME_SPACE::GDCM_FILESEPARATOR +
+ // "d3proc";
+ if (verbose)
+ std::cout << "--- => [" << char_reco << "]" << std::endl;
+ std::string str_reco(char_reco);
+ canOpen = br_reco.LoadFile(str_reco);
+
+ if (!canOpen) // we try in directory ../1
+ {
+ if (verbose)
+ std::cout << "[" << str_reco << "] not found " << std::endl;
+ std::string lastDirName = GDCM_NAME_SPACE::Util::GetPath(level3Directory);
+ //lastDirName = GDCM_NAME_SPACE::Util::GetPath(lastDirName);
+ sprintf(char_reco,"%s%c1%c%s", lastDirName.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR,GDCM_NAME_SPACE::GDCM_FILESEPARATOR,"reco" );
+ str_reco=char_reco;
+ canOpen = br_reco.LoadFile(str_reco);
+ if (!canOpen)
+ {
+ std::cout << "Hopeless! cannot find 'reco' in [" << str_reco << "]" << std::endl;
+ exit(0); /// \TODO throw an exception !
+ }
+ }
+
+ canOpen = br_reco.FillMap();
+ if (!canOpen)
+ {
+ std::cout << "Hopeless! FillMap failed on [" << str_reco << "]" << std::endl;
+ exit(0); /// \TODO throw an exception !
+ }
+ //std::cout << "------------------------------------------------------------------------------------------------" << std::cout;
+ // br_reco.PrintSelf();
+ // std::cout << "------------------------------------------------------------------------------------------------" << std::cout;
+
+ // -------------------end try reco
+
+
+ BrukerFieldData bX = br_d3proc.GetFieldData("IM_SIX");
+ int NX = bX.GetIntValue()[0];
+
+ std::cout << "IM_SIX " << NX << std::endl;
+ BrukerFieldData bY=br_d3proc.GetFieldData("IM_SIY");
+ int NY = bY.GetIntValue()[0];
+
+ std::cout << "IM_SIY " << NY << std::endl;
+ /// \todo : check if there are actually 3 dimensions or only 2
+
+ BrukerFieldData bZ= br_d3proc.GetFieldData("IM_SIZ");
+ int nbFrames = bZ.GetIntValue()[0];
+ std::cout << "IM_SIZ " << nbFrames << std::endl;
+
+ // WARNING DATTYPE is, either in {ip_short, ip_int, ip_char, ...}, or in {1, 2, 3, ...}
+
+ BrukerFieldData bDPT = br_d3proc.GetFieldData("DATTYPE");
+
+ std::string mhdDataPixelType;
+ int pixelSize;
+ getImhDataType(bDPT, mhdDataPixelType, pixelSize);
+
+ BrukerFieldData fov = br_method.GetFieldData("PVM_Fov");
+ double fovX = fov.GetDoubleValue()[0];
+ double fovY = fov.GetDoubleValue()[1];
+ if (verbose)
+ std::cout << "FOV (ds method) " << fovX << " " << fovY << std::endl;
+
+ /// \TODO probabely a more sophisticated accessor will be necessary :
+ /// (cf : non contiguous slices, overlapping, slice thickness, space between clices, etc)
+ BrukerFieldData bsliceDistance = br_method.GetFieldData("PVM_SPackArrSliceDistance");
+ double sliceDistance = bsliceDistance.GetDoubleValue()[0];
+
+ if (mhd)
+ {
+ sprintf(currentOutputMhdDirName, "%s%c%s", currentOutputDirName.c_str(),
+ GDCM_NAME_SPACE::GDCM_FILESEPARATOR, "MhdFiles");
+ res = CreateDirectory( currentOutputMhdDirName );
+ if (!res) {
+ std::cout << "[" << currentOutputDirName << "] Directory creation failure " << std::endl;
+ exit (0);
+ }
+
+ if (verbose)
+ std::cout << "Directory creation [" << currentOutputDirName << "]" << std::endl;
+ } // end if mhd
+
+ std::cout << "nbFrames " << nbFrames << std::endl;
+ std::cout << "nbSlices " << nbSlices << std::endl;
+ int k;
+ int nbInstants = nbFrames/nbSlices;
+ std::cout << "nbInstants (deduced )" << nbInstants << std::endl;
+ int instantNb;
+ int sliceNb;
+ FILE *fp; // for MHD files
+
+ sprintf( original2dseqName, "%s%c%s", level3Directory.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR, "2dseq");
+
+/**/
+ // \TODO : tenir compte du bazar precedent
+
+ // load 2dseq in memory
+
+ fp = fopen(original2dseqName, "rb");
+ if (!fp)
+ {
+ std::cout << "Cannot open [" << original2dseqName << "] for reading" << std::endl;
+ exit (0);
+ }
+
+ unsigned char * buffer_2dseq = new unsigned char[NX*NY*pixelSize*nbSlices*nbInstants];
+ ///\ TODO : find a safer way to be sure to read everything!
+ size_t lgr = fread(buffer_2dseq, 1, NX*NY*pixelSize*nbSlices*nbInstants, fp);
+
+ // This one will be important!
+ // ---------------------------
+ imageSet = CreateImageSet ( );
+
+ strSerieUID = GDCM_NAME_SPACE::Util::CreateUniqueUID();
+ if (nbInstants==1) // creer un seul fichier .mhd pour toutes les Slices! (images natives)
+ {
+ std::cout << "Single instant : do not split" << std::endl;
+ if (mhd)
+ {
+ sprintf(outputMhdFileName, "%s%cMhdData_Toutes_les_Slices.mhd", currentOutputMhdDirName,
+ GDCM_NAME_SPACE::GDCM_FILESEPARATOR);
+ fp=fopen(outputMhdFileName, "w");
+ if (!fp)
+ {
+ std::cout << "Cannot open [" << outputMhdFileName << "] for writting" << std::endl;
+ exit(0);
+ }
+ else
+ {
+ fprintf(fp, "ObjectType = Image\n");
+ fprintf(fp, "NDims = 3\n" );
+ fprintf(fp, "BinaryData = True \n" );
+ fprintf(fp, "BinaryDataByteOrderMSB = False\n" );
+ 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, "Position = 0 0 %d\n", 0 );
+ fprintf(fp, "Offset = 0 0 0\n" );
+ fprintf(fp, "CenterOfRotation = 0 0 0\n" );
+ fprintf(fp, "ElementNumberOfChannels = 1\n" );
+ fprintf(fp, "ElementType = %s\n", mhdDataPixelType.c_str() );
+ fprintf(fp, "ElementDataFile = %s\n", "../2dseq_toutes_les_Slices" );
+ fclose(fp);
+ }
+ sprintf(output2dseqSliceFileName, "%s%c2dseq_toutes_les_Slices",
+ currentOutputDirName.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR);
+ fp=fopen(output2dseqSliceFileName, "wb");
+ if (!fp)
+ {
+ std::cout << "Cannot open [" << output2dseqSliceFileName << "] for writting" << std::endl;
+ }
+ else
+ {
+ fwrite( buffer_2dseq, NX*NY*pixelSize, nbSlices, fp);
+ }
+ fclose(fp);
+ strSerieUID = GDCM_NAME_SPACE::Util::CreateUniqueUID();
+ } // end if mhd
+ if (dicom)
+ {
+ sprintf(output2dseqSliceFileName, "%s%c2dseq_toutes_les_Slices.dcm",
+ currentOutputDirName.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR);
+
+ /* ----------- Write Dicom Image ---------------*/
+ MakeDicomImage(buffer_2dseq,
+ NX,
+ NY,
+ nbFrames,
+ pixelSize,
+ fovX/NY, fovY/NY, sliceDistance,
+ output2dseqSliceFileName,
+ strPatientName,
+ day,
+ strStudyUID,
+ strSerieUID,
+ strStudyDescr,
+ strSerieDescr,
+ strStudyTimeDate,
+ 0,// index frame number
+ GDCM_NAME_SPACE::UNMODIFIED_PIXELS_IMAGE
+ );
+ } // end if dicom
+ } // end if nbInstants = 1
+
+ else // more than ONE instant
+ {
+ // Interleaved !
+ // it's (slice1,slide2, ...)t1 ; (slice1,slide2, ...)t2 ; ...
+
+ unsigned char * pixelsForCurrentSlice = new unsigned char[NX*NY*pixelSize*nbInstants];
+
+ k = 0;
+ for (sliceNb=0; sliceNb<nbSlices; sliceNb++)
+ {
+ if (mhd)
+ {
+ sprintf(outputMhdFileName, "%s%cMhdData_%03d.mhd", currentOutputMhdDirName,
+ GDCM_NAME_SPACE::GDCM_FILESEPARATOR, k );
+ if (verbose)
+ std::cout << "--- Output MHD file [" << outputMhdFileName << "]" << std::endl;
+ fp=fopen(outputMhdFileName, "w");
+ if (!fp)
+ {
+ std::cout << "Cannot open [" << outputMhdFileName << "] for writting" << std::endl;
+ exit(0);
+ }
+ else
+ {
+ /* ----------- Write MHD Image ---------------*/
+ //if (verbose)
+ // std::cout << "Open sucessfully[" << outputMhdFileName << "] for writting" << std::endl;
+ fprintf(fp, "ObjectType = Image\n");
+ fprintf(fp, "NDims = 3\n" );
+ fprintf(fp, "BinaryData = True \n" );
+ fprintf(fp, "BinaryDataByteOrderMSB = False\n" );
+ fprintf(fp, "DimSize = %d %d %d\n", NX, NY, nbInstants);
+ fprintf(fp, "HeaderSize = %d\n", 0);
+ fprintf(fp, "ElementSpacing = %lf %lf %lf\n",fovX/NY, fovY/NY, 1.0 ); // slice distance : no meaning for temporal serie
+ fprintf(fp, "Position = 0 0 %d\n", sliceNb );
+ fprintf(fp, "Offset = 0 0 0\n" );
+ fprintf(fp, "CenterOfRotation = 0 0 0\n" );
+ fprintf(fp, "ElementNumberOfChannels = 1\n" );
+ fprintf(fp, "ElementType = %s\n", mhdDataPixelType.c_str() );
+ fprintf(fp, "ElementDataFile = ..%c2dseq_Slice_%d\n", GDCM_NAME_SPACE::GDCM_FILESEPARATOR, sliceNb );
+ fclose(fp);
+ } // end write MHD
+
+ sprintf(output2dseqSliceFileName, "%s%c2dseq_Slice_%d",
+ currentOutputDirName.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR,sliceNb);
+ fp=fopen(output2dseqSliceFileName, "wb");
+ if (!fp)
+ {
+ std::cout << "Cannot open [" << output2dseqSliceFileName << "] for writting" << std::endl;
+ exit (0);
+ }
+ int frameSize = NX*NY*pixelSize;
+ for (instantNb=0; instantNb<nbInstants; instantNb++)
+ {
+// std::cout << "------------SN " << sliceNb << " IN " << instantNb << " T " << nbSlices*instantNb + sliceNb << std::endl;
+ fwrite( buffer_2dseq +(nbSlices*instantNb + sliceNb)*frameSize,
+ frameSize,
+ 1, fp);
+ }
+ fclose(fp);
+// std::cout << "end writting[" << output2dseqSliceFileName << "]" << std::endl;
+ } // end if mhd
+
+ if (dicom)
+ {
+ // desperate try !
+ /*
+ sprintf(output2dseqSliceFileName, "%sdummy_buffer",
+ currentOutputDirName.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR);
+ fp=fopen(output2dseqSliceFileName, "wb");
+ if (!fp)
+ {
+ std::cout << "Cannot open [" << output2dseqSliceFileName << "] for writting" << std::endl;
+ exit (0);
+ }
+ int frameSize = NX*NY*pixelSize;
+ for (instantNb=0; instantNb<nbInstants; instantNb++)
+ {
+// std::cout << "------------SN " << sliceNb << " IN " << instantNb << " T " << nbSlices*instantNb + sliceNb << std::endl;
+ fwrite( buffer_2dseq +(nbSlices*instantNb + sliceNb)*frameSize,
+ frameSize,
+ 1, fp);
+ }
+ fclose(fp);
+
+ fp=fopen(output2dseqSliceFileName, "rb");
+ if (!fp)
+ {
+ std::cout << "Cannot open [" << output2dseqSliceFileName << "] for reading" << std::endl;
+ exit (0);
+ }
+ fread( pixelsForCurrentSlice,
+ frameSize*nbInstants,
+ 1, fp);
+ fclose(fp);
+ // end of desperate try !
+ */
+
+ /* ----------- Write Dicom Image ---------------*/
+
+ int frameSize = NX*NY*pixelSize;
+ for (instantNb=0; instantNb<nbInstants; instantNb++)
+ {
+ memcpy(pixelsForCurrentSlice + frameSize*instantNb, buffer_2dseq +(nbSlices*instantNb + sliceNb)*frameSize, frameSize);
+ }
+
+ int indOfFirsImageWithinImageSet = nbSlices*instantNb;
+ sprintf(output2dseqSliceFileName, "%s%c2dseq_Slice_%d.dcm",
+ currentOutputDirName.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR, sliceNb);
+
+ MakeDicomImage(
+ pixelsForCurrentSlice,
+ NX,
+ NY,
+ nbInstants,
+ pixelSize,
+ fovX/NY, fovY/NY, sliceDistance,
+ output2dseqSliceFileName,
+ strPatientName,
+ day,
+ strStudyUID,
+ strSerieUID,
+ strStudyDescr,
+ strSerieDescr,
+ strStudyTimeDate,
+ sliceNb*nbInstants,
+ GDCM_NAME_SPACE::UNMODIFIED_PIXELS_IMAGE
+ );
+ if (verbose)
+ std::cout << "--- Output DCM file [" << output2dseqSliceFileName << "]" << std::endl;
+
+ } // en if dicom
+
+ k++;
+ }
+ delete [] pixelsForCurrentSlice;
+ } // end nbInstants == 1
+ delete [] buffer_2dseq;
+/**/
+
+
+ // -----------------------------------------------------
+ // deal with MatLab-generated Carto file.
+ // -----------------------------------------------------
+
+ dealWithCarto(fileNames, NX, NY, nbSlices, fovX, fovY, sliceDistance,
+ copyFile, currentOutputDirName, outputMhdFileName, output2dseqCartoName);
+}
+
+
+// ===========================================================================================
+
+void Bruker2Dicom::dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX, int NY, int nbSlices,
+ double fovX, double fovY, double sliceDistance,
+ char *copyFile, std::string ¤tOutputDirName,
+ char *outputMhdFileName, char *output2dseqCartoName)
+{
+ // -----------------------------------------------------
+ // deal with MatLab-generated Carto file.
+ // -----------------------------------------------------
+
+ char *code[] ={ "ADC", "adc", "TTP", "ttp", "PEAK", "peak" , ""}; // add more carto file name identifiers if necessary; end with ""
+ int icode;
+ GDCM_NAME_SPACE::DirListType::iterator it;
+ char file_name_ident[500];
+ FILE *fp;
+
+ // Iterate to ALL the objets(files/directories) found in the input directory
+ for (it = fileNames.begin();
+ it != fileNames.end();
+ ++it)
+ {
+ if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(*it) )
+ {
+ if (verbose)
+ std::cout << "--- [" << *it << "] is a file" << std::endl;
+
+ icode = 0;
+
+ while (code[icode][0] != 0)
+ {
+ sprintf(file_name_ident, "2dseq_%s",code[icode]); // e.g "2dseq_ADC"
+ std::string::size_type loc = (*it).rfind(file_name_ident);
+
+ if ( loc != std::string::npos )
+ {
+
+ ///\ TODO : find a safer way to be sure to read everything!
+ unsigned char *buffer_carto = new unsigned char[NX*NY*sizeof(double)*nbSlices];
+ fp = fopen ( (*it).c_str(), "rb");
+ if (!fp){
+ std::cout << "Cannot open [" << *it << "] for reading" << std::endl;
+
+ }
+ fread(buffer_carto, NX*NY*sizeof(double), nbSlices, fp);
+
+ std::cout << "Deal with Carto file :[" <<*it << "], computed length : "
+ << NX*NY*sizeof(double)*nbSlices << std::endl;
+ std::string lastFileName = GDCM_NAME_SPACE::Util::GetName((*it).c_str());
+ if (mhd)
+ {
+ // Copy the data file in the new directory
+ sprintf(copyFile, "cp %s %s%c%s", (*it).c_str() ,
+ currentOutputDirName.c_str(),GDCM_NAME_SPACE::GDCM_FILESEPARATOR, lastFileName.c_str());
+ system(copyFile);
+ sprintf(outputMhdFileName, "%s%c%s%s",
+ currentOutputDirName.c_str(),GDCM_NAME_SPACE::GDCM_FILESEPARATOR, lastFileName.c_str(), ".mhd" );
+ if (verbose)
+ std::cout << "--- Output Carto MHD file [" << outputMhdFileName << "]" << std::endl;
+
+ FILE *fp;
+ fp=fopen(outputMhdFileName, "w");
+ if (!fp)
+ {
+ std::cout << "Cannot open [" << outputMhdFileName << "] for writting" << std::endl;
+ }
+ else
+ {
+ fprintf(fp, "ObjectType = Image\n");
+ fprintf(fp, "NDims = 3\n" );
+ fprintf(fp, "BinaryData = True \n" );
+ fprintf(fp, "BinaryDataByteOrderMSB = False\n" );
+ fprintf(fp, "DimSize = %d %d %d\n", NX, NY, nbSlices);
+ fprintf(fp, "ElementSpacing = %lf %lf %lf\n",fovX/NY, fovY/NY, sliceDistance );
+ fprintf(fp, "HeaderSize = %d\n", 0 );
+ fprintf(fp, "ElementSpacing = %lf %lf %lf\n",fovX/NY, fovY/NY, sliceDistance );
+ fprintf(fp, "Position = 0 0 0\n" );
+ fprintf(fp, "Offset = 0 0 0\n" );
+ fprintf(fp, "CenterOfRotation = 0 0 0\n" );
+ fprintf(fp, "ElementNumberOfChannels = 1\n" );
+ fprintf(fp, "ElementType = %s\n", "MET_DOUBLE" );
+ fprintf(fp, "ElementDataFile = %s\n", lastFileName.c_str() );
+
+ fclose(fp);
+ }
+ if (verbose)
+ std::cout << "--- end write Carto MHD file [" << outputMhdFileName << "]" << std::endl;
+ } // end if mhd
+
+ // ----------- Write Dicom Image ---------------
+
+ if (dicom)
+ {
+ sprintf(output2dseqCartoName, "%s%c%s%s",
+ currentOutputDirName.c_str(),GDCM_NAME_SPACE::GDCM_FILESEPARATOR, lastFileName.c_str(), ".dcm" );
+ if (verbose)
+ std::cout << "--- end create name output2dseqCartoName file [" << output2dseqCartoName << "]" << std::endl;
+
+ strSerieUID = GDCM_NAME_SPACE::Util::CreateUniqueUID(); //New SerieUID for each carto.
+ std::string strNewSerieDescr(strSerieDescr+ "_" +GDCM_NAME_SPACE::Util::GetName((*it).c_str()));
+ MakeDicomImage(buffer_carto,
+ NX,
+ NY,
+ nbSlices,
+ 8, // pixelSize
+ fovX/NY, fovY/NY, sliceDistance,
+ output2dseqCartoName,
+ strPatientName,
+ day,
+ strStudyUID,
+ strSerieUID,
+ strStudyDescr,
+ strNewSerieDescr,
+ strStudyTimeDate,
+ 0,
+ GDCM_NAME_SPACE::CREATED_IMAGE
+ );
+ } // end if dicom
+
+ delete [] buffer_carto;
+ if (verbose)
+ std::cout << "--- End writing Carto DICOM file [" << output2dseqCartoName << "]" << std::endl;
+ break; // don't check for more ident on same file name!
+
+ }
+ icode++;
+ }
+ }
+ } // end iterate on files
+}
+
+
+// ==========================================================================================================
+
+bool Bruker2Dicom::CreateDirectory(std::string OutputDirName)
+{
+ std::string systemCommand;
+
+ if (verbose)
+ std::cout << "Check for output directory :[" << OutputDirName << "]."
+ <<std::endl;
+ if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(OutputDirName) ) // dirout not found
+ {
+ std::string strDirNameout(OutputDirName); // to please gcc 4
+ systemCommand = "mkdir " + strDirNameout; // create it!
+ if (verbose)
+ std::cout << systemCommand << std::endl;
+ system (systemCommand.c_str());
+ if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(OutputDirName) ) // be sure it worked
+ {
+ if (verbose)
+ std::cout << "KO : not a dir : [" << OutputDirName << "] (creation failure ?)" << std::endl;
+ return 0;
+ /// \todo : THROW AN EXCEPTION
+ }
+ else
+ {
+ if (verbose)
+ std::cout << "Directory [" << OutputDirName << "] created." << std::endl;
+ }
+ }
+ else
+ {
+ if (verbose)
+ std::cout << "Output Directory [" << OutputDirName << "] already exists; Used as is." << std::endl;
+ }
+
+ return 1;
+
+}
+
+
+// ===========================================================================================
+
+/// \TODO move cleanString to 'crea' ?
+
+void Bruker2Dicom::cleanString(std::string &s)
+{
+ int l = s.size();
+ if (s[l-1] == 0x0A || s[l-1] == 0x0D ) // CR or NL
+ {
+ l--;
+ s = s.substr(0, l);
+ }
+ if (s[l-1] == ' ' ) // blank space
+ {
+ l--;
+ s = s.substr(0, l);
+ }
+
+ if (s[0] == '<')
+ s= s.substr(1,l-2);
+ std::string repChar("_");
+ GDCM_NAME_SPACE::Util::ReplaceSpecChar(s, repChar);
+}
+
+
+
+// ===========================================================================================
+
+
+void Bruker2Dicom::getImhDataType(BrukerFieldData &bDPT, std::string &mhdDataPixelType, int &pixelSize)
+{
+ if(bDPT.GetDataType() == "string")
+ {
+ std::string brukerDataPixelType = bDPT.GetStringValue()[0];
+ std::cout << "DATTYPE " << brukerDataPixelType << std::endl;
+ //std::string brukerDataPixelType = br_d3proc.GetFieldData("DATTYPE").GetStringValue()[0];
+
+ if (brukerDataPixelType == "ip_short") {
+ mhdDataPixelType = "MET_USHORT";
+ pixelSize = 2;
+ }
+ if (brukerDataPixelType == "ip_int") {
+ mhdDataPixelType = "MET_UINT";
+ pixelSize = 4;
+ }
+ if (brukerDataPixelType == "ip_char") {
+ mhdDataPixelType = "MET_UCHAR";
+ pixelSize = 1;
+ }
+ /// \TODO : finish the list
+ /*
+ case 0 : fp << "ElementType = MET_CHAR" << std::endl;
+ break;
+ case 1 : fp << "ElementType = MET_UCHAR" << std::endl;
+ break;
+ case 2 : fp << "ElementType = MET_SHORT" << std::endl;
+ break;
+ case 3 : fp << "ElementType = MET_USHORT" << std::endl;
+ break;
+ case 4 : fp << "ElementType = MET_INT" << std::endl;
+ break;
+ case 5 : fp << "ElementType = MET_UINT" << std::endl;
+ break;
+ case 6 : fp << "ElementType = MET_FLOAT" << std::endl;
+ break;
+ case 7 : fp << "ElementType = MET_DOUBLE" << std::endl;
+ */
+ }
+ else
+ {
+ int brukerDataPixelType = bDPT.GetIntValue()[0];
+ std::cout << "DATTYPE " << brukerDataPixelType << std::endl;
+ //std::string brukerDataPixelType = br_d3proc.GetFieldData("DATTYPE").GetStringValue()[0];
+
+// Cross your fingers !!!
+
+// pb : found values : 2, 3, 5
+
+ if (brukerDataPixelType == 2) {
+ mhdDataPixelType = "MET_USHORT";
+ pixelSize = 2;
+ }
+ if (brukerDataPixelType == 3) {
+ mhdDataPixelType = "MET_USHORT";
+ pixelSize = 2;
+ }
+ if (brukerDataPixelType == 1) {
+ mhdDataPixelType = "MET_UCHAR";
+ pixelSize = 1;
+ }
+ }
+}
+
+// ===========================================================================================
+
+std::vector<BrukerImage> Bruker2Dicom::CreateImageSet ( )
+{
+ std::vector<BrukerImage> imageSet;
+ br_acqp.SetLoopStructure();
+ std::vector<int> tempVect = br_acqp.GetLoopStructure() ;
+ std::map<std::string, BrukerFieldData> map = br_acqp.GetBrukerHeaderMap();
+ bool result = br_acqp.ObjectVaryingProperties.init(map,tempVect);
+
+ br_acqp.SetImageLoopStructure();
+ br_acqp.SetBrukerImageList();
+ std::vector<std::vector<int> > brukerImageList = br_acqp.GetBrukerImageList();
+
+ 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] ;
+ imageOrientation = imageSet[i].getRotationMatrixRPS2XYZ();
+ std::cout << "\t Orientation " ;
+ for(int i1=0; i1<3;i1++)for(int i2=0; i2<3;i2++)
+ std::cout << imageOrientation[i1][i2] << " ";
+
+ //std::cout << "\t Abs Time " << imageSet[i].getAbsoluteTimePosition();
+ std::cout << "\t Relat Time " << imageSet[i].getRelativeTimePosition();
+
+ std::cout << "\t [";
+ for (int i3=0; i3<imageSet[i].getLoopStamp().size();i3++)
+ std::cout << " " << imageSet[i].getLoopStamp()[i3];
+ std::cout << "]" << std::endl;
+ }
+*/
+ return imageSet;
+}
+
+
+// ===========================================================================================
+
+void Bruker2Dicom::MakeDicomImage(unsigned char *tabPixels,
+ int X,
+ int Y,
+ int nbFrames,
+ int pixelSize,
+ double spacingX, double spacingY, double sliceDistance,
+ std::string dcmImageName,
+ const std::string &patientName,
+ const char *day,
+ std::string &studyUID,
+ std::string &serieUID,
+ std::string &studyDescr,
+ std::string &serieDescr,
+ std::string &strStudyTimeDate,
+ int imgNum,
+ GDCM_NAME_SPACE::ImageContentType contentType
+ )
+{
+ std::ostringstream str;
+
+ GDCM_NAME_SPACE::File *file;
+ file = GDCM_NAME_SPACE::File::New();
+
+ // Set the image size
+ str.str("");
+ str << X;
+ file->InsertEntryString(str.str(),0x0028,0x0011,"US"); // Columns
+ str.str("");
+ str << Y;
+ file->InsertEntryString(str.str(),0x0028,0x0010,"US"); // Rows
+
+ if (nbFrames != 1)
+ {
+ str.str("");
+ str << nbFrames;
+ file->InsertEntryString(str.str(),0x0028,0x0008,"IS"); // Number of Frames
+ }
+
+ // Set the pixel type
+ // //8, 16, 32, 64 (for double ?)
+ str.str("");
+ str << pixelSize*8;
+ file->InsertEntryString(str.str(),0x0028,0x0100,"US"); // Bits Allocated
+
+ file->InsertEntryString(str.str(),0x0028,0x0101,"US"); // Bits Stored
+
+ str.str("");
+ str << pixelSize*8-1;
+ file->InsertEntryString(str.str(),0x0028,0x0102,"US"); // High Bit
+
+ // 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
+
+// 0028 0030 DS 2 Pixel Spacing
+ 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");
+
+ // 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" , 0x0008, 0x0016, "UI"); // [SOP Class UID]
+
+
+// OK : MR is NOT multiframe, but I want just a quick an dirty solution
+// 1.2.840.10008.5.1.4.1.1.4 MR Image Storage
+ file->InsertEntryString("1.2.840.10008.5.1.4.1.1.4" , 0x0002, 0x0002, "UI"); // [Media Storage SOP Class UID]
+ file->InsertEntryString("1.2.840.10008.5.1.4.1.1.4" , 0x0008, 0x0016, "UI"); // [SOP Class UID]
+
+ // if (strlen(patientName) != 0)
+ file->InsertEntryString(patientName.c_str(),0x0010,0x0010, "PN"); // Patient's Name
+
+ file->InsertEntryString(studyUID, 0x0020, 0x000d, "UI");
+ file->InsertEntryString(serieUID, 0x0020, 0x000e, "UI");
+
+// 0008 0020 DA 1 Study Date
+// 0008 0030 TM 1 Study Time
+
+/// \TODO split into 2 strings!
+ file->InsertEntryString(strStudyTimeDate.substr(10,11).c_str(),0x0008,0x0020, "DA");
+ file->InsertEntryString(strStudyTimeDate.substr(1,8).c_str(),0x0008,0x0030, "TM");
+
+ file->InsertEntryString(studyDescr,0x0008,0x1030, "LO"); // Study Description
+ file->InsertEntryString(serieDescr,0x0008,0x103e, "LO"); // Series Description
+
+//0008|0060 [CS] [Modality]
+ file->InsertEntryString("MR",0x0008,0x0060, "CS");
+
+// 0020 0037 DS 6 Image Orientation (Patient)
+ char charImageOrientation[256];
+
+/*
+std::cout << "try charImageOrientation " <<
+ imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][0] << " " <<
+ imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][1] << " " <<
+ imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][2] << " " <<
+ imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][0] << " " <<
+ imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][1] << " " <<
+ imageSet[imgNum].getRotationMatrixRPS2XYZ()[1][2] << std::endl ;
+*/
+ sprintf(charImageOrientation,"%f\\%f\\%f \\ %f\\%f\\%f",
+ imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][0],
+ imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][1],
+ imageSet[imgNum].getRotationMatrixRPS2XYZ()[0][2],
+ 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)
+
+ char charImagePosition[256];
+ sprintf(charImagePosition,"%f\\%f\\%f",
+ 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)
+
+
+
+// 0020 0x1041 DS 1 Slice Location
+// sprintf(charImagePosition,"%f",float(imgNum));
+// file->InsertEntryString(charImagePosition,0x0020,0x1041, "DS");
+/*
+ // Set Rescale Intercept
+ str.str("");
+ str << div;
+ file->InsertEntryString(str.str(),0x0028,0x1052,"DS");
+
+ // Set Rescale Slope
+ str.str("");
+ str << mini;
+ file->InsertEntryString(str.str(),0x0028,0x1053,"DS");
+*/
+
+ GDCM_NAME_SPACE::FileHelper *fileH;
+ fileH = GDCM_NAME_SPACE::FileHelper::New(file);
+ 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!
+
+//std::cout << "-------------------------------- X*Y*nbFrames*pixelSize " << X << " " << Y << " " << nbFrames << " " << pixelSize << std::endl;
+
+ fileH->SetImageData((uint8_t *)tabPixels, X*Y*nbFrames*pixelSize);
+ fileH->SetWriteModeToRaw();
+ fileH->SetWriteTypeToDcmExplVR();
+ if( !fileH->Write(dcmImageName))
+ std::cout << "Failed for [" << dcmImageName << "]\n"
+ << " File is unwrittable" << std::endl;
+
+ if (verbose)
+ file->Print();
+
+ file->Delete();
+ fileH->Delete();
+}
+
+
--- /dev/null
+#ifndef BRUKER2DICOM_H
+#define BRUKER2DICOM_H
+
+
+#include "gdcmFile.h"
+#include "gdcmFileHelper.h"
+#include "gdcmCommon.h"
+#include "gdcmDebug.h"
+#include "gdcmUtil.h"
+#include "gdcmDirList.h"
+
+#include "gdcmArgMgr.h"
+#include "brukerSystem.h"
+#include "brukerdataset.h"
+#include "brukerkspaceobject.h"
+#include "brukerimage.h"
+
+#include <iostream>
+#include <sstream>
+
+
+
+class creaBruker_EXPORT Bruker2Dicom {
+
+public:
+ /*! \brief Constructor
+*/
+ Bruker2Dicom () /* : verbose(0), mhd(0), dicom(0), day(O)*/ {};
+/*! \brief Destructor
+*/
+ ~Bruker2Dicom (){};
+
+ void SetInputDirectory (const std::string &i) { InputDirName = i; }
+ void SetOutputDirectory(const std::string &o) { OutputDirName = o; }
+ void SetConvertModeToDicom() { dicom = 1; mhd = 0;}
+ void SetConvertModeToMhd() { dicom = 0; mhd = 1;}
+ bool Execute();
+
+ /*
+ // For debugging pupose only.
+ //Don't need accessors : Attributes are 'public'
+
+ void SetVerbose(int v) { verbose = v;}
+ void SetMhd(int m) { mhd = m; }
+ void SetDicom(int d) { dicom = d; }
+ */
+
+private :
+
+void MakeDicomImage(unsigned char *tabPixels,
+ int X,
+ int Y,
+ int nbFrames,
+ int pixelSize,
+ double spacingX, double spacingY, double sliceDistance,
+ std::string dcmImageName,
+ const std::string &patientName,
+ const char *day,
+ std::string &studyUID,
+ std::string &serieUID,
+ std::string &studyDescr,
+ std::string &serieDescr,
+ std::string &strStudyTimeDate,
+ int imgNum,
+ GDCM_NAME_SPACE::ImageContentType contentType
+ );
+
+std::vector<BrukerImage> CreateImageSet ( );
+
+void getImhDataType(BrukerFieldData &bDPT,
+ std::string &mhdDataPixelType,
+ int &pixelSize);
+
+void cleanString(std::string &s);
+
+bool CreateDirectory(std::string dirNameout);
+
+void DealWithNiveau1(std::string level1Directory, std::string currentOutputDirName);
+void DealWithNiveau2(std::string level2Directory, std::string currentOutputDirName);
+void DealWithNiveau3(std::string level3Directory, std::string currentOutputDirName);
+
+void dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX, int NY, int nbSlices,
+ double fovX, double fovY, double sliceDistance,
+ char *copyFile, std::string ¤tOutputDirName,
+ char *outputMhdFileName, char *output2dseqCartoName);
+
+public:
+
+// these ones are for debugging only
+// don't bbfy the accessors.
+
+ int verbose;
+ const char *day;
+
+private :
+ std::string InputDirName;
+ std::string OutputDirName;
+
+ int mhd;
+ int dicom;
+
+ int nbSlices;
+ BrukerDataSet br_subject;
+ BrukerDataSet br_acqp;
+ BrukerDataSet br_method;
+ BrukerDataSet br_d3proc;
+ BrukerDataSet br_isa;
+ BrukerDataSet br_reco;
+
+ std::vector<BrukerImage> imageSet;
+
+// For DICOM images.
+
+ std::string strStudyUID;
+ std::string strSerieUID;
+ std::string strStudyDescr;
+ std::string strSerieDescr;
+ std::string strStudyTimeDate;
+ std::string strPatientName;
+};
+
+
+#endif
--- /dev/null
+#include "brukerFieldData.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+
+void BrukerFieldData::PrintSelf()
+{
+ int i;
+
+ //std::cout<< "KeyWord = "<<KeyWord <<std::endl;
+ std::string dataType = DataType;
+
+ std::cout<<"DataType = "<<dataType<<std::endl;
+
+ std::cout<<"DimensionNumber = "<<DimensionNumber<<std::endl;
+ for (i=1;i<=DimensionNumber;i++)
+ std::cout<<"DimensionNumberValue["<<i<<"] = "<<DimensionNumberValue[i]<<std::endl;
+
+ int numberOfElements = NumberOfElements;
+ std::cout<<"NumberOfElements = " << numberOfElements <<std::endl;
+
+ for(i=0;i<numberOfElements;i++)
+ {
+ if (dataType == "int")
+ std::cout<<" value["<<i<<"] = ["<<IntValue[i]<< "]" <<std::endl;
+ if (dataType == "float")
+ std::cout<<"value["<<i<<"] = ["<<DoubleValue[i]<< "]" <<std::endl;
+ if (dataType == "string")
+ std::cout<<"value["<<i<<"] = ["<<StringValue[i]<< "]" << std::endl;
+ }
+
+}
--- /dev/null
+#ifndef BRUKERFIELDDATA_H
+#define BRUKERFIELDDATA_H
+/*! \file brukerFieldData.h
+*/
+#include <string>
+#include <vector>
+#include "brukerSystem.h"
+
+ /**
+\class BrukerFieldData
+ \brief This class is an atom to generate a BrukerDataSet
+ */
+class creaBruker_EXPORT BrukerFieldData {
+friend class BrukerDataSet;
+public:
+ /*! \brief Constructor
+*/
+ BrukerFieldData () {};
+/*! \brief Destructor
+*/
+ ~BrukerFieldData (){};
+/*! \brief Returns the keyword type: int, float, string as a string
+*/
+ const std::string &GetDataType() { return DataType;}
+/*! \fn int GetDimensionNumber()
+ \brief Returns the dimension of the keyword:
+ 0-> scalar
+ 1-> 1D vector
+ 2-> 2D vector
+ ...
+*/
+ int GetDimensionNumber() { return DimensionNumber;}
+/*! \fn const std::vector<int> &GetDimensionNumberValue( )
+\brief Returns a vector of size DimensionNumber giving the size of each dimension of the keyword
+*/
+ const std::vector<int> &GetDimensionNumberValue( ) { return DimensionNumberValue;}
+/*! \fn int GetNumberOfElements()
+\brief Returns the total number of elements for keyword
+*/
+ int GetNumberOfElements() { return NumberOfElements;}
+/*!
+\fn const std::vector<std::string> &GetStringValue()
+\brief Return a string vector of all the element of keyword
+*/
+ const std::vector<std::string> &GetStringValue() { return StringValue;}
+/*!
+\fn const std::vector<int> &GetIntValue ()
+\brief Return an int vector of all the element of keyword
+*/
+ const std::vector<int> &GetIntValue () { return IntValue;}
+/*!
+\fn const std::vector<double> &GetDoubleValue()
+\brief Return a double vector of all the element of keyword
+*/
+ const std::vector<double> &GetDoubleValue() { return DoubleValue;}
+
+
+ void PrintSelf();
+
+private :
+/*! \var DataType
+\brief Datatype of the keyword content
+*/
+ std::string DataType;
+/*! \var DimensionNumber
+\brief Dimmensionnality of the keyword
+*/
+ int DimensionNumber;
+/*! \var DimensionNumberValue
+\brief Vector of int giving the dimension of each dimension of the keyword content
+*/
+ std::vector<int> DimensionNumberValue;
+/*! \var NumberOfElements
+\brief Total number of elements contained in keyword
+*/
+ int NumberOfElements;
+/*! \var StringValue
+\brief Vector of string containing the elements of keyword if they are string
+*/
+ std::vector<std::string> StringValue;
+/*! \var IntValue
+\brief Vector of string containing the elements of keyword if they are string
+*/
+ std::vector<int> IntValue;
+/*! \var DoubleValue
+\brief Vector of string containing the elements of keyword if they are string
+*/
+ std::vector<double> DoubleValue;
+};
+#endif
--- /dev/null
+
+#ifndef _BRUKERSYSTEM_H_
+#define _BRUKERSYSTEM_H_
+
+
+// Windoze related troubles (as usual)
+
+//-----------------------------------------------------------------------------
+
+#if defined(_WIN32)
+ #ifdef creaBruker_EXPORT_SYMBOLS
+ #define creaBruker_EXPORT __declspec( dllexport )
+#else
+ #define creaBruker_EXPORT __declspec( dllimport )
+ #endif
+ #define creaBruker_CDECL __cdecl
+#else
+ #define creaBruker_EXPORT
+ #define creaBruker_CDECL
+#endif // defined(_WIN32)
+
+#ifdef __BORLANDC__
+ #include <mem.h>
+#endif
+
+#endif
--- /dev/null
+//
+// C++ Implementation: brukerdataset
+//
+// Description:
+//
+//
+// Author: <Denis Grenier>, (C) 2008
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+
+#define DEBUG 0
+
+#include "brukerdataset.h"
+
+BrukerDataSet::BrukerDataSet(){}
+
+
+BrukerDataSet::~BrukerDataSet(){}
+
+
+bool BrukerDataSet::LoadFile(std::string& fileToRead)
+{
+
+//std::cout <<
+//"------------- BrukerDataSet::LoadFile() Open : [" << fileToRead << "]" << std::endl;
+ std::ifstream FID;
+ char * buffer;
+ FID.open(fileToRead.c_str(), std::ios::binary);
+ if (FID.rdstate()==std::ios::failbit) {
+ //std::cout << "BrukerDataSet::LoadFile() Cannot open : [" << fileToRead << "]" << std::endl;
+ return false;
+ }
+
+ FID.seekg (0, std::ios::end);
+ int length = FID.tellg();
+ FID.seekg (0, std::ios::beg);
+
+ buffer = new char [length];
+ FID.read (buffer,length);
+ FID.close();
+ BrukerDataSet::WholeHeader=buffer;
+ delete [] buffer;
+ return true;
+}
+
+
+
+std::string BrukerDataSet::SearchBufferForText(std::string& file, const boost::regex& RegExp)
+{
+ boost::cmatch what;
+ if (regex_search(file.c_str(), what, RegExp))
+ return what[1];
+ return "";
+}
+
+
+/**
+ *
+ * @param file
+ * @param RegExp
+ * @return bool
+ */
+bool BrukerDataSet::BoolMatchBufferForText(std::string& file, const boost::regex& RegExp)
+{
+ boost::cmatch what;
+ if (regex_match(file.c_str(), what, RegExp))
+ return true;
+ return false;
+}
+
+
+
+std::string BrukerDataSet::MatchBufferForText(std::string& file,const boost::regex& RegExp)
+{
+ boost::cmatch what;
+ if (regex_match(file.c_str(), what, RegExp))
+ return what[1];
+ return "";
+}
+
+
+
+std::string BrukerDataSet::GetKeyword(std::string& file)
+{
+ return MatchBufferForText( file,KeyWord);
+}
+
+
+
+int BrukerDataSet::GetDimensionnality(std::string& file)
+{
+ int iterator=0;
+ std::string DimensionnalityBuffer=SearchBufferForText(file,Dimensionnality);
+ if (DimensionnalityBuffer=="")
+ return iterator;
+ boost::match_results<std::string::const_iterator> what;
+ boost::match_flag_type flags= boost::match_default;
+ std::string::const_iterator start,end;
+ start=DimensionnalityBuffer.begin();
+ end=DimensionnalityBuffer.end();
+
+ while (regex_search(start, end, what, UnsignedInteger))
+ {
+ iterator++;
+ start=what[0].second;
+ flags |= boost::match_prev_avail;
+ flags |= boost::match_not_bob;
+ }
+ return iterator;
+}
+
+
+
+int BrukerDataSet::GetIntValueOfDimN(std::string& file, int N)
+{
+ int iterator=0;
+ std::string DimensionnalityBuffer=SearchBufferForText(file,Dimensionnality);
+ if (N < 1 || DimensionnalityBuffer=="")
+ return 0;
+ //std::cout << DimensionnalityBuffer << std::endl;
+ boost::match_results<std::string::const_iterator> what;
+ boost::match_flag_type flags= boost::match_default;
+ std::string::const_iterator start,end;
+ start=DimensionnalityBuffer.begin();
+ end=DimensionnalityBuffer.end();
+
+ for (int i=1;i<=N;i++)
+ {
+ regex_search(start,end, what, UnsignedInteger);
+ iterator++;
+ start=what[0].second;
+ flags |= boost::match_prev_avail;
+ flags |= boost::match_not_bob;
+ }
+ return atoi(std::string(what[1].first,what[1].second).c_str());
+}
+
+
+
+std::string BrukerDataSet::GetValuesPart(std::string& file)
+{
+ std::string Result;
+ Result=MatchBufferForText(file,BufferNValues);
+ if (Result !="")
+ return Result;
+ return MatchBufferForText(file,Buffer1Value);
+}
+
+
+std::string BrukerDataSet::GetContentType(std::string& file)
+{
+ std::string ValuesPart, Result;
+ ValuesPart=GetValuesPart(file);
+ if (BoolMatchBufferForText(ValuesPart,IntSeries))
+ return "int";
+ if (BoolMatchBufferForText(ValuesPart,FloatSeries))
+ return "float";
+ return "string";
+}
+
+
+
+int BrukerDataSet::GetIntValueN(std::string& file,int N)
+{
+ std::string ValuesPart=GetValuesPart(file);
+ int iterator=0;
+ if (N < 1 || ValuesPart=="")
+ return -32767;
+
+ boost::match_results<std::string::const_iterator> what;
+ boost::match_flag_type flags= boost::match_default;
+ std::string::const_iterator start,end;
+ start=ValuesPart.begin();
+ end=ValuesPart.end();
+
+ while (iterator != N)
+ {
+ regex_search(start,end, what, SignedInteger);
+ iterator++;
+ start=what[0].second;
+ flags |= boost::match_prev_avail;
+ flags |= boost::match_not_bob;
+ }
+ return (atoi((std::string(what[1].first,what[1].second)).c_str()));
+}
+
+
+
+double BrukerDataSet::GetDoubleValueN(std::string& file, int N)
+{
+ std::string ValuesPart=GetValuesPart(file);
+ int iterator=0;
+ if (N < 1 || ValuesPart=="")
+ return 0;
+ boost::match_results<std::string::const_iterator> what;
+ boost::match_flag_type flags= boost::match_default;
+ std::string::const_iterator start,end;
+ start=ValuesPart.begin();
+ end=ValuesPart.end();
+
+ while (iterator != N)
+ {
+ regex_search(start,end, what, IntOrFloat);
+ iterator++;
+ start=what[0].second;
+ flags |= boost::match_prev_avail;
+ flags |= boost::match_not_bob;
+ }
+ return (atof((std::string(what[1].first,what[1].second)).c_str()));
+}
+
+
+
+std::string BrukerDataSet::GetTextValueN(std::string& file, int N)
+{
+ return GetValuesPart(file);
+}
+
+
+
+int BrukerDataSet::GetKeywordNumberOfElements(std::string& file)
+{
+ int NumberOfElements=1;
+ for (int i=1;i<=GetDimensionnality(file);i++)
+ NumberOfElements*=GetIntValueOfDimN(file, i);
+ return NumberOfElements;
+}
+
+
+
+/**
+ *
+@fn bool BrukerDataSet::FillMap()
+@brief This method fills the Bruker headermap with everything contained in the acqp file
+
+The map is made of BrukerFieldData containing the keywords:
+Datatype (string, int, double)
+DimensionNumber: The number of Dimensions of the keyword-> 0 scalar, 1-> 1D-vector, 2-> 2D-Matrix, 3->3D-Matrix, ...
+DimensionNumberValue: Gives the size of each dimension
+DoubleValue: return a vector of values if they are of type double
+IntValue: return a vector of values if they are of type int
+StringValue: return a string if the values where not identified as a serie of numbers
+NumberOfElements: Number of elements corresponding to the keyword given
+ * @return bool
+ */
+bool BrukerDataSet::FillMap()
+{
+
+ std::string ValuesBuffer, Keyword,TempString, Substring;
+ int i;
+ int KeywordNumber=0;
+ int PositionDebut=WholeHeader.find("##");
+ int PositionFin=PositionDebut+2;
+ int PosRel;
+ BrukerFieldData data;
+ if (PositionFin>=WholeHeader.length())
+ return false;
+
+ while(PositionDebut!=std::string::npos)
+ {
+ PositionFin=WholeHeader.find("##",PositionDebut+2);
+ if (-1 == PositionFin) break ;
+ Substring=WholeHeader.substr (PositionDebut,PositionFin-PositionDebut-1);
+ PosRel=Substring.find("$$",0);
+ if (-1 != PosRel) Substring=Substring.substr (0,PosRel-1);
+
+
+ if (DEBUG) std::cout<<"Substring=[" << Substring << "]" <<std::endl;
+
+ PositionDebut=PositionFin;
+ Keyword=GetKeyword(Substring);
+ if (DEBUG) std::cout<<"Keyword="<< Keyword <<std::endl;
+ data.DimensionNumber=GetDimensionnality(Substring);
+ if (DEBUG) std::cout<<"data.DimensionNumber="<< data.DimensionNumber <<std::endl;
+
+ data.DataType=GetContentType(Substring);
+ if (DEBUG) std::cout<<"data.DataType="<< data.DataType <<std::endl;
+ data.NumberOfElements=GetKeywordNumberOfElements(Substring);
+ if(data.DataType=="string")
+ data.DimensionNumber=0;
+ if(data.DataType=="string")
+ data.NumberOfElements=1;
+ if (DEBUG) std::cout<<"data.NumberOfElements="<< data.NumberOfElements <<std::endl;
+
+ i=0;
+ while (i<=data.DimensionNumber)
+ {
+ data.DimensionNumberValue.push_back(GetIntValueOfDimN(Substring,i));
+ if (DEBUG) std::cout<<"data.DimensionNumberValue["<<i<<"]="<< data.DimensionNumberValue[i] <<std::endl;
+ i++;
+ }
+
+ if (DEBUG) std::cout<< "data= ";
+
+ for(i =1;i<=data.NumberOfElements;i++)
+ {
+
+ if (data.DataType=="int")
+ {
+ data.IntValue.push_back(GetIntValueN(Substring,i));
+ data.DoubleValue.push_back((double) GetIntValueN(Substring,i));
+ if (DEBUG) std::cout<< data.IntValue[i-1]<<" ";
+ }
+
+ if (data.DataType=="float")
+ {
+ data.DoubleValue.push_back(GetDoubleValueN(Substring,i));
+ if (DEBUG) std::cout<< data.DoubleValue[i-1]<<" ";
+ }
+
+ }
+
+ if (data.DataType=="string")
+ {
+ data.StringValue.push_back(GetTextValueN(Substring,0));
+ if (DEBUG) std::cout<< "[" << data.StringValue[0]<<"] ";
+ }
+
+ if (DEBUG) std::cout<< std::endl << "---- " <<std::endl;
+
+ BrukerDataSet::BrukerHeaderMap[ Keyword ] = data;
+ data.DimensionNumberValue.clear();
+ data.IntValue.clear();
+ data.DoubleValue.clear();
+ data.StringValue.clear();
+ data.DataType.clear();
+ KeywordNumber++;
+ //std::cout<<std::endl;
+ }
+ return true;
+}
+
+
+void BrukerDataSet::PrintKey(std::string & KeyWord)
+{
+ int i;
+ if(!BrukerDataSet::CheckExistKeyword(KeyWord))
+ {
+ std::cout<< "KeyWord = "<<KeyWord <<" doesn't exist !"<<std::endl;
+ }
+ else
+ {
+ std::cout<< "KeyWord = "<<KeyWord <<std::endl;
+ BrukerDataSet::BrukerHeaderMap[ KeyWord ].PrintSelf();
+
+ }
+}
+
+
+
+void BrukerDataSet::PrintSelf()
+{
+ BrukMapType::iterator it;
+ for (it= BrukerHeaderMap.begin();
+ it != BrukerHeaderMap.end();
+ ++it )
+ {
+ std::cout << std::endl << "-----------------[" <<(*it).first << "]" << std::endl;
+ std::string a = (*it).first;
+ PrintKey(a);
+ }
+}
+
+
+bool BrukerDataSet::CheckExistKeyword(std::string &KeyWord)
+{
+ BrukMapType::iterator element;
+ element = BrukerHeaderMap.find(KeyWord);
+ if (element != BrukerHeaderMap.end() )
+ return true;
+ return false;
+}
+
+bool BrukerDataSet::CheckExistKeyword(const char *KeyWord)
+{
+std::string temp(KeyWord);
+BrukerDataSet::CheckExistKeyword(temp);
+ return true;
+}
+
+
+const BrukerFieldData& BrukerDataSet::GetFieldData(std::string & kw)
+{
+ return BrukerHeaderMap[kw];
+}
+
+const BrukerFieldData& BrukerDataSet::GetFieldData(const char *kw)
+{
+ std::string str_kw(kw);
+ return BrukerHeaderMap[str_kw];
+}
+
+
+bool BrukerDataSet::Getkspace(std::string &FileToRead)
+{
+ std::string GO_raw_data_format("GO_raw_data_format");
+ if (!CheckExistKeyword(GO_raw_data_format))
+ return false;
+ std::ifstream FID;
+
+ FID.open(FileToRead.c_str(), std::ios::binary);
+ if (FID.rdstate()==std::ios::failbit)
+ return false;
+ FID.seekg (0, std::ios::end);
+ long length = FID.tellg();
+ FID.seekg (0, std::ios::beg);
+ long NumberOfValues;
+
+
+ if (GetTextValueN(GO_raw_data_format,1)=="GO_32BIT_SGN_INT")
+ NumberOfValues=length/4;
+ if (GetTextValueN(GO_raw_data_format,1)=="GO_16BIT_SGN_INT")
+ NumberOfValues=length/2;
+ if (GetTextValueN(GO_raw_data_format,1)=="GO_32BIT_FLOAT")
+ NumberOfValues=length/4;
+
+ char * buffer;
+ buffer = new char[length];
+
+ FID.read (buffer,length);
+ FID.close();
+//for (long i=0;i<NumberOfValues;i++) BrukerDataSet::WholeKspace.pushback(buffer[i]);
+ delete [] buffer;
+ return true;
+}
+
+
+std::vector< int > BrukerDataSet::GetLoopStructure() const
+{
+ return LoopStructure;
+}
+
+/**
+ @fn bool BrukerDataSet::SetLoopStructure (const std::vector<int> & theValue )
+ * @brief this methods provide a way to inject a userdefined loop structure, be very aware that this method is not foolproof
+ * @param theValue
+ * @return bool
+ */
+bool BrukerDataSet::SetLoopStructure ( const std::vector<int> & theValue )
+{
+ LoopStructure = theValue;
+}
+
+
+/**
+ @fn bool BrukerDataSet::SetLoopStructureOld ( )
+ * @brief method to set the default Bruker loopstructure (not yet able to deal with EPI, SPIRAL or spectroscopic experiments
+ * @return bool
+ @todo implement multicoil version
+ */
+bool BrukerDataSet::SetLoopStructureOld ()
+{
+ LoopStructure.clear();
+/*
+\file brukerdataset.cpp
+\fn bool BrukerDataSet::setGenericLoopStructure ( )
+\brief sets the loop structure of a standard Bruker experiment
+
+NR (Nbre de repetitions)
+ NILoop (Boucle eventuelle extra (Diffusion par exemple) si NI<>(NSLICES x NECHOES) cette boucle est a� NI/(NSLICES x NECHOES)
+ (Attention NILoop peut masquer plusieurs boucles imbriquees !!!!!)
+ ACQ_size[1..M] (Codage suivant les autres dimensions)
+ NSLICES (Nombre de tranches)
+ ACQ_phase_factor (Facteur turbo de la sequence)
+ ACQ_ns_list_size (Nombre d'echos)
+ ACQ_size[0] (Ligne acq reelle)
+
+*/
+
+
+ std::string NRStr("NR");
+ std::string NIStr("NI");
+ std::string ACQ_sizeStr("ACQ_size");
+ std::string ACQ_phase_factorStr("ACQ_phase_factor");
+ std::string ACQ_ns_listStr("ACQ_ns_list");
+ std::string ACQ_ns_list_sizeStr("ACQ_ns_list_size");
+ std::string NSLICESStr("NSLICES");
+
+ int i, temp;
+ std::vector<int> TempIntVect;
+ TempIntVect.clear();
+
+ if (! CheckExistKeyword(NRStr)) return false;
+ if (! CheckExistKeyword(NIStr)) return false;
+ if (! CheckExistKeyword(ACQ_sizeStr)) return false;
+ if (! CheckExistKeyword(ACQ_phase_factorStr))return false;
+ if (! CheckExistKeyword(ACQ_ns_list_sizeStr))return false;
+ if (! CheckExistKeyword(NSLICESStr)) return false;
+
+ TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_size" ].IntValue[0]);
+ TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[(std::string) "ACQ_ns_list_size"].IntValue[0]);
+ TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[(std::string) "ACQ_phase_factor"].IntValue[0]);
+ TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[(std::string) "NSLICES"].IntValue[0]);
+ if (1<=BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_size" ].DimensionNumber ){
+ TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_size" ].IntValue[1]/BrukerDataSet::BrukerHeaderMap[(std::string) "ACQ_phase_factor"].IntValue[0]);
+ if (2<=BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_size" ].DimensionNumber )
+ {
+ for(i=2;i<=BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_size" ].DimensionNumber;i++)
+ {
+ TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_size" ].IntValue[i]);
+ }
+ }
+}
+// Ici, boucles additionnelles si elles existent regroupees en une seule
+//temp=GetIntValueN(NIStr,1)/(GetIntValueN(NSLICESStr,1)*GetIntValueN(NECHOESStr,1));
+ temp=BrukerDataSet::BrukerHeaderMap[ (std::string) "NI" ].IntValue[0]/(BrukerDataSet::BrukerHeaderMap[ (std::string) "NSLICES" ].IntValue[0]*BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_ns_list_size" ].IntValue[0]);
+ if (1 < temp)
+ TempIntVect.push_back(temp);
+// fin des boucles cachees
+
+ TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string) "NR" ].IntValue[0]);
+
+ LoopStructure=TempIntVect;
+ return true;
+}
+
+
+/**
+ @fn bool BrukerDataSet::SetLoopStructure ( )
+ * @brief method to set the default Bruker loopstructure (not yet able to deal with EPI, SPIRAL or spectroscopic experiments
+ * @return bool
+ @todo implement multicoil version
+ */
+bool BrukerDataSet::SetLoopStructure ()
+{
+ if (! SetInnerObjectLoopStructure()) return false;
+ if (! SetOuterObjectLoopStructure()) return false;
+ std::vector<int> Inner=GetInnerObjectLoopStructure();
+ std::vector<int> Outer=GetOuterObjectLoopStructure();
+ std::vector<int> TmpVect;
+ TmpVect=Inner;
+ TmpVect.insert(TmpVect.end(),Outer.begin(),Outer.end());
+ LoopStructure=TmpVect;
+ return true;
+}
+
+std::vector< std :: vector < int > > BrukerDataSet::GetBrukerObjectsLineList() const
+{
+ return BrukerObjectsLineList;
+}
+
+
+bool BrukerDataSet::SetBrukerObjectsLineList ()
+{
+
+ std::vector<int> Loop =GetLoopStructure();
+ int NumberOfLines, i,j;
+ NumberOfLines=1;
+ i=1;
+
+ while (i<Loop.size())
+ {
+ NumberOfLines=NumberOfLines*Loop[i];
+ i++;
+ }
+
+ std::vector<int> TempVect (Loop.size()-1,0);
+ std::vector<int> k (Loop.size()-1,0);
+ std::vector<std::vector<int> > TempLineList (NumberOfLines,TempVect);
+
+ for (i=0;i<NumberOfLines;i++){
+ for (j=1;j<=Loop.size()-1;j++) {
+ if (k[j-1] >= Loop[j]) {
+ k[j-1]=0;
+ k[j]++;
+ }
+ }
+ for (j=1;j<=Loop.size()-1;j++)
+ TempLineList[i][j-1]=k[j-1];
+ k[0]++;
+ }
+ BrukerObjectsLineList=TempLineList;
+ return true;
+}
+
+
+std::vector< std::vector < int > > BrukerDataSet::GetBrukerImageList() const
+{
+ return BrukerImageList;
+}
+
+
+bool BrukerDataSet::SetBrukerImageList ()
+{
+ if (LoopStructure.size()==0)
+ SetImageLoopStructure();
+
+ std::vector<int> Loop =GetImageLoopStructure();
+ int NumberOfLines, i,j;
+ NumberOfLines=1;
+ i=1;
+
+ while (i<Loop.size())
+ {
+ NumberOfLines=NumberOfLines*Loop[i];
+ i++;
+ }
+
+ std::vector<int> TempVect (Loop.size()-1,0);
+ std::vector<int> k (Loop.size()-1,0);
+ std::vector<std::vector<int> > TempLineList (NumberOfLines,TempVect);
+
+ for (i=0;i<NumberOfLines;i++){
+ for (j=1;j<=Loop.size()-1;j++) {
+ if (k[j-1] >= Loop[j]) {
+ k[j-1]=0;
+ k[j]++;
+ }
+ }
+ for (j=1;j<=Loop.size()-1;j++)
+ TempLineList[i][j-1]=k[j-1];
+ k[0]++;
+ }
+ BrukerImageList=TempLineList;
+ return true;
+}
+
+
+
+std::map<std::string, BrukerFieldData> BrukerDataSet::GetBrukerHeaderMap() const
+{
+ return BrukerHeaderMap;
+}
+
+
+
+
+//std::map<std::string, BrukerFieldData> BrukerDataSet::GetBrukerHeaderMap() const
+//{
+// return BrukerHeaderMap;
+//}
+
+
+bool BrukerDataSet::SetInnerObjectLoopStructure()
+{
+/*
+ ACQ_size[1..M] (Codage suivant les autres dimensions)
+ NSLICES (Nombre de tranches)
+ ACQ_phase_factor (Facteur turbo de la sequence)
+ ACQ_ns_list_size (Nombre d'echos)
+ ACQ_size[0] (Ligne acq reelle)
+
+*/
+
+ int i, temp;
+ std::vector<int> TempIntVect;
+ TempIntVect.clear();
+
+
+ if (! CheckExistKeyword("ACQ_size")) return false;
+ if (! CheckExistKeyword("ACQ_phase_factor"))return false;
+ if (! CheckExistKeyword("ACQ_ns_list_size"))return false;
+ if (! CheckExistKeyword("NSLICES")) return false;
+
+
+//std::cout<< "BrukerDataSet::BrukerHeaderMap[ (std::string) ACQ_size ].IntValue[0]" <<BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_size" ].IntValue[0] << std::endl;
+ TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_size" ].IntValue[0]);
+//std::cout<< "BrukerDataSet::BrukerHeaderMap[ (std::string) ACQ_size ].IntValue[0]" <<BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_size" ].IntValue[0] << std::endl;
+ TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[(std::string) "ACQ_ns_list_size"].IntValue[0]);
+//std::cout<<"BrukerDataSet::BrukerHeaderMap[(std::string) ACQ_ns_list_size].IntValue[0]" << BrukerDataSet::BrukerHeaderMap[(std::string) "ACQ_ns_list_size"].IntValue[0] << std::endl;
+ TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[(std::string) "ACQ_phase_factor"].IntValue[0]);
+//std::cout<<"BrukerDataSet::BrukerHeaderMap[(std::string) ACQ_phase_factor].IntValue[0]" << BrukerDataSet::BrukerHeaderMap[(std::string) "ACQ_phase_factor"].IntValue[0]<< std::endl;
+ TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[(std::string) "NSLICES"].IntValue[0]);
+//std::cout << "BrukerDataSet::BrukerHeaderMap[(std::string) NSLICES].IntValue[0]" << BrukerDataSet::BrukerHeaderMap[(std::string) "NSLICES"].IntValue[0] << std::endl;
+ if (1<=BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_size" ].DimensionNumber )
+ {
+ TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_size" ].IntValue[1]/BrukerDataSet::BrukerHeaderMap[(std::string) "ACQ_phase_factor"].IntValue[0]);
+//std::cout << "BrukerDataSet::BrukerHeaderMap[ (std::string) ACQ_size ].IntValue[1]/BrukerDataSet::BrukerHeaderMap[(std::string) ACQ_phase_factor].IntValue[0]" << BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_size"
+//].IntValue[1]/BrukerDataSet::BrukerHeaderMap[(std::string) "ACQ_phase_factor"].IntValue[0] << std::endl;
+ if (2<=BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_size" ].DimensionNumber )
+ {
+ for(i=2;i<=BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_size" ].DimensionNumber;i++)
+ {
+ TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_size" ].IntValue[i]);
+ }
+ }
+ }
+
+ InnerObjectLoopStructure=TempIntVect;
+ return true;
+}
+
+
+std::vector< int > BrukerDataSet::GetInnerObjectLoopStructure() const
+{
+ return InnerObjectLoopStructure;
+}
+
+std::vector< int > BrukerDataSet::GetOuterObjectLoopStructure() const
+{
+ return OuterObjectLoopStructure;
+}
+
+
+bool BrukerDataSet::SetOuterObjectLoopStructure ()
+{
+ OuterObjectLoopStructure.clear();
+ /*
+ NR (Nbre de repetitions)
+ NILoop (Boucle eventuelle extra (Diffusion par exemple) si NI<>(NSLICES x NECHOES) cette boucle est a� NI/(NSLICES x NECHOES)
+ (Attention NILoop peut masquer plusieurs boucles imbriquees !!!!!)
+ */
+ int temp;
+ std::vector<int> TempIntVect;
+ TempIntVect.clear();
+ if (! CheckExistKeyword("NR")) return false;
+ if (! CheckExistKeyword("NI")) return false;
+// Ici, boucles additionnelles si elles existent regroupees en une seule
+//temp=GetIntValueN(NIStr,1)/(GetIntValueN(NSLICESStr,1)*GetIntValueN(NECHOESStr,1));
+ temp=BrukerDataSet::BrukerHeaderMap[ (std::string) "NI" ].IntValue[0]/(BrukerDataSet::BrukerHeaderMap[ (std::string) "NSLICES" ].IntValue[0]*BrukerDataSet::BrukerHeaderMap[ (std::string) "ACQ_ns_list_size" ].IntValue[0]);
+ if (1 < temp)
+ TempIntVect.push_back(temp);
+// fin des boucles cachees
+ TempIntVect.push_back(BrukerDataSet::BrukerHeaderMap[ (std::string) "NR" ].IntValue[0]);
+ OuterObjectLoopStructure=TempIntVect;
+ return true;
+}
+
+
+std::vector< int > BrukerDataSet::GetImageLoopStructure() const
+{
+ return ImageLoopStructure;
+}
+
+
+bool BrukerDataSet::SetImageLoopStructure ( )
+{
+ ImageLoopStructure.clear();
+ std::vector<int> TempIntVect1=GetInnerObjectLoopStructure();
+ std::vector<int> TempIntVect2=GetOuterObjectLoopStructure();
+ std::vector<int> TempIntVect3(TempIntVect1.size(),1);
+ std::vector<int> TempIntVect4;
+ TempIntVect3[1]=TempIntVect1[1];
+ TempIntVect3[3]=TempIntVect1[3];
+ TempIntVect4=TempIntVect3;
+ TempIntVect4.insert(TempIntVect4.end(),TempIntVect2.begin(),TempIntVect2.end());
+ ImageLoopStructure = TempIntVect4;
+ return true;
+}
--- /dev/null
+//
+// C++ Interface: brukerdataset
+//
+// Description:
+//
+//
+// Author: <Denis Grenier>, (C) 2008
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef BRUKERDATASET_H
+#define BRUKERDATASET_H
+
+/*! \file brukerdataset.h
+*/
+#include <cstdlib>
+#include <stdlib.h>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <stdio.h>
+#include <fstream>
+#include <map>
+#include <algorithm>
+#include "boost/regex.hpp"
+
+#include "brukerSystem.h"
+#include "brukerFieldData.h"
+#include "brukerobjectvaryingproperties.h"
+
+ const boost::regex KeyWord("^##\\$?([^[:cntrl:]]+)=.*");
+ const boost::regex UnsignedInteger("([0-9]+)");
+ const boost::regex SignedInteger("(\\-?[0-9]+)");
+ const boost::regex Float("([\\-\\+eE0-9\\.]+)");
+ const boost::regex IntOrFloat("([\\-\\+eE0-9\\.]+)");
+ const boost::regex Dimensionnality("=\\( ([^[:cntrl:]]+) \\)");
+ const boost::regex BufferNValues("^##\\$?[^[:cntrl:]]+=\\( [^[:cntrl:]]+ \\)[[:space:]]*[[:cntrl:]]*([^[.dollar-sign.]]+).*");
+ const boost::regex Buffer1Value("^##\\$?[^[:cntrl:]]+=(.*)");
+ const boost::regex IntSeries("([\\-0-9]*[[:space:]]*[[:cntrl:]]*)+");
+ const boost::regex FloatSeries("([\\-\\+eE0-9\\.]+[[:space:]]*[[:cntrl:]]*)+");
+
+
+/*! \class BrukerDataSet
+\brief This class purpose is to extract information from a bruker experiment and setup the extracted information for an easy use
+*/
+
+class creaBruker_EXPORT BrukerDataSet{
+friend class BrukerKspaceObject;
+ typedef std::map<std::string, BrukerFieldData> BrukMapType;
+ //typedef BrukMapType::iterator iterator;
+ //typedef BrukMapType::const_iterator const_iterator;
+public:
+ BrukerDataSet();
+ ~BrukerDataSet();
+ bool LoadFile(std::string& FileToRead);
+ bool FillMap();
+ void PrintKey(std::string &);
+ void PrintSelf();
+ bool Getkspace (std::string &);
+ const BrukerFieldData& GetFieldData(std::string &);
+ const BrukerFieldData& GetFieldData(const char *);
+ bool SetLoopStructure ( );
+ bool SetLoopStructureOld ( );
+ bool SetLoopStructure (const std::vector<int >& theValue);
+ std::vector<int > GetLoopStructure ( ) const;
+ bool SetBrukerObjectsLineList( );
+ bool SetBrukerImageList ( );
+
+ std::vector<std::vector <int > > GetBrukerObjectsLineList() const;
+ std::vector<std::vector <int > > GetBrukerImageList() const;
+ std::map<std::string, BrukerFieldData > GetBrukerHeaderMap() const;
+
+ bool SetInnerObjectLoopStructure ();
+ std::vector<int > GetInnerObjectLoopStructure() const;
+ bool SetOuterObjectLoopStructure ();
+ std::vector<int > GetOuterObjectLoopStructure() const;
+ bool SetImageLoopStructure ();
+ std::vector<int > GetImageLoopStructure() const;
+
+ BrukerObjectVaryingProperties ObjectVaryingProperties;
+private:
+
+ std::string GetKeyword (std::string &kw);
+ std::string SearchBufferForText (std::string &kw, const boost::regex& RegExp);
+ bool BoolMatchBufferForText (std::string &kw, const boost::regex& RegExp);
+ std::string MatchBufferForText (std::string &kw, const boost::regex& RegExp);
+ int GetDimensionnality (std::string &kw);
+ int GetIntValueOfDimN (std::string &kw, int n);
+ int GetIntValueN (std::string &kw, int n);
+ std::string GetContentType (std::string &kw);
+ std::string GetValuesPart (std::string &kw);
+ double GetDoubleValueN (std::string &kw, int n);
+ int GetKeywordNumberOfElements(std::string &kw);
+ std::string GetTextValueN (std::string &kw, int n);
+ bool CheckExistKeyword (std::string &kw);
+ bool CheckExistKeyword (const char *kw);
+
+ //BrukMapType
+
+ std::map<std::string, BrukerFieldData> BrukerHeaderMap;
+ std::string WholeHeader;
+ std::vector<double> WholeKspace;
+ std::vector<int> LoopStructure;
+ std::vector<int> InnerObjectLoopStructure;
+ std::vector<int> OuterObjectLoopStructure;
+ std::vector<int> ImageLoopStructure;
+ std::vector <std::vector<int> > BrukerObjectsLineList;
+ std::vector <std::vector<int> > BrukerImageList;
+
+protected:
+};
+
+#endif
--- /dev/null
+//
+// C++ Implementation: brukerimage
+//
+// Description:
+//
+//
+// Author: Denis Grenier, (C) 2009
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+/**
+@file brukerimage.cpp
+*/
+#include "brukerimage.h"
+
+/**
+* This method takes care of the initialization of the main parameters usually needed to deal with an MRI experiment
+ * @fn bool BrukerImage::Init(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::Init(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+
+// on devrait plutot les nommer 'computeXXX' (setXXX est d'habitude réservé aux accesseurs 'publics')
+
+ setAbsoluteTimePosition (TheOrigAcqp,TheOrigReco,TheValue);
+ setRelativeTimePosition (TheOrigAcqp,TheOrigReco,TheValue);
+ setFOVpixels (TheOrigAcqp,TheOrigReco,TheValue);
+ setFOVcm (TheOrigAcqp,TheOrigReco,TheValue);
+ setSliceThickness (TheOrigAcqp,TheOrigReco,TheValue);
+ setTE (TheOrigAcqp,TheOrigReco,TheValue);
+ setTR (TheOrigAcqp,TheOrigReco,TheValue);
+ setTI (TheOrigAcqp,TheOrigReco,TheValue);
+ setFlipAngle (TheOrigAcqp,TheOrigReco,TheValue);
+ setLoopStamp (TheOrigAcqp,TheOrigReco,TheValue);
+ setNA (TheOrigAcqp,TheOrigReco,TheValue);
+ setNR (TheOrigAcqp,TheOrigReco,TheValue);
+ setNAE (TheOrigAcqp,TheOrigReco,TheValue);
+ setDS (TheOrigAcqp,TheOrigReco,TheValue);
+ setACQ_phase_factor (TheOrigAcqp,TheOrigReco,TheValue);
+ setRotationMatrixRPS2XYZ (TheOrigAcqp,TheOrigReco,TheValue);
+ setTranslationVectorRPS2XYZ (TheOrigAcqp,TheOrigReco,TheValue);
+ setWordType (TheOrigAcqp,TheOrigReco,TheValue);
+ setImageType (TheOrigAcqp,TheOrigReco,TheValue);
+ setDataEndianness (TheOrigAcqp,TheOrigReco,TheValue);
+ setImageByteSize (TheOrigAcqp,TheOrigReco,TheValue);
+ setBeginingOfImageInBytes (TheOrigAcqp,TheOrigReco,TheValue);
+}
+
+/**
+ * @brief the constructor uses the BrukerDataSet's of the acqp and reco file
+ * @fn BrukerImage::BrukerImage(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ */
+BrukerImage::BrukerImage(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco)
+{
+}
+
+BrukerImage::~BrukerImage()
+{
+}
+
+/**
+* @fn int BrukerImage::getAbsoluteTimePosition() const
+ * @brief AbsoluteTimePosition is an integer number giving the time of the begining of the acquisition of the dataset
+ * @return AbsoluteTimePosition int
+ */
+int BrukerImage::getAbsoluteTimePosition() const
+{
+ return AbsoluteTimePosition;
+}
+
+/**
+* @fn bool BrukerImage::setAbsoluteTimePosition (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue )
+ * @brief AbsoluteTimePosition is an integer number giving the time of the begining of the acquisition of the dataset
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setAbsoluteTimePosition (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue )
+{
+ AbsoluteTimePosition = TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "ACQ_abs_time"].GetIntValue()[0];
+ return true;
+}
+
+
+/**
+ * @brief RelativeTimePosition is the estimated time position of the time the k-space center was acquired
+ * This notion is very relative when dealing with long experiments and a line or object averaging (NA or NAE <> 1)
+ * @fn double BrukerImage::getRelativeTimePosition() const
+ * @return double
+ */
+double BrukerImage::getRelativeTimePosition() const
+{
+ return RelativeTimePosition;
+}
+
+/**
+ * @brief RelativeTimePosition is the estimated instant when the k-space center of each image was acquired
+
+ This notion is very relative when dealing with long experiments and a line or object averaging (NA or NAE <> 1)
+* @fn bool BrukerImage::setRelativeTimePosition (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue )
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setRelativeTimePosition (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue )
+{
+ long lTEMP = TheOrigAcqp.GetBrukerImageList()[TheValue].back();
+ RelativeTimePosition = TheOrigAcqp.ObjectVaryingProperties.getPositionTimePerNR(lTEMP);
+ return true;
+}
+
+
+/**
+ * @brief FOVpixels is a 1x2 integer vector. it's one of the view value we need to pick in the reco headermap
+ * @fn bool BrukerImage::setFOVpixels(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setFOVpixels(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ FOVpixels = TheOrigReco.GetBrukerHeaderMap()[(std::string) "RECO_size"].GetIntValue();
+ return true;
+}
+
+/**
+ * @brief FOVpixels is a 1x2 integer vector. it's one of the view value we need to pick in the reco headermap
+ * @fn std::vector <int > BrukerImage::getFOVpixels() const
+ * @return std::vector <int >
+ */
+const std::vector<int > &BrukerImage::getFOVpixels() const
+{
+ return FOVpixels;
+}
+
+
+/**
+ * @brief FOVcm is also picked in reco headermap
+ * @fn bool BrukerImage::setFOVcm(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setFOVcm(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ FOVcm = TheOrigReco.GetBrukerHeaderMap()[(std::string) "RECO_fov"].GetDoubleValue();
+ return true;
+}
+
+/**
+ * @brief FOVcm is also picked in reco headermap
+ * @fn std::vector <double > BrukerImage::getFOVcm() const
+ * @return std::vector <double >
+ */
+const std::vector <double > &BrukerImage::getFOVcm() const
+{
+ return FOVcm;
+}
+
+/**
+ * @brief SliceThickness is in milimeter
+ * @fn bool BrukerImage::setSliceThickness( BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco,int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setSliceThickness( BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco,int TheValue)
+{
+ SliceThickness = TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "ACQ_slice_thick"].GetDoubleValue()[0];
+ return true;
+}
+
+/**
+ * @brief SliceThickness is in milimeter
+ * @fn double BrukerImage::getSliceThickness() const
+ * @return double
+ */
+double BrukerImage::getSliceThickness() const
+{
+ return SliceThickness;
+}
+
+/**
+* @brief picks the echo time of the image number TheValue
+ * @fn bool BrukerImage::setTE( BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco,int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setTE( BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco,int TheValue)
+{
+ TE = TheOrigAcqp.ObjectVaryingProperties.getTE(TheOrigAcqp.GetBrukerImageList()[TheValue][0]);
+ return true;
+}
+
+/**
+ * @fn double BrukerImage::getTE() const
+ * @brief picks the echo time of the image number TheValue
+ * @return TE
+ */
+double BrukerImage::getTE() const
+{
+ return TE;
+}
+
+
+/**
+ * @brief picks the repetition time of the image number TheValue
+ * @fn bool BrukerImage::setTR( BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco,int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setTR(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ TR=TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "ACQ_repetition_time"].GetDoubleValue()[0];
+ return true;
+}
+
+ /**
+ * @fn double BrukerImage::getTR() const
+ * @brief picks the echo time of the image number TheValue
+ * @return TR
+ */
+double BrukerImage::getTR() const
+{
+ return TR;
+}
+
+/**
+* @brief picks the invertion time of the image number TheValue
+ * @fn bool BrukerImage::setTI( BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco,int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setTI(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ TI = TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "ACQ_inversion_time"].GetDoubleValue()[0];
+ return true;
+}
+
+ /**
+ * @fn double BrukerImage::getTI() const
+ * @brief picks the invertion time of the image number TheValue
+ * @return TI
+ */
+double BrukerImage::getTI() const
+{
+ return TI;
+}
+
+/**
+* @brief picks the flip angle of the image number TheValue
+ * @fn bool BrukerImage::setFlipAngle( BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco,int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setFlipAngle(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ FlipAngle = TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "ACQ_flip_angle"].GetIntValue()[0];
+ return true;
+}
+
+/**
+ * @fn double BrukerImage::getFlipAngle() const
+ * @brief picks the flip angle of the image number TheValue
+ * @return FlipAngle
+*/
+double BrukerImage::getFlipAngle() const
+{
+ return FlipAngle;
+}
+
+
+/**
+ * @brief LoopStamp is a vector, copy of the values of all the loop for the image number TheValue
+
+ * The purpose of this "loopstamp" is to provide additionnal information if the methods provided by this class are not sufficient to singularize each image
+ * @fn bool BrukerImage::setLoopStamp(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setLoopStamp(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ LoopStamp = TheOrigAcqp.GetBrukerImageList()[TheValue];
+ return true;
+}
+
+/**
+ * @brief LoopStamp is a vector, copy of the values of all the loop for the image number TheValue
+ * The purpose of this "loopstamp" is to provide additionnal information if the methods provided by this class are not sufficient to singularize each image
+ * @fn std::vector<int> BrukerImage::getLoopStamp() const
+ * @return LoopStamp
+ */
+const std::vector<int> &BrukerImage::getLoopStamp() const
+{
+ return LoopStamp;
+}
+
+
+/**
+ * @brief NA number of accumulation is useful to track image quality
+ * @fn bool BrukerImage::setNA(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return
+ */
+bool BrukerImage::setNA(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ NA=TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "NA"].GetIntValue()[0];
+ return true;
+}
+
+/**
+ * @brief NA number of accumulation is useful to track image quality
+ * @fn int BrukerImage::getNA() const
+ *
+ * @return NA
+ */
+int BrukerImage::getNA() const
+{
+ return NA;
+}
+
+/**
+@brief NAE number of object exterior accumulation is useful to track image quality and rather used than NA to average movement artefacts
+ * @fn bool BrukerImage::setNAE(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setNAE(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ NAE=TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "NAE"].GetIntValue()[0];
+ return true;
+}
+
+/**
+ @brief NAE number of object exterior accumulation is useful to track image quality and rather used than NA to average movement artefacts
+ * @fn int BrukerImage::getNAE() const
+ * @return NAE
+ */
+
+int BrukerImage::getNAE() const
+{
+ return NAE;
+}
+
+/**
+@brief DS (dummy scan) is useful to establish a dynamic equilibrium or to know if one was used
+ * @fn bool BrukerImage::setDS(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+
+bool BrukerImage::setDS(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ DS=TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "DS"].GetIntValue()[0];
+ return true;
+}
+
+/**
+ @brief DS (dummy scan) is useful to establish a dynamic equilibrium or to know if one was used
+ @fn int BrukerImage::get() const
+ @return DS
+*/
+int BrukerImage::getDS() const
+{
+ return DS;
+}
+
+/**
+@brief Phase factor is the number of kspace line acquired in a single shot
+ * @fn bool BrukerImage::setACQ_phase_factor(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setACQ_phase_factor(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ ACQ_phase_factor=TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "ACQ_phase_factor"].GetIntValue()[0];
+ return true;
+}
+
+/**
+ @brief Phase factor is the number of kspace line acquired in a single shot
+ @fn int BrukerImage::getACQ_phase_factor() const
+ @return
+*/
+int BrukerImage::getACQ_phase_factor() const
+{
+ return ACQ_phase_factor;
+}
+
+
+/**
+@brief The number of repetition NR is used to repeat a full objects acquisition NR times with a given delay
+* This method returns at which repetition belongs the image TheValue
+ * @fn bool BrukerImage::NR(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setNR(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ NR= TheOrigAcqp.GetBrukerImageList()[TheValue].back();
+ return true;
+}
+
+ /**
+ @brief The number of repetition NR is used to repeat a full objects acquisition NR times with a given delay
+ * This method returns at which repetition belongs the image TheValue
+ @fn int BrukerImage::getNR() const
+ @return NR
+ */
+int BrukerImage::getNR() const
+{
+ return NR;
+}
+
+
+
+/**
+@brief RotationMatrixRPS2XYZ is a 3x3 rotation matrix giving the orientation of the TheValue image
+ * @fn bool BrukerImage::setRotationMatrixRPS2XYZ(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setRotationMatrixRPS2XYZ(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ RotationMatrixRPS2XYZ = TheOrigAcqp.ObjectVaryingProperties.getOrientation(TheOrigAcqp.GetBrukerImageList()[TheValue][2]);
+ return true;
+}
+
+ /**
+ @brief RotationMatrixRPS2XYZ is a 3x3 rotation matrix giving the orientation of the TheValue image
+ @fn std::vector<std::vector<double> > BrukerImage::getRotationMatrixRPS2XYZ() const
+ @return RotationMatrixRPS2XYZ
+ */
+const std::vector<std::vector<double> > &BrukerImage::getRotationMatrixRPS2XYZ() const
+{
+ return RotationMatrixRPS2XYZ;
+}
+
+
+
+/**
+@brief TranslationVectorRPS2XYZ is a 1x3 vector of the TheValue image position to the magnet center (in mm)
+ * @fn bool BrukerImage::setTranslationVectorRPS2XYZ(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setTranslationVectorRPS2XYZ(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ TranslationVectorRPS2XYZ.clear();
+ TranslationVectorRPS2XYZ.push_back(TheOrigAcqp.ObjectVaryingProperties.getPositionR(TheOrigAcqp.GetBrukerImageList()[TheValue][2]));
+ TranslationVectorRPS2XYZ.push_back(TheOrigAcqp.ObjectVaryingProperties.getPositionP(TheOrigAcqp.GetBrukerImageList()[TheValue][2]));
+ TranslationVectorRPS2XYZ.push_back(TheOrigAcqp.ObjectVaryingProperties.getPositionS(TheOrigAcqp.GetBrukerImageList()[TheValue][2]));
+ return true;
+}
+
+/**
+ @brief TranslationVectorRPS2XYZ is a 1x3 vector of the TheValue image position to the magnet center (in mm)
+ @fn std::vector<double> BrukerImage::getTranslationVectorRPS2XYZ() const
+ @return TranslationVectorRPS2XYZ
+*/
+const std::vector<double> &BrukerImage::getTranslationVectorRPS2XYZ() const
+{
+ return TranslationVectorRPS2XYZ;
+}
+
+/**
+@brief WordType returns the type of data to read int32_t, int16_t, uint8_t or float32_t
+ * @fn bool BrukerImage::setWordType(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setWordType(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ WordType=TheOrigReco.GetBrukerHeaderMap()[(std::string) "RECO_wordtype"].GetStringValue()[0];
+ return true;
+}
+
+ /**
+ @brief WordType returns the type of data to read int32_t, int16_t, uint8_t or float32_t
+ @fn std::string BrukerImage::getWordType() const
+ @return int32_t, int16_t, uint8_t or float32_t or UNKNOWN
+ */
+std::string BrukerImage::getWordType() const
+{
+ if(WordType == ((std::string) "_32BIT_SGN_INT")) return ((std::string)"int32_t");
+ if(WordType == ((std::string) "_16BIT_SGN_INT")) return ((std::string)"int16_t");
+ if(WordType == ((std::string) "_8BIT_UNSGN_INT")) return ((std::string)"uint8_t");
+ if(WordType == ((std::string) "_32BIT_FLOAT")) return ((std::string)"float32_t");
+ return ((std::string)"UNKNOWN");
+}
+
+/**
+@brief ImageType returns the type of image : values real for amplitude, real imaginary or phase images and complex for complex images
+ * @fn bool BrukerImage::setImageType(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setImageType(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ ImageType=TheOrigReco.GetBrukerHeaderMap()[(std::string) "RECO_image_type"].GetStringValue()[0];
+ return true;
+}
+
+ /**
+ @brief ImageType returns the type of image : values real for amplitude, real imaginary or phase images and complex for complex images
+ @fn std::string BrukerImage::getImageType() const
+ @return complex or real
+ */
+std::string BrukerImage::getImageType() const
+{
+ if(ImageType == ((std::string) "COMPLEXE_IMAGE")) return ((std::string)"complex");
+ return ((std::string)"real");
+}
+
+
+/**
+@brief DataEndianness gives information on how to swap or no the binary data to read
+ * @fn bool BrukerImage::setDataEndianness(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setDataEndianness(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ DataEndianness=TheOrigReco.GetBrukerHeaderMap()[(std::string) "RECO_byte_order"].GetStringValue()[0];
+ return true;
+}
+
+ /**
+ @brief DataEndianness gives information on how to swap or no the binary data to read
+ @fn std::string BrukerImage::getDataEndianness() const
+ @return DataEndianness
+ */
+const std::string &BrukerImage::getDataEndianness() const
+{
+ return DataEndianness;
+}
+
+/**
+@brief Information on the image size in byte, useful for offsets calculation
+ * @fn bool BrukerImage::setImageByteSize(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setImageByteSize(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ int Dimension, WordSize;
+ if (getImageType()==((std::string)"complex")) Dimension=2;
+ else if (getImageType()==((std::string)"real")) Dimension=1;
+ else return false;
+
+ if (getWordType()==((std::string)"int32_t")||getWordType()==((std::string)"float32_t")) WordSize=4;
+ else if (getWordType()==((std::string)"int16_t")) WordSize=2;
+ else if (getWordType()==((std::string)"uint8_t")) WordSize=1;
+ else /*if (getWordType()==((std::string)"UNKNOWN"))*/ return false;
+
+ ImageByteSize = Dimension*WordSize*getFOVpixels()[0]*getFOVpixels()[1];
+ return true;
+}
+
+ /**
+ @brief Information on the image size in byte, useful for offsets calculation
+ @fn size_t BrukerImage::getImageByteSize() const
+ @return ImageByteSize
+ */
+size_t BrukerImage::getImageByteSize() const
+{
+ return ImageByteSize;
+}
+
+
+/**
+ @brief BeginingOfImageInBytes is the offset of the image number TheValue to the begining of 2dseq file
+ @fn size_t BrukerImage::getBeginingOfImageInBytes() const
+ @return BeginingOfImageInBytes
+*/
+
+
+size_t BrukerImage::getBeginingOfImageInBytes() const
+{
+ return BeginingOfImageInBytes;
+}
+
+
+/**
+@brief BeginingOfImageInBytes is the offset of the image number TheValue to the begining of 2dseq file
+ * @fn bool BrukerImage::setBeginingOfImageInBytes(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+ * @param TheOrigAcqp
+ * @param TheOrigReco
+ * @param TheValue
+ * @return bool
+ */
+bool BrukerImage::setBeginingOfImageInBytes (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
+{
+ BeginingOfImageInBytes = TheValue*getImageByteSize();
+}
--- /dev/null
+//
+// C++ Interface: brukerimage
+//
+// Description:
+//
+//
+// Author: Denis Grenier, (C) 2009
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef BRUKERIMAGE_H
+#define BRUKERIMAGE_H
+
+#include "brukerdataset.h"
+#include "brukerSystem.h"
+/**
+This class centralizes the informations "needed" to exploit a bruker image file 2dseq
+
+ @author Denis Grenier
+ @file brukerimage.h
+*/
+class creaBruker_EXPORT BrukerImage{
+public:
+ BrukerImage(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco);
+ ~BrukerImage();
+
+ bool Init(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+
+ int getAbsoluteTimePosition() const;
+ double getRelativeTimePosition() const;
+ const std::vector <int> &getFOVpixels() const;
+ const std::vector <double> &getFOVcm() const;
+ double getSliceThickness() const;
+ double getTE() const;
+ double getTR() const;
+ double getTI() const;
+ double getFlipAngle() const;
+ int getNA() const;
+ int getNR() const;
+ int getDS() const;
+ int getNAE() const;
+ int getACQ_phase_factor() const;
+ std::string getWordType() const;
+ std::string getImageType() const;
+ const std::string &getDataEndianness() const;
+ size_t getImageByteSize() const;
+ size_t getBeginingOfImageInBytes() const;
+
+ const std::vector <int> &getLoopStamp() const;
+
+ const std::vector<std::vector <double> > &getRotationMatrixRPS2XYZ() const;
+ const std::vector <double> &getTranslationVectorRPS2XYZ() const;
+
+
+protected:
+
+private:
+
+// on devrait plutot les nommer 'computeXXX' (setXXX est d'habitude reserve aux accesseurs 'publics')
+
+ bool setAbsoluteTimePosition (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setRelativeTimePosition (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setFOVpixels (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setFOVcm (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setSliceThickness (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setTE (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setTR (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setTI (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setFlipAngle (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setLoopStamp (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setNA (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setNR (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setNAE (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setDS (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setACQ_phase_factor (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setRotationMatrixRPS2XYZ (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setTranslationVectorRPS2XYZ(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setWordType (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setImageType (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setDataEndianness (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setImageByteSize (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+ bool setBeginingOfImageInBytes (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue);
+
+ std::vector<int> FOVpixels;
+ std::vector<double> FOVcm;
+ std::vector<int> LoopStamp;
+ double SliceThickness;
+ double TE;
+ double TR;
+ double TI;
+ double FlipAngle;
+ double RelativeTimePosition;
+ int NA;
+ int NR;
+ int NAE;
+ int DS;
+ int ACQ_phase_factor;
+ std::vector<std::vector<double> > RotationMatrixRPS2XYZ;
+ std::vector<double> TranslationVectorRPS2XYZ;
+ int AbsoluteTimePosition;
+ std::string WordType;
+ std::string ImageType;
+ std::string DataEndianness;
+ size_t ImageByteSize;
+ size_t BeginingOfImageInBytes;
+
+};
+
+#endif
--- /dev/null
+#include "brukerimageset.h"
--- /dev/null
+//
+#ifndef BRUKERIMAGESET_H
+#define BRUKERIMAGESET_H
+
+/*
+#include "brukerSystem.h"
+#include "brukerimage.h"
+#include <vector>
+
+typedef bool (*BOOL_FUNCTION_PFILE_PFILE_POINTER)(File *, File *);
+typedef std::map<std::string, BrukerImageSet> CoherentBrukerImageSetMap;
+
+class BRUKER_EXPORT BrukerImageSet : public std::vector<BrukerImage> {
+public:
+ BrukerImageSet();
+ ~BrukerImageSet();
+
+
+ /// to allow user to give is own comparison function
+ void SetUserLessThanFunction( BOOL_FUNCTION_PFILE_PFILE_POINTER userFunc )
+ { UserLessThanFunction = userFunc; }
+
+ CoherentBrukerImageSetMap SplitOnOrientation();
+ CoherentBrukerImageSetMap SplitOnPosition();
+
+};
+*/
+#endif
--- /dev/null
+//
+// C++ Implementation: brukerobject
+//
+// Description:
+//
+//
+// Author: <Denis Grenier>, (C) 2008
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "brukerkspaceobject.h"
+
+
+
+bool BrukerKspaceObject::FillWithObject(BrukerDataSet DataSet, int ObjectNumber)
+{
+
+ std::string TempString;
+ std::vector< int > TempVectInt;
+ std::vector<double> TempVectDouble;
+
+ TempString="ACQ_abs_time";
+ if (DataSet.CheckExistKeyword(TempString)) {
+ setAbsoluteTimePosition ( DataSet.BrukerHeaderMap[TempString].GetIntValue()[0] );
+ }
+ else return false;
+
+ TempString="ACQ_phase_factor";
+ if (DataSet.CheckExistKeyword(TempString)) {
+ setACQ_phase_factor(DataSet.BrukerHeaderMap[TempString].GetIntValue()[0]);
+ }
+ else return false;
+
+ TempString="ACQ_dim";
+ if (DataSet.CheckExistKeyword(TempString)) {
+ setDimension(DataSet.BrukerHeaderMap[TempString].GetIntValue()[0]);
+ }
+ else return false;
+
+ TempString="ACQ_size";
+ if (DataSet.CheckExistKeyword(TempString)){
+ for (int i=0;i<getDimension();i++)
+ TempVectInt.push_back(DataSet.BrukerHeaderMap[TempString].GetIntValue()[i]);
+ setDimensionSizes(TempVectInt);
+ TempVectInt.clear();
+ }
+ else return false;
+
+ TempString="ACQ_flip_angle";
+ if (DataSet.CheckExistKeyword(TempString)){
+ setFlipAngle(DataSet.BrukerHeaderMap[TempString].GetIntValue()[0]);
+ }
+ else return false;
+
+ TempString="ACQ_fov";
+ if (DataSet.CheckExistKeyword(TempString)) {
+ if ( 1!=DataSet.BrukerHeaderMap[TempString].GetDimensionNumber())
+ return false;
+ for (int i=0;i<DataSet.BrukerHeaderMap[TempString].GetNumberOfElements();i++){
+ TempVectDouble.push_back(DataSet.BrukerHeaderMap[TempString].GetDoubleValue()[i]);
+ }
+ setFOV(TempVectDouble);
+ TempVectDouble.clear();
+ }
+ else return false;
+
+ TempString="NA";
+ if (DataSet.CheckExistKeyword(TempString)){
+ setNA(DataSet.BrukerHeaderMap[TempString].GetIntValue()[0]);
+ }
+ else return false;
+
+ TempString="NR";
+ if (DataSet.CheckExistKeyword(TempString)){
+ setNA(DataSet.BrukerHeaderMap[TempString].GetIntValue()[0]);
+ }
+ else return false;
+
+ TempString="NSLICES";
+ if (DataSet.CheckExistKeyword(TempString)){
+ setNA(DataSet.BrukerHeaderMap[TempString].GetIntValue()[0]);
+ }
+ else return false;
+
+ TempString="NI";
+ if (DataSet.CheckExistKeyword(TempString)){
+ setNI(DataSet.BrukerHeaderMap[TempString].GetIntValue()[0]);
+ }
+ else return false;
+
+ TempString="NAE";
+ if (DataSet.CheckExistKeyword(TempString)){
+ setNAE(DataSet.BrukerHeaderMap[TempString].GetIntValue()[0]);
+ }
+ else return false;
+
+ TempString="DS";
+ if (DataSet.CheckExistKeyword(TempString)){
+ setDS(DataSet.BrukerHeaderMap[TempString].GetIntValue()[0]);
+ }
+ else return false;
+
+
+ TempString="ACQ_ns_list";
+ if (DataSet.CheckExistKeyword(TempString)) {
+ for (int i=0;i<DataSet.BrukerHeaderMap[TempString].GetNumberOfElements();i++){
+ TempVectInt.push_back(DataSet.BrukerHeaderMap[TempString].GetIntValue()[i]);
+ }
+ setACQ_ns_list(TempVectInt);
+ TempVectInt.clear();
+ }
+ else return false;
+
+ TempString="ACQ_obj_order";
+ if (DataSet.CheckExistKeyword(TempString)) {
+ for (int i=0;i<DataSet.BrukerHeaderMap[TempString].GetNumberOfElements();i++){
+ TempVectInt.push_back(DataSet.BrukerHeaderMap[TempString].GetIntValue()[i]);
+ }
+ setACQ_obj_order(TempVectInt);
+ TempVectInt.clear();
+ }
+ else return false;
+
+ TempString="ACQ_echo_time";
+ if (DataSet.CheckExistKeyword(TempString)) {
+ for (int i=0;i<DataSet.BrukerHeaderMap[TempString].GetNumberOfElements();i++){
+ TempVectInt.push_back(DataSet.BrukerHeaderMap[TempString].GetIntValue()[i]);
+ }
+ setACQ_echo_time(TempVectInt);
+ TempVectInt.clear();
+ }
+ else return false;
+
+ return true;
+}
+
--- /dev/null
+//
+// C++ Interface: brukerobject
+//
+// Description:
+//
+//
+// Author: <Denis Grenier>, (C) 2008
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef BRUKERKSPACEOBJECT_H
+#define BRUKERKSPACEOBJECT_H
+
+#include <vector>
+#include "brukerSystem.h"
+#include "brukerdataset.h"
+
+
+class creaBruker_EXPORT BrukerKspaceObject{
+public:
+ BrukerKspaceObject(BrukerDataSet DataSet);
+ ~BrukerKspaceObject();
+
+
+
+ void setAbsoluteTimePosition ( long theValue )
+ {
+ AbsoluteTimePosition = theValue;
+ }
+
+
+
+ long getAbsoluteTimePosition() const
+ {
+ return AbsoluteTimePosition;
+ }
+
+ void setACQ_phase_factor ( int theValue )
+ {
+ ACQ_phase_factor = theValue;
+ }
+
+
+ int getACQ_phase_factor() const
+ {
+ return ACQ_phase_factor;
+ }
+
+ void setDimension ( int theValue )
+ {
+ Dimension = theValue;
+ }
+
+ int getDimension() const
+ {
+ return Dimension;
+ }
+
+ void setFlipAngle ( double theValue )
+ {
+ FlipAngle = theValue;
+ }
+
+ double getFlipAngle() const
+ {
+ return FlipAngle;
+ }
+
+ void setImaginaryPart ( const std::vector< double >& theValue )
+ {
+ ImaginaryPart = theValue;
+ }
+
+ std::vector< double > getImaginaryPart() const
+ {
+ return ImaginaryPart;
+ }
+
+ void setNA ( int theValue )
+ {
+ NA = theValue;
+ }
+
+ int getNA() const
+ {
+ return NA;
+ }
+
+ void setNR ( int theValue )
+ {
+ NR = theValue;
+ }
+
+ int getNR() const
+ {
+ return NR;
+ }
+
+ void setNumberOfSlices ( int theValue )
+ {
+ NumberOfSlices = theValue;
+ }
+
+
+int getNumberOfSlices() const
+{
+ return NumberOfSlices;
+}
+
+void setObjectNumber ( int theValue )
+{
+ ObjectNumber = theValue;
+}
+
+
+int getObjectNumber() const
+{
+ return ObjectNumber;
+}
+
+void setRealPart ( const std::vector< double >& theValue )
+{
+ RealPart = theValue;
+}
+
+
+std::vector< double > getRealPart() const
+{
+ return RealPart;
+}
+
+void setRG ( double theValue )
+{
+ RG = theValue;
+}
+
+
+double getRG() const
+{
+ return RG;
+}
+
+void setRotationMatrixRPS2XYZ ( const std::vector< std :: vector < double > >& theValue )
+{
+ RotationMatrixRPS2XYZ = theValue;
+}
+
+
+std::vector< std :: vector < double > > getRotationMatrixRPS2XYZ() const
+{
+ return RotationMatrixRPS2XYZ;
+}
+
+void setSliceNumber ( int theValue )
+{
+ SliceNumber = theValue;
+}
+
+
+int getSliceNumber() const
+{
+ return SliceNumber;
+}
+
+void setSliceThickness ( double theValue )
+{
+ SliceThickness = theValue;
+}
+
+
+double getSliceThickness() const
+{
+ return SliceThickness;
+}
+
+void setTE ( double theValue )
+{
+ TE = theValue;
+}
+
+
+double getTE() const
+{
+ return TE;
+}
+
+
+void setTI ( double theValue )
+{
+ TI = theValue;
+}
+
+
+double getTI() const
+{
+ return TI;
+}
+
+void setTR ( double theValue )
+{
+ TR = theValue;
+}
+
+
+double getTR() const
+{
+ return TR;
+}
+
+void setTranslationVectorRPS2XYZ ( const std::vector< double >& theValue )
+{
+ TranslationVectorRPS2XYZ = theValue;
+}
+
+
+std::vector< double > getTranslationVectorRPS2XYZ() const
+{
+ return TranslationVectorRPS2XYZ;
+}
+
+void setDimensionSizes ( const std::vector< int >& theValue )
+{
+ DimensionSizes = theValue;
+}
+
+
+std::vector< int > getDimensionSizes() const
+{
+ return DimensionSizes;
+}
+
+void setFOV ( const std::vector< double >& theValue )
+{
+ FOV = theValue;
+}
+
+
+std::vector< double > getFOV() const
+{
+ return FOV;
+}
+
+
+bool FillWithObject(BrukerDataSet DataSet, int ObjectNumber);
+
+
+void setNI ( int theValue )
+{
+ NI = theValue;
+}
+
+
+int getNI() const
+{
+ return NI;
+}
+
+void setNAE ( int theValue )
+{
+ NAE = theValue;
+}
+
+
+int getNAE() const
+{
+ return NAE;
+}
+
+void setDS ( int theValue )
+{
+ DS = theValue;
+}
+
+
+int getDS() const
+{
+ return DS;
+}
+
+void setACQ_ns_list ( const std::vector< int >& theValue )
+{
+ ACQ_ns_list = theValue;
+}
+
+
+std::vector< int > getACQ_ns_list() const
+{
+ return ACQ_ns_list;
+}
+
+void setACQ_obj_order ( const std::vector< int >& theValue )
+{
+ ACQ_obj_order = theValue;
+}
+
+
+std::vector< int > getACQ_obj_order() const
+{
+ return ACQ_obj_order;
+}
+
+void setACQ_echo_time ( const std::vector< int >& theValue )
+{
+ ACQ_echo_time = theValue;
+}
+
+std::vector< int > getACQ_echo_time() const
+{
+ return ACQ_echo_time;
+}
+
+
+
+private:
+ int ObjectNumber;
+ int Dimension;
+ std::vector <int> DimensionSizes;
+ std::vector <int> ACQ_ns_list;
+ std::vector <int> ACQ_obj_order;
+ std::vector <int> ACQ_echo_time;
+ double TE;
+ double TR;
+ double TI;
+ double FlipAngle;
+ double RG;
+ int NA;
+ int ACQ_phase_factor;
+ std::vector<std::vector<double> > RotationMatrixRPS2XYZ;
+ std::vector <double> TranslationVectorRPS2XYZ;
+ long AbsoluteTimePosition;
+ int NR;
+ int NI;
+ int NAE;
+ int DS;
+ int NumberOfSlices;
+ int SliceNumber;
+ std::vector <double> FOV;
+ double SliceThickness;
+ std::vector<double> RealPart;
+ std::vector<double> ImaginaryPart;
+};
+
+#endif
--- /dev/null
+//
+// C++ Implementation: brukerobjectvaryingproperties
+//
+// Description:
+//
+//
+// Author: denis grenier <denis.grenier@creatis.univ-lyon1.fr>, (C) 2009
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include "brukerobjectvaryingproperties.h"
+
+
+
+BrukerObjectVaryingProperties::BrukerObjectVaryingProperties()
+{
+}
+
+
+BrukerObjectVaryingProperties::~BrukerObjectVaryingProperties()
+{
+}
+
+
+
+void BrukerObjectVaryingProperties::setPositionS(std::map<std::string, BrukerFieldData> & BrukerHM){
+ std::vector<double> PosiS =BrukerHM[(std::string) "ACQ_slice_offset"].GetDoubleValue();
+ PositionS =PosiS;
+};
+
+void BrukerObjectVaryingProperties::setPositionR(std::map<std::string, BrukerFieldData> & BrukerHM){
+ PositionR =BrukerHM[(std::string) "ACQ_read_offset"].GetDoubleValue() ;
+};
+
+void BrukerObjectVaryingProperties::setPositionP(std::map<std::string, BrukerFieldData> & BrukerHM){
+ PositionP =BrukerHM[(std::string) "ACQ_phase1_offset"].GetDoubleValue();
+};
+
+void BrukerObjectVaryingProperties::setTE(std::map<std::string, BrukerFieldData> & BrukerHM){
+ TE = BrukerHM[(std::string) "ACQ_echo_time"].GetDoubleValue();
+};
+
+double BrukerObjectVaryingProperties::getTE(int theValue) const{
+ if (theValue < TE.size() && theValue >=0) {return TE[theValue];}
+ else throw 0;
+}
+
+/*void BrukerObjectVaryingProperties::setTE(const std::vector< double >& theValue)
+{
+ TE = theValue;
+}*/
+
+double BrukerObjectVaryingProperties::getPositionP(int theValue) const{
+ if (theValue < PositionP.size() && theValue >=0) return PositionP[theValue];
+ else throw 0;
+}
+
+/*void BrukerObjectVaryingProperties::setPositionP(const std::vector< double >& theValue)
+{
+ PositionP = theValue;
+}*/
+
+double BrukerObjectVaryingProperties::getPositionR(int theValue) const{
+ if (theValue < PositionR.size() && theValue >=0) return PositionR[theValue];
+ else throw 0;
+}
+
+/*void BrukerObjectVaryingProperties::setPositionR(const std::vector< double >& theValue)
+{
+ PositionP = theValue;
+}*/
+
+double BrukerObjectVaryingProperties::getPositionS(int theValue) const{
+ if (theValue < PositionS.size() && theValue >=0) return PositionS[theValue];
+ else throw 0;
+}
+
+/*void BrukerObjectVaryingProperties::setPositionS(const std::vector< double >& theValue)
+{
+ PositionP = theValue;
+}*/
+
+int BrukerObjectVaryingProperties::getAcquisitionOrder(int theValue) const{
+ if (theValue <AcquisitionOrder.size() && theValue >=0) return AcquisitionOrder[theValue];
+ else throw 0;
+}
+
+/*void BrukerObjectVaryingProperties::setAcquisitionOrder(const std::vector< int >& theValue1, const std::vector< int >& theValue2)
+{
+ AcquisitionOrder.clear();
+ if (theValue1.size() != theValue2[3]*theValue2[1]) throw 0;
+ if (theValue2.size() < 4 ) throw 0;
+ for (int i =0 ;i<theValue2[3];i++)AcquisitionOrder.push_back()=(int) theValue1[i*theValue2[1]]/theValue2[1];
+}*/
+
+void BrukerObjectVaryingProperties::setAcquisitionOrder(std::map<std::string, BrukerFieldData> & BrukerHM, std::vector<int> & LoopStruct){
+ std::vector<int> AcqOrder;
+ if (BrukerHM[(std::string) "ACQ_obj_order"].GetIntValue().size() != LoopStruct[3]*LoopStruct[1]) throw 0;
+ if (LoopStruct.size() < 4 ) throw 0;
+ for (int i =0 ;i<LoopStruct[3];i++)
+ AcqOrder.push_back((int) BrukerHM[(std::string) "ACQ_obj_order"].GetIntValue()[i*LoopStruct[1]]/LoopStruct[1]);
+ AcquisitionOrder=AcqOrder;
+};
+
+std :: vector < std :: vector < double > > BrukerObjectVaryingProperties::getOrientation(int theValue) const{
+ if (theValue <Orientation.size() && theValue >=0)return Orientation[theValue];
+ else throw 0;
+}
+
+/*void BrukerObjectVaryingProperties::setOrientation( std :: vector < double > & theValue1,const std::vector< int >& theValue2)
+{
+ if (theValue1.size() != theValue2[3]*9) throw 0;
+ if (theValue2.size() < 4 ) throw 0;
+ int counter=0;
+ for(int i=0;i<theValue2[3];i++){
+ for(int j=0;j<3;j++){
+ for(int k=0;k<3;k++){
+ Orientation[i][j][k]=theValue1[counter];
+ counter++;
+ }
+ }
+ }
+}*/
+
+void BrukerObjectVaryingProperties::setOrientation(std::map<std::string, BrukerFieldData> & BrukerHM, std::vector<int> & LoopStruct){
+ if (BrukerHM[(std::string) "ACQ_grad_matrix"].GetDoubleValue().size() != LoopStruct[3]*9) throw 0;
+ if (LoopStruct.size() < 4 ) throw 0;
+
+ std::vector<double> Temp1D(3,0.0);
+ std::vector<std::vector<double> > Temp2D;
+ std::vector<std::vector<std::vector<double> > > Temp3D;
+ int i, j ,k;
+
+ for(i=0;i<3;i++)
+ Temp2D.push_back(Temp1D);
+ for (i=0;i<LoopStruct[3];i++)
+ Temp3D.push_back(Temp2D);
+
+ int counter=0;
+ for(i=0;i<LoopStruct[3];i++){
+ for(j=0;j<3;j++){
+ for(k=0;k<3;k++){
+ Temp3D[i][j][k]=BrukerHM[(std::string) "ACQ_grad_matrix"].GetDoubleValue()[counter];
+ counter++;
+ }
+ }
+ }
+ Orientation=Temp3D;
+};
+
+double BrukerObjectVaryingProperties::getPositionTimePerNR(int theValue) const{
+ if (theValue <PositionTimePerNR.size() && theValue >=0) return PositionTimePerNR[theValue];
+ else throw 0;
+}
+
+void BrukerObjectVaryingProperties::setPositionTimePerNR(std::map<std::string, BrukerFieldData> & BrukerHM, std::vector<int> & LoopStruct){
+ double FloatPositionTimePerNR=BrukerHM[(std::string) "ACQ_repetition_time"].GetDoubleValue()[0];
+ int i=0;
+ int NA=BrukerHM[(std::string) "NA"].GetIntValue()[0];
+ int NAE=BrukerHM[(std::string) "NAE"].GetIntValue()[0];
+ double temp;
+
+/*
+ les loop de 0 a 3 ne sont pas conceres par le temps car ils creent presque systematiquement
+un melange temporel des donnees, c'est pour cela que je ne calcule q'un temps moyen a partir de celles -ci
+*/
+ for (i=4; i<(LoopStruct.size()-1);i++)
+ {
+ FloatPositionTimePerNR=FloatPositionTimePerNR*LoopStruct[i];
+ }
+ FloatPositionTimePerNR=FloatPositionTimePerNR*NA*NAE/2000.0;
+ if (BrukerHM[(std::string) "ACQ_temporal_delay"].GetDoubleValue().size()==1)
+ {
+ temp=BrukerHM[(std::string)"ACQ_temporal_delay"].GetDoubleValue()[0]/1000.0;
+ for (i=1; i<=LoopStruct.back();i++)
+ {
+ PositionTimePerNR.push_back(FloatPositionTimePerNR+ (2*FloatPositionTimePerNR+temp)*(i-1));
+ }
+ }
+
+ if (BrukerHM[(std::string) "ACQ_temporal_delay"].GetDoubleValue().size()!=1&& BrukerHM[(std::string) "ACQ_temporal_delay"].GetDoubleValue().size()!=(LoopStruct.back()-1))
+ {
+ throw 0;
+ }
+ if (BrukerHM[(std::string) "ACQ_temporal_delay"].GetDoubleValue().size()!=1&& BrukerHM[(std::string) "ACQ_temporal_delay"].GetDoubleValue().size()==(LoopStruct.back()-1))
+ {
+ PositionTimePerNR[0] = FloatPositionTimePerNR;
+ for (int i=1; i<=LoopStruct.back();i++)
+ {
+ PositionTimePerNR[i] = PositionTimePerNR[i-1]+ (2*FloatPositionTimePerNR+BrukerHM[(std::string) "ACQ_temporal_delay"].GetDoubleValue()[i-1]/1000.0);
+ }
+ }
+}
+
+
+/*!
+ \fn BrukerObjectVaryingProperties::init(std::map<std::string, BrukerFieldData> BrukerHM,std::vector<int> LoopStruct)
+ */
+bool BrukerObjectVaryingProperties::init(std::map<std::string, BrukerFieldData> & BrukerHM, std::vector<int> & LoopStruct)
+{
+ setAcquisitionOrder( BrukerHM, LoopStruct);
+ setOrientation(BrukerHM, LoopStruct);
+ setPositionP(BrukerHM);
+ setPositionR(BrukerHM);
+ setPositionS(BrukerHM);
+ setPositionTimePerNR(BrukerHM, LoopStruct);
+ setTE(BrukerHM);
+}
+
--- /dev/null
+//
+// C++ Interface: brukerobjectvaryingproperties
+//
+// Description:
+//
+//
+// Author: denis grenier <denis.grenier@creatis.univ-lyon1.fr>, (C) 2009
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef BRUKEROBJECTVARYINGPROPERTIES_H
+#define BRUKEROBJECTVARYINGPROPERTIES_H
+#include <cstdlib>
+#include <stdlib.h>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <stdio.h>
+#include <fstream>
+#include <map>
+#include <algorithm>
+#include "boost/regex.hpp"
+#include "brukerFieldData.h"
+#include "brukerSystem.h"
+
+/**
+ @author denis grenier <denis.grenier@creatis.univ-lyon1.fr>
+*/
+class creaBruker_EXPORT BrukerObjectVaryingProperties{
+public:
+ BrukerObjectVaryingProperties();
+ ~BrukerObjectVaryingProperties();
+
+ double getTE (int theValue) const;
+ double getPositionP (int theValue) const;
+ double getPositionR (int theValue) const;
+ double getPositionS (int theValue) const;
+ double getPositionTimePerNR(int theValue) const;
+ int getAcquisitionOrder (int theValue) const;
+
+ std::vector<std::vector<double> > getOrientation(int theValue) const;
+
+ bool init(std::map<std::string, BrukerFieldData> &BrukerHM, std::vector<int> &LoopStruct);
+
+private:
+
+ void setPositionTimePerNR (std::map<std::string, BrukerFieldData> &BrukerHM, std::vector<int> &LoopStruct);
+ void setOrientation (std::map<std::string, BrukerFieldData> &BrukerHM, std::vector<int> &LoopStruct);
+ void setAcquisitionOrder (std::map<std::string, BrukerFieldData> &BrukerHM, std::vector<int> &LoopStruct);
+ void setPositionS (std::map<std::string, BrukerFieldData> &BrukerHM);
+ void setPositionR (std::map<std::string, BrukerFieldData> &BrukerHM);
+ void setPositionP (std::map<std::string, BrukerFieldData> &BrukerHM);
+ void setTE (std::map<std::string, BrukerFieldData> &BrukerHM);
+ std::vector<double> TE;
+ std::vector<double> PositionR;
+ std::vector<double> PositionP;
+ std::vector<double> PositionS;
+ std::vector<double> PositionTimePerNR;
+ std::vector<int> AcquisitionOrder;
+ std::vector<std::vector<std::vector <double> > > Orientation;
+};
+
+#endif
--- /dev/null
+#----------------------------------------------------------------------------
+# SET THE NAME OF YOUR LIBRARY
+SET ( LIBRARY_NAME MyLib )
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# CREATES A USER OPTION IN CMAKE
+OPTION ( BUILD_${LIBRARY_NAME} "Build ${LIBRARY_NAME} library ?" ON)
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+IF ( BUILD_${LIBRARY_NAME} )
+#----------------------------------------------------------------------------
+
+ #----------------------------------------------------------------------------
+ # BUILD LIBRARY
+ #----------------------------------------------------------------------------
+
+ #----------------------------------------------------------------------------
+ # LIBRARY HEADERS (TO BE INSTALLED)
+ # EITHER LIST ALL .h IN CURRENT DIR USING NEXT LINE:
+ FILE(GLOB ${LIBRARY_NAME}_HEADERS "*.h")
+ # OR MANUALLY LIST YOUR HEADERS WITH NEXT COMMAND
+ # SET ( ${LIBRARY_NAME}_HEADERS
+ #
+ # )
+ #----------------------------------------------------------------------------
+
+ #----------------------------------------------------------------------------
+ # LIBRARY SOURCES (TO BE COMPILED)
+ # EITHER LIST ALL .cxx, *.cpp, *.cc IN CURRENT DIR USING NEXT LINE:
+ FILE(GLOB ${LIBRARY_NAME}_SOURCES *.cxx *.cpp *.cc)
+ # OR MANUALLY LIST YOUR FILES WITH NEXT COMMAND (WITHOUT EXTENSION)
+ # SET ( ${LIBRARY_NAME}_SOURCES
+ #
+ # )
+ #----------------------------------------------------------------------------
+
+ #----------------------------------------------------------------------------
+ # LIBRARY DEPENDENCIES (LIBRARIES TO LINK WITH)
+ SET ( ${LIBRARY_NAME}_LINK_LIBRARIES
+ ${crea_LIBRARIES}
+ # ${WXWIDGETS_LIBRARIES}
+ # ${VTK_LIBRARIES}
+ # ${ITK_LIBRARIES}
+ # ${GDCM_LIBRARIES}
+ # ${BOOST_LIBRARIES}
+ )
+ #----------------------------------------------------------------------------
+
+
+ #----------------------------------------------------------------------------
+ # MACRO WHICH DOES ALL THE JOB : BUILD AND INSTALL
+ CREA_ADD_LIBRARY( ${LIBRARY_NAME} )
+ #----------------------------------------------------------------------------
+
+
+ #---------------------------------------------------------------------------
+ENDIF ( BUILD_${LIBRARY_NAME} )