From 557c580ad207bbb5ee3772020fce9af9ed6c48f9 Mon Sep 17 00:00:00 2001 From: pierre gueth Date: Fri, 21 Oct 2011 13:58:37 +0200 Subject: [PATCH] read gate ascii file header --- .gitignore | 1 + common/clitkGateAsciiImageIO.cxx | 155 +++++++++++++++++++++++--- common/clitkGateAsciiImageIO.h | 4 +- common/clitkGateAsciiImageIOFactory.h | 82 +++++++------- tools/clitkGammaIndex.cxx | 7 ++ 5 files changed, 189 insertions(+), 60 deletions(-) diff --git a/.gitignore b/.gitignore index 378eac2..d5a1572 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ +*.swp build diff --git a/common/clitkGateAsciiImageIO.cxx b/common/clitkGateAsciiImageIO.cxx index aa785f6..02250cb 100644 --- a/common/clitkGateAsciiImageIO.cxx +++ b/common/clitkGateAsciiImageIO.cxx @@ -17,7 +17,12 @@ ===========================================================================**/ // std include -#include +#include +#include +#include +#include +using std::cout; +using std::endl; // clitk include #include "clitkGateAsciiImageIO.h" @@ -26,6 +31,15 @@ // itk include #include +std::ostream& operator<<(std::ostream& os, const clitk::GateAsciiImageIO::GateAsciiHeader& header) +{ + os << "matrix_size=[" << header.matrix_size[0] << "," << header.matrix_size[1] << "," << header.matrix_size[2] << "]" << endl; + os << "resolution=[" << header.resolution[0] << "," << header.resolution[1] << "," << header.resolution[2] << "]" << endl; + os << "voxel_size=[" << header.voxel_size[0] << "," << header.voxel_size[1] << "," << header.voxel_size[2] << "]" << endl; + os << "nb_value=" << header.nb_value << endl; + return os; +} + //-------------------------------------------------------------------- // Read Image Information void clitk::GateAsciiImageIO::ReadImageInformation() @@ -33,28 +47,135 @@ void clitk::GateAsciiImageIO::ReadImageInformation() itkGenericExceptionMacro(<< "Could not open file (for reading): " << m_FileName); - /* Convert hnd to ITK image information */ - SetNumberOfDimensions(2); - //SetDimensions(0, hnd.SizeX); - //SetDimensions(1, hnd.SizeY); - //SetSpacing(0, hnd.dIDUResolutionX); - //SetSpacing(1, hnd.dIDUResolutionY); - //SetOrigin(0, -0.5*(hnd.SizeX-1)*hnd.dIDUResolutionX); //SR: assumed centered - //SetOrigin(1, -0.5*(hnd.SizeY-1)*hnd.dIDUResolutionY); //SR: assumed centered - //SetComponentType(itk::ImageIOBase::UINT); + /* Convert hnd to ITK image information */ + SetNumberOfDimensions(2); + //SetDimensions(0, hnd.SizeX); + //SetDimensions(1, hnd.SizeY); + //SetSpacing(0, hnd.dIDUResolutionX); + //SetSpacing(1, hnd.dIDUResolutionY); + //SetOrigin(0, -0.5*(hnd.SizeX-1)*hnd.dIDUResolutionX); //SR: assumed centered + //SetOrigin(1, -0.5*(hnd.SizeY-1)*hnd.dIDUResolutionY); //SR: assumed centered + //SetComponentType(itk::ImageIOBase::UINT); - /* Store important meta information in the meta data dictionary */ - //itk::EncapsulateMetaData(this->GetMetaDataDictionary(), "dCTProjectionAngle", hnd.dCTProjectionAngle); - //itk::ExposeMetaData( this->GetMetaDataDictionary(), &(hnd.dCTProjectionAngle), "dCTProjectionAngle"); + /* Store important meta information in the meta data dictionary */ + //itk::EncapsulateMetaData(this->GetMetaDataDictionary(), "dCTProjectionAngle", hnd.dCTProjectionAngle); + //itk::ExposeMetaData( this->GetMetaDataDictionary(), &(hnd.dCTProjectionAngle), "dCTProjectionAngle"); } //-------------------------------------------------------------------- bool clitk::GateAsciiImageIO::CanReadFile(const char* FileNameToRead) { - std::string filename(FileNameToRead); - std::string filenameext = GetExtension(filename); - if (filenameext != std::string("hnd")) return false; - return true; + std::string filename(FileNameToRead); + + { // check extension + std::string filenameext = GetExtension(filename); + if (filenameext != std::string("txt")) return false; + } + + { // check header + FILE* handle = fopen(filename.c_str(),"r"); + if (!handle) return false; + + GateAsciiHeader header; + if (!ReadHeader(handle,header)) { fclose(handle); return false; } + fclose(handle); + } + + return true; +} + +//-------------------------------------------------------------------- +// Read Line in file +bool clitk::GateAsciiImageIO::ReadLine(FILE* handle, std::string& line) +{ + std::stringstream stream; + while (true) + { + char item; + if (ferror(handle)) return false; + if (fread(&item,1,1,handle) != 1) return false; + + if (item=='\n' or feof(handle)) { + line = stream.str(); + return true; + } + + stream << item; + } +} + +std::string ExtractMatch(const std::string& base, const regmatch_t& match) +{ + return base.substr(match.rm_so,match.rm_eo-match.rm_so); +} + +template +T ConvertFromString(const std::string& value) +{ + std::stringstream stream; + stream << value; + T converted; + stream >> converted; + return converted; +} + +//-------------------------------------------------------------------- +// Read Image Header +bool clitk::GateAsciiImageIO::ReadHeader(FILE* handle, GateAsciiHeader& header) +{ + assert(handle); + std::string line; + + regex_t re_comment; + regex_t re_matrix_size; + regex_t re_resol; + regex_t re_voxel_size; + regex_t re_nb_value; + regmatch_t matches[4]; + + { // build regex + int ret = 0; + ret = regcomp(&re_comment,"^#.+$",REG_EXTENDED|REG_NEWLINE); + assert(ret); + ret = regcomp(&re_matrix_size,"^# +Matrix *Size *= +\\(([0-9]+\\.?[0-9]*),([0-9]+\\.?[0-9]*),([0-9]+\\.?[0-9]*)\\)$",REG_EXTENDED|REG_NEWLINE); + assert(ret); + ret = regcomp(&re_resol,"^# +Resol *= +\\(([0-9]+),([0-9]+),([0-9]+)\\)$",REG_EXTENDED|REG_NEWLINE); + assert(ret); + ret = regcomp(&re_voxel_size,"^# +Voxel *Size *= +\\(([0-9]+\\.?[0-9]*),([0-9]+\\.?[0-9]*),([0-9]+\\.?[0-9]*)\\)$",REG_EXTENDED|REG_NEWLINE); + assert(ret); + ret = regcomp(&re_nb_value,"^# +nbVal *= +([0-9]+)$",REG_EXTENDED|REG_NEWLINE); + assert(ret); + } + + if (!ReadLine(handle,line)) return false; + if (regexec(&re_comment,line.c_str(),1,matches,0) == REG_NOMATCH) return false; + + if (!ReadLine(handle,line)) return false; + if (regexec(&re_matrix_size,line.c_str(),4,matches,0) == REG_NOMATCH) return false; + header.matrix_size[0] = ConvertFromString(ExtractMatch(line,matches[1])); + header.matrix_size[1] = ConvertFromString(ExtractMatch(line,matches[2])); + header.matrix_size[2] = ConvertFromString(ExtractMatch(line,matches[3])); + + if (!ReadLine(handle,line)) return false; + if (regexec(&re_resol,line.c_str(),4,matches,0) == REG_NOMATCH) return false; + header.resolution[0] = ConvertFromString(ExtractMatch(line,matches[1])); + header.resolution[1] = ConvertFromString(ExtractMatch(line,matches[2])); + header.resolution[2] = ConvertFromString(ExtractMatch(line,matches[3])); + + if (!ReadLine(handle,line)) return false; + if (regexec(&re_voxel_size,line.c_str(),4,matches,0) == REG_NOMATCH) return false; + header.voxel_size[0] = ConvertFromString(ExtractMatch(line,matches[1])); + header.voxel_size[1] = ConvertFromString(ExtractMatch(line,matches[2])); + header.voxel_size[2] = ConvertFromString(ExtractMatch(line,matches[3])); + + if (!ReadLine(handle,line)) return false; + if (regexec(&re_nb_value,line.c_str(),2,matches,0) == REG_NOMATCH) return false; + header.nb_value = ConvertFromString(ExtractMatch(line,matches[1])); + + if (!ReadLine(handle,line)) return false; + if (regexec(&re_comment,line.c_str(),1,matches,0) == REG_NOMATCH) return false; + + return true; } //-------------------------------------------------------------------- diff --git a/common/clitkGateAsciiImageIO.h b/common/clitkGateAsciiImageIO.h index b7fa18f..cc9bb8d 100644 --- a/common/clitkGateAsciiImageIO.h +++ b/common/clitkGateAsciiImageIO.h @@ -69,7 +69,9 @@ namespace clitk { virtual void Write(const void* buffer); protected: - int m_HeaderSize; + + static bool ReadHeader(FILE* handle, GateAsciiHeader& header); + static bool ReadLine(FILE* handle, std::string& line); }; // end class GateAsciiImageIO } // end namespace diff --git a/common/clitkGateAsciiImageIOFactory.h b/common/clitkGateAsciiImageIOFactory.h index 3a3b4fe..bae5ac3 100644 --- a/common/clitkGateAsciiImageIOFactory.h +++ b/common/clitkGateAsciiImageIOFactory.h @@ -27,48 +27,46 @@ #include "itkVersion.h" namespace clitk { - - //==================================================================== - // Factory for reading GateAscii Image file format - class GateAsciiImageIOFactory: public itk::ObjectFactoryBase - { - public: - /** Standard class typedefs. */ - typedef GateAsciiImageIOFactory Self; - typedef itk::ObjectFactoryBase Superclass; - typedef itk::SmartPointer Pointer; - typedef itk::SmartPointer ConstPointer; - - /** Class methods used to interface with the registered factories. */ - const char* GetITKSourceVersion(void) const { - return ITK_SOURCE_VERSION; - } - - const char* GetDescription(void) const { - return "GateAscii ImageIO Factory, allows the loading of gate ascii images into insight"; - } - - /** Method for class instantiation. */ - itkFactorylessNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(GateAsciiImageIOFactory, ObjectFactoryBase); - - /** Register one factory of this type */ - static void RegisterOneFactory(void) { - ObjectFactoryBase::RegisterFactory( Self::New() ); - } - - protected: - GateAsciiImageIOFactory(); - ~GateAsciiImageIOFactory() {}; - typedef GateAsciiImageIOFactory myProductType; - const myProductType* m_MyProduct; - - private: - GateAsciiImageIOFactory(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented - }; + + //==================================================================== + // Factory for reading GateAscii Image file format + class GateAsciiImageIOFactory: public itk::ObjectFactoryBase + { + public: + /** Standard class typedefs. */ + typedef GateAsciiImageIOFactory Self; + typedef itk::ObjectFactoryBase Superclass; + typedef itk::SmartPointer Pointer; + typedef itk::SmartPointer ConstPointer; + + /** Class methods used to interface with the registered factories. */ + const char* GetITKSourceVersion(void) const { + return ITK_SOURCE_VERSION; + } + + const char* GetDescription(void) const { + return "GateAscii ImageIO Factory, allows the loading of gate ascii images into insight"; + } + + /** Method for class instantiation. */ + itkFactorylessNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(GateAsciiImageIOFactory, ObjectFactoryBase); + + /** Register one factory of this type */ + static void RegisterOneFactory(void) { + ObjectFactoryBase::RegisterFactory( Self::New() ); + } + + protected: + GateAsciiImageIOFactory(); + ~GateAsciiImageIOFactory() {}; + + private: + GateAsciiImageIOFactory(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented + }; } // end namespace diff --git a/tools/clitkGammaIndex.cxx b/tools/clitkGammaIndex.cxx index e2369d0..59d5d83 100644 --- a/tools/clitkGammaIndex.cxx +++ b/tools/clitkGammaIndex.cxx @@ -32,6 +32,7 @@ using std::cout; #include "clitkGammaIndex_ggo.h" +#include #include #include @@ -148,6 +149,8 @@ vtkPolyData *buildPlane(vtkImageData *image,double spatial_margin,double dose_ma int main(int argc,char * argv[]) { + clitk::RegisterClitkFactories(); + args_info_clitkGammaIndex args_info; if (cmdline_parser_clitkGammaIndex(argc, argv, &args_info) != 0) @@ -184,7 +187,9 @@ int main(int argc,char * argv[]) reader->SetInputFilename(reference_filename); reader->Update(); vvImage::Pointer vvimage = reader->GetOutput(); + if (!vvimage) { cerr << "can't load " << reference_filename << endl; return 2; } reference = vvimage->GetFirstVTKImageData(); + assert(reference); } // intensity normalisation @@ -211,7 +216,9 @@ int main(int argc,char * argv[]) reader->SetInputFilename(target_filename); reader->Update(); vvImage::Pointer vvimage = reader->GetOutput(); + if (!vvimage) { cerr << "can't load " << target_filename << endl; return 2; } target = vvimage->GetFirstVTKImageData(); + if (!target) return 2; } // allocate output -- 2.45.1