diff --git a/code/io/dicom/files.cmake b/code/io/dicom/files.cmake index 5cd768c..587b85f 100644 --- a/code/io/dicom/files.cmake +++ b/code/io/dicom/files.cmake @@ -1,25 +1,23 @@ SET(CPP_FILES rttbDcmrtException.cpp rttbDicomDoseAccessor.cpp - rttbDicomFileDoseAccessorConverter.cpp rttbDicomFileDoseAccessorGenerator.cpp + rttbDicomFileDoseAccessorWriter.cpp rttbDicomFileReaderHelper.cpp rttbDicomFileStructureSetGenerator.cpp - rttbDicomIODDoseAccessorConverter.cpp rttbDicomIODDoseAccessorGenerator.cpp rttbDicomIODStructureSetGenerator.cpp rttbDVHDicomFileReader.cpp ) SET(H_FILES rttbDcmrtException.h rttbDicomDoseAccessor.h - rttbDicomFileDoseAccessorConverter.h rttbDicomFileDoseAccessorGenerator.h + rttbDicomFileDoseAccessorWriter.h rttbDicomFileReaderHelper.h rttbDicomFileStructureSetGenerator.h - rttbDicomIODDoseAccessorConverter.h rttbDicomIODDoseAccessorGenerator.h rttbDicomIODStructureSetGenerator.h rttbDVHDicomFileReader.h ) diff --git a/code/io/dicom/rttbDicomFileDoseAccessorConverter.h b/code/io/dicom/rttbDicomFileDoseAccessorConverter.h deleted file mode 100644 index 9558143..0000000 --- a/code/io/dicom/rttbDicomFileDoseAccessorConverter.h +++ /dev/null @@ -1,88 +0,0 @@ -// ----------------------------------------------------------------------- -// RTToolbox - DKFZ radiotherapy quantitative evaluation library -// -// Copyright (c) German Cancer Research Center (DKFZ), -// Software development for Integrated Diagnostics and Therapy (SIDT). -// ALL RIGHTS RESERVED. -// See rttbCopyright.txt or -// http://www.dkfz.de/en/sidt/projects/rttb/copyright.html -// -// 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. -// -//------------------------------------------------------------------------ -/*! -// @file -// @version $Revision: 793 $ (last changed revision) -// @date $Date: 2014-10-10 10:24:45 +0200 (Fr, 10 Okt 2014) $ (last change date) -// @author $Author: hentsch $ (last changed by) -*/ -#ifndef __DICOM_FILE_DOSE_ACCESSOR_CONVERTER_H -#define __DICOM_FILE_DOSE_ACCESSOR_CONVERTER_H - - -#include "../itk/rttbDoseAccessorProcessorBase.h" -#include "../itk/rttbDoseAccessorConversionSettingInterface.h" -#include "rttbDicomDoseAccessor.h" - -namespace rttb -{ - namespace io - { - namespace dicom - { - /*! @class DicomFileDoseAccessorConverter - @brief Class converts/dumps the processed accessor into an dicom file - @remark DoseAccessorConversionInterface defines how the converter should react on non valid dose values. - */ - class DicomFileDoseAccessorConverter: public core::DoseAccessorProcessorBase, - public core::DoseAccessorConversionSettingInterface - { - public: - typedef core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; - typedef DicomDoseAccessor::DRTDoseIODPtr DRTDoseIODPointer; - - /*! @brief Constructor. Initialisation with a dose accessor and a file name to write the dose - @param aFileName a file name to write the dose - */ - DicomFileDoseAccessorConverter(DoseAccessorPointer aAccessor, DICOMRTFileNameString aFileName); - - virtual ~DicomFileDoseAccessorConverter() {}; - - /*! @brief Convert the accessor into dicom dataset - @exception InvalidDoseException thrown if put and insert pixel data into dicom dataset failed - */ - bool process(); - - /*! @brief Write dicom dataset to a file - @pre process() should be true before writeDicomDoseFile() is called - */ - void writeDicomDoseFile(); - - - private: - DicomFileDoseAccessorConverter(const - DicomFileDoseAccessorConverter&); //not implemented on purpose -> non-copyable - DicomFileDoseAccessorConverter& operator=(const - DicomFileDoseAccessorConverter&);//not implemented on purpose -> non-copyable - - /* code from plastimatch - std::string formatting by Erik Aronesty - http://stackoverflow.com/questions/2342162/stdstring-formating-like-sprintf - Distributed under Attribution-ShareAlike 3.0 Unported license (CC BY-SA 3.0) - http://creativecommons.org/licenses/by-sa/3.0/ - */ - std::string string_format (const char *fmt, va_list ap); - std::string string_format (const char *fmt, ...); - - DRTDoseIODPointer _doseIOD; - DICOMRTFileNameString _fileName; - DcmFileFormat _fileformat; - DcmDataset *_dataset; - - }; - } - } -} -#endif diff --git a/code/io/dicom/rttbDicomFileDoseAccessorConverter.cpp b/code/io/dicom/rttbDicomFileDoseAccessorWriter.cpp similarity index 72% rename from code/io/dicom/rttbDicomFileDoseAccessorConverter.cpp rename to code/io/dicom/rttbDicomFileDoseAccessorWriter.cpp index 550fcd9..72c984e 100644 --- a/code/io/dicom/rttbDicomFileDoseAccessorConverter.cpp +++ b/code/io/dicom/rttbDicomFileDoseAccessorWriter.cpp @@ -1,280 +1,242 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // 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. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 747 $ (last changed revision) // @date $Date: 2014-09-17 12:01:00 +0200 (Mi, 17 Sep 2014) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include #include #include #include -#include "rttbDicomFileDoseAccessorConverter.h" -#include "rttbDicomIODDoseAccessorConverter.h" +#include "rttbDicomFileDoseAccessorWriter.h" #include "rttbInvalidDoseException.h" #include "rttbGeometricInfo.h" #include "rttbGeometricInfo.h" #include "rttbGenericDoseIterator.h" #include "rttbDoseStatistics.h" namespace rttb { namespace io { namespace dicom { - DicomFileDoseAccessorConverter::DicomFileDoseAccessorConverter(DoseAccessorPointer aAccessor, DICOMRTFileNameString aFileName) - :_fileName(aFileName) + DicomFileDoseAccessorWriter::DicomFileDoseAccessorWriter() { - setDoseAccessor(aAccessor); _doseIOD = boost::make_shared(); _dataset = _fileformat.getDataset(); } - bool DicomFileDoseAccessorConverter::process() + void DicomFileDoseAccessorWriter::setFileName(DICOMRTFileNameString aFileName) { - std::string s; + _fileName = aFileName; + } + + bool DicomFileDoseAccessorWriter::process() + { OFCondition status; /* Prepare dcmtk */ DcmItem *dcm_item = 0; //get geometric info rttb::core::GeometricInfo geometricInfo = _doseAccessor->getGeometricInfo(); /* ----------------------------------------------------------------- */ /* Part 1 -- General header */ /* ----------------------------------------------------------------- */ OFString CreationUID(_doseAccessor->getDoseUID().c_str()); _dataset->putAndInsertString (DCM_ImageType, "DERIVED\\SECONDARY\\REFORMATTED"); _dataset->putAndInsertOFStringArray(DCM_InstanceCreationDate, "");//Creation Date _dataset->putAndInsertOFStringArray(DCM_InstanceCreationTime, "");//Creation Time _dataset->putAndInsertOFStringArray(DCM_InstanceCreatorUID, CreationUID); _dataset->putAndInsertString (DCM_SOPClassUID, UID_RTDoseStorage); _dataset->putAndInsertString (DCM_SOPInstanceUID, _doseAccessor->getDoseUID().c_str()); _dataset->putAndInsertOFStringArray (DCM_StudyDate, ""); _dataset->putAndInsertOFStringArray (DCM_StudyTime, ""); _dataset->putAndInsertOFStringArray (DCM_AccessionNumber, ""); _dataset->putAndInsertOFStringArray (DCM_Modality, "RTDOSE"); _dataset->putAndInsertString (DCM_Manufacturer, "RTToolbox"); _dataset->putAndInsertString (DCM_InstitutionName, ""); _dataset->putAndInsertString (DCM_ReferringPhysicianName, ""); _dataset->putAndInsertString (DCM_StationName, ""); _dataset->putAndInsertString (DCM_ManufacturerModelName, "RTToolbox"); /* (0008,1140) DCM_ReferencedImageSequence -- MIM likes this */ dcm_item = 0; _dataset->findOrCreateSequenceItem ( DCM_ReferencedImageSequence, dcm_item, -2); dcm_item->putAndInsertString (DCM_ReferencedSOPClassUID, UID_CTImageStorage); dcm_item->putAndInsertString (DCM_ReferencedSOPInstanceUID, "");//ct_series_uid? _dataset->putAndInsertString (DCM_PatientName, ""); _dataset->putAndInsertString (DCM_PatientID, ""); _dataset->putAndInsertString (DCM_PatientBirthDate, ""); _dataset->putAndInsertString (DCM_PatientSex, "O"); _dataset->putAndInsertString (DCM_SliceThickness, boost::lexical_cast(geometricInfo.getSliceThickness()).c_str()); _dataset->putAndInsertString (DCM_SoftwareVersions, ""); _dataset->putAndInsertString (DCM_StudyInstanceUID, ""); _dataset->putAndInsertString (DCM_SeriesInstanceUID, ""); _dataset->putAndInsertString (DCM_StudyID, "10001"); _dataset->putAndInsertString (DCM_SeriesNumber, ""); _dataset->putAndInsertString (DCM_InstanceNumber, "1"); - s = string_format ("%g\\%g\\%g", geometricInfo.getImagePositionPatient().x(), - geometricInfo.getImagePositionPatient().y(), geometricInfo.getImagePositionPatient().z()); + /* GCS FIX: PatientOrientation */ + std::ostringstream sstr; + sstr << geometricInfo.getImagePositionPatient().x() << "\\" << geometricInfo.getImagePositionPatient().y() + << "\\" << geometricInfo.getImagePositionPatient().z(); _dataset->putAndInsertString (DCM_PatientOrientation, "L/P"); - _dataset->putAndInsertString (DCM_ImagePositionPatient, s.c_str()); - s = string_format ("%g\\%g\\%g\\%g\\%g\\%g", - geometricInfo.getImageOrientationRow().x(), - geometricInfo.getImageOrientationRow().y(), - geometricInfo.getImageOrientationRow().z(), - geometricInfo.getImageOrientationColumn().x(), - geometricInfo.getImageOrientationColumn().y(), - geometricInfo.getImageOrientationColumn().z()); - _dataset->putAndInsertString (DCM_ImageOrientationPatient, s.c_str()); + _dataset->putAndInsertString (DCM_ImagePositionPatient, sstr.str().c_str()); + + sstr.str(""); + sstr << geometricInfo.getImageOrientationRow().x() << "\\" + << geometricInfo.getImageOrientationRow().y() << "\\" + << geometricInfo.getImageOrientationRow().z() << "\\" + << geometricInfo.getImageOrientationColumn().x() << "\\" + << geometricInfo.getImageOrientationColumn().y() << "\\" + << geometricInfo.getImageOrientationColumn().z(); + _dataset->putAndInsertString (DCM_ImageOrientationPatient, sstr.str().c_str()); _dataset->putAndInsertString (DCM_FrameOfReferenceUID, "");//FrameOfReferenceUID? _dataset->putAndInsertString (DCM_SamplesPerPixel, "1"); _dataset->putAndInsertString (DCM_PhotometricInterpretation, "MONOCHROME2"); - s = string_format ("%d", geometricInfo.getNumSlices()); - _dataset->putAndInsertString (DCM_NumberOfFrames, s.c_str()); + sstr.str(""); + sstr << geometricInfo.getNumSlices(); + _dataset->putAndInsertString (DCM_NumberOfFrames, sstr.str().c_str()); /* GCS FIX: Add FrameIncrementPointer */ _dataset->putAndInsertString (DCM_FrameIncrementPointer, "(3004,000c)"); _dataset->putAndInsertUint16 (DCM_Rows, geometricInfo.getNumRows()); _dataset->putAndInsertUint16 (DCM_Columns, geometricInfo.getNumColumns()); - s = string_format ("%g\\%g", - geometricInfo.getSpacing()(1), geometricInfo.getSpacing()(0)); - _dataset->putAndInsertString (DCM_PixelSpacing, s.c_str()); + sstr.str(""); + sstr << geometricInfo.getSpacing()(1) << "\\"<putAndInsertString (DCM_PixelSpacing, sstr.str().c_str()); _dataset->putAndInsertString (DCM_BitsAllocated, "32"); _dataset->putAndInsertString (DCM_BitsStored, "32"); _dataset->putAndInsertString (DCM_HighBit, "31"); - /*if (dose_metadata - && dose_metadata->get_metadata(0x3004, 0x0004) == "ERROR") - { - _dataset->putAndInsertString (DCM_PixelRepresentation, "1"); - } else { - _dataset->putAndInsertString (DCM_PixelRepresentation, "0"); - }*/ _dataset->putAndInsertString (DCM_DoseUnits, "GY"); - /*dcmtk_copy_from_metadata (_dataset, dose_metadata, - DCM_DoseType, "PHYSICAL");*/ + _dataset->putAndInsertString (DCM_DoseSummationType, "PLAN"); - s = std::string ("0"); + sstr.str("0"); for (int i = 1; i < geometricInfo.getNumSlices(); i++) { - s += string_format ("\\%g", i * geometricInfo.getSpacing()(2));//*dose_volume->direction_cosines[8]? What is dose_volume->direction_cosines[8] + sstr << "\\" << i * geometricInfo.getSpacing()(2);//*dose_volume->direction_cosines[8]? What is dose_volume->direction_cosines[8] } - _dataset->putAndInsertString (DCM_GridFrameOffsetVector, s.c_str()); + _dataset->putAndInsertString (DCM_GridFrameOffsetVector, sstr.str().c_str()); - /* GCS FIX: - Leave ReferencedRTPlanSequence empty (until I can cross reference) */ /* We need to convert image to uint16_t, but first we need to scale it so that the maximum dose fits in a 16-bit unsigned integer. Compute an appropriate scaling factor based on the maximum dose. */ - /* Find the maximum value in the image */ boost::shared_ptr spTestDoseIterator = boost::make_shared(_doseAccessor); rttb::core::GenericDoseIterator::DoseIteratorPointer spDoseIterator (spTestDoseIterator); rttb::algorithms::DoseStatistics doseStat (spDoseIterator); boost::shared_ptr< std::vector > > myResultPairs = boost::make_shared< std::vector > >(); rttb::algorithms::DoseStatistics::ResultListPointer spMyResultPairs(myResultPairs); double minDose = doseStat.getMinimum(myResultPairs); double maxDose = doseStat.getMaximum(myResultPairs); /* Find scale factor */ float dose_scale; dose_scale = maxDose /PixelDataMaxValue; /* Scale the image and add scale factor to _dataset */ - s = string_format ("%g", dose_scale); - _dataset->putAndInsertString (DCM_DoseGridScaling, s.c_str()); + sstr.str(""); + sstr << dose_scale; + _dataset->putAndInsertString (DCM_DoseGridScaling, sstr.str().c_str()); /* (300c,0002) ReferencedRTPlanSequence -- for future expansion */ dcm_item = 0; _dataset->findOrCreateSequenceItem ( DCM_ReferencedRTPlanSequence, dcm_item, -2); dcm_item->putAndInsertString (DCM_ReferencedSOPClassUID, UID_RTPlanStorage); dcm_item->putAndInsertString (DCM_ReferencedSOPInstanceUID, "");//ReferencedSOPInstanceUID?? /* (300c,0060) DCM_ReferencedStructureSetSequence -- MIM likes this */ dcm_item = 0; _dataset->findOrCreateSequenceItem ( DCM_ReferencedStructureSetSequence, dcm_item, -2); dcm_item->putAndInsertString (DCM_ReferencedSOPClassUID, UID_RTStructureSetStorage); dcm_item->putAndInsertString (DCM_ReferencedSOPInstanceUID, "");//ReferencedSOPInstanceUID?? /* Convert image bytes to integer, then add to _dataset */ Uint16* pixelData; int pixelCount = geometricInfo.getNumRows() * geometricInfo.getNumColumns() * geometricInfo.getNumSlices(); pixelData = new Uint16[pixelCount]; for(unsigned int i=0; igetDoseAt(i); double pixelValue = doseValue/dose_scale; if(pixelValue > PixelDataMaxValue){ pixelValue = PixelDataMaxValue; } pixelData[i] =boost::numeric_cast(pixelValue); } status = _dataset->putAndInsertUint16Array (DCM_PixelData, pixelData, pixelCount); if(!status.good()){ throw core::InvalidDoseException("Error: put and insert pixel data failed!"); } - return true; - } - - void DicomFileDoseAccessorConverter::writeDicomDoseFile(){ - OFCondition status; - + //Write dose to file status = _fileformat.saveFile (_fileName.c_str(), EXS_LittleEndianExplicit); if (status.bad()) { std::cerr << "Error: cannot write DICOM RTDOSE!" << std::endl; } + return true; } - std::string DicomFileDoseAccessorConverter::string_format (const char *fmt, va_list ap) - { - int size=100; - std::string str; - while (1) { - str.resize(size); - va_list ap_copy = ap; //va_list ap_copy; va_copy (ap_copy, ap); va_copy() is supported starting in Visual Studio 2013. - int n = vsnprintf((char *)str.c_str(), size, fmt, ap_copy); - va_end (ap_copy); - if (n > -1 && n < size) { - str = std::string (str.c_str()); /* Strip excess padding */ - return str; - } - if (n > -1) - size=n+1; - else - size*=2; - } - } - - std::string DicomFileDoseAccessorConverter::string_format (const char *fmt, ...) - { - va_list ap; - va_start (ap, fmt); - std::string string = string_format (fmt, ap); - va_end (ap); - return string; - } - }//end namespace itk }//end namespace io }//end namespace rttb diff --git a/code/io/dicom/rttbDicomIODDoseAccessorConverter.h b/code/io/dicom/rttbDicomFileDoseAccessorWriter.h similarity index 57% rename from code/io/dicom/rttbDicomIODDoseAccessorConverter.h rename to code/io/dicom/rttbDicomFileDoseAccessorWriter.h index 0d7242a..3473645 100644 --- a/code/io/dicom/rttbDicomIODDoseAccessorConverter.h +++ b/code/io/dicom/rttbDicomFileDoseAccessorWriter.h @@ -1,77 +1,82 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // 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. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 793 $ (last changed revision) // @date $Date: 2014-10-10 10:24:45 +0200 (Fr, 10 Okt 2014) $ (last change date) // @author $Author: hentsch $ (last changed by) */ -#ifndef __DICOM_IOD_DOSE_ACCESSOR_CONVERTER_H -#define __DICOM_IOD_DOSE_ACCESSOR_CONVERTER_H +#ifndef __DICOM_FILE_DOSE_ACCESSOR_WRITER_H +#define __DICOM_FILE_DOSE_ACCESSOR_WRITER_H #include "../itk/rttbDoseAccessorProcessorBase.h" #include "../itk/rttbDoseAccessorConversionSettingInterface.h" #include "rttbDicomDoseAccessor.h" -#include - //pixel data max value #define PixelDataMaxValue UINT16_MAX namespace rttb { namespace io { namespace dicom { - - /*! @class DicomIODDoseAccessorConverter - @brief Class converts/dumps the processed accessor into an dicom dose iod + /*! @class DicomFileDoseAccessorWriter + @brief Class converts/dumps the processed accessor into an dicom file @remark DoseAccessorConversionInterface defines how the converter should react on non valid dose values. - @remark Not implemented because of no usage now, please use DicomFileDoseAccessorConverter */ - class DicomIODDoseAccessorConverter: public core::DoseAccessorProcessorBase, + class DicomFileDoseAccessorWriter: public core::DoseAccessorProcessorBase, public core::DoseAccessorConversionSettingInterface { - public: typedef core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; typedef DicomDoseAccessor::DRTDoseIODPtr DRTDoseIODPointer; - typedef boost::shared_ptr DcmItemPtr; - DicomIODDoseAccessorConverter(DoseAccessorPointer accessor); - virtual ~DicomIODDoseAccessorConverter() {}; + /*! @brief Standard Constructor. + */ + DicomFileDoseAccessorWriter(); - bool process();//not implemented because of no usage now, please use DicomFileDoseAccessorConverter + virtual ~DicomFileDoseAccessorWriter() {}; - DRTDoseIODPointer getDicomDoseIOD() - { - return _doseIOD; - } + /*! Set a file name to write the dose + @param aFileName a file name to write the dose + */ + void setFileName(DICOMRTFileNameString aFileName); - private: - DicomIODDoseAccessorConverter(const - DicomIODDoseAccessorConverter&); //not implemented on purpose -> non-copyable - DicomIODDoseAccessorConverter& operator=(const - DicomIODDoseAccessorConverter&);//not implemented on purpose -> non-copyable + /*! @brief Convert the accessor into dicom dataset and write dicom dataset to a file + @exception InvalidDoseException thrown if put and insert pixel data into dicom dataset failed + */ + bool process(); + + + private: + DicomFileDoseAccessorWriter(const + DicomFileDoseAccessorWriter&); //not implemented on purpose -> non-copyable + DicomFileDoseAccessorWriter& operator=(const + DicomFileDoseAccessorWriter&);//not implemented on purpose -> non-copyable DRTDoseIODPointer _doseIOD; + DICOMRTFileNameString _fileName; + DcmFileFormat _fileformat; + DcmDataset *_dataset; + }; } } } #endif diff --git a/code/io/dicom/rttbDicomIODDoseAccessorConverter.cpp b/code/io/dicom/rttbDicomIODDoseAccessorConverter.cpp deleted file mode 100644 index a019a56..0000000 --- a/code/io/dicom/rttbDicomIODDoseAccessorConverter.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// ----------------------------------------------------------------------- -// RTToolbox - DKFZ radiotherapy quantitative evaluation library -// -// Copyright (c) German Cancer Research Center (DKFZ), -// Software development for Integrated Diagnostics and Therapy (SIDT). -// ALL RIGHTS RESERVED. -// See rttbCopyright.txt or -// http://www.dkfz.de/en/sidt/projects/rttb/copyright.html -// -// 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. -// -//------------------------------------------------------------------------ -/*! -// @file -// @version $Revision: 747 $ (last changed revision) -// @date $Date: 2014-09-17 12:01:00 +0200 (Mi, 17 Sep 2014) $ (last change date) -// @author $Author: hentsch $ (last changed by) -*/ - -#include -#include -#include /* va_list, va_start, va_copy, va_arg, va_end */ - - -#include -#include -#include - -#include "rttbDicomIODDoseAccessorConverter.h" -#include "rttbException.h" -#include "rttbInvalidDoseException.h" -#include "rttbGeometricInfo.h" -#include "rttbGenericDoseIterator.h" -#include "rttbDoseStatistics.h" - - -namespace rttb -{ - namespace io - { - namespace dicom - { - - DicomIODDoseAccessorConverter::DicomIODDoseAccessorConverter(DoseAccessorPointer accessor) - { - setDoseAccessor(accessor); - _doseIOD = boost::make_shared(); - } - - - }//end namespace itk - }//end namespace io -}//end namespace rttb - diff --git a/testing/io/dicom/DicomDoseAccessorConverterTest.cpp b/testing/io/dicom/DicomDoseAccessorConverterTest.cpp index d435c8b..51db803 100644 --- a/testing/io/dicom/DicomDoseAccessorConverterTest.cpp +++ b/testing/io/dicom/DicomDoseAccessorConverterTest.cpp @@ -1,131 +1,132 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // 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. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 856 $ (last changed revision) // @date $Date: 2014-11-27 13:39:53 +0100 (Do, 27 Nov 2014) $ (last change date) // @author $Author: zhangl $ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbDicomDoseAccessor.h" #include "rttbDicomFileDoseAccessorGenerator.h" -#include "rttbDicomFileDoseAccessorConverter.h" +#include "rttbDicomFileDoseAccessorWriter.h" #include "rttbInvalidDoseException.h" #include "rttbDcmrtException.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace testing { /*!@brief DicomDoseAccessorGeneratorTest - test the generators for dicom data 1) test dicom file generator generateDoseAccessor() 2) test dicom IOD generator generateDoseAccessor() */ int DicomDoseAccessorConverterTest(int argc, char* argv[]) { typedef boost::shared_ptr DRTDoseIODPointer; typedef rttb::io::dicom::DicomDoseAccessor::DoseAccessorPointer DoseAccessorPointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: // 1: the file name of the dose to read // 2: the file name of the dose to write std::string RTDOSE_FILENAME_R; std::string RTDOSE_FILENAME_W; if (argc > 2) { RTDOSE_FILENAME_R = argv[1]; RTDOSE_FILENAME_W = argv[2]; } double errorConstant = 1e-3; DoseAccessorPointer doseAccessor_r = io::dicom::DicomFileDoseAccessorGenerator(RTDOSE_FILENAME_R.c_str()).generateDoseAccessor(); - CHECK_NO_THROW(io::dicom::DicomFileDoseAccessorConverter(doseAccessor_r, RTDOSE_FILENAME_W)); - io::dicom::DicomFileDoseAccessorConverter doseConverter(doseAccessor_r, RTDOSE_FILENAME_W); + CHECK_NO_THROW(io::dicom::DicomFileDoseAccessorWriter()); + io::dicom::DicomFileDoseAccessorWriter doseConverter; + CHECK_NO_THROW(doseConverter.setDoseAccessor(doseAccessor_r)); + CHECK_NO_THROW(doseConverter.setFileName(RTDOSE_FILENAME_W)); CHECK_EQUAL(doseConverter.process(), true); - CHECK_NO_THROW(doseConverter.writeDicomDoseFile()); DoseAccessorPointer doseAccessor_w = io::dicom::DicomFileDoseAccessorGenerator(RTDOSE_FILENAME_W).generateDoseAccessor(); //Check geometricinfo CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getImagePositionPatient().x(), doseAccessor_w->getGeometricInfo().getImagePositionPatient().x(), errorConstant); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getImagePositionPatient().y(), doseAccessor_w->getGeometricInfo().getImagePositionPatient().y(), errorConstant); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getImagePositionPatient().z(), doseAccessor_w->getGeometricInfo().getImagePositionPatient().z(), errorConstant); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getImageOrientationColumn().x(), doseAccessor_w->getGeometricInfo().getImageOrientationColumn().x(), errorConstant); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getImageOrientationColumn().y(), doseAccessor_w->getGeometricInfo().getImageOrientationColumn().y(), errorConstant); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getImageOrientationColumn().z(), doseAccessor_w->getGeometricInfo().getImageOrientationColumn().z(), errorConstant); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getImageOrientationRow().x(), doseAccessor_w->getGeometricInfo().getImageOrientationRow().x(), errorConstant); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getImageOrientationRow().y(), doseAccessor_w->getGeometricInfo().getImageOrientationRow().y(), errorConstant); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getImageOrientationRow().z(), doseAccessor_w->getGeometricInfo().getImageOrientationRow().z(), errorConstant); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getSpacing().x(), doseAccessor_w->getGeometricInfo().getSpacing().x(), errorConstant); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getSpacing().y(), doseAccessor_w->getGeometricInfo().getSpacing().y(), errorConstant); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getSpacing().z(), doseAccessor_w->getGeometricInfo().getSpacing().z(), errorConstant); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getNumColumns(), doseAccessor_w->getGeometricInfo().getNumColumns(), errorConstant); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getNumRows(), doseAccessor_w->getGeometricInfo().getNumRows(), errorConstant); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getNumSlices(), doseAccessor_w->getGeometricInfo().getNumSlices(), errorConstant); //Check pixel data int size = doseAccessor_r->getGeometricInfo().getNumColumns() * doseAccessor_r->getGeometricInfo().getNumRows() * doseAccessor_r->getGeometricInfo().getNumSlices() ; for(unsigned int index=0; index<30; index++){ CHECK_CLOSE(doseAccessor_r->getDoseAt(index), doseAccessor_w->getDoseAt(index), errorConstant); if(size/2 - index >=0 && size/2-index < size){ CHECK_CLOSE(doseAccessor_r->getDoseAt(size/2 - index), doseAccessor_w->getDoseAt(size/2 - index), errorConstant); } CHECK_CLOSE(doseAccessor_r->getDoseAt(size-index-1), doseAccessor_w->getDoseAt(size-index-1), errorConstant); } RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb