]> Creatis software - clitk.git/commitdiff
Converted plastimatch dicom RT dose reader in ITK IO format.
authorsrit <srit>
Wed, 8 Sep 2010 09:56:02 +0000 (09:56 +0000)
committersrit <srit>
Wed, 8 Sep 2010 09:56:02 +0000 (09:56 +0000)
common/CMakeLists.txt
common/clitkDicomRTDoseIO.cxx [new file with mode: 0644]
common/clitkDicomRTDoseIO.h [new file with mode: 0644]
common/clitkDicomRTDoseIOFactory.cxx [new file with mode: 0644]
common/clitkDicomRTDoseIOFactory.h [new file with mode: 0644]

index 74a5786eddc2b76f5d78d592240ebe94b856705d..76e9179a825f4cf4905ff21dd9a73741270974bc 100644 (file)
@@ -24,6 +24,8 @@ SET(clitkCommon_SRC
   clitkXdrImageIOFactory.cxx
   clitkHndImageIO.cxx
   clitkHndImageIOFactory.cxx
+  clitkDicomRTDoseIO.cxx
+  clitkDicomRTDoseIOFactory.cxx
   clitkOrientation.cxx
   vvImage.cxx
   clitkImageToImageGenericFilterBase.cxx
diff --git a/common/clitkDicomRTDoseIO.cxx b/common/clitkDicomRTDoseIO.cxx
new file mode 100644 (file)
index 0000000..6e3eba0
--- /dev/null
@@ -0,0 +1,246 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+
+// clitk include
+#include "clitkDicomRTDoseIO.h"
+#include "clitkCommon.h"
+
+// itk include
+#include <gdcmFileHelper.h>
+
+#define GFOV_SPACING_TOL (1e-1)
+
+//--------------------------------------------------------------------
+// Read Image Information
+void clitk::DicomRTDoseIO::ReadImageInformation()
+{
+  if(m_GdcmFile)
+    delete m_GdcmFile;
+  m_GdcmFile = new gdcm::File;
+
+  int i, rc;
+  std::string tmp;
+  float ipp[3];
+  int dim[3];
+  float spacing[3];
+  float *gfov;    /* gfov = GridFrameOffsetVector */
+  int gfov_len;
+  const char *gfov_str;
+
+  m_GdcmFile->SetMaxSizeLoadEntry (0xffff);
+  m_GdcmFile->SetFileName (m_FileName.c_str());
+  m_GdcmFile->SetLoadMode (0);
+  m_GdcmFile->Load();
+
+  /* Modality -- better be RTSTRUCT */
+  tmp = m_GdcmFile->GetEntryValue (0x0008, 0x0060);
+  if (strncmp (tmp.c_str(), "RTDOSE", strlen("RTDOSE"))) {
+    itkExceptionMacro(<< "Error.  Input file not RTDOSE: " << m_FileName);
+  }
+
+  /* ImagePositionPatient */
+  tmp = m_GdcmFile->GetEntryValue (0x0020, 0x0032);
+  rc = sscanf (tmp.c_str(), "%f\\%f\\%f", &ipp[0], &ipp[1], &ipp[2]);
+  if (rc != 3) {
+    itkExceptionMacro(<< "Error parsing RTDOSE ipp.");
+  }
+
+  /* Rows */
+  tmp = m_GdcmFile->GetEntryValue (0x0028, 0x0010);
+  rc = sscanf (tmp.c_str(), "%d", &dim[1]);
+  if (rc != 1) {
+    itkExceptionMacro(<< "Error parsing RTDOSE rows.");
+  }
+
+  /* Columns */
+  tmp = m_GdcmFile->GetEntryValue (0x0028, 0x0011);
+  rc = sscanf (tmp.c_str(), "%d", &dim[0]);
+  if (rc != 1) {
+    itkExceptionMacro(<< "Error parsing RTDOSE columns.");
+  }
+
+  /* PixelSpacing */
+  tmp = m_GdcmFile->GetEntryValue (0x0028, 0x0030);
+  rc = sscanf (tmp.c_str(), "%g\\%g", &spacing[0], &spacing[1]);
+
+  if (rc != 2) {
+    itkExceptionMacro(<< "Error parsing RTDOSE pixel spacing.");
+  }
+
+  /* GridFrameOffsetVector */
+  tmp = m_GdcmFile->GetEntryValue (0x3004, 0x000C);
+  gfov = 0;
+  gfov_len = 0;
+  gfov_str = tmp.c_str();
+  while (1) {
+    int len;
+    gfov = (float*) realloc (gfov, (gfov_len + 1) * sizeof(float));
+    rc = sscanf (gfov_str, "%g%n", &gfov[gfov_len], &len);
+    if (rc != 1) {
+      break;
+    }
+    gfov_len ++;
+    gfov_str += len;
+    if (gfov_str[0] == '\\') {
+      gfov_str ++;
+    }
+  }
+  dim[2] = gfov_len;
+  if (gfov_len == 0) {
+    itkExceptionMacro(<< "Error parsing RTDOSE gfov.");
+  }
+
+  /* --- Analyze GridFrameOffsetVector --- */
+
+  /* (1) Make sure first element is 0. */
+  if (gfov[0] != 0.) {
+    itkExceptionMacro(<< "Error RTDOSE gfov[0] is not 0.");
+  }
+
+  /* (2) Handle case where gfov_len == 1 (only one slice). */
+  if (gfov_len == 1) {
+    spacing[2] = spacing[0];
+  }
+
+  /* (3) Check to make sure spacing is regular. */
+  for (i = 1; i < gfov_len; i++) {
+    if (i == 1) {
+      spacing[2] = gfov[1] - gfov[0];
+    } else {
+      float sp = gfov[i] - gfov[i-1];
+      if (fabs(sp - spacing[2]) > GFOV_SPACING_TOL) {
+        itkExceptionMacro(<< "Error RTDOSE grid has irregular spacing:"
+                          << sp << " vs " << spacing[2]);
+      }
+    }
+  }
+
+  free (gfov);
+
+  /* DoseGridScaling */
+  m_DoseScaling = 1.0;
+  tmp = m_GdcmFile->GetEntryValue (0x3004, 0x000E);
+  rc = sscanf (tmp.c_str(), "%f", &m_DoseScaling);
+  /* If element doesn't exist, scaling is 1.0 */
+
+  // set dimension values
+  SetNumberOfDimensions(3);
+  for(int i=0; i<3; i++) {
+    SetDimensions(i, dim[i]);
+    SetSpacing(i, spacing[i]);
+    SetOrigin(i, ipp[i]);
+  }
+
+  // set other information
+  SetByteOrderToLittleEndian();
+  SetPixelType(itk::ImageIOBase::SCALAR);
+  SetNumberOfComponents(1);
+  SetComponentType(itk::ImageIOBase::FLOAT);
+}
+
+//--------------------------------------------------------------------
+// Read Image Information
+bool clitk::DicomRTDoseIO::CanReadFile(const char* FileNameToRead)
+{
+  // opening dicom input file
+  gdcm::File dcmFile;
+  dcmFile.SetFileName(FileNameToRead);
+  if (!dcmFile.OpenFile())
+    return false;
+
+  //Taken from plastimatch
+  dcmFile.SetMaxSizeLoadEntry (0xffff);
+  dcmFile.SetLoadMode (0);
+  dcmFile.Load();
+
+  /* Modality -- better be RTDOSE */
+  std::string tmp = dcmFile.GetEntryValue (0x0008, 0x0060);
+  if (!strncmp (tmp.c_str(), "RTDOSE", strlen("RTDOSE"))) {
+    return true;
+  }
+
+  return false;
+}
+
+//--------------------------------------------------------------------
+template <class T>
+void
+clitk::DicomRTDoseIO::dose_copy_raw (float *img_out, T *img_in, int nvox, float scale)
+{
+  for (int i = 0; i < nvox; i++) {
+    img_out[i] = img_in[i] * scale;
+  }
+}
+
+//--------------------------------------------------------------------
+// Read Image Content
+void clitk::DicomRTDoseIO::Read(void * buffer)
+{
+  float *img = (float*) buffer;
+
+  unsigned long npix = 1;
+  for(unsigned int i=0; i<GetNumberOfDimensions(); i++)
+    npix *= GetDimensions(i);
+
+  /* PixelData */
+  gdcm::FileHelper m_GdcmFile_helper (m_GdcmFile);
+
+  //size_t image_data_size = m_GdcmFile_helper.GetImageDataSize();
+  if (strcmp (m_GdcmFile->GetPixelType().c_str(), "16U")==0) {
+    unsigned short* image_data = (unsigned short*) m_GdcmFile_helper.GetImageData();
+    dose_copy_raw (img, image_data, npix, m_DoseScaling);
+  } else if (strcmp(m_GdcmFile->GetPixelType().c_str(),"32U")==0) {
+    unsigned long* image_data = (unsigned long*) m_GdcmFile_helper.GetImageData ();
+    dose_copy_raw (img, image_data, npix, m_DoseScaling);
+  } else {
+    itkExceptionMacro(<< "Error RTDOSE not type 16U and 32U (type="
+                      << m_GdcmFile->GetPixelType().c_str() << ")");
+  }
+
+  /* GCS FIX: Do I need to do something about endian-ness? */
+
+
+
+  /* Copy data to volume */
+//   float *img = (float*) vol->img;
+//   for (i = 0; i < vol->npix; i++) {
+  //img[i] = image_data[i] * m_DoseScaling;
+//   }
+
+  delete m_GdcmFile;
+}
+
+//--------------------------------------------------------------------
+// Write Image Information
+void clitk::DicomRTDoseIO::WriteImageInformation(bool keepOfStream)
+{
+}
+
+//--------------------------------------------------------------------
+// Write Image Information
+bool clitk::DicomRTDoseIO::CanWriteFile(const char* FileNameToWrite)
+{
+  return false;
+}
+
+//--------------------------------------------------------------------
+// Write Image
+void clitk::DicomRTDoseIO::Write(const void * buffer)
+{
+}
+
diff --git a/common/clitkDicomRTDoseIO.h b/common/clitkDicomRTDoseIO.h
new file mode 100644 (file)
index 0000000..b5679aa
--- /dev/null
@@ -0,0 +1,82 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+#ifndef clitkDicomRTDoseIO_h
+#define clitkDicomRTDoseIO_h
+
+// clitk include
+#include "clitkCommon.h"
+
+// itk include
+#include <itkImageIOBase.h>
+#include <gdcmFile.h>
+
+// std include
+#include <fstream>
+
+namespace clitk
+{
+
+//====================================================================
+// Class for reading Vox Image file format
+class DicomRTDoseIO: public itk::ImageIOBase
+{
+public:
+  /** Standard class typedefs. */
+  typedef DicomRTDoseIO              Self;
+  typedef itk::ImageIOBase        Superclass;
+  typedef itk::SmartPointer<Self> Pointer;
+  typedef signed short int        PixelType;
+
+  DicomRTDoseIO():Superclass() {
+    mustWriteHeader = false;
+    m_GdcmFile=NULL;
+  }
+
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self);
+
+  /** Run-time type information (and related methods). */
+  itkTypeMacro(DicomRTDoseIO, ImageIOBase);
+
+  /*-------- This part of the interface deals with reading data. ------ */
+  virtual void ReadImageInformation();
+  virtual bool CanReadFile( const char* FileNameToRead );
+  virtual void Read(void * buffer);
+
+  /*-------- This part of the interfaces deals with writing data. ----- */
+  virtual void WriteImageInformation(bool keepOfStream);
+  virtual void WriteImageInformation() {
+    WriteImageInformation(false);
+  }
+  virtual bool CanWriteFile(const char* filename);
+  virtual void Write(const void* buffer);
+
+protected:
+  template <class T> void dose_copy_raw (float *img_out, T *img_in, int nvox, float scale);
+
+  bool mustWriteHeader;
+  int m_HeaderSize;
+  std::ofstream file;
+  gdcm::File *m_GdcmFile;
+  float m_DoseScaling;
+}; // end class DicomRTDoseIO
+
+} // end namespace
+
+#endif /* end #define clitkDicomRTDoseIO_h */
+
diff --git a/common/clitkDicomRTDoseIOFactory.cxx b/common/clitkDicomRTDoseIOFactory.cxx
new file mode 100644 (file)
index 0000000..42e963a
--- /dev/null
@@ -0,0 +1,35 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+#ifndef clitkDicomRTDoseIOFactory_cxx
+#define clitkDicomRTDoseIOFactory_cxx
+
+#include "clitkDicomRTDoseIOFactory.h"
+
+//====================================================================
+clitk::DicomRTDoseIOFactory::DicomRTDoseIOFactory()
+{
+  this->RegisterOverride("itkImageIOBase",
+                         "DicomRTDoseIO",
+                         "Dicom RT dose IO",
+                         1,
+                         itk::CreateObjectFunction<DicomRTDoseIO>::New());
+}
+
+
+#endif /* end #define clitkDicomRTDoseIOFactory_cxx */
+
diff --git a/common/clitkDicomRTDoseIOFactory.h b/common/clitkDicomRTDoseIOFactory.h
new file mode 100644 (file)
index 0000000..93f3da1
--- /dev/null
@@ -0,0 +1,75 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+#ifndef clitkDicomRTDoseIOFactory_h
+#define clitkDicomRTDoseIOFactory_h
+
+// clitk include
+#include "clitkDicomRTDoseIO.h"
+
+// itk include
+#include "itkImageIOBase.h"
+#include "itkObjectFactoryBase.h"
+#include "itkVersion.h"
+
+namespace clitk
+{
+
+//====================================================================
+// Factory for reading Dicom RT Dose file
+class DicomRTDoseIOFactory: public itk::ObjectFactoryBase
+{
+public:
+  /** Standard class typedefs. */
+  typedef DicomRTDoseIOFactory           Self;
+  typedef itk::ObjectFactoryBase         Superclass;
+  typedef itk::SmartPointer<Self>        Pointer;
+  typedef itk::SmartPointer<const Self>  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 "Dicom RT Dose IO factory";
+  }
+
+  /** Method for class instantiation. */
+  itkFactorylessNewMacro(Self);
+
+  /** Run-time type information (and related methods). */
+  itkTypeMacro(DicomRTDoseIOFactory, ObjectFactoryBase);
+
+  /** Register one factory of this type  */
+  static void RegisterOneFactory(void) {
+    ObjectFactoryBase::RegisterFactory( Self::New() );
+  }
+
+protected:
+  DicomRTDoseIOFactory();
+  ~DicomRTDoseIOFactory() {};
+
+private:
+  DicomRTDoseIOFactory(const Self&); //purposely not implemented
+  void operator=(const Self&); //purposely not implemented
+};
+
+} // end namespace
+
+#endif /* end #define clitkDicomRTDoseIOFactory_h */
+