diff --git a/cmake/PackageDepends/RTTB_ArgumentParsingLib_Config.cmake b/cmake/PackageDepends/RTTB_ArgumentParsingLib_Config.cmake new file mode 100644 index 0000000..5f87b84 --- /dev/null +++ b/cmake/PackageDepends/RTTB_ArgumentParsingLib_Config.cmake @@ -0,0 +1,18 @@ +#----------------------------------------------------------------------------- +# Find ArgumentParsingLib +#----------------------------------------------------------------------------- +FIND_PACKAGE(ArgumentParsingLib REQUIRED) +if (ArgumentParsingLib_DIR) + include(${ArgumentParsingLib_DIR}/ArgumentParsingLibConfig.cmake) + set(ArgumentParsingLib_INCLUDE_DIR ${ArgumentParsingLib_SOURCE_DIR}/main) + set(ArgumentParsingLib_LIBRARY_DIR ${ArgumentParsingLib_BINARY_DIR}/main) + set(ArgumentParsingLib_Boost_INCLUDE_DIR ${ArgumentParsingLib_Boost_INCLUDE_DIR}) + set(ArgumentParsingLib_Boost_LIBRARY_DIR ${ArgumentParsingLib_Boost_LIBRARY_DIR}) + set(ArgumentParsingLib_Boost_LIBRARIES ${ArgumentParsingLib_Boost_LIBRARIES}) +else() + message(FATAL_ERROR "Missing build directory of ArgumentParsingLib. Please specify it manually.") +endif() +LIST(APPEND ALL_INCLUDE_DIRECTORIES ${ArgumentParsingLib_INCLUDE_DIR} ${ArgumentParsingLib_Boost_INCLUDE_DIR}) +LIST(APPEND ALL_LIBRARIES "${CMAKE_STATIC_LIBRARY_PREFIX}ArgumentParsingLib${CMAKE_STATIC_LIBRARY_SUFFIX}") + +LINK_DIRECTORIES(${ArgumentParsingLib_LIBRARY_DIR} ${ArgumentParsingLib_Boost_LIBRARY_DIR}) \ No newline at end of file diff --git a/code/algorithms/files.cmake b/code/algorithms/files.cmake index 4ec421d..3577b8e 100644 --- a/code/algorithms/files.cmake +++ b/code/algorithms/files.cmake @@ -1,14 +1,18 @@ SET(CPP_FILES rttbDoseStatistics.cpp rttbDoseStatisticsCalculator.cpp rttbArithmetic.cpp ) SET(H_FILES rttbDoseStatistics.h - rttbArithmetic.h - rttbArithmetic.tpp - rttbBinaryFunctorDoseAccessor.h - rttbBinaryFunctorDoseAccessor.tpp rttbDoseStatisticsCalculator.h + rttbArithmetic.h + rttbBinaryFunctorAccessor.h ) + +SET(TXX_FILES + rttbArithmetic.tpp + rttbBinaryFunctorAccessor.tpp + ) + diff --git a/code/algorithms/rttbArithmetic.tpp b/code/algorithms/rttbArithmetic.tpp index c494ca7..2d833ce 100644 --- a/code/algorithms/rttbArithmetic.tpp +++ b/code/algorithms/rttbArithmetic.tpp @@ -1,127 +1,127 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __ARITHMETIC_TPP #define __ARITHMETIC_TPP namespace rttb { namespace algorithms { namespace arithmetic { template void arithmetic(const DoseAccessorPointer dose1, const DoseAccessorPointer dose2, - MutableDoseAccessorPointer result, TDoseOperation op) + MutableDoseAccessorPointer result, TDoseOperation op) { //handle null pointers if (dose1 == NULL || dose2 == NULL || result == NULL) { throw core::NullPointerException("Pointers to input accessors cannot be NULL."); } //handle differences in geometricInfo if (!(dose1->getGeometricInfo() == dose2->getGeometricInfo() - && dose1->getGeometricInfo() == result->getGeometricInfo())) + && dose1->getGeometricInfo() == result->getGeometricInfo())) { throw core::InvalidParameterException("The geometricInfo of all given accessors needs to be equal."); } //apply operation op to doses with equal geometricInfo (same grid) GridSizeType numVoxels = dose1->getGridSize(); for (VoxelGridID id = 0; id < numVoxels; ++id) { - DoseTypeGy opVal = op.calc(dose1->getDoseAt(id), dose2->getDoseAt(id)); + DoseTypeGy opVal = op.calc(dose1->getValueAt(id), dose2->getValueAt(id)); result->setDoseAt(id, opVal); } } template void arithmetic(const DoseAccessorPointer dose, const MaskAccessorPointer mask, - MutableDoseAccessorPointer result, TDoseMaskOperation op) + MutableDoseAccessorPointer result, TDoseMaskOperation op) { //handle null pointers if (dose == NULL || mask == NULL || result == NULL) { throw core::NullPointerException("Pointers to input accessors cannot be NULL."); } //handle differences in geometricInfo if (!(dose->getGeometricInfo() == mask->getGeometricInfo() - && dose->getGeometricInfo() == result->getGeometricInfo())) + && dose->getGeometricInfo() == result->getGeometricInfo())) { throw core::InvalidParameterException("The geometricInfo of all given accessors needs to be equal."); } //apply operation op to accessors with equal geometricInfo (same grid) core::MaskVoxel mVoxel(0); GridSizeType numVoxels = dose->getGridSize(); for (VoxelGridID id = 0; id < numVoxels; ++id) { mask->getMaskAt(id, mVoxel); - DoseTypeGy opVal = op.calc(dose->getDoseAt(id), mVoxel.getRelevantVolumeFraction()); + DoseTypeGy opVal = op.calc(dose->getValueAt(id), mVoxel.getRelevantVolumeFraction()); result->setDoseAt(id, opVal); } } template void arithmetic(const MaskAccessorPointer mask1, const MaskAccessorPointer mask2, - MutableMaskAccessorPointer result, TMaskOperation op) + MutableMaskAccessorPointer result, TMaskOperation op) { //handle null pointers if (mask1 == NULL || mask2 == NULL || result == NULL) { throw core::NullPointerException("Pointers to input accessors cannot be NULL."); } //handle differences in geometricInfo if (!(mask1->getGeometricInfo() == mask2->getGeometricInfo() - && mask1->getGeometricInfo() == result->getGeometricInfo())) + && mask1->getGeometricInfo() == result->getGeometricInfo())) { throw core::InvalidParameterException("The geometricInfo of all given accessors needs to be equal."); } //apply operation op to accessors with equal geometricInfo (same grid) core::MaskVoxel m1Voxel(0); //initialize results list with mask1 values result->setRelevantVoxelVector(mask1->getRelevantVoxelVector()); MaskVoxelListPointer voxelListMask2 = mask2->getRelevantVoxelVector(); MaskVoxelList::iterator it = voxelListMask2->begin(); while (it != voxelListMask2->end()) { mask1->getMaskAt(it->getVoxelGridID(), m1Voxel); FractionType opVal = op.calc(m1Voxel.getRelevantVolumeFraction(), it->getRelevantVolumeFraction()); result->setMaskAt(it->getVoxelGridID(), core::MaskVoxel(it->getVoxelGridID(), opVal)); ++it; } } } } } #endif \ No newline at end of file diff --git a/code/algorithms/rttbBinaryFunctorDoseAccessor.h b/code/algorithms/rttbBinaryFunctorAccessor.h similarity index 58% rename from code/algorithms/rttbBinaryFunctorDoseAccessor.h rename to code/algorithms/rttbBinaryFunctorAccessor.h index c10dd23..149fe1e 100644 --- a/code/algorithms/rttbBinaryFunctorDoseAccessor.h +++ b/code/algorithms/rttbBinaryFunctorAccessor.h @@ -1,106 +1,104 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) -// @date $Date$ (last change date) -// @author $Author$ (last changed by) +// @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) */ -#ifndef __BINARY_FUNCTOR_DOSE_ACCESSOR_H -#define __BINARY_FUNCTOR_DOSE_ACCESSOR_H +#ifndef __BINARY_FUNCTOR_ACCESSOR_H +#define __BINARY_FUNCTOR_ACCESSOR_H #include -#include "rttbDoseAccessorInterface.h" +#include "rttbAccessorInterface.h" #include "rttbGeometricInfo.h" #include "rttbBaseType.h" namespace rttb { namespace algorithms { - /*! @class BinaryFunctorDoseAccessor - @brief Class that allows to access the results of a binary dose operation. - @details this Accessor takes two dose accessors as operants (the operants must have the same geometry) - and computes a resulting dose value be using a given dose operation functor. - The resulting dose value will be returned from the accessor as its value upon request. + /*! @class BinaryFunctorAccessor + @brief Class that allows to access the results of a binary operation. + @details this Accessor takes two accessors as operants (the operants must have the same geometry) + and computes a resulting value by using a given operation functor. + The resulting value will be returned from the accessor as its value upon request. @remark this can be seen as a lazy filter pattern, thus the accessor is filtering/operating on dose values upon request. */ template - class BinaryFunctorDoseAccessor: public core::DoseAccessorInterface + class BinaryFunctorAccessor: public core::AccessorInterface { - public: - typedef boost::shared_ptr BinaryFunctorDoseAccessorPointer; protected: - DoseAccessorPointer _spDose1; - DoseAccessorPointer _spDose2; + AccessorPointer _spData1; + AccessorPointer _spData2; TDoseOperation _functor; public: /*! @brief Constructor. - @param dose1 pointer to the 1st dose operand - @param dose2 pointer to the 2nd dose operand + @param data1 pointer to the 1st data operand + @param data2 pointer to the 2nd data operand @param functor Instance of the operation that should be used @pre all input parameters have to be valid @exception core::NullPointerException if one input parameter is NULL or if geometricInfos don't match */ - BinaryFunctorDoseAccessor(const DoseAccessorPointer dose1, const DoseAccessorPointer dose2, - const TDoseOperation& functor); + BinaryFunctorAccessor(const AccessorPointer data1, const DoseAccessorPointer data2, + const TDoseOperation& functor); /*! @brief Virtual destructor */ - virtual ~BinaryFunctorDoseAccessor() {}; + virtual ~BinaryFunctorAccessor() {}; /*! @pre: the geometricInfo of both doseAccessors are equal */ inline const core::GeometricInfo& getGeometricInfo() const { - return _spDose1->getGeometricInfo(); + return _spData1->getGeometricInfo(); }; /*! @pre: the geometricInfo of both doseAccessors are equal */ inline GridSizeType getGridSize() const { - return _spDose1->getGeometricInfo().getNumberOfVoxels(); + return _spData1->getGeometricInfo().getNumberOfVoxels(); }; /*! @brief Returns the result dose computed by the functor. It uses the dose values of both operand doses specified via the passed ID. @return the dose value if inside, -1 else @pre .calc(dose1,dose2) has to be implemented */ - DoseTypeGy getDoseAt(const VoxelGridID aID) const; + GenericValueType getValueAt(const VoxelGridID aID) const; /*! @brief Returns the result dose computed by the functor. It uses the dose values of both operand doses specified via the passed index. @return the dose value if inside, -1 else @pre .calc(dose1,dose2) has to be implemented */ - DoseTypeGy getDoseAt(const VoxelGridIndex3D& aIndex) const; + GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const; //@todo: which UID should be used here? - const IDType getDoseUID() const + const IDType getUID() const { return IDType(); } }; } } -#include "rttbBinaryFunctorDoseAccessor.tpp" +#include "rttbBinaryFunctorAccessor.tpp" #endif diff --git a/code/algorithms/rttbBinaryFunctorDoseAccessor.tpp b/code/algorithms/rttbBinaryFunctorAccessor.tpp similarity index 56% rename from code/algorithms/rttbBinaryFunctorDoseAccessor.tpp rename to code/algorithms/rttbBinaryFunctorAccessor.tpp index 9e43e1a..f4a6dcb 100644 --- a/code/algorithms/rttbBinaryFunctorDoseAccessor.tpp +++ b/code/algorithms/rttbBinaryFunctorAccessor.tpp @@ -1,82 +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$ (last changed revision) -// @date $Date$ (last change date) -// @author $Author$ (last changed by) +// @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 "rttbBinaryFunctorDoseAccessor.h" +#include "rttbBinaryFunctorAccessor.h" -#ifndef __BINARY_FUNCTOR_DOSE_ACCESSOR_TPP -#define __BINARY_FUNCTOR_DOSE_ACCESSOR_TPP +#ifndef __BINARY_FUNCTOR_ACCESSOR_TPP +#define __BINARY_FUNCTOR_ACCESSOR_TPP namespace rttb { namespace algorithms { template - BinaryFunctorDoseAccessor::BinaryFunctorDoseAccessor(const DoseAccessorPointer - dose1, const DoseAccessorPointer dose2, + BinaryFunctorAccessor::BinaryFunctorAccessor(const AccessorPointer + data1, const AccessorPointer data2, const TDoseOperation& functor) { - if (dose1 == NULL || dose2 == NULL) + if (data1 == NULL || data2 == NULL) { throw core::NullPointerException("Pointers to input accessors cannot be NULL."); } - if (!(dose1->getGeometricInfo() == dose2->getGeometricInfo())) + if (!(data1->getGeometricInfo() == data2->getGeometricInfo())) { throw core::InvalidParameterException("The geometricInfo of all given accessors needs to be equal."); } - _spDose1 = dose1; - _spDose2 = dose2; + _spData1 = data1; + _spData2 = data2; _functor = functor; } - template DoseTypeGy BinaryFunctorDoseAccessor::getDoseAt( + template GenericValueType BinaryFunctorAccessor::getValueAt( const VoxelGridID aID) const { if (getGeometricInfo().validID(aID)) { - DoseTypeGy value = _functor.calc(_spDose1->getDoseAt(aID), _spDose2->getDoseAt(aID)); + GenericValueType value = _functor.calc(_spData1->getValueAt(aID), _spData2->getValueAt(aID)); return value; } else { return -1; } } - template DoseTypeGy BinaryFunctorDoseAccessor::getDoseAt( + template DoseTypeGy BinaryFunctorAccessor::getValueAt( const VoxelGridIndex3D& aIndex) const { VoxelGridID aVoxelGridID; - if (_spDose1->getGeometricInfo().convert(aIndex, aVoxelGridID)) + if (_spData1->getGeometricInfo().convert(aIndex, aVoxelGridID)) { - return getDoseAt(aVoxelGridID); + return getValueAt(aVoxelGridID); } else { return -1; } } } } #endif \ No newline at end of file diff --git a/code/core/files.cmake b/code/core/files.cmake index 1510e4f..2a97822 100644 --- a/code/core/files.cmake +++ b/code/core/files.cmake @@ -1,64 +1,65 @@ SET(CPP_FILES + rttbAccessorWithGeoInfoBase.cpp rttbDoseIteratorInterface.cpp rttbDVH.cpp rttbDVHCalculator.cpp rttbDVHSet.cpp rttbDataNotAvailableException.cpp rttbException.cpp rttbGenericDoseIterator.cpp rttbGenericMaskedDoseIterator.cpp rttbGeometricInfo.cpp rttbIndexOutOfBoundsException.cpp rttbInvalidDoseException.cpp rttbInvalidParameterException.cpp rttbMappingOutsideOfImageException.cpp rttbMaskedDoseIteratorInterface.cpp rttbMaskVoxel.cpp rttbNullPointerException.cpp rttbPaddingException.cpp rttbPhysicalInfo.cpp rttbStructure.cpp rttbStructureSet.cpp rttbStrVectorStructureSetGenerator.cpp - rttbDoseAccessorWithGeoInfoBase.cpp ) SET(H_FILES + rttbAccessorInterface.h + rttbAccessorWithGeoInfoBase.h rttbBaseType.h rttbDataNotAvailableException.h - rttbDoseAccessorGeneratorBase.h - rttbDoseAccessorGeneratorInterface.h rttbDoseAccessorInterface.h - rttbDoseAccessorWithGeoInfoBase.h rttbDoseIteratorInterface.h + rttbDoseAccessorGeneratorBase.h + rttbDoseAccessorGeneratorInterface.h rttbDVH.h rttbDVHCalculator.h rttbDVHGeneratorInterface.h rttbDVHSet.h rttbException.h rttbExceptionMacros.h rttbGenericDoseIterator.h rttbGenericMaskedDoseIterator.h rttbGeometricInfo.h rttbIndexConversionInterface.h rttbIndexOutOfBoundsException.h rttbInvalidDoseException.h rttbInvalidParameterException.h rttbMappingOutsideOfImageException.h rttbMaskAccessorGeneratorBase.h rttbMaskAccessorGeneratorInterface.h rttbMaskAccessorInterface.h rttbMaskAccessorProcessorBase.h rttbMaskAccessorProcessorInterface.h rttbMaskedDoseIteratorInterface.h rttbMaskVoxel.h rttbMutableDoseAccessorInterface.h rttbMutableMaskAccessorInterface.h rttbNullPointerException.h rttbPaddingException.h rttbPhysicalInfo.h rttbStructure.h rttbStructureSet.h rttbStructureSetGeneratorInterface.h rttbStrVectorStructureSetGenerator.h ) diff --git a/code/core/rttbAccessorInterface.h b/code/core/rttbAccessorInterface.h new file mode 100644 index 0000000..5a70489 --- /dev/null +++ b/code/core/rttbAccessorInterface.h @@ -0,0 +1,93 @@ +// ----------------------------------------------------------------------- +// 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: 1066 $ (last changed revision) +// @date $Date: 2015-08-19 11:47:07 +0200 (Mi, 19 Aug 2015) $ (last change date) +// @author $Author: floca $ (last changed by) +*/ +#ifndef __ACCESSOR_INTERFACE_H +#define __ACCESSOR_INTERFACE_H + +#include + +#include "rttbBaseType.h" +#include "rttbGeometricInfo.h" +#include "rttbIndexConversionInterface.h" + +namespace rttb +{ + namespace core + { + + /*! @class AccessorInterface + @brief Interface for any sort of Accessor + */ + class AccessorInterface: public IndexConversionInterface + { + public: + typedef boost::shared_ptr AccessorPointer; + typedef boost::shared_ptr DoseAccessorPointer; + private: + AccessorInterface(const AccessorInterface&); //not implemented on purpose -> non-copyable + AccessorInterface& operator=(const + AccessorInterface&);//not implemented on purpose -> non-copyable + + public: + AccessorInterface() {}; + virtual ~AccessorInterface() {}; + + /*! @brief test if given ID is inside current dose grid + */ + bool validID(const VoxelGridID aID) const + { + return this->getGeometricInfo().validID(aID); + }; + + + /*! @brief test if given index is inside current dose grid + */ + bool validIndex(const VoxelGridIndex3D& aIndex) const + { + return this->getGeometricInfo().validIndex(aIndex); + }; + + virtual const core::GeometricInfo& getGeometricInfo() const = 0; + + virtual GridSizeType getGridSize() const + { + return this->getGeometricInfo().getNumberOfVoxels(); + }; + + virtual GenericValueType getValueAt(const VoxelGridID aID) const = 0; + + virtual GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const = 0; + + /*! @brief is true if dose is on a homogeneous grid + @remarks Inhomogeneous grids are not supported at the moment, but if they will be supported in the future + the interface does not need to change. + */ + virtual bool isGridHomogeneous() const + { + return true; + } + + virtual const IDType getUID() const = 0; + + }; + } +} + +#endif diff --git a/code/core/rttbDoseAccessorWithGeoInfoBase.cpp b/code/core/rttbAccessorWithGeoInfoBase.cpp similarity index 69% rename from code/core/rttbDoseAccessorWithGeoInfoBase.cpp rename to code/core/rttbAccessorWithGeoInfoBase.cpp index 15b9452..a9962c4 100644 --- a/code/core/rttbDoseAccessorWithGeoInfoBase.cpp +++ b/code/core/rttbAccessorWithGeoInfoBase.cpp @@ -1,47 +1,47 @@ // ----------------------------------------------------------------------- // 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: 877 $ (last changed revision) // @date $Date: 2015-01-09 10:51:10 +0100 (Fr, 09 Jan 2015) $ (last change date) // @author $Author: hentsch $ (last changed by) */ -#include "rttbDoseAccessorWithGeoInfoBase.h" +#include "rttbAccessorWithGeoInfoBase.h" namespace rttb { - namespace core - { + namespace core + { - const core::GeometricInfo& - DoseAccessorWithGeoInfoBase:: - getGeometricInfo() const - { - return _geoInfo; - } + const core::GeometricInfo& + AccessorWithGeoInfoBase:: + getGeometricInfo() const + { + return _geoInfo; + } - DoseAccessorWithGeoInfoBase::~DoseAccessorWithGeoInfoBase() - { - } + AccessorWithGeoInfoBase::~AccessorWithGeoInfoBase() + { + } - DoseAccessorWithGeoInfoBase::DoseAccessorWithGeoInfoBase() - { - } + AccessorWithGeoInfoBase::AccessorWithGeoInfoBase() + { + } - } + } } diff --git a/code/core/rttbDoseAccessorWithGeoInfoBase.h b/code/core/rttbAccessorWithGeoInfoBase.h similarity index 58% rename from code/core/rttbDoseAccessorWithGeoInfoBase.h rename to code/core/rttbAccessorWithGeoInfoBase.h index 2891d36..e32b998 100644 --- a/code/core/rttbDoseAccessorWithGeoInfoBase.h +++ b/code/core/rttbAccessorWithGeoInfoBase.h @@ -1,50 +1,50 @@ // ----------------------------------------------------------------------- // 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: 877 $ (last changed revision) // @date $Date: 2015-01-09 10:51:10 +0100 (Fr, 09 Jan 2015) $ (last change date) // @author $Author: hentsch $ (last changed by) */ -#ifndef __DOSE_ACCESSOR_WITH_GEO_INFO_BASE_H -#define __DOSE_ACCESSOR_WITH_GEO_INFO_BASE_H +#ifndef __ACCESSOR_WITH_GEO_INFO_BASE_H +#define __ACCESSOR_WITH_GEO_INFO_BASE_H -#include "rttbDoseAccessorInterface.h" +#include "rttbAccessorInterface.h" namespace rttb { - namespace core - { + namespace core + { - /*! @class DoseAccessorWithGeoInfoBase - @brief Base class for all accessor implementations that have there own geometric info. - */ - class DoseAccessorWithGeoInfoBase: public core::DoseAccessorInterface - { - protected: - core::GeometricInfo _geoInfo; + /*! @class AccessorWithGeoInfoBase + @brief Base class for all accessor implementations that have there own geometric info. + */ + class AccessorWithGeoInfoBase: public core::AccessorInterface + { + protected: + core::GeometricInfo _geoInfo; - public: - ~DoseAccessorWithGeoInfoBase(); + public: + ~AccessorWithGeoInfoBase(); - DoseAccessorWithGeoInfoBase(); + AccessorWithGeoInfoBase(); - virtual const core::GeometricInfo& getGeometricInfo() const; + virtual const core::GeometricInfo& getGeometricInfo() const; - }; - } + }; + } } #endif diff --git a/code/core/rttbBaseType.h b/code/core/rttbBaseType.h index 3161aee..b53f71d 100644 --- a/code/core/rttbBaseType.h +++ b/code/core/rttbBaseType.h @@ -1,720 +1,721 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __BASE_TYPE_NEW_H #define __BASE_TYPE_NEW_H #include #include #include #include #include #include #include #include #include #include namespace rttb { const double errorConstant = 1e-5; typedef unsigned short UnsignedIndex1D; /*! @class UnsignedIndex2D @brief 2D index. @todo Both UnsignedIndex2D and VoxelGridIndex2D required? */ class UnsignedIndex2D: public boost::numeric::ublas::vector { public: UnsignedIndex2D() : boost::numeric::ublas::vector(2) {} UnsignedIndex2D(const UnsignedIndex1D value) : boost::numeric::ublas::vector(2, value) {} const UnsignedIndex1D x() const { return (*this)(0); } const UnsignedIndex1D y() const { return (*this)(1); } }; /*! @class UnsignedIndex3D @brief 3D index. @todo Both UnsignedIndex3D and VoxelGridIndex3D required? */ class UnsignedIndex3D: public boost::numeric::ublas::vector { public: UnsignedIndex3D() : boost::numeric::ublas::vector(3) {} UnsignedIndex3D(const UnsignedIndex1D value) : boost::numeric::ublas::vector(3, value) {} UnsignedIndex3D(const UnsignedIndex1D xValue, const UnsignedIndex1D yValue, const UnsignedIndex1D zValue) : boost::numeric::ublas::vector(3, xValue) { (*this)(1) = yValue; (*this)(2) = zValue; } const UnsignedIndex1D x() const { return (*this)(0); } const UnsignedIndex1D y() const { return (*this)(1); } const UnsignedIndex1D z() const { return (*this)(2); } friend bool operator==(const UnsignedIndex3D& gi1, const UnsignedIndex3D& gi2) { if (gi1.size() != gi2.size()) { return false; } for (int i = 0; i < gi1.size(); i++) { if (gi1(i) != gi2(i)) { return false; } } return true; } friend std::ostream& operator<<(std::ostream& s, const UnsignedIndex3D& aVector) { s << "[ " << aVector(0) << ", " << aVector(1) << ", " << aVector(2) << " ]"; return s; } }; typedef std::list UnsignedIndexList; typedef std::string FileNameString; typedef std::string ContourGeometricTypeString; typedef double WorldCoordinate; /*! @class WorldCoordinate2D @brief 2D coordinate in real world coordinates. */ class WorldCoordinate2D: public boost::numeric::ublas::vector { public: WorldCoordinate2D() : boost::numeric::ublas::vector (2) {} WorldCoordinate2D(const WorldCoordinate value) : boost::numeric::ublas::vector(2, value) {} WorldCoordinate2D(const WorldCoordinate xValue, const WorldCoordinate yValue) : boost::numeric::ublas::vector(2, xValue) { (*this)(1) = yValue; } const WorldCoordinate x() const { return (*this)(0); } const WorldCoordinate y() const { return (*this)(1); } const std::string toString() const { std::stringstream ss; ss << x() << ' ' << y(); return ss.str(); } friend bool operator==(const WorldCoordinate2D& wc1, const WorldCoordinate2D& wc2) { if (wc1.size() != wc2.size()) { return false; } for (int i = 0; i < wc1.size(); i++) { if (wc1(i) != wc2(i)) { return false; } } return true; } }; /*! @class WorldCoordinate3D @brief 3D coordinate in real world coordinates. */ class WorldCoordinate3D: public boost::numeric::ublas::vector { public: WorldCoordinate3D() : boost::numeric::ublas::vector(3) {} WorldCoordinate3D(const WorldCoordinate value) : boost::numeric::ublas::vector(3, value) {} WorldCoordinate3D(const WorldCoordinate xValue, const WorldCoordinate yValue, const WorldCoordinate zValue) : boost::numeric::ublas::vector(3, xValue) { (*this)(1) = yValue; (*this)(2) = zValue; } WorldCoordinate3D(const WorldCoordinate3D& w): boost::numeric::ublas::vector(3) { (*this)(0) = w.x(); (*this)(1) = w.y(); (*this)(2) = w.z(); } const WorldCoordinate x() const { return (*this)(0); } const WorldCoordinate y() const { return (*this)(1); } const WorldCoordinate z() const { return (*this)(2); } //vector cross product (not included in boost.ublas) WorldCoordinate3D cross(WorldCoordinate3D aVector) const { WorldCoordinate3D result; WorldCoordinate x = (*this)(0); WorldCoordinate y = (*this)(1); WorldCoordinate z = (*this)(2); result(0) = y * aVector(2) - z * aVector(1); result(1) = z * aVector(0) - x * aVector(2); result(2) = x * aVector(1) - y * aVector(0); return result; } WorldCoordinate2D getXY() const { WorldCoordinate2D result; result(0) = (*this)(0); result(1) = (*this)(1); return result; } const std::string toString() const { std::stringstream ss; ss << x() << ' ' << y() << ' ' << z(); return ss.str(); } WorldCoordinate3D& operator=(const WorldCoordinate3D& wc) { (*this)(0) = wc.x(); (*this)(1) = wc.y(); (*this)(2) = wc.z(); return (*this); } WorldCoordinate3D& operator=(const boost::numeric::ublas::vector wc) { (*this)(0) = wc(0); (*this)(1) = wc(1); (*this)(2) = wc(2); return (*this); } WorldCoordinate3D operator-(const boost::numeric::ublas::vector wc) { return WorldCoordinate3D((*this)(0) - wc(0), (*this)(1) - wc(1), (*this)(2) - wc(2)); } WorldCoordinate3D operator+(const boost::numeric::ublas::vector wc) { return WorldCoordinate3D((*this)(0) + wc(0), (*this)(1) + wc(1), (*this)(2) + wc(2)); } friend bool operator==(const WorldCoordinate3D& wc1, const WorldCoordinate3D& wc2) { if (wc1.size() != wc2.size()) { return false; } for (int i = 0; i < wc1.size(); i++) { if (wc1(i) != wc2(i)) { return false; } } return true; } friend std::ostream& operator<<(std::ostream& s, const WorldCoordinate3D& aVector) { s << "[ " << aVector(0) << ", " << aVector(1) << ", " << aVector(2) << " ]"; return s; } }; typedef UnsignedIndex3D ImageSize; /*! @deprecated Use OrientationMatrix instead. */ typedef WorldCoordinate3D ImageOrientation; typedef double GridVolumeType; /*! @class SpacingVectorType3D @brief 3D spacing vector. @pre values of this vector may not be negative. @todo should SpacingVectorType/GridVolumeType be forced to be non-negative? If yes add corresponding tests */ class SpacingVectorType3D: public boost::numeric::ublas::vector { public: SpacingVectorType3D() : boost::numeric::ublas::vector(3) {} SpacingVectorType3D(const GridVolumeType value) : boost::numeric::ublas::vector(3, value) {} SpacingVectorType3D(const GridVolumeType xValue, const GridVolumeType yValue, const GridVolumeType zValue) : boost::numeric::ublas::vector(3, xValue) { (*this)(1) = yValue; (*this)(2) = zValue; } SpacingVectorType3D(const SpacingVectorType3D& w): boost::numeric::ublas::vector(3) { (*this)(0) = w.x(); (*this)(1) = w.y(); (*this)(2) = w.z(); } const GridVolumeType x() const { return (*this)(0); } const GridVolumeType y() const { return (*this)(1); } const GridVolumeType z() const { return (*this)(2); } const std::string toString() const { std::stringstream ss; ss << x() << ' ' << y() << ' ' << z(); return ss.str(); } SpacingVectorType3D& operator=(const SpacingVectorType3D& wc) { (*this)(0) = wc.x(); (*this)(1) = wc.y(); (*this)(2) = wc.z(); return (*this); } SpacingVectorType3D& operator=(const WorldCoordinate3D& wc) { (*this)(0) = GridVolumeType(wc.x()); (*this)(1) = GridVolumeType(wc.y()); (*this)(2) = GridVolumeType(wc.z()); return (*this); } SpacingVectorType3D& operator=(const boost::numeric::ublas::vector wc) { (*this)(0) = wc(0); (*this)(1) = wc(1); (*this)(2) = wc(2); return (*this); } friend bool operator==(const SpacingVectorType3D& wc1, const SpacingVectorType3D& wc2) { if (wc1.size() != wc2.size()) { return false; } for (int i = 0; i < wc1.size(); i++) { if (wc1(i) != wc2(i)) { return false; } } return true; } friend std::ostream& operator<<(std::ostream& s, const SpacingVectorType3D& aVector) { s << "[ " << aVector(0) << ", " << aVector(1) << ", " << aVector(2) << " ]"; return s; } }; /*! @class OrientationMatrix @brief Used to store image orientation information @todo should OrientationMatrix be forced to be non-negative? If yes add corresponding tests */ class OrientationMatrix : public boost::numeric::ublas::matrix { public: /*! The default constructor generates a 3x3 unit matrix */ OrientationMatrix() : boost::numeric::ublas::matrix(3, 3, 0) { for (std::size_t m = 0; m < (*this).size1(); m++) { (*this)(m, m) = 1; } } OrientationMatrix(const WorldCoordinate value) : boost::numeric::ublas::matrix(3, 3, value) {} bool equal(const OrientationMatrix& anOrientationMatrix) const { if (anOrientationMatrix.size1() == (*this).size1()) { if (anOrientationMatrix.size2() == (*this).size2()) { for (std::size_t m = 0; m < anOrientationMatrix.size1(); m++) { for (std::size_t n = 0; n < anOrientationMatrix.size2(); n++) { if (!((*this)(m, n) == anOrientationMatrix(m, n))) { return false; } } }// end element comparison } else { return false; } } else { return false; } return true; } friend bool operator==(const OrientationMatrix& om1, const OrientationMatrix& om2) { return om1.equal(om2); } friend std::ostream& operator<<(std::ostream& s, const OrientationMatrix& anOrientationMatrix) { s << "[ "; for (std::size_t m = 0; m < anOrientationMatrix.size1(); m++) { s << "[ "; for (std::size_t n = 0; n < anOrientationMatrix.size2(); n++) { if (n == 0) { s << anOrientationMatrix(m, n); } else { s << ", " << anOrientationMatrix(m, n); } } s << " ]"; } s << " ]"; return s; } }; /*! base for 2D and 3D VoxelIndex; Therefore required beside VoxelGridID */ typedef unsigned int GridIndexType; /*! @class VoxelGridIndex3D @brief 3D voxel grid index. */ class VoxelGridIndex3D: public boost::numeric::ublas::vector { public: VoxelGridIndex3D() : boost::numeric::ublas::vector(3) {} VoxelGridIndex3D(const GridIndexType value) : boost::numeric::ublas::vector(3, value) {} VoxelGridIndex3D(const GridIndexType xValue, const GridIndexType yValue, const GridIndexType zValue) : boost::numeric::ublas::vector(3, xValue) { (*this)(1) = yValue; (*this)(2) = zValue; } const GridIndexType x() const { return (*this)(0); } const GridIndexType y() const { return (*this)(1); } const GridIndexType z() const { return (*this)(2); } const std::string toString() const { std::stringstream ss; ss << x() << ' ' << y() << ' ' << z(); return ss.str(); } VoxelGridIndex3D& operator=(const UnsignedIndex3D& ui) { (*this)(0) = ui(0); (*this)(1) = ui(1); (*this)(2) = ui(2); return (*this); } friend bool operator==(const VoxelGridIndex3D& gi1, const VoxelGridIndex3D& gi2) { if (gi1.size() != gi2.size()) { return false; } for (int i = 0; i < gi1.size(); i++) { if (gi1(i) != gi2(i)) { return false; } } return true; } friend std::ostream& operator<<(std::ostream& s, const VoxelGridIndex3D& aVector) { s << "[ " << aVector(0) << ", " << aVector(1) << ", " << aVector(2) << " ]"; return s; } }; /*! @class VoxelGridIndex3D @brief 2D voxel grid index. */ class VoxelGridIndex2D: public boost::numeric::ublas::vector { public: VoxelGridIndex2D() : boost::numeric::ublas::vector(2) {} VoxelGridIndex2D(const GridIndexType value) : boost::numeric::ublas::vector(2, value) {} VoxelGridIndex2D(const GridIndexType xValue, const GridIndexType yValue) : boost::numeric::ublas::vector(2, xValue) { (*this)(1) = yValue; } const GridIndexType x() const { return (*this)(0); } const GridIndexType y() const { return (*this)(1); } const std::string toString() const { std::stringstream ss; ss << x() << ' ' << y(); return ss.str(); } friend bool operator==(const VoxelGridIndex2D& gi1, const VoxelGridIndex2D& gi2) { if (gi1.size() != gi2.size()) { return false; } for (int i = 0; i < gi1.size(); i++) { if (gi1(i) != gi2(i)) { return false; } } return true; } friend std::ostream& operator<<(std::ostream& s, const VoxelGridIndex2D& aVector) { s << "[ " << aVector(0) << ", " << aVector(1) << " ]"; return s; } }; typedef long GridSizeType; typedef int VoxelGridID; //starts from 0 and is continuously counting all positions on the grid typedef int VoxelGridDimensionType; typedef boost::numeric::ublas::vector VoxelGridDimensionVectorType; typedef double FractionType, VoxelSizeType, DVHVoxelNumber; - typedef double DoseCalcType, DoseTypeGy, DoseVoxelVolumeType, VolumeType, GridVolumeType, VoxelNumberType, BEDType, + typedef double DoseCalcType, DoseTypeGy, GenericValueType, DoseVoxelVolumeType, VolumeType, GridVolumeType, + VoxelNumberType, BEDType, LQEDType; typedef std::string IDType; typedef std::string StructureLabel; struct DVHRole { enum Type { TargetVolume = 1, HealthyTissue = 2, WholeVolume = 4, UserDefined = 128 } Type; }; struct DVHType { enum Type { Differential = 1, Cumulative = 2 } Type; }; typedef std::string PatientInfoString; typedef std::string TimeString; typedef std::string FileNameType; typedef std::vector PolygonType; typedef std::vector PolygonSequenceType; typedef double IndexValueType; typedef double DoseStatisticType; typedef std::string DBStringType; typedef std::string VirtuosFileNameString, DICOMRTFileNameString; typedef unsigned short Uint16; struct Area2D { WorldCoordinate x_begin; WorldCoordinate x_end; WorldCoordinate y_begin; WorldCoordinate y_end; VoxelGridIndex2D index_begin; VoxelGridIndex2D index_end; void Init() { x_begin = -1000000; x_end = -1000000; y_begin = -1000000; y_end = -1000000; index_begin(0) = 0; index_begin(1) = 0; index_end(0) = 0; index_end(1) = 0; } }; struct Segment2D { WorldCoordinate2D begin; WorldCoordinate2D end; }; struct Segment3D { WorldCoordinate3D begin; WorldCoordinate3D end; }; typedef int DistributionType; typedef std::string PathType; typedef std::string XMLString, StatisticsString; }//end: namespace rttb #endif diff --git a/code/core/rttbDoseAccessorGeneratorBase.h b/code/core/rttbDoseAccessorGeneratorBase.h index 1fe3251..8a27f68 100644 --- a/code/core/rttbDoseAccessorGeneratorBase.h +++ b/code/core/rttbDoseAccessorGeneratorBase.h @@ -1,54 +1,44 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DOSE_ACCESSOR_GENERATOR_BASE_H #define __DOSE_ACCESSOR_GENERATOR_BASE_H #include #include "rttbDoseAccessorGeneratorInterface.h" -namespace rttb{ +namespace rttb +{ namespace core - { + { /*! @class DoseAccessorGeneratorBase - @brief Abstract class for all DoseAccessor generating classes + @brief Abstract class for all Dose Accessor generating classes */ class DoseAccessorGeneratorBase: public DoseAccessorGeneratorInterface - { - public: - typedef core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; - - - private: - - - protected: - /*! @brief Dose accessor which should be generated */ - DoseAccessorPointer _doseAccessor; - - - public: - - }; - } + { + protected: + /*! @brief Dose accessor which should be generated */ + DoseAccessorPointer _doseAccessor; + }; } +} #endif diff --git a/code/core/rttbDoseAccessorGeneratorInterface.h b/code/core/rttbDoseAccessorGeneratorInterface.h index cbd32b4..a772cb7 100644 --- a/code/core/rttbDoseAccessorGeneratorInterface.h +++ b/code/core/rttbDoseAccessorGeneratorInterface.h @@ -1,60 +1,62 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DOSE_ACCESSOR_GENERATOR_INTERFACE_H #define __DOSE_ACCESSOR_GENERATOR_INTERFACE_H #include #include "rttbDoseAccessorInterface.h" -namespace rttb{ +namespace rttb +{ namespace core - { + { /*! @class DoseAccessorGeneratorInterface - @brief Interface for all DoseAccessor generating classes + @brief Interface for all Dose Accessor generating classes */ class DoseAccessorGeneratorInterface - { - public: - typedef core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; - - - private: - DoseAccessorGeneratorInterface(const DoseAccessorGeneratorInterface&); //not implemented on purpose -> non-copyable - DoseAccessorGeneratorInterface& operator=(const DoseAccessorGeneratorInterface&);//not implemented on purpose -> non-copyable - - - protected: - DoseAccessorGeneratorInterface() {}; - virtual ~DoseAccessorGeneratorInterface() {}; - - public: - - - /*! @brief Generate DoseAccessor - @return Return shared pointer of DoseAccessor. - */ - virtual DoseAccessorPointer generateDoseAccessor() = 0; - }; - } + { + public: + typedef core::AccessorInterface::AccessorPointer DoseAccessorPointer; + + + private: + DoseAccessorGeneratorInterface(const DoseAccessorGeneratorInterface&); //not implemented on purpose -> non-copyable + DoseAccessorGeneratorInterface& operator=(const + DoseAccessorGeneratorInterface&);//not implemented on purpose -> non-copyable + + + protected: + DoseAccessorGeneratorInterface() {}; + virtual ~DoseAccessorGeneratorInterface() {}; + + public: + + + /*! @brief Generate DoseAccessor + @return Return shared pointer of DoseAccessor. + */ + virtual DoseAccessorPointer generateDoseAccessor() = 0; + }; } +} #endif diff --git a/code/core/rttbDoseAccessorInterface.h b/code/core/rttbDoseAccessorInterface.h index c6b1727..da5c37c 100644 --- a/code/core/rttbDoseAccessorInterface.h +++ b/code/core/rttbDoseAccessorInterface.h @@ -1,92 +1,34 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DOSE_ACCESSOR_INTERFACE_NEW_H #define __DOSE_ACCESSOR_INTERFACE_NEW_H -#include - -#include "rttbBaseType.h" -#include "rttbGeometricInfo.h" -#include "rttbIndexConversionInterface.h" +#include "rttbAccessorInterface.h" namespace rttb { - namespace core - { - - /*! @class IndexConversionInterface - @brief This class represents the conversion of 3D grid indices to 1D grid IDs. - */ - class DoseAccessorInterface: public IndexConversionInterface - { - public: - typedef boost::shared_ptr DoseAccessorPointer; - private: - DoseAccessorInterface(const DoseAccessorInterface&); //not implemented on purpose -> non-copyable - DoseAccessorInterface& operator=(const - DoseAccessorInterface&);//not implemented on purpose -> non-copyable - - public: - DoseAccessorInterface() {}; - virtual ~DoseAccessorInterface() {}; - - /*! @brief test if given ID is inside current dose grid - */ - bool validID(const VoxelGridID aID) const - { - return this->getGeometricInfo().validID(aID); - }; - - - /*! @brief test if given index is inside current dose grid - */ - bool validIndex(const VoxelGridIndex3D& aIndex) const - { - return this->getGeometricInfo().validIndex(aIndex); - }; - - virtual const core::GeometricInfo& getGeometricInfo() const = 0; - - virtual GridSizeType getGridSize() const - { - return this->getGeometricInfo().getNumberOfVoxels(); - }; - - virtual DoseTypeGy getDoseAt(const VoxelGridID aID) const = 0; - - virtual DoseTypeGy getDoseAt(const VoxelGridIndex3D& aIndex) const = 0; - - /*! @brief is true if dose is on a homogeneous grid - @remarks Inhomogeneous grids are not supported at the moment, but if they will be supported in the future - the interface does not need to change. - */ - virtual bool isGridHomogeneous() const - { - return true; - } - - virtual const IDType getDoseUID() const = 0; - - }; - } + namespace core + { + typedef AccessorInterface DoseAccessorInterface; + } } #endif diff --git a/code/core/rttbDoseIteratorInterface.h b/code/core/rttbDoseIteratorInterface.h index 2e8ec25..e55f9a3 100644 --- a/code/core/rttbDoseIteratorInterface.h +++ b/code/core/rttbDoseIteratorInterface.h @@ -1,104 +1,108 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DOSE_ITERATOR_INTERFACE_NEW_H #define __DOSE_ITERATOR_INTERFACE_NEW_H #include #include "rttbBaseType.h" #include "rttbGeometricInfo.h" #include "rttbDoseAccessorInterface.h" -namespace rttb{ +namespace rttb +{ namespace core - { + { /*! @class DoseIteratorInterface @brief This class represents the dose iterator interface. */ class DoseIteratorInterface - { - public: - typedef boost::shared_ptr DoseAccessorPointer; - typedef boost::shared_ptr DoseIteratorPointer; + { + public: + typedef boost::shared_ptr DoseAccessorPointer; + typedef boost::shared_ptr DoseIteratorPointer; - private: - DoseIteratorInterface(const DoseIteratorInterface&); //not implemented on purpose -> non-copyable - DoseIteratorInterface& operator=(const DoseIteratorInterface&);//not implemented on purpose -> non-copyable - DoseIteratorInterface(){}; + private: + DoseIteratorInterface(const DoseIteratorInterface&); //not implemented on purpose -> non-copyable + DoseIteratorInterface& operator=(const DoseIteratorInterface&);//not implemented on purpose -> non-copyable + DoseIteratorInterface() {}; - protected: - /*! @brief DoseAccessor to get access to actual dose data */ - DoseAccessorPointer _spDoseAccessor; + protected: + /*! @brief DoseAccessor to get access to actual dose data */ + DoseAccessorPointer _spDoseAccessor; - public: - /*! @brief Constructor with a DoseIterator this should be the default for all implememntations. - */ - DoseIteratorInterface(DoseAccessorPointer aDoseAccessor); + public: + /*! @brief Constructor with a DoseIterator this should be the default for all implememntations. + */ + DoseIteratorInterface(DoseAccessorPointer aDoseAccessor); - virtual ~DoseIteratorInterface() {}; + virtual ~DoseIteratorInterface() {}; - /*! @brief Set the itterator to the start of the dose. - */ - virtual bool reset()=0; + /*! @brief Set the itterator to the start of the dose. + */ + virtual bool reset() = 0; - /*! @brief Move to next position. If this position is valid is not necessarily tested. - */ - virtual void next() = 0; + /*! @brief Move to next position. If this position is valid is not necessarily tested. + */ + virtual void next() = 0; - virtual bool isPositionValid() const = 0; + virtual bool isPositionValid() const = 0; - /*! @brief Return volume of one voxel (in cm3)*/ //previously getDeltaV() - virtual DoseVoxelVolumeType getCurrentVoxelVolume() const = 0; + /*! @brief Return volume of one voxel (in cm3)*/ //previously getDeltaV() + virtual DoseVoxelVolumeType getCurrentVoxelVolume() const = 0; - virtual DoseTypeGy getCurrentDoseValue() const = 0; + virtual DoseTypeGy getCurrentDoseValue() const = 0; - inline const core::GeometricInfo& getGeometricInfo() const - { - return _spDoseAccessor->getGeometricInfo(); - }; + inline const core::GeometricInfo& getGeometricInfo() const + { + return _spDoseAccessor->getGeometricInfo(); + }; - /*! @return If this is a masked dose iterator, return the voxel proportion inside a given structure, - value 0~1; Otherwise, 1 - */ - virtual FractionType getCurrentRelevantVolumeFraction() const=0; + /*! @return If this is a masked dose iterator, return the voxel proportion inside a given structure, + value 0~1; Otherwise, 1 + */ + virtual FractionType getCurrentRelevantVolumeFraction() const = 0; - inline const DoseAccessorPointer getDoseAccessor() const - { - return _spDoseAccessor; - }; + inline const DoseAccessorPointer getDoseAccessor() const + { + return _spDoseAccessor; + }; - virtual VoxelGridID getCurrentVoxelGridID() const=0; + virtual VoxelGridID getCurrentVoxelGridID() const = 0; - virtual IDType getVoxelizationID() const { return "";}; + virtual IDType getVoxelizationID() const + { + return ""; + }; - IDType getDoseUID() const - { - return _spDoseAccessor->getDoseUID(); - }; + IDType getDoseUID() const + { + return _spDoseAccessor->getUID(); + }; - }; //end class - }//end: namespace core - }//end: namespace rttb + }; //end class + }//end: namespace core +}//end: namespace rttb #endif diff --git a/code/core/rttbGenericDoseIterator.cpp b/code/core/rttbGenericDoseIterator.cpp index b45116c..4468277 100644 --- a/code/core/rttbGenericDoseIterator.cpp +++ b/code/core/rttbGenericDoseIterator.cpp @@ -1,94 +1,94 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbGenericDoseIterator.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace core { GenericDoseIterator::GenericDoseIterator(DoseAccessorPointer aDoseAccessor) : DoseIteratorInterface( aDoseAccessor) { _currentDoseVoxelGridID = 0; _currentVoxelVolume = 0; } bool GenericDoseIterator::reset() { _currentDoseVoxelGridID = 0; if (_spDoseAccessor->isGridHomogeneous()) { SpacingVectorType3D voxelSizeVec = (_spDoseAccessor->getGeometricInfo()).getSpacing(); _currentVoxelVolume = voxelSizeVec(0) * voxelSizeVec(1) * voxelSizeVec(2) / 1000; } else { _currentVoxelVolume = 0; throw InvalidParameterException("Inhomogeneous grids are currently not supported!"); } return true; } void GenericDoseIterator::next() { if (_spDoseAccessor->getGeometricInfo().getNumberOfVoxels() > _currentDoseVoxelGridID) { ++_currentDoseVoxelGridID; } } bool GenericDoseIterator::isPositionValid() const { return _spDoseAccessor->getGeometricInfo().validID(_currentDoseVoxelGridID); } DoseVoxelVolumeType GenericDoseIterator::getCurrentVoxelVolume() const { if (_spDoseAccessor->isGridHomogeneous()) { return _currentVoxelVolume; } else { throw InvalidParameterException("Inhomogeneous grids are currently not supported!"); return _currentVoxelVolume; } } DoseTypeGy GenericDoseIterator::getCurrentDoseValue() const { if (isPositionValid()) { - return _spDoseAccessor->getDoseAt(_currentDoseVoxelGridID); + return _spDoseAccessor->getValueAt(_currentDoseVoxelGridID); } else { return 0; } } }//end: namespace core }//end: namespace rttb \ No newline at end of file diff --git a/code/core/rttbGenericMaskedDoseIterator.cpp b/code/core/rttbGenericMaskedDoseIterator.cpp index 0390307..47c0ad9 100644 --- a/code/core/rttbGenericMaskedDoseIterator.cpp +++ b/code/core/rttbGenericMaskedDoseIterator.cpp @@ -1,101 +1,101 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbGenericMaskedDoseIterator.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace core { bool GenericMaskedDoseIterator::reset() { _maskVoxelVec = _spMask->getRelevantVoxelVector(); _currentMaskPos = _maskVoxelVec->begin(); core::GeometricInfo geoInfo = _spDoseAccessor->getGeometricInfo(); _currentVoxelVolume = geoInfo.getSpacing()(0) * geoInfo.getSpacing()(1) * geoInfo.getSpacing()( 2) / 1000; return true; } void GenericMaskedDoseIterator::next() { ++_currentMaskPos; } DoseVoxelVolumeType GenericMaskedDoseIterator::getCurrentVoxelVolume() const { if (_spDoseAccessor->isGridHomogeneous()) { return _currentVoxelVolume; } else { throw InvalidParameterException("Inhomogeneous grids are currently not supported! "); return _currentVoxelVolume; } } FractionType GenericMaskedDoseIterator::getCurrentRelevantVolumeFraction() const { if (!(_currentMaskPos == _maskVoxelVec->end())) { assert(_spMask->getGeometricInfo().validID(_currentMaskPos->getVoxelGridID())); return _currentMaskPos->getProportionInStr(); } return 0; } bool GenericMaskedDoseIterator::isPositionValid() const { if (_currentMaskPos == _maskVoxelVec->end()) { return false; } return _spDoseAccessor->getGeometricInfo().validID(_currentMaskPos->getVoxelGridID()) && _spMask->getGeometricInfo().validID(_currentMaskPos->getVoxelGridID()); } VoxelGridID GenericMaskedDoseIterator::getCurrentVoxelGridID() const { return _currentMaskPos->getVoxelGridID(); } DoseTypeGy GenericMaskedDoseIterator::getCurrentMaskedDoseValue() const { assert(isPositionValid()); return getCurrentDoseValue() * getCurrentRelevantVolumeFraction(); } DoseTypeGy GenericMaskedDoseIterator::getCurrentDoseValue() const { assert(_spDoseAccessor->getGeometricInfo().validID(_currentMaskPos->getVoxelGridID())); - return _spDoseAccessor->getDoseAt(_currentMaskPos->getVoxelGridID()); + return _spDoseAccessor->getValueAt(_currentMaskPos->getVoxelGridID()); } }//end namespace core }//end namespace rttb \ No newline at end of file diff --git a/code/core/rttbMaskAccessorGeneratorBase.h b/code/core/rttbMaskAccessorGeneratorBase.h index 14566f0..6e62fb2 100644 --- a/code/core/rttbMaskAccessorGeneratorBase.h +++ b/code/core/rttbMaskAccessorGeneratorBase.h @@ -1,53 +1,54 @@ // ----------------------------------------------------------------------- // 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: 707 $ (last changed revision) // @date $Date: 2014-09-04 16:37:24 +0200 (Do, 04 Sep 2014) $ (last change date) // @author $Author: floca $ (last changed by) */ #ifndef __MASK_ACCESSOR_GENERATOR_BASE_H #define __MASK_ACCESSOR_GENERATOR_BASE_H #include "rttbMaskAccessorGeneratorInterface.h" -namespace rttb{ +namespace rttb +{ namespace core - { + { /*! @class MaskAccessorGeneratorBase @brief Abstract class for all DoseAccessor generating classes */ class MaskAccessorGeneratorBase: public MaskAccessorGeneratorInterface - { - public: - typedef core::MaskAccessorInterface::MaskAccessorPointer MaskAccessorPointer; - - - private: - - - protected: - /*! @brief Mask accessor which should be generated */ - MaskAccessorPointer _maskAccessor; - - - public: - - }; - } + { + public: + typedef core::MaskAccessorInterface::MaskAccessorPointer MaskAccessorPointer; + + + private: + + + protected: + /*! @brief Mask accessor which should be generated */ + MaskAccessorPointer _maskAccessor; + + + public: + + }; } +} #endif diff --git a/code/interpolation/rttbInterpolationBase.cpp b/code/interpolation/rttbInterpolationBase.cpp index 5d18704..f255271 100644 --- a/code/interpolation/rttbInterpolationBase.cpp +++ b/code/interpolation/rttbInterpolationBase.cpp @@ -1,196 +1,196 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include "rttbInterpolationBase.h" #include "rttbInvalidParameterException.h" #include "rttbNullPointerException.h" #include "rttbMappingOutsideOfImageException.h" namespace rttb { namespace interpolation { - void InterpolationBase::setDoseAccessorPointer(const DoseAccessorPointer originalDose) + void InterpolationBase::setAccessorPointer(const AccessorPointer originalData) { - if (originalDose != NULL) + if (originalData != NULL) { - _spOriginalDose = originalDose; + _spOriginalData = originalData; } else { throw core::NullPointerException("originalDose is NULL!"); } }; void InterpolationBase::getNeighborhoodVoxelValues( const WorldCoordinate3D& aWorldCoordinate, unsigned int neighborhood, boost::array& target, boost::shared_ptr values) const { - if (_spOriginalDose == NULL) + if (_spOriginalData == NULL) { throw core::NullPointerException("originalDose is NULL!"); } //Determine target (abs(desired worldCoordinate- corner pixel world coordinate/pixel spacing) and values of corner pixels (from originalDose) VoxelGridIndex3D aIndex; - if (_spOriginalDose->getGeometricInfo().worldCoordinateToIndex(aWorldCoordinate, aIndex)) + if (_spOriginalData->getGeometricInfo().worldCoordinateToIndex(aWorldCoordinate, aIndex)) { //determine just the nearest voxel to the world coordinate if (neighborhood == 0) { - values[0] = _spOriginalDose->getDoseAt(aIndex); + values[0] = _spOriginalData->getValueAt(aIndex); } //determine the 8 voxels around the world coordinate else if (neighborhood == 8) { std::list cornerPoints; WorldCoordinate3D theNextVoxel; - _spOriginalDose->getGeometricInfo().indexToWorldCoordinate(aIndex, theNextVoxel); - SpacingVectorType3D pixelSpacing = (_spOriginalDose->getGeometricInfo()).getSpacing(); + _spOriginalData->getGeometricInfo().indexToWorldCoordinate(aIndex, theNextVoxel); + SpacingVectorType3D pixelSpacing = (_spOriginalData->getGeometricInfo()).getSpacing(); VoxelGridIndex3D leftTopFrontCoordinate; //find the voxel with the smallest coordinate values in each dimension. This defines the standard cube for (int i = 0; i < 3; i++) { if (aWorldCoordinate[i] < theNextVoxel[i]) { if (aIndex[i] > 0) { leftTopFrontCoordinate[i] = aIndex[i] - 1; target[i] = (aWorldCoordinate[i] - (theNextVoxel[i] - pixelSpacing[i])) / pixelSpacing[i]; } //@todo: this is a workaround, not a good solution else { leftTopFrontCoordinate[i] = aIndex[i]; target[i] = (aWorldCoordinate[i] - (theNextVoxel[i] - pixelSpacing[i])) / pixelSpacing[i]; } } else { leftTopFrontCoordinate[i] = aIndex[i]; target[i] = (aWorldCoordinate[i] - theNextVoxel[i]) / pixelSpacing[i]; } } for (int zIncr = 0; zIncr < 2; zIncr++) { for (int yIncr = 0; yIncr < 2; yIncr++) { for (int xIncr = 0; xIncr < 2; xIncr++) { cornerPoints.push_back(VoxelGridIndex3D(leftTopFrontCoordinate[0] + xIncr, leftTopFrontCoordinate[1] + yIncr, leftTopFrontCoordinate[2] + zIncr)); } } } //target range has to be always [0,1] for (int i = 0; i < 3; i++) { assert(target[i] >= 0.0 && target[i] <= 1.0); } unsigned int count = 0; //now just get the values of all (dose) voxels and store them in values for (auto cornerPointsIterator = cornerPoints.begin(); cornerPointsIterator != cornerPoints.end(); ++cornerPointsIterator, ++count) { - if (_spOriginalDose->getGeometricInfo().isInside(*cornerPointsIterator)) + if (_spOriginalData->getGeometricInfo().isInside(*cornerPointsIterator)) { - values[count] = _spOriginalDose->getDoseAt(*cornerPointsIterator); + values[count] = _spOriginalData->getValueAt(*cornerPointsIterator); } else { //outside value! boundary treatment values[count] = getNearestInsideVoxelValue(*cornerPointsIterator); } assert(values[count] != -1); } } else { throw core::InvalidParameterException("neighborhoods other than 0 and 8 not yet supported in Interpolation"); } } else { throw core::MappingOutsideOfImageException("Error in conversion from world coordinates to index"); } } DoseTypeGy InterpolationBase::getNearestInsideVoxelValue(const VoxelGridIndex3D& currentVoxelIndex) const { VoxelGridIndex3D voxelChangedXYZ[] = {currentVoxelIndex, currentVoxelIndex, currentVoxelIndex, currentVoxelIndex, currentVoxelIndex, currentVoxelIndex, currentVoxelIndex}; int runningIndex; //x,y,z for (runningIndex = 0; runningIndex < 3; ++runningIndex) { voxelChangedXYZ[runningIndex][runningIndex] -= 1; } //xy voxelChangedXYZ[runningIndex][0] -= 1; voxelChangedXYZ[runningIndex][1] -= 1; ++runningIndex; //xz voxelChangedXYZ[runningIndex][0] -= 1; voxelChangedXYZ[runningIndex][2] -= 1; ++runningIndex; //yz voxelChangedXYZ[runningIndex][1] -= 1; voxelChangedXYZ[runningIndex][2] -= 1; ++runningIndex; //xyz voxelChangedXYZ[runningIndex][0] -= 1; voxelChangedXYZ[runningIndex][1] -= 1; voxelChangedXYZ[runningIndex][2] -= 1; ++runningIndex; int replacementVoxelIndex = 0; while (replacementVoxelIndex < runningIndex) { - if (_spOriginalDose->getGeometricInfo().validIndex(voxelChangedXYZ[replacementVoxelIndex])) + if (_spOriginalData->getGeometricInfo().validIndex(voxelChangedXYZ[replacementVoxelIndex])) { - return _spOriginalDose->getDoseAt(voxelChangedXYZ[replacementVoxelIndex]); + return _spOriginalData->getValueAt(voxelChangedXYZ[replacementVoxelIndex]); } ++replacementVoxelIndex; } return -1; } }//end namespace core }//end namespace rttb diff --git a/code/interpolation/rttbInterpolationBase.h b/code/interpolation/rttbInterpolationBase.h index 2f0d46f..66d9412 100644 --- a/code/interpolation/rttbInterpolationBase.h +++ b/code/interpolation/rttbInterpolationBase.h @@ -1,92 +1,92 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __INTERPOLATION_BASE_H #define __INTERPOLATION_BASE_H #include #include #include -#include "rttbDoseAccessorInterface.h" +#include "rttbAccessorInterface.h" #include "rttbBaseType.h" namespace rttb { namespace interpolation { /*! @class InterpolationBase @brief Base class for interpolation. @ingroup interpolation */ class InterpolationBase { public: typedef boost::shared_ptr Pointer; - typedef rttb::core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; + typedef rttb::core::AccessorInterface::AccessorPointer AccessorPointer; /*! @brief Constructor */ InterpolationBase() {}; /*! @brief Virtual destructor of base class */ virtual ~InterpolationBase() {}; - /*! @brief Sets the DoseAccessPointer - @pre originalDose initialized - @exception core::NullPointerException if originalDose==NULL + /*! @brief Sets the AccessorPointer + @pre originalData initialized + @exception core::NullPointerException if originalData==NULL */ - void setDoseAccessorPointer(const DoseAccessorPointer originalDose); + void setAccessorPointer(const AccessorPointer originalData); /*! @brief Returns the interpolated value for the given world coordinate */ virtual DoseTypeGy getValue(const WorldCoordinate3D& aWorldCoordinate) const = 0; protected: - DoseAccessorPointer _spOriginalDose; + AccessorPointer _spOriginalData; /*! @brief determines voxels in a certain neighborhood of a physical based coordinate and converts in a standard cube with corner points [0 0 0], [1 0 0], [0 1 0], [1 1 0], [0 0 1], [1 0 1], [0 1 1], [1 1 1]. @param aWorldCoordinate the coordinate where to start @param neighborhood voxel around coordinate (currently only 0 and 8 implemented) @param target coordinates inside the standard cube with values [0 1] in each dimension. @param values dose values at all corner points of the standard cube. Is of type boost:shared_ptr[neighborhood] @pre target and values have to be correctly initialized (e.g. boost::array target = {0.0, 0.0, 0.0}; boost::shared_ptr values(new DoseTypeGy[8]()); where 8 is neighborhood) @exception core::InvalidParameterException if neighborhood =! 0 && !=8 @exception core::MappingOutsideOfImageException if initial mapping of aWorldCoordinate is outside image @exception core::NullPointerException if dose is NULL */ void getNeighborhoodVoxelValues(const WorldCoordinate3D& aWorldCoordinate, unsigned int neighborhood, boost::array& target, boost::shared_ptr values) const; /*! @brief returns the nearest inside voxel value @pre the voxelGridIndex is outside the image and voxelGridIndex>image.size() for all dimensions. Also voxelGridIndex[]>=0 for all dimensions @note used for virtually expanding the image by one voxel as edge handling */ DoseTypeGy getNearestInsideVoxelValue(const VoxelGridIndex3D& currentVoxelIndex) const; }; } } #endif diff --git a/code/interpolation/rttbLinearInterpolation.h b/code/interpolation/rttbLinearInterpolation.h index ea3f3c3..3308afb 100644 --- a/code/interpolation/rttbLinearInterpolation.h +++ b/code/interpolation/rttbLinearInterpolation.h @@ -1,61 +1,60 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __LINEAR_INTERPOLATION_H #define __LINEAR_INTERPOLATION_H #include #include "rttbInterpolationBase.h" namespace rttb { namespace interpolation { /*! @class LinearInterpolation @brief Linear interpolation. @ingroup interpolation */ class LinearInterpolation : public InterpolationBase { public: - typedef rttb::core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; /*! @brief Constructor */ LinearInterpolation() {}; /*! @brief Returns the interpolated value */ DoseTypeGy getValue(const WorldCoordinate3D& aWorldCoordinate) const; private: /*! @brief Trilinar interpolation @sa InterpolationBase for details about target and values @note Source: http://en.wikipedia.org/wiki/Trilinear_interpolation */ DoseTypeGy trilinear(boost::array target, boost::shared_ptr values) const; }; } } #endif diff --git a/code/interpolation/rttbMappableDoseAccessorInterface.h b/code/interpolation/rttbMappableDoseAccessorInterface.h index 0d18e33..d94b442 100644 --- a/code/interpolation/rttbMappableDoseAccessorInterface.h +++ b/code/interpolation/rttbMappableDoseAccessorInterface.h @@ -1,109 +1,109 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __MAPPABLE_DOSE_ACCESSOR_BASE_H #define __MAPPABLE_DOSE_ACCESSOR_BASE_H #include #include "rttbDoseAccessorInterface.h" #include "rttbGeometricInfo.h" #include "rttbBaseType.h" #include "rttbTransformationInterface.h" #include "rttbNullPointerException.h" namespace rttb { namespace interpolation { /*! @class MappableDoseAccessorInterface @brief Interface for dealing with dose information that has to be transformed into another geometry than the original dose image @details implementation of strategy is done by derived class (e.g. SimpleMappableDoseAccessor or RosuMappableDoseAccessor. Transformation is defined in TransformationInterface @ingroup interpolation */ class MappableDoseAccessorInterface: public core::DoseAccessorInterface { public: typedef boost::shared_ptr Pointer; protected: DoseAccessorPointer _spOriginalDoseDataMovingImage; TransformationInterface::Pointer _spTransformation; core::GeometricInfo _geoInfoTargetImage; bool _acceptPadding; DoseTypeGy _defaultOutsideValue; public: /*! @brief Constructor. @param geoInfoTargetImage target image geometry @param doseMovingImage dose of moving image @param aTransformation the transformation @param acceptPadding is mapping outside the image allowed @param defaultOutsideValue the default outside voxel value if accepptPadding=true @pre all input parameters have to be valid @exception core::NullPointerException if one input parameter is NULL */ MappableDoseAccessorInterface(const core::GeometricInfo& geoInfoTargetImage, const DoseAccessorPointer doseMovingImage, const TransformationInterface::Pointer aTransformation, bool acceptPadding = true, DoseTypeGy defaultOutsideValue = 0.0): _spOriginalDoseDataMovingImage(doseMovingImage), _spTransformation(aTransformation), _geoInfoTargetImage(geoInfoTargetImage), _acceptPadding(acceptPadding), _defaultOutsideValue(defaultOutsideValue) { //handle null pointers if (doseMovingImage == NULL || aTransformation == NULL) { throw core::NullPointerException("Pointers to input accessors/transformation cannot be NULL."); } } /*! @brief Virtual destructor of base class */ virtual ~MappableDoseAccessorInterface() {}; inline const core::GeometricInfo& getGeometricInfo() const { return _geoInfoTargetImage; }; inline GridSizeType getGridSize() const { return _geoInfoTargetImage.getNumberOfVoxels(); }; /*! @brief Returns the dose for a given VoxelGridID (convenience function that handles conversion VoxelGridID->VoxelGridIndex3D) @sa getDoseAt(const VoxelGridIndex3D& aIndex) */ - DoseTypeGy getDoseAt(const VoxelGridID aID) const = 0; + virtual GenericValueType getValueAt(const VoxelGridID aID) const = 0; /*! @brief Returns the dose for a given VoxelGridIndex3D */ - virtual DoseTypeGy getDoseAt(const VoxelGridIndex3D& aIndex) const = 0 ; + virtual GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const = 0 ; - const IDType getDoseUID() const + const IDType getUID() const { - return _spOriginalDoseDataMovingImage->getDoseUID(); + return _spOriginalDoseDataMovingImage->getUID(); }; }; } } #endif diff --git a/code/interpolation/rttbNearestNeighborInterpolation.h b/code/interpolation/rttbNearestNeighborInterpolation.h index ffc8079..c20ad85 100644 --- a/code/interpolation/rttbNearestNeighborInterpolation.h +++ b/code/interpolation/rttbNearestNeighborInterpolation.h @@ -1,51 +1,51 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __NEAREST_NEIGHBOR_INTERPOLATION_H #define __NEAREST_NEIGHBOR_INTERPOLATION_H #include "rttbInterpolationBase.h" namespace rttb { namespace interpolation { /*! @class NearestNeighborInterpolation @brief Nearest Neighbor interpolation @ingroup interpolation */ class NearestNeighborInterpolation : public InterpolationBase { public: /*! @brief Constructor */ NearestNeighborInterpolation() {}; - /*! @brief Returns the interpolated value (the nearest voxel value given by _spOriginalDose->getGeometricInfo().worldCoordinateToIndex()) + /*! @brief Returns the interpolated value (the nearest voxel value given by _spOriginalData->getGeometricInfo().worldCoordinateToIndex()) */ DoseTypeGy getValue(const WorldCoordinate3D& aWorldCoordinate) const; }; } } #endif diff --git a/code/interpolation/rttbRosuMappableDoseAccessor.cpp b/code/interpolation/rttbRosuMappableDoseAccessor.cpp index 44d4b8a..e2b3f75 100644 --- a/code/interpolation/rttbRosuMappableDoseAccessor.cpp +++ b/code/interpolation/rttbRosuMappableDoseAccessor.cpp @@ -1,174 +1,174 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbRosuMappableDoseAccessor.h" #include "rttbNullPointerException.h" #include "rttbMappingOutsideOfImageException.h" #include "rttbLinearInterpolation.h" namespace rttb { namespace interpolation { RosuMappableDoseAccessor::RosuMappableDoseAccessor(const core::GeometricInfo& geoInfoTargetImage, const DoseAccessorPointer doseMovingImage, const TransformationInterface::Pointer aTransformation, bool acceptPadding, DoseTypeGy defaultOutsideValue): MappableDoseAccessorInterface(geoInfoTargetImage, doseMovingImage, aTransformation, acceptPadding, defaultOutsideValue) { //define linear interpolation InterpolationBase::Pointer interpolationLinear = InterpolationBase::Pointer( new LinearInterpolation()); _spInterpolation = interpolationLinear; - _spInterpolation->setDoseAccessorPointer(_spOriginalDoseDataMovingImage); + _spInterpolation->setAccessorPointer(_spOriginalDoseDataMovingImage); } - DoseTypeGy RosuMappableDoseAccessor::getDoseAt(const VoxelGridID aID) const + GenericValueType RosuMappableDoseAccessor::getValueAt(const VoxelGridID aID) const { VoxelGridIndex3D aVoxelGridIndex3D; if (_geoInfoTargetImage.convert(aID, aVoxelGridIndex3D)) { - return getDoseAt(aVoxelGridIndex3D); + return getValueAt(aVoxelGridIndex3D); } else { if (_acceptPadding) { return _defaultOutsideValue; } else { throw core::MappingOutsideOfImageException("Error in conversion from index to world coordinates"); return -1; } } } - DoseTypeGy RosuMappableDoseAccessor::getDoseAt(const VoxelGridIndex3D& aIndex) const + GenericValueType RosuMappableDoseAccessor::getValueAt(const VoxelGridIndex3D& aIndex) const { //Transform requested voxel coordinates of original image into world coordinates with RTTB WorldCoordinate3D worldCoordinateTarget; if (_geoInfoTargetImage.indexToWorldCoordinate(aIndex, worldCoordinateTarget)) { std::vector octants = getOctants(worldCoordinateTarget); if (octants.size() > 2) { DoseTypeGy interpolatedDoseValue = 0.0; //get trilinear interpolation value of every octant point for (std::vector::const_iterator octantIterator = octants.begin(); octantIterator != octants.end(); ++octantIterator) { //transform coordinates WorldCoordinate3D worldCoordinateMoving; WorldCoordinate3D worldCoordinateTargetOctant = *octantIterator; _spTransformation->transformInverse(worldCoordinateTargetOctant, worldCoordinateMoving); try { interpolatedDoseValue += _spInterpolation->getValue(worldCoordinateMoving); } //Mapped outside of image? Check if padding is allowed catch (core::MappingOutsideOfImageException& /*e*/) { if (_acceptPadding) { interpolatedDoseValue += _defaultOutsideValue; } else { throw core::MappingOutsideOfImageException("Mapping outside of image"); } } catch (core::Exception& e) { std::cout << e.what() << std::endl; return -1; } } return interpolatedDoseValue / (DoseTypeGy)octants.size(); } else { if (_acceptPadding) { return _defaultOutsideValue; } else { throw core::MappingOutsideOfImageException("Too many samples are mapped outside the image!"); return -1; } } } else { if (_acceptPadding) { return _defaultOutsideValue; } else { throw core::MappingOutsideOfImageException("Error in conversion from index to world coordinates"); return -1; } } } std::vector RosuMappableDoseAccessor::getOctants( const WorldCoordinate3D& aCoordinate) const { std::vector octants; SpacingVectorType3D spacingTargetImage = _geoInfoTargetImage.getSpacing(); core::GeometricInfo geometricInfoDoseData = _spOriginalDoseDataMovingImage->getGeometricInfo(); //as the corner point is the coordinate of the voxel (grid), 0.25 and 0.75 are the center of the subvoxels for (double xOct = -0.25; xOct <= 0.25; xOct += 0.5) { for (double yOct = -0.25; yOct <= 0.25; yOct += 0.5) { for (double zOct = -0.25; zOct <= 0.25; zOct += 0.5) { WorldCoordinate3D aWorldCoordinate(aCoordinate.x() + (xOct * spacingTargetImage.x()), aCoordinate.y() + (yOct * spacingTargetImage.y()), aCoordinate.z() + (zOct * spacingTargetImage.z())); if (geometricInfoDoseData.isInside(aWorldCoordinate)) { octants.push_back(aWorldCoordinate); } } } } return octants; } }//end namespace interpolation }//end namespace rttb diff --git a/code/interpolation/rttbRosuMappableDoseAccessor.h b/code/interpolation/rttbRosuMappableDoseAccessor.h index 60e3786..a5a0b4c 100644 --- a/code/interpolation/rttbRosuMappableDoseAccessor.h +++ b/code/interpolation/rttbRosuMappableDoseAccessor.h @@ -1,82 +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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __ROSU_MAPPABLE_DOSE_ACCESSOR_H #define __ROSU_MAPPABLE_DOSE_ACCESSOR_H #include #include "rttbBaseType.h" #include "rttbInterpolationBase.h" #include "rttbTransformationInterface.h" #include "rttbMappableDoseAccessorInterface.h" namespace rttb { namespace interpolation { /*! @class RosuMappableDoseAccessor @brief Class for dose mapping based on interpolation described in the Rosu2005 paper @details implementation of the following paper: Rosu, M., Chetty, I. J., Balter, J. M., Kessler, M. L., McShan, D. L., & Ten Haken, R. K. (2005). Dose reconstruction in deforming lung anatomy: Dose grid size effects and clinical implications. Medical Physics, 32(8), 2487. @ingroup interpolation */ class RosuMappableDoseAccessor: public MappableDoseAccessorInterface { private: InterpolationBase::Pointer _spInterpolation; public: typedef boost::shared_ptr Pointer; /*! @brief Constructor. Just hands values over to base class constructor. @note no interpolation as parameter since linear interpolation is fixed. @sa MappableDoseAccessorBase */ RosuMappableDoseAccessor(const core::GeometricInfo& geoInfoTargetImage, const DoseAccessorPointer doseMovingImage, const TransformationInterface::Pointer aTransformation, bool acceptPadding = true, DoseTypeGy defaultOutsideValue = 0.0); /*! @brief Virtual destructor. */ virtual ~RosuMappableDoseAccessor() {}; - DoseTypeGy getDoseAt(const VoxelGridID aID) const; + GenericValueType getValueAt(const VoxelGridID aID) const; /*! @brief Returns the dose for a given voxel grid index. The computation of the octant around the voxel is done and the interpolation is performed. @details Boundary treatment: if more than 6 subvoxels are outside: return _defaultOutsideValue. Otherwise: ignore the outside values. @return the dose or if (isOutside==true && _acceptPadding==true) then _defaultValue @exception core::MappingOutsideOfImageException if the point is mapped outside and if _acceptPadding==false, possibly returning _defaultValue) */ - DoseTypeGy getDoseAt(const VoxelGridIndex3D& aIndex) const; + GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const; private: /*! @brief returns the octant coordinates around a coordinate. @details i.e. coordinate is the center of a virtual voxel. Then, each side is divided into equal parts. The centers of the new subvoxels are then returned. @return a vector of the octant coordinates. */ std::vector getOctants(const WorldCoordinate3D& aCoordinate) const; }; } } #endif diff --git a/code/interpolation/rttbSimpleMappableDoseAccessor.cpp b/code/interpolation/rttbSimpleMappableDoseAccessor.cpp index 4a56a74..7652b16 100644 --- a/code/interpolation/rttbSimpleMappableDoseAccessor.cpp +++ b/code/interpolation/rttbSimpleMappableDoseAccessor.cpp @@ -1,122 +1,122 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbSimpleMappableDoseAccessor.h" #include "rttbNullPointerException.h" #include "rttbMappingOutsideOfImageException.h" namespace rttb { namespace interpolation { SimpleMappableDoseAccessor::SimpleMappableDoseAccessor(const core::GeometricInfo& geoInfoTargetImage, const DoseAccessorPointer doseMovingImage, TransformationInterface::Pointer aTransformation, const InterpolationBase::Pointer aInterpolation, bool acceptPadding, double defaultOutsideValue): MappableDoseAccessorInterface(geoInfoTargetImage, doseMovingImage, aTransformation, acceptPadding, defaultOutsideValue), _spInterpolation(aInterpolation) { //handle null pointers if (aInterpolation == NULL) { throw core::NullPointerException("Pointer to interpolation cannot be NULL."); } else { - _spInterpolation->setDoseAccessorPointer(_spOriginalDoseDataMovingImage); + _spInterpolation->setAccessorPointer(_spOriginalDoseDataMovingImage); } } - DoseTypeGy SimpleMappableDoseAccessor::getDoseAt(const VoxelGridID aID) const + GenericValueType SimpleMappableDoseAccessor::getValueAt(const VoxelGridID aID) const { VoxelGridIndex3D aVoxelGridIndex3D; if (_geoInfoTargetImage.convert(aID, aVoxelGridIndex3D)) { - return getDoseAt(aVoxelGridIndex3D); + return getValueAt(aVoxelGridIndex3D); } else { if (_acceptPadding) { return _defaultOutsideValue; } else { throw core::MappingOutsideOfImageException("Error in conversion from index to world coordinates"); return -1; } } } - DoseTypeGy SimpleMappableDoseAccessor::getDoseAt(const VoxelGridIndex3D& aIndex) const + GenericValueType SimpleMappableDoseAccessor::getValueAt(const VoxelGridIndex3D& aIndex) const { //Transform requested voxel coordinates of original image into world coordinates with RTTB WorldCoordinate3D worldCoordinateTarget; if (_geoInfoTargetImage.indexToWorldCoordinate(aIndex, worldCoordinateTarget)) { //transform coordinates WorldCoordinate3D worldCoordinateMoving; _spTransformation->transformInverse(worldCoordinateTarget, worldCoordinateMoving); //Use Interpolation to compute dose at mappedImage try { return _spInterpolation->getValue(worldCoordinateMoving); } //Mapped outside of image? Check if padding is allowed catch (core::MappingOutsideOfImageException& /*e*/) { if (_acceptPadding) { return _defaultOutsideValue; } else { throw core::MappingOutsideOfImageException("Error in conversion from index to world coordinates"); return -1; } } catch (core::Exception& e) { std::cout << e.what() << std::endl; return -1; } } //ok, if that fails, throw exception. Makes no sense to go further else { if (_acceptPadding) { return _defaultOutsideValue; } else { throw core::MappingOutsideOfImageException("Error in conversion from index to world coordinates"); return -1; } } } }//end namespace interpolation }//end namespace rttb diff --git a/code/interpolation/rttbSimpleMappableDoseAccessor.h b/code/interpolation/rttbSimpleMappableDoseAccessor.h index e9ae94a..06dcb9a 100644 --- a/code/interpolation/rttbSimpleMappableDoseAccessor.h +++ b/code/interpolation/rttbSimpleMappableDoseAccessor.h @@ -1,75 +1,75 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __SIMPLE_MAPPABLE_DOSE_ACCESSOR_H #define __SIMPLE_MAPPABLE_DOSE_ACCESSOR_H #include #include "rttbBaseType.h" #include "rttbInterpolationBase.h" #include "rttbTransformationInterface.h" #include "rttbMappableDoseAccessorInterface.h" namespace rttb { namespace interpolation { /*! @class SimpleMappableDoseAccessor @brief Class for dose mapping based on simple trilinear interpolation @ingroup interpolation */ class SimpleMappableDoseAccessor: public MappableDoseAccessorInterface { private: InterpolationBase::Pointer _spInterpolation; public: typedef boost::shared_ptr Pointer; /*! @brief Constructor. Just hands values over to base class constructor. @param aInterpolation the used interpolation. @sa MappableDoseAccessorBase */ SimpleMappableDoseAccessor(const core::GeometricInfo& geoInfoTargetImage, const DoseAccessorPointer doseMovingImage, const TransformationInterface::Pointer aTransformation, const InterpolationBase::Pointer aInterpolation, bool acceptPadding = true, DoseTypeGy defaultOutsideValue = 0.0); /*! @brief Virtual destructor of class */ virtual ~SimpleMappableDoseAccessor() {}; /*! @brief Returns the dose for a given voxel grid id. Plain trilinear interpolation is performed. @sa getDoseAt(const VoxelGridIndex3D& aIndex) */ - DoseTypeGy getDoseAt(const VoxelGridID aID) const; + GenericValueType getValueAt(const VoxelGridID aID) const; /*! @brief Returns the dose for a given voxel grid index. Plain trilinear interpolation is performed. @return the dose or if (isOutside==true && _acceptPadding==true) then _defaultValue @exception core::MappingOutsideOfImageException if the point is mapped outside and if _acceptPadding==false, possibly returning _defaultValue) */ - DoseTypeGy getDoseAt(const VoxelGridIndex3D& aIndex) const; + GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const; }; } } #endif diff --git a/code/io/dicom/rttbDicomDoseAccessor.cpp b/code/io/dicom/rttbDicomDoseAccessor.cpp index 36adcc6..9a1b0f5 100644 --- a/code/io/dicom/rttbDicomDoseAccessor.cpp +++ b/code/io/dicom/rttbDicomDoseAccessor.cpp @@ -1,294 +1,294 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include "rttbDicomDoseAccessor.h" #include "rttbNullPointerException.h" #include "rttbInvalidDoseException.h" #include "rttbDcmrtException.h" #include "rttbIndexOutOfBoundsException.h" namespace rttb { namespace io { namespace dicom { DicomDoseAccessor::~DicomDoseAccessor() { } DicomDoseAccessor::DicomDoseAccessor(DRTDoseIODPtr aDRTDoseIODP, DcmItemPtr aDcmDataset) { _dose = aDRTDoseIODP; _dataSet = aDcmDataset; OFString uid; _dose->getSeriesInstanceUID(uid); _doseUID = uid.c_str(); this->begin(); } bool DicomDoseAccessor::begin() { assembleGeometricInfo(); doseData.clear(); OFString doseGridScalingStr; this->_dose->getDoseGridScaling(doseGridScalingStr); try { _doseGridScaling = boost::lexical_cast(doseGridScalingStr.c_str()); } catch (boost::bad_lexical_cast&) { throw core::InvalidDoseException("Dose grid scaling not readable or = 0!") ; } OFCondition status; unsigned long count; const Uint16* pixelData; status = _dataSet->findAndGetUint16Array(DcmTagKey(0x7fe0, 0x0010), pixelData, &count); if (status.good()) { for (unsigned int i = 0; i < static_cast(this->_geoInfo.getNumberOfVoxels()); i++) { this->doseData.push_back(pixelData[i]); } return true; } else { throw io::dicom::DcmrtException("Read Pixel Data (7FE0,0010) failed!"); } } bool DicomDoseAccessor::assembleGeometricInfo() { Uint16 temp = 0; this->_dose->getColumns(temp); _geoInfo.setNumColumns(temp); temp = 0; this->_dose->getRows(temp); _geoInfo.setNumRows(temp); if (_geoInfo.getNumColumns() == 0 || _geoInfo.getNumRows() == 0) { throw core::InvalidDoseException("Empty dicom dose!") ; } OFString numberOfFramesStr; OFString imageOrientationRowX, imageOrientationRowY, imageOrientationRowZ; OFString imageOrientationColumnX, imageOrientationColumnY, imageOrientationColumnZ; WorldCoordinate3D imageOrientationRow; WorldCoordinate3D imageOrientationColumn; try { this->_dose->getNumberOfFrames(numberOfFramesStr); _geoInfo.setNumSlices(boost::lexical_cast(numberOfFramesStr.c_str())); _dose->getImageOrientationPatient(imageOrientationRowX, 0); _dose->getImageOrientationPatient(imageOrientationRowY, 1); _dose->getImageOrientationPatient(imageOrientationRowZ, 2); _dose->getImageOrientationPatient(imageOrientationColumnX, 3); _dose->getImageOrientationPatient(imageOrientationColumnY, 4); _dose->getImageOrientationPatient(imageOrientationColumnZ, 5); imageOrientationRow(0) = boost::lexical_cast(imageOrientationRowX.c_str()); imageOrientationRow(1) = boost::lexical_cast(imageOrientationRowY.c_str()); imageOrientationRow(2) = boost::lexical_cast(imageOrientationRowZ.c_str()); imageOrientationColumn(0) = boost::lexical_cast(imageOrientationColumnX.c_str()); imageOrientationColumn(1) = boost::lexical_cast(imageOrientationColumnY.c_str()); imageOrientationColumn(2) = boost::lexical_cast(imageOrientationColumnZ.c_str()); } catch (boost::bad_lexical_cast&) { throw core::InvalidDoseException("boost::lexical_cast failed! Empty dicom dose!") ; } /*Get orientation*/ OrientationMatrix orientation; orientation(0, 0) = imageOrientationRow.x(); orientation(1, 0) = imageOrientationRow.y(); orientation(2, 0) = imageOrientationRow.z(); orientation(0, 1) = imageOrientationColumn.x(); orientation(1, 1) = imageOrientationColumn.y(); orientation(2, 1) = imageOrientationColumn.z(); WorldCoordinate3D perpendicular = imageOrientationRow.cross(imageOrientationColumn); orientation(0, 2) = perpendicular.x(); orientation(1, 2) = perpendicular.y(); orientation(2, 2) = perpendicular.z(); _geoInfo.setOrientationMatrix(orientation); OFString imagePositionX, imagePositionY, imagePositionZ; _dose->getImagePositionPatient(imagePositionX, 0); _dose->getImagePositionPatient(imagePositionY, 1); _dose->getImagePositionPatient(imagePositionZ, 2); WorldCoordinate3D imagePositionPatient; try { imagePositionPatient(0) = boost::lexical_cast(imagePositionX.c_str()); imagePositionPatient(1) = boost::lexical_cast(imagePositionY.c_str()); imagePositionPatient(2) = boost::lexical_cast(imagePositionZ.c_str()); } catch (boost::bad_lexical_cast&) { throw core::InvalidDoseException("Can not read image position X/Y/Z!") ; } _geoInfo.setImagePositionPatient(imagePositionPatient); /*Get spacing*/ SpacingVectorType3D spacingVector; OFString pixelSpacingRowStr, pixelSpacingColumnStr, sliceThicknessStr; _dose->getPixelSpacing(pixelSpacingRowStr, 0); _dose->getPixelSpacing(pixelSpacingColumnStr, 1); try { spacingVector(1) = boost::lexical_cast(pixelSpacingRowStr.c_str()); spacingVector(0) = boost::lexical_cast(pixelSpacingColumnStr.c_str()); } catch (boost::bad_lexical_cast&) { throw core::InvalidDoseException("Can not read Pixel Spacing Row/Column!") ; } _geoInfo.setSpacing(spacingVector); if (_geoInfo.getPixelSpacingRow() == 0 || _geoInfo.getPixelSpacingColumn() == 0) { throw core::InvalidDoseException("Pixel spacing = 0!"); } _dose->getSliceThickness(sliceThicknessStr); try { spacingVector(2) = boost::lexical_cast(sliceThicknessStr.c_str()); } catch (boost::bad_lexical_cast&) { spacingVector(2) = 0 ; } if (spacingVector(2) == 0) { OFVector gridFrameOffsetVector; _dose->getGridFrameOffsetVector(gridFrameOffsetVector); if (gridFrameOffsetVector.size() >= 2) { spacingVector(2) = gridFrameOffsetVector.at(1) - gridFrameOffsetVector.at( - 0); //read slice thickness from GridFrameOffsetVector (3004,000c) + 0); //read slice thickness from GridFrameOffsetVector (3004,000c) } if (spacingVector(2) == 0) { OFCondition status; DcmItem doseitem; OFString pixelSpacingBetweenSlices; status = _dose->write(doseitem); if (status.good()) { status = doseitem.findAndGetOFString(DcmTagKey(0x0018, 0x0088), pixelSpacingBetweenSlices); try { spacingVector(2) = boost::lexical_cast - (pixelSpacingBetweenSlices.c_str());//read slice thickness from PixelSpacingBetweenSlices (0018,0088) + (pixelSpacingBetweenSlices.c_str());//read slice thickness from PixelSpacingBetweenSlices (0018,0088) } catch (boost::bad_lexical_cast&) { spacingVector(2) = 0 ; } } //if no useful tags to compute slicing -> set slice thickness to spacingVector(0) if (spacingVector(2) == 0) { std::cerr << "sliceThickness == 0! It wird be replaced with pixelSpacingRow=" << - _geoInfo.getPixelSpacingRow() - << "!" << std::endl; + _geoInfo.getPixelSpacingRow() + << "!" << std::endl; spacingVector(2) = spacingVector(0); } } } _geoInfo.setSpacing(spacingVector); return true; } - DoseTypeGy DicomDoseAccessor::getDoseAt(const VoxelGridID aID) const + GenericValueType DicomDoseAccessor::getValueAt(const VoxelGridID aID) const { return doseData.at(aID) * _doseGridScaling; } - DoseTypeGy DicomDoseAccessor::getDoseAt(const VoxelGridIndex3D& aIndex) const + GenericValueType DicomDoseAccessor::getValueAt(const VoxelGridIndex3D& aIndex) const { VoxelGridID aVoxelGridID; if (_geoInfo.convert(aIndex, aVoxelGridID)) { - return getDoseAt(aVoxelGridID); + return getValueAt(aVoxelGridID); } else { return -1; } } } } } diff --git a/code/io/dicom/rttbDicomDoseAccessor.h b/code/io/dicom/rttbDicomDoseAccessor.h index 13f935e..9f4df69 100644 --- a/code/io/dicom/rttbDicomDoseAccessor.h +++ b/code/io/dicom/rttbDicomDoseAccessor.h @@ -1,101 +1,101 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DICOM_DOSE_ACCESSOR_H #define __DICOM_DOSE_ACCESSOR_H #include #include #include #include #include "osconfig.h" /* make sure OS specific configuration is included first */ #include "drtdose.h" -#include "rttbDoseAccessorWithGeoInfoBase.h" +#include "rttbAccessorWithGeoInfoBase.h" #include "rttbBaseType.h" namespace rttb { - namespace io - { - namespace dicom - { - - /*! @class DicomDoseAccessor - @brief This class gives access to dose information from DRTDoseIOD and DcmItem - */ - class DicomDoseAccessor: public core::DoseAccessorWithGeoInfoBase - { - public: - typedef boost::shared_ptr DRTDoseIODPtr; - typedef boost::shared_ptr DcmItemPtr; - - private: - DRTDoseIODPtr _dose; - DcmItemPtr _dataSet; - - /*! vector of dose data(absolute Gy dose/doseGridScaling)*/ - std::vector doseData; - - double _doseGridScaling; - - IDType _doseUID; - - DicomDoseAccessor(); - - protected: - /*! @brief Initialize dose data - @exception InvalidDoseException Thrown if _dose is invalid: one of column/row/numberOfFrames/doseGridScaling/pixelSpacing=0 - @exception DcmrtException Throw if dcmrt error - @exception boost/bad_lexical_cast Thrown if the imported header tags are not numerical. - */ - bool begin(); - - /*! @brief get all required data from dicom information contained in _dose - @exception boost/bad_lexical_cast Thrown if the imported header tags are not numerical. - */ - bool assembleGeometricInfo(); - - - public: - ~DicomDoseAccessor(); - - /*! @brief Constructor. Initialisation with a boost::shared_ptr of DRTDoseIOD and of DcmItem to get the pixel data - @exception DcmrtException Throw if dcmrt error - */ - DicomDoseAccessor(DRTDoseIODPtr aDRTDoseIODP, DcmItemPtr aDcmDataset); - - DoseTypeGy getDoseAt(const VoxelGridID aID) const; - - DoseTypeGy getDoseAt(const VoxelGridIndex3D& aIndex) const; - - const IDType getDoseUID() const - { - return _doseUID; - }; - }; - } - } + namespace io + { + namespace dicom + { + + /*! @class DicomDoseAccessor + @brief This class gives access to dose information from DRTDoseIOD and DcmItem + */ + class DicomDoseAccessor: public core::AccessorWithGeoInfoBase + { + public: + typedef boost::shared_ptr DRTDoseIODPtr; + typedef boost::shared_ptr DcmItemPtr; + + private: + DRTDoseIODPtr _dose; + DcmItemPtr _dataSet; + + /*! vector of dose data(absolute Gy dose/doseGridScaling)*/ + std::vector doseData; + + double _doseGridScaling; + + IDType _doseUID; + + DicomDoseAccessor(); + + protected: + /*! @brief Initialize dose data + @exception InvalidDoseException Thrown if _dose is invalid: one of column/row/numberOfFrames/doseGridScaling/pixelSpacing=0 + @exception DcmrtException Throw if dcmrt error + @exception boost/bad_lexical_cast Thrown if the imported header tags are not numerical. + */ + bool begin(); + + /*! @brief get all required data from dicom information contained in _dose + @exception boost/bad_lexical_cast Thrown if the imported header tags are not numerical. + */ + bool assembleGeometricInfo(); + + + public: + ~DicomDoseAccessor(); + + /*! @brief Constructor. Initialisation with a boost::shared_ptr of DRTDoseIOD and of DcmItem to get the pixel data + @exception DcmrtException Throw if dcmrt error + */ + DicomDoseAccessor(DRTDoseIODPtr aDRTDoseIODP, DcmItemPtr aDcmDataset); + + GenericValueType getValueAt(const VoxelGridID aID) const; + + GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const; + + const IDType getUID() const + { + return _doseUID; + }; + }; + } + } } #endif diff --git a/code/io/dicom/rttbDicomFileDoseAccessorGenerator.cpp b/code/io/dicom/rttbDicomFileDoseAccessorGenerator.cpp index 8acb537..159e216 100644 --- a/code/io/dicom/rttbDicomFileDoseAccessorGenerator.cpp +++ b/code/io/dicom/rttbDicomFileDoseAccessorGenerator.cpp @@ -1,97 +1,107 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomDoseAccessor.h" #include "rttbNullPointerException.h" #include "rttbInvalidDoseException.h" #include "rttbDcmrtException.h" #include "rttbIndexOutOfBoundsException.h" #include "rttbDicomFileReaderHelper.h" #include "rttbInvalidParameterException.h" -namespace rttb{ - namespace io{ - namespace dicom{ +namespace rttb +{ + namespace io + { + namespace dicom + { - DicomFileDoseAccessorGenerator::~DicomFileDoseAccessorGenerator(){} + DicomFileDoseAccessorGenerator::~DicomFileDoseAccessorGenerator() {} - DicomFileDoseAccessorGenerator::DicomFileDoseAccessorGenerator(FileNameType aDICOMRTDoseFileName){ - _dicomDoseFileName=aDICOMRTDoseFileName; - + DicomFileDoseAccessorGenerator::DicomFileDoseAccessorGenerator(FileNameType aDICOMRTDoseFileName) + { + _dicomDoseFileName = aDICOMRTDoseFileName; + } - core::DoseAccessorGeneratorInterface::DoseAccessorPointer DicomFileDoseAccessorGenerator::generateDoseAccessor() { + core::DoseAccessorGeneratorInterface::DoseAccessorPointer DicomFileDoseAccessorGenerator::generateDoseAccessor() + { std::vector fileVector; //if a file - if(isFile(_dicomDoseFileName)){ + if (isFile(_dicomDoseFileName)) + { fileVector.push_back(_dicomDoseFileName); } //if a directory - else if(isDirectory(_dicomDoseFileName)){ - rttb::io::dicom::Modality doseModality= {rttb::io::dicom::Modality::RTDOSE}; + else if (isDirectory(_dicomDoseFileName)) + { + rttb::io::dicom::Modality doseModality = {rttb::io::dicom::Modality::RTDOSE}; fileVector = getFileNamesWithSameUID(_dicomDoseFileName, doseModality); } - else{ + else + { throw rttb::core::InvalidParameterException("Invalid file/directory name!"); } - if(fileVector.size()<1){ + if (fileVector.size() < 1) + { throw rttb::core::InvalidParameterException("There is no structure set files in the directory!"); } - OFCondition status; DcmFileFormat fileformat; - DRTDoseIODPtr dose= boost::make_shared(); + DRTDoseIODPtr dose = boost::make_shared(); status = fileformat.loadFile(fileVector.at(0).c_str()); + if (!status.good()) { - std::cerr << "Error: load rtdose loadFile("<(*fileformat.getDataset()); status = dose->read(*dataSet); - if(!status.good()) + + if (!status.good()) { - std::cerr << "Error: read DRTDoseIOD failed!"<(dose, dataSet); + _doseAccessor = boost::make_shared(dose, dataSet); return _doseAccessor; - + } - + } } } diff --git a/code/io/dicom/rttbDicomFileDoseAccessorGenerator.h b/code/io/dicom/rttbDicomFileDoseAccessorGenerator.h index b2cfa9a..ad0dd78 100644 --- a/code/io/dicom/rttbDicomFileDoseAccessorGenerator.h +++ b/code/io/dicom/rttbDicomFileDoseAccessorGenerator.h @@ -1,79 +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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DICOM_FILE_DOSE_ACCESSOR_GENERATOR_H #define __DICOM_FILE_DOSE_ACCESSOR_GENERATOR_H #include #include #include #include "osconfig.h" /* make sure OS specific configuration is included first */ #include "drtdose.h" #include "rttbDoseAccessorGeneratorBase.h" #include "rttbBaseType.h" -namespace rttb{ - namespace io{ - namespace dicom{ +namespace rttb +{ + namespace io + { + namespace dicom + { - /*! @class DicomFileDoseAccessorGenerator + /*! @class DicomFileDoseAccessorGenerator @brief Load dose data from dicom file and generate DicomDoseAccessor. */ class DicomFileDoseAccessorGenerator: public core::DoseAccessorGeneratorBase { - public: + public: typedef boost::shared_ptr DRTDoseIODPtr; typedef boost::shared_ptr DcmItemPtr; - + private: FileNameType _dicomDoseFileName; - - DicomFileDoseAccessorGenerator(); + + DicomFileDoseAccessorGenerator(); protected: - public: + public: ~DicomFileDoseAccessorGenerator(); /*! @brief Constructor. Initialisation with a DICOM-RT dose file or a directory name @param aDICOMRTDoseFileName a DICOM-RT dose file name or a directory name @exception InvalidParameterException thrown if the file does not exist or the directory has no dicom dose file - @exception DcmrtException thrown if load and read file failed + @exception DcmrtException thrown if load and read file failed */ DicomFileDoseAccessorGenerator(FileNameType aDICOMRTDoseFileName); - /*! @brief Generate DoseAccessor - @return Return shared pointer of DoseAccessor. + /*! @brief Generate DoseAccessor + @return Return shared pointer of DoseAccessor. @exception InvalidDoseException Thrown if the loaded dose is invalid: one of column/row/numberOfFrames/doseGridScaling/pixelSpacing=0 @exception DcmrtException Throw if dcmrt error */ DoseAccessorPointer generateDoseAccessor() ; }; } } } #endif diff --git a/code/io/dicom/rttbDicomFileDoseAccessorWriter.cpp b/code/io/dicom/rttbDicomFileDoseAccessorWriter.cpp index 49b5a57..32729a5 100644 --- a/code/io/dicom/rttbDicomFileDoseAccessorWriter.cpp +++ b/code/io/dicom/rttbDicomFileDoseAccessorWriter.cpp @@ -1,257 +1,257 @@ // ----------------------------------------------------------------------- // 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 "rttbDicomFileDoseAccessorWriter.h" #include "rttbInvalidDoseException.h" #include "rttbGeometricInfo.h" #include "rttbGeometricInfo.h" #include "rttbGenericDoseIterator.h" #include "rttbDoseStatisticsCalculator.h" namespace rttb { namespace io { namespace dicom { DicomFileDoseAccessorWriter::DicomFileDoseAccessorWriter() { _doseIOD = boost::make_shared(); _dataset = _fileformat.getDataset(); } void DicomFileDoseAccessorWriter::setFileName(DICOMRTFileNameString aFileName) { _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()); + OFString CreationUID(_doseAccessor->getUID().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()); + _doseAccessor->getUID().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, ""); _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"); /* 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, 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, ""); _dataset->putAndInsertString(DCM_SamplesPerPixel, "1"); _dataset->putAndInsertString(DCM_PhotometricInterpretation, "MONOCHROME2"); 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()); sstr.str(""); sstr << geometricInfo.getSpacing()(1) << "\\" << geometricInfo.getSpacing()(0); _dataset->putAndInsertString(DCM_PixelSpacing, sstr.str().c_str()); _dataset->putAndInsertString(DCM_BitsAllocated, "32"); _dataset->putAndInsertString(DCM_BitsStored, "32"); _dataset->putAndInsertString(DCM_HighBit, "31"); _dataset->putAndInsertString(DCM_DoseUnits, "GY"); _dataset->putAndInsertString(DCM_DoseSummationType, "PLAN"); sstr.str("0"); for (int i = 1; i < geometricInfo.getNumSlices(); i++) { sstr << "\\" << i* geometricInfo.getSpacing()(2); } _dataset->putAndInsertString(DCM_GridFrameOffsetVector, sstr.str().c_str()); /* 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::DoseStatisticsCalculator myDoseStatsCalculator(spDoseIterator); rttb::algorithms::DoseStatistics::DoseStatisticsPointer doseStatistics = myDoseStatsCalculator.calculateDoseStatistics(); //rttb::algorithms::DoseStatistics doseStat(spDoseIterator); //boost::shared_ptr< std::vector > > myResultPairs = // boost::make_shared< std::vector > >(); //rttb::algorithms::DoseStatistics::ResultListPointer spMyResultPairs(myResultPairs); double maxDose = doseStatistics->getMaximum(); /* Find scale factor */ float dose_scale; dose_scale = maxDose / PixelDataMaxValue; /* Scale the image and add scale factor to _dataset */ 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, ""); /* (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, ""); /* 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; i < pixelCount; ++i) { - double doseValue = _doseAccessor->getDoseAt(i); + double doseValue = _doseAccessor->getValueAt(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!"); } //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; } }//end namespace itk }//end namespace io }//end namespace rttb diff --git a/code/io/dicom/rttbDicomFileDoseAccessorWriter.h b/code/io/dicom/rttbDicomFileDoseAccessorWriter.h index 0a47613..0c21d8b 100644 --- a/code/io/dicom/rttbDicomFileDoseAccessorWriter.h +++ b/code/io/dicom/rttbDicomFileDoseAccessorWriter.h @@ -1,82 +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_FILE_DOSE_ACCESSOR_WRITER_H #define __DICOM_FILE_DOSE_ACCESSOR_WRITER_H #include "../itk/rttbDoseAccessorProcessorBase.h" #include "../itk/rttbDoseAccessorConversionSettingInterface.h" #include "rttbDicomDoseAccessor.h" //pixel data max value ‘UINT16_MAX’ #define PixelDataMaxValue 0xffff namespace rttb { namespace io { namespace dicom { /*! @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. */ class DicomFileDoseAccessorWriter: public core::DoseAccessorProcessorBase, public core::DoseAccessorConversionSettingInterface { public: typedef core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; typedef DicomDoseAccessor::DRTDoseIODPtr DRTDoseIODPointer; /*! @brief Standard Constructor. */ DicomFileDoseAccessorWriter(); virtual ~DicomFileDoseAccessorWriter() {}; /*! Set a file name to write the dose @param aFileName a file name to write the dose */ void setFileName(DICOMRTFileNameString aFileName); /*! @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; + DcmFileFormat _fileformat; DcmDataset *_dataset; }; } } } #endif diff --git a/code/io/dicom/rttbDicomIODDoseAccessorGenerator.cpp b/code/io/dicom/rttbDicomIODDoseAccessorGenerator.cpp index 238c7b0..95cc37b 100644 --- a/code/io/dicom/rttbDicomIODDoseAccessorGenerator.cpp +++ b/code/io/dicom/rttbDicomIODDoseAccessorGenerator.cpp @@ -1,64 +1,70 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include "rttbDicomIODDoseAccessorGenerator.h" #include "rttbDicomDoseAccessor.h" #include "rttbNullPointerException.h" #include "rttbInvalidDoseException.h" #include "rttbDcmrtException.h" #include "rttbIndexOutOfBoundsException.h" -namespace rttb{ - namespace io{ - namespace dicom{ +namespace rttb +{ + namespace io + { + namespace dicom + { - DicomIODDoseAccessorGenerator::~DicomIODDoseAccessorGenerator(){} + DicomIODDoseAccessorGenerator::~DicomIODDoseAccessorGenerator() {} + + DicomIODDoseAccessorGenerator::DicomIODDoseAccessorGenerator(DRTDoseIODPtr aDRTDoseIODP) + { + _doseIODPtr = aDRTDoseIODP; - DicomIODDoseAccessorGenerator::DicomIODDoseAccessorGenerator(DRTDoseIODPtr aDRTDoseIODP){ - _doseIODPtr=aDRTDoseIODP; - } - core::DoseAccessorGeneratorInterface::DoseAccessorPointer DicomIODDoseAccessorGenerator::generateDoseAccessor() { + core::DoseAccessorGeneratorInterface::DoseAccessorPointer DicomIODDoseAccessorGenerator::generateDoseAccessor() + { DcmItem doseitem; OFCondition status; status = _doseIODPtr->write(doseitem);//write DoseIOD to DcmItem to get pixel data - if(status.good()){ + if (status.good()) + { DcmItemPtr dataSetPtr = boost::make_shared(doseitem); - _doseAccessor=boost::make_shared(_doseIODPtr, dataSetPtr); - return _doseAccessor; - } + _doseAccessor = boost::make_shared(_doseIODPtr, dataSetPtr); + return _doseAccessor; + } else { throw io::dicom::DcmrtException("Write DICOM RT Dose to DcmItem failed!"); } } - + } } } diff --git a/code/io/dicom/rttbDicomIODDoseAccessorGenerator.h b/code/io/dicom/rttbDicomIODDoseAccessorGenerator.h index df32063..1d05795 100644 --- a/code/io/dicom/rttbDicomIODDoseAccessorGenerator.h +++ b/code/io/dicom/rttbDicomIODDoseAccessorGenerator.h @@ -1,77 +1,80 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DICOM_IOD_DOSE_ACCESSOR_GENERATOR_H #define __DICOM_IOD_DOSE_ACCESSOR_GENERATOR_H #include #include #include #include "osconfig.h" /* make sure OS specific configuration is included first */ #include "drtdose.h" #include "rttbDoseAccessorGeneratorBase.h" #include "rttbBaseType.h" -namespace rttb{ - namespace io{ - namespace dicom{ - - /*! @class DicomIODDoseAccessorGenerator +namespace rttb +{ + namespace io + { + namespace dicom + { + + /*! @class DicomIODDoseAccessorGenerator @brief Generate DicomDoseAccessor with a DRTDoseIOD. */ class DicomIODDoseAccessorGenerator: public core::DoseAccessorGeneratorBase { - public: + public: typedef boost::shared_ptr DRTDoseIODPtr; typedef boost::shared_ptr DcmItemPtr; protected: private: DRTDoseIODPtr _doseIODPtr; DicomIODDoseAccessorGenerator(); - public: + public: ~DicomIODDoseAccessorGenerator(); - /*! @brief Constructor. Initialisation with a boost shared pointer of DRTDoseIOD - + /*! @brief Constructor. Initialisation with a boost shared pointer of DRTDoseIOD + */ DicomIODDoseAccessorGenerator(DRTDoseIODPtr aDRTDoseIODP); - /*! @brief Generate DoseAccessor - @return Return shared pointer of DoseAccessor. + /*! @brief Generate DoseAccessor + @return Return shared pointer of DoseAccessor. @exception InvalidDoseException Thrown if aDRTDoseIODP is invalid: one of column/row/numberOfFrames/doseGridScaling/pixelSpacing=0 @exception DcmrtException Throw if dcmrt error */ DoseAccessorPointer generateDoseAccessor() ; }; } } } #endif diff --git a/code/io/helax/rttbDicomHelaxDoseAccessor.cpp b/code/io/helax/rttbDicomHelaxDoseAccessor.cpp index a0487fe..f112b7d 100644 --- a/code/io/helax/rttbDicomHelaxDoseAccessor.cpp +++ b/code/io/helax/rttbDicomHelaxDoseAccessor.cpp @@ -1,325 +1,325 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include "boost/filesystem/operations.hpp" #include "boost/filesystem/path.hpp" #include "boost/progress.hpp" #include #include "rttbDicomHelaxDoseAccessor.h" #include "rttbInvalidDoseException.h" #include "rttbDcmrtException.h" #include "rttbIndexOutOfBoundsException.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace io { namespace helax { DicomHelaxDoseAccessor::~DicomHelaxDoseAccessor() { } DicomHelaxDoseAccessor::DicomHelaxDoseAccessor(std::vector aDICOMRTDoseVector) { for (int i = 0; i < aDICOMRTDoseVector.size(); i++) { _doseVector.push_back(aDICOMRTDoseVector.at(i)); } this->begin(); } bool DicomHelaxDoseAccessor::begin() { if (_doseVector.size() == 0) { throw core::InvalidParameterException(" The size of aDICOMRTDoseVector is 0!"); } assembleGeometricInfo(); _doseData.clear(); OFString doseGridScalingStr; _doseVector.at(0)->getDoseGridScaling( doseGridScalingStr);//get the first dose grid scaling as _doseGridScaling try { _doseGridScaling = boost::lexical_cast(doseGridScalingStr.c_str()); } catch (boost::bad_lexical_cast&) { throw core::InvalidDoseException("Dose grid scaling not readable or = 0!") ; } for (int i = 0; i < _doseVector.size(); i++) { DRTDoseIODPtr dose = _doseVector.at(i); OFString currentDoseGridScalingStr; dose->getDoseGridScaling(currentDoseGridScalingStr); double currentDoseGridScaling; try { currentDoseGridScaling = boost::lexical_cast(currentDoseGridScalingStr.c_str()); } catch (boost::bad_lexical_cast&) { throw core::InvalidDoseException("Dose grid scaling not readable or = 0!") ; } OFCondition status; DcmFileFormat fileformat; DcmItem doseitem; status = dose->write(doseitem); if (status.good()) { unsigned long count; const Uint16* pixelData; status = doseitem.findAndGetUint16Array(DcmTagKey(0x7fe0, 0x0010), pixelData, &count); if (status.good()) { for (unsigned int i = 0; i < static_cast(_geoInfo.getNumColumns()*_geoInfo.getNumRows()); i++) { this->_doseData.push_back(pixelData[i]*currentDoseGridScaling / _doseGridScaling); //recalculate dose data } } else { throw dicom::DcmrtException("Read Pixel Data (7FE0,0010) failed!"); } } else { throw dicom::DcmrtException("Read DICOM-RT Dose file failed!"); } } return true; } bool DicomHelaxDoseAccessor::assembleGeometricInfo() { DRTDoseIODPtr dose = _doseVector.at(0); Uint16 temp = 0; dose->getColumns(temp); _geoInfo.setNumColumns(temp); temp = 0; dose->getRows(temp); _geoInfo.setNumRows(temp); OFString numberOfFramesStr; dose->getNumberOfFrames(numberOfFramesStr); if (!numberOfFramesStr.empty()) { _geoInfo.setNumSlices(boost::lexical_cast(numberOfFramesStr.c_str())); } else { _geoInfo.setNumSlices((VoxelGridDimensionType)_doseVector.size()); } if (_geoInfo.getNumColumns() == 0 || _geoInfo.getNumRows() == 0 || _geoInfo.getNumSlices() == 0) { throw core::InvalidDoseException("Empty dicom dose!") ; } OFString imageOrientationRowX; dose->getImageOrientationPatient(imageOrientationRowX, 0); OFString imageOrientationRowY; dose->getImageOrientationPatient(imageOrientationRowY, 1); OFString imageOrientationRowZ; dose->getImageOrientationPatient(imageOrientationRowZ, 2); OFString imageOrientationColumnX; dose->getImageOrientationPatient(imageOrientationColumnX, 3); OFString imageOrientationColumnY; dose->getImageOrientationPatient(imageOrientationColumnY, 4); OFString imageOrientationColumnZ; dose->getImageOrientationPatient(imageOrientationColumnZ, 5); WorldCoordinate3D imageOrientationRow; WorldCoordinate3D imageOrientationColumn; try { imageOrientationRow(0) = boost::lexical_cast(imageOrientationRowX.c_str()); imageOrientationRow(1) = boost::lexical_cast(imageOrientationRowY.c_str()); imageOrientationRow(2) = boost::lexical_cast(imageOrientationRowZ.c_str()); imageOrientationColumn(0) = boost::lexical_cast(imageOrientationColumnX.c_str()); imageOrientationColumn(1) = boost::lexical_cast(imageOrientationColumnY.c_str()); imageOrientationColumn(2) = boost::lexical_cast(imageOrientationColumnZ.c_str()); } catch (boost::bad_lexical_cast&) { throw core::InvalidDoseException("boost::lexical_cast ImageOrientation failed! Can not read image orientation X/Y/Z!") ; } OrientationMatrix orientation; orientation(0, 0) = imageOrientationRow.x(); orientation(1, 0) = imageOrientationRow.y(); orientation(2, 0) = imageOrientationRow.z(); orientation(0, 1) = imageOrientationColumn.x(); orientation(1, 1) = imageOrientationColumn.y(); orientation(2, 1) = imageOrientationColumn.z(); WorldCoordinate3D perpendicular = imageOrientationRow.cross(imageOrientationColumn); orientation(0, 2) = perpendicular.x(); orientation(1, 2) = perpendicular.y(); orientation(2, 2) = perpendicular.z(); _geoInfo.setOrientationMatrix(orientation); OFString imagePositionX; dose->getImagePositionPatient(imagePositionX, 0); OFString imagePositionY; dose->getImagePositionPatient(imagePositionY, 1); OFString imagePositionZ; dose->getImagePositionPatient(imagePositionZ, 2); WorldCoordinate3D imagePositionPatient; try { imagePositionPatient(0) = boost::lexical_cast(imagePositionX.c_str()); imagePositionPatient(1) = boost::lexical_cast(imagePositionY.c_str()); imagePositionPatient(2) = boost::lexical_cast(imagePositionZ.c_str()); } catch (boost::bad_lexical_cast&) { throw core::InvalidDoseException("boost::lexical_cast ImagePosition failed! Can not read image position X/Y/Z!") ; } _geoInfo.setImagePositionPatient(imagePositionPatient); SpacingVectorType3D spacingVector; OFString pixelSpacingRowStr; dose->getPixelSpacing(pixelSpacingRowStr, 0); OFString pixelSpacingColumnStr; dose->getPixelSpacing(pixelSpacingColumnStr, 1); try { spacingVector(1) = boost::lexical_cast(pixelSpacingRowStr.c_str()); spacingVector(0) = boost::lexical_cast(pixelSpacingColumnStr.c_str()); } catch (boost::bad_lexical_cast&) { throw core::InvalidDoseException("Can not read Pixel Spacing Row/Column!") ; } _geoInfo.setSpacing(spacingVector); if (_geoInfo.getPixelSpacingRow() == 0 || _geoInfo.getPixelSpacingColumn() == 0) { throw core::InvalidDoseException("Pixel spacing not readable or = 0!"); } OFString sliceThicknessStr; dose->getSliceThickness(sliceThicknessStr); try { spacingVector(2) = boost::lexical_cast(sliceThicknessStr.c_str()); } catch (boost::bad_lexical_cast&) { spacingVector(2) = 0 ;//if no information about slice thickness, set to 0 and calculate it using z coordinate difference between 1. and 2. dose } if (spacingVector(2) == 0) { if (_doseVector.size() > 1) { DRTDoseIODPtr dose2 = _doseVector.at(1);//get the 2. dose OFString imagePositionZ2; dose2->getImagePositionPatient(imagePositionZ2, 2); try { spacingVector(2) = boost::lexical_cast(imagePositionZ2.c_str()) - imagePositionPatient( 2); //caculate slicethickness } catch (boost::bad_lexical_cast&) { throw core::InvalidDoseException("Can not read image position Z of the 2. dose!"); } } else { std::cerr << "sliceThickness == 0! It will be replaced with pixelSpacingRow=" << _geoInfo.getPixelSpacingRow() << "!" << std::endl; spacingVector(2) = spacingVector(0); } } _geoInfo.setSpacing(spacingVector); return true; } - DoseTypeGy DicomHelaxDoseAccessor::getDoseAt(const VoxelGridID aID) const + GenericValueType DicomHelaxDoseAccessor::getValueAt(const VoxelGridID aID) const { return _doseData.at(aID) * _doseGridScaling; } - DoseTypeGy DicomHelaxDoseAccessor::getDoseAt(const VoxelGridIndex3D& aIndex) const + GenericValueType DicomHelaxDoseAccessor::getValueAt(const VoxelGridIndex3D& aIndex) const { VoxelGridID aVoxelGridID; if (_geoInfo.convert(aIndex, aVoxelGridID)) { - return getDoseAt(aVoxelGridID); + return getValueAt(aVoxelGridID); } else { return -1; } } } } } diff --git a/code/io/helax/rttbDicomHelaxDoseAccessor.h b/code/io/helax/rttbDicomHelaxDoseAccessor.h index 3eee9e4..cd0e037 100644 --- a/code/io/helax/rttbDicomHelaxDoseAccessor.h +++ b/code/io/helax/rttbDicomHelaxDoseAccessor.h @@ -1,105 +1,105 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DICOM_HELAX_DOSE_ACCESSOR_H #define __DICOM_HELAX_DOSE_ACCESSOR_H #include #include #include #include #include "osconfig.h" /* make sure OS specific configuration is included first */ #include "drtdose.h" -#include "rttbDoseAccessorWithGeoInfoBase.h" +#include "rttbAccessorWithGeoInfoBase.h" #include "rttbGeometricInfo.h" #include "rttbBaseType.h" namespace rttb { - namespace io - { - namespace helax - { + namespace io + { + namespace helax + { - /*! @class DicomHelaxDoseAccessor - @brief Load dose data from a directory containing dicom dose files, each file describes the helax dose in one slice. - */ - class DicomHelaxDoseAccessor: public core::DoseAccessorWithGeoInfoBase - { - public: - typedef boost::shared_ptr DRTDoseIODPtr; + /*! @class DicomHelaxDoseAccessor + @brief Load dose data from a directory containing dicom dose files, each file describes the helax dose in one slice. + */ + class DicomHelaxDoseAccessor: public core::AccessorWithGeoInfoBase + { + public: + typedef boost::shared_ptr DRTDoseIODPtr; - private: - /*! vector of DRTDoseIOD shared pointers, each DRTDoseIOD pointer presents the dose in one slice*/ - std::vector _doseVector; + private: + /*! vector of DRTDoseIOD shared pointers, each DRTDoseIOD pointer presents the dose in one slice*/ + std::vector _doseVector; - /*! vector of dose data(absolute Gy dose/doseGridScaling)*/ - std::vector _doseData; + /*! vector of dose data(absolute Gy dose/doseGridScaling)*/ + std::vector _doseData; - double _doseGridScaling; + double _doseGridScaling; - IDType _doseUID; + IDType _doseUID; - DicomHelaxDoseAccessor(); + DicomHelaxDoseAccessor(); - protected: - /*! @brief Initialize dose data - @exception InvalidDoseException Thrown if any DRTDoseIOD pointer of _doseVector is invalid: one of column/row/numberOfFrames/doseGridScaling/pixelSpacing=0 - @exception DcmrtException Throw if dcmrt error - @exception boost/bad_lexical_cast Thrown if the imported header tags are not numerical. - */ - bool begin(); + protected: + /*! @brief Initialize dose data + @exception InvalidDoseException Thrown if any DRTDoseIOD pointer of _doseVector is invalid: one of column/row/numberOfFrames/doseGridScaling/pixelSpacing=0 + @exception DcmrtException Throw if dcmrt error + @exception boost/bad_lexical_cast Thrown if the imported header tags are not numerical. + */ + bool begin(); - /*! @brief get all required data from dicom information contained in _dose - @exception boost/bad_lexical_cast Thrown if the imported header tags are not numerical. - */ - bool assembleGeometricInfo(); + /*! @brief get all required data from dicom information contained in _dose + @exception boost/bad_lexical_cast Thrown if the imported header tags are not numerical. + */ + bool assembleGeometricInfo(); - public: + public: - ~DicomHelaxDoseAccessor(); + ~DicomHelaxDoseAccessor(); - /*! @brief Constructor. Initialisation with a vector of DRTDoseIOD pointers - @exception InvalidDoseException Thrown if any DRTDoseIOD pointer of _doseVector is invalid: one of column/row/numberOfFrames/doseGridScaling/pixelSpacing=0 - @exception DcmrtException Throw if dcmrt error - */ - DicomHelaxDoseAccessor(std::vector aDICOMRTDoseVector); + /*! @brief Constructor. Initialisation with a vector of DRTDoseIOD pointers + @exception InvalidDoseException Thrown if any DRTDoseIOD pointer of _doseVector is invalid: one of column/row/numberOfFrames/doseGridScaling/pixelSpacing=0 + @exception DcmrtException Throw if dcmrt error + */ + DicomHelaxDoseAccessor(std::vector aDICOMRTDoseVector); - DoseTypeGy getDoseAt(const VoxelGridID aID) const; + GenericValueType getValueAt(const VoxelGridID aID) const; - DoseTypeGy getDoseAt(const VoxelGridIndex3D& aIndex) const; + GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const; - const IDType getDoseUID() const - { - return _doseUID; - }; - }; - } - } + const IDType getUID() const + { + return _doseUID; + }; + }; + } + } } #endif diff --git a/code/io/helax/rttbDicomHelaxFileDoseAccessorGenerator.cpp b/code/io/helax/rttbDicomHelaxFileDoseAccessorGenerator.cpp index afd5caf..2cecf9f 100644 --- a/code/io/helax/rttbDicomHelaxFileDoseAccessorGenerator.cpp +++ b/code/io/helax/rttbDicomHelaxFileDoseAccessorGenerator.cpp @@ -1,84 +1,91 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include #include "boost/filesystem/operations.hpp" #include "boost/filesystem/path.hpp" #include "boost/progress.hpp" #include "rttbDicomHelaxFileDoseAccessorGenerator.h" #include "rttbDicomHelaxDoseAccessor.h" #include "rttbInvalidDoseException.h" #include "rttbDcmrtException.h" #include "rttbIndexOutOfBoundsException.h" #include "rttbInvalidParameterException.h" #include "rttbDicomFileReaderHelper.h" -namespace rttb{ - namespace io{ - namespace helax{ - DicomHelaxFileDoseAccessorGenerator::~DicomHelaxFileDoseAccessorGenerator(){} +namespace rttb +{ + namespace io + { + namespace helax + { + DicomHelaxFileDoseAccessorGenerator::~DicomHelaxFileDoseAccessorGenerator() {} + + DicomHelaxFileDoseAccessorGenerator::DicomHelaxFileDoseAccessorGenerator(FileNameType aDICOMRTDoseDirName) + { + _doseDirName = aDICOMRTDoseDirName; - DicomHelaxFileDoseAccessorGenerator::DicomHelaxFileDoseAccessorGenerator(FileNameType aDICOMRTDoseDirName){ - _doseDirName=aDICOMRTDoseDirName; - } - core::DoseAccessorGeneratorInterface::DoseAccessorPointer DicomHelaxFileDoseAccessorGenerator::generateDoseAccessor() { - rttb::io::dicom::Modality doseModality= {rttb::io::dicom::Modality::RTDOSE}; + core::DoseAccessorGeneratorInterface::DoseAccessorPointer DicomHelaxFileDoseAccessorGenerator::generateDoseAccessor() + { + rttb::io::dicom::Modality doseModality = {rttb::io::dicom::Modality::RTDOSE}; std::vector fileVector = rttb::io::dicom::getFileNamesWithSameUID(_doseDirName, doseModality); OFCondition status; DcmFileFormat fileformat; std::vector doseVector; - for(int i=0; i(); + for (int i = 0; i < fileVector.size(); i++) + { + DRTDoseIODPtr dose = boost::make_shared(); status = fileformat.loadFile(fileVector.at(i).c_str()); - if (!status.good()) - { - throw core::InvalidDoseException("Error: load dose fileformat.loadFile failed!"); - } - - status = dose->read(*fileformat.getDataset()); - if(!status.good()) - { - throw core::InvalidDoseException("Error: read DRTDoseIOD failed!"); - } - - doseVector.push_back(dose); - } - - _doseAccessor=boost::make_shared(doseVector); + + if (!status.good()) + { + throw core::InvalidDoseException("Error: load dose fileformat.loadFile failed!"); + } + + status = dose->read(*fileformat.getDataset()); + + if (!status.good()) + { + throw core::InvalidDoseException("Error: read DRTDoseIOD failed!"); + } + + doseVector.push_back(dose); + } + + _doseAccessor = boost::make_shared(doseVector); return _doseAccessor; } } } } diff --git a/code/io/helax/rttbDicomHelaxFileDoseAccessorGenerator.h b/code/io/helax/rttbDicomHelaxFileDoseAccessorGenerator.h index 43017d1..a7aab3b 100644 --- a/code/io/helax/rttbDicomHelaxFileDoseAccessorGenerator.h +++ b/code/io/helax/rttbDicomHelaxFileDoseAccessorGenerator.h @@ -1,76 +1,79 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DICOM_HELAX_FILE_DOSE_ACCESSOR_GENERATOR_H #define __DICOM_HELAX_FILE_DOSE_ACCESSOR_GENERATOR_H #include #include #include #include "osconfig.h" /* make sure OS specific configuration is included first */ #include "drtdose.h" #include "rttbDoseAccessorGeneratorBase.h" #include "rttbBaseType.h" -namespace rttb{ - namespace io{ - namespace helax{ +namespace rttb +{ + namespace io + { + namespace helax + { - /*! @class DicomHelaxFileDoseAccessorGenerator + /*! @class DicomHelaxFileDoseAccessorGenerator @brief Load dose data from dicom helax files and generate DoseAccessor */ class DicomHelaxFileDoseAccessorGenerator: public core::DoseAccessorGeneratorBase { public: typedef boost::shared_ptr DRTDoseIODPtr; - + protected: private: FileNameType _doseDirName; DicomHelaxFileDoseAccessorGenerator(); - public: + public: ~DicomHelaxFileDoseAccessorGenerator(); /*! @brief Constructor. Initialisation with a directory name - + */ DicomHelaxFileDoseAccessorGenerator(FileNameType aDICOMRTDoseDirName); - /*! @brief Generate DoseAccessor - @return Return shared pointer of DoseAccessor. - @exception InvalidParameterException Thrown if aDICOMRTDoseDirName is not found + /*! @brief Generate DoseAccessor + @return Return shared pointer of DoseAccessor. + @exception InvalidParameterException Thrown if aDICOMRTDoseDirName is not found @exception InvalidDoseException Thrown if any loaded dose is invalid: one of column/row/numberOfFrames/doseGridScaling/pixelSpacing=0 @exception DcmrtException Throw if dcmrt error */ DoseAccessorPointer generateDoseAccessor() ; }; } } } #endif diff --git a/code/io/helax/rttbDicomHelaxIODVecDoseAccessorGenerator.cpp b/code/io/helax/rttbDicomHelaxIODVecDoseAccessorGenerator.cpp index a008f05..355fa9b 100644 --- a/code/io/helax/rttbDicomHelaxIODVecDoseAccessorGenerator.cpp +++ b/code/io/helax/rttbDicomHelaxIODVecDoseAccessorGenerator.cpp @@ -1,57 +1,63 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include #include "boost/filesystem/operations.hpp" #include "boost/filesystem/path.hpp" #include "boost/progress.hpp" #include "rttbDicomHelaxIODVecDoseAccessorGenerator.h" #include "rttbDicomHelaxDoseAccessor.h" #include "rttbInvalidDoseException.h" #include "rttbDcmrtException.h" #include "rttbIndexOutOfBoundsException.h" #include "rttbInvalidParameterException.h" -namespace rttb{ - namespace io{ - namespace helax{ +namespace rttb +{ + namespace io + { + namespace helax + { - DicomHelaxIODVecDoseAccessorGenerator::~DicomHelaxIODVecDoseAccessorGenerator(){} + DicomHelaxIODVecDoseAccessorGenerator::~DicomHelaxIODVecDoseAccessorGenerator() {} + + DicomHelaxIODVecDoseAccessorGenerator::DicomHelaxIODVecDoseAccessorGenerator(std::vector& + aDICOMRTDoseVector) + { + _dosePtrVector = aDICOMRTDoseVector; - DicomHelaxIODVecDoseAccessorGenerator::DicomHelaxIODVecDoseAccessorGenerator(std::vector& aDICOMRTDoseVector){ - _dosePtrVector=aDICOMRTDoseVector; - } - core::DoseAccessorGeneratorInterface::DoseAccessorPointer DicomHelaxIODVecDoseAccessorGenerator::generateDoseAccessor() { - _doseAccessor=boost::make_shared(_dosePtrVector); + core::DoseAccessorGeneratorInterface::DoseAccessorPointer DicomHelaxIODVecDoseAccessorGenerator::generateDoseAccessor() + { + _doseAccessor = boost::make_shared(_dosePtrVector); return _doseAccessor; } } } } diff --git a/code/io/helax/rttbDicomHelaxIODVecDoseAccessorGenerator.h b/code/io/helax/rttbDicomHelaxIODVecDoseAccessorGenerator.h index 8ea5ba4..2aecfdb 100644 --- a/code/io/helax/rttbDicomHelaxIODVecDoseAccessorGenerator.h +++ b/code/io/helax/rttbDicomHelaxIODVecDoseAccessorGenerator.h @@ -1,74 +1,77 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DICOM_HELAX_IOD_VEC_DOSE_ACCESSOR_GENERATOR_H #define __DICOM_HELAX_IOD_VEC_DOSE_ACCESSOR_GENERATOR_H #include #include #include #include "osconfig.h" /* make sure OS specific configuration is included first */ #include "drtdose.h" #include "rttbDoseAccessorGeneratorBase.h" #include "rttbBaseType.h" -namespace rttb{ - namespace io{ - namespace helax{ +namespace rttb +{ + namespace io + { + namespace helax + { - /*! @class DicomHelaxIODVecDoseAccessorGenerator + /*! @class DicomHelaxIODVecDoseAccessorGenerator @brief Generate DoseAccessor with a vector of DRTDoseIOD. */ class DicomHelaxIODVecDoseAccessorGenerator: public core::DoseAccessorGeneratorBase { public: typedef boost::shared_ptr DRTDoseIODPtr; - + protected: private: std::vector _dosePtrVector; DicomHelaxIODVecDoseAccessorGenerator(); - public: + public: ~DicomHelaxIODVecDoseAccessorGenerator(); /*! @brief Constructor. Initialisation with a vector of DRTDoseIOD pointers - + */ DicomHelaxIODVecDoseAccessorGenerator(std::vector& aDICOMRTDoseVector); - /*! @brief Generate DoseAccessor - @return Return shared pointer of DoseAccessor. + /*! @brief Generate DoseAccessor + @return Return shared pointer of DoseAccessor. @exception InvalidDoseException Thrown if any DRTDoseIOD pointer of _doseVector is invalid: one of column/row/numberOfFrames/doseGridScaling/pixelSpacing=0 @exception DcmrtException Throw if dcmrt error */ DoseAccessorPointer generateDoseAccessor() ; }; } } } #endif diff --git a/code/io/itk/files.cmake b/code/io/itk/files.cmake index 6930adc..ec508f0 100644 --- a/code/io/itk/files.cmake +++ b/code/io/itk/files.cmake @@ -1,38 +1,38 @@ SET(CPP_FILES rttbFileDispatch.cpp rttbGenericImageReader.cpp rttbImageWriter.cpp rttbITKException.cpp - rttbITKImageDoseAccessor.cpp - rttbITKImageDoseAccessorConverter.cpp - rttbITKImageDoseAccessorGenerator.cpp - rttbITKImageFileDoseAccessorGenerator.cpp + rttbITKImageAccessor.cpp + rttbITKImageAccessorConverter.cpp + rttbITKImageAccessorGenerator.cpp + rttbITKImageFileAccessorGenerator.cpp rttbITKImageFileMaskAccessorGenerator.cpp rttbITKImageMaskAccessor.cpp rttbITKImageMaskAccessorGenerator.cpp rttbITKImageMaskAccessorConverter.cpp rttbITKIOHelper.cpp ) SET(H_FILES rttbDoseAccessorConversionSettingInterface.h rttbDoseAccessorProcessorBase.h rttbDoseAccessorProcessorInterface.h rttbFileDispatch.h rttbGenericImageReader.h rttbImageReader.h rttbImageReader.tpp rttbImageWriter.h rttbITKException.h - rttbITKImageDoseAccessor.h - rttbITKImageDoseAccessorConverter.h - rttbITKImageDoseAccessorGenerator.h - rttbITKImageFileDoseAccessorGenerator.h + rttbITKImageAccessor.h + rttbITKImageAccessorConverter.h + rttbITKImageAccessorGenerator.h + rttbITKImageFileAccessorGenerator.h rttbITKImageFileMaskAccessorGenerator.h rttbITKImageMaskAccessor.h rttbITKImageMaskAccessorConverter.h rttbITKImageMaskAccessorGenerator.h rttbITKIOHelper.h rttbITKIOHelper.tpp ) diff --git a/code/io/itk/rttbITKIOHelper.cpp b/code/io/itk/rttbITKIOHelper.cpp index 5ad1001..22bd16a 100644 --- a/code/io/itk/rttbITKIOHelper.cpp +++ b/code/io/itk/rttbITKIOHelper.cpp @@ -1,168 +1,170 @@ // ----------------------------------------------------------------------- // 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) */ #include "rttbITKIOHelper.h" #include "rttbException.h" #include "rttbInvalidDoseException.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace io { namespace itk { - ITKDoseImageType::Pointer readITKDoubleImage(FileNameType aITKImageFile){ - ITKDoseImageType::Pointer itkDoubleImage; + ITKImageType::Pointer readITKDoubleImage(FileNameType aITKImageFile) + { + ITKImageType::Pointer itkDoubleImage; GenericImageReader::Pointer spReader = GenericImageReader::New(); spReader->setFileName(aITKImageFile); GenericImageReader::GenericOutputImageType::Pointer itkGenericImage; - ITKDoseImageType::ConstPointer itkDoubleImageConst; + ITKImageType::ConstPointer itkDoubleImageConst; try { unsigned int loadedDimensions; GenericImageReader::LoadedPixelType loadedPixelType; GenericImageReader::LoadedComponentType loadedComponentType; itkGenericImage = spReader->GetOutput(loadedDimensions, loadedPixelType, loadedComponentType); if (loadedDimensions != 3) { throw core::InvalidParameterException("image dimensions != 3. Only dim = 3 supported."); } if (loadedPixelType != ::itk::ImageIOBase::SCALAR) { throw core::InvalidParameterException("image component type != SCALAR. Only SCALAR supported."); } if (loadedComponentType == ::itk::ImageIOBase::DOUBLE) { - itkDoubleImage = dynamic_cast(itkGenericImage.GetPointer()); + itkDoubleImage = dynamic_cast(itkGenericImage.GetPointer()); } else { itkDoubleImage = handleGenericImage(itkGenericImage, loadedComponentType); } if (itkDoubleImage.IsNull()) { throw core::InvalidDoseException("Error!!! unable to load input image. File is not existing or has an unsupported format."); } } catch (::itk::ExceptionObject& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e << std::endl; throw rttb::core::InvalidDoseException(e.GetDescription()); } return itkDoubleImage; } - ITKDoseImageType::Pointer handleGenericImage( - GenericImageReader::GenericOutputImageType* itkGenericImage, - ::itk::ImageIOBase::IOComponentType& loadedComponentType) + ITKImageType::Pointer handleGenericImage( + GenericImageReader::GenericOutputImageType* itkGenericImage, + ::itk::ImageIOBase::IOComponentType& loadedComponentType) { - ITKDoseImageType::Pointer itkDoubleImage; + ITKImageType::Pointer itkDoubleImage; switch (loadedComponentType) { - case ::itk::ImageIOBase::UCHAR: + case ::itk::ImageIOBase::UCHAR: { itkDoubleImage = doCasting(itkGenericImage); break; } - case ::itk::ImageIOBase::CHAR: + case ::itk::ImageIOBase::CHAR: { itkDoubleImage = doCasting(itkGenericImage); break; } - case ::itk::ImageIOBase::USHORT: + case ::itk::ImageIOBase::USHORT: { itkDoubleImage = doCasting(itkGenericImage); break; } - case ::itk::ImageIOBase::SHORT: + case ::itk::ImageIOBase::SHORT: { itkDoubleImage = doCasting(itkGenericImage); break; } - case ::itk::ImageIOBase::UINT: + case ::itk::ImageIOBase::UINT: { itkDoubleImage = doCasting(itkGenericImage); break; } - case ::itk::ImageIOBase::INT: + case ::itk::ImageIOBase::INT: { itkDoubleImage = doCasting(itkGenericImage); break; } - case ::itk::ImageIOBase::ULONG: + case ::itk::ImageIOBase::ULONG: { itkDoubleImage = doCasting(itkGenericImage); break; } - case ::itk::ImageIOBase::LONG: + case ::itk::ImageIOBase::LONG: { itkDoubleImage = doCasting(itkGenericImage); break; } - case ::itk::ImageIOBase::FLOAT: + case ::itk::ImageIOBase::FLOAT: { itkDoubleImage = doCasting(itkGenericImage); break; } - case ::itk::ImageIOBase::DOUBLE: + case ::itk::ImageIOBase::DOUBLE: { itkDoubleImage = doCasting(itkGenericImage); break; } - default: + default: { throw core::InvalidParameterException("image type unknown"); } } + return itkDoubleImage; } }//end namespace itk }//end namespace io }//end namespace rttb diff --git a/code/io/itk/rttbITKIOHelper.h b/code/io/itk/rttbITKIOHelper.h index 7b4069b..e8a1036 100644 --- a/code/io/itk/rttbITKIOHelper.h +++ b/code/io/itk/rttbITKIOHelper.h @@ -1,64 +1,65 @@ // ----------------------------------------------------------------------- // 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 __ITK_IO_HELPER_H #define __ITK_IO_HELPER_H #include "rttbDoseAccessorGeneratorBase.h" #include "rttbBaseType.h" -#include "rttbITKImageDoseAccessor.h" +#include "rttbITKImageAccessorConverter.h" #include "rttbGenericImageReader.h" #include "itkImage.h" #include "itkCastImageFilter.h" namespace rttb { namespace io { namespace itk { - - /*! @brief Read a itk image file into itkImage - */ - ITKDoseImageType::Pointer readITKDoubleImage(FileNameType aITKImageFile); + typedef ::itk::Image ITKImageType; + /*! @brief Read a itk image file into itkImage + */ + ITKImageType::Pointer readITKDoubleImage(FileNameType aITKImageFile); - /*! @brief Converts a generic image to itkImage - @param itkGenericImage the image read by GenericImageReader - @param loadedComponentType the component type (used for casting later on) - @exception InvalidParameterException if component type is not supported - @sa GenericImageReader - */ - ITKDoseImageType::Pointer handleGenericImage(GenericImageReader::GenericOutputImageType* itkGenericImage, - ::itk::ImageIOBase::IOComponentType& loadedComponentType); + /*! @brief Converts a generic image to itkImage + @param itkGenericImage the image read by GenericImageReader + @param loadedComponentType the component type (used for casting later on) + @exception InvalidParameterException if component type is not supported + @sa GenericImageReader + */ + ITKImageType::Pointer handleGenericImage(GenericImageReader::GenericOutputImageType* itkGenericImage, + ::itk::ImageIOBase::IOComponentType& loadedComponentType); + + /*! @brief Casts into itkImage + */ + template ITKImageType::Pointer doCasting(GenericImageReader::GenericOutputImageType* + genericImage); - /*! @brief Casts into itkImage - */ - template ITKDoseImageType::Pointer doCasting(GenericImageReader::GenericOutputImageType* genericImage); - }//end namespace itk }//end namespace io }//end namespace rttb #include "rttbITKIOHelper.tpp" #endif diff --git a/code/io/itk/rttbITKIOHelper.tpp b/code/io/itk/rttbITKIOHelper.tpp index 38be7e4..4fa5ccd 100644 --- a/code/io/itk/rttbITKIOHelper.tpp +++ b/code/io/itk/rttbITKIOHelper.tpp @@ -1,66 +1,66 @@ // ----------------------------------------------------------------------- // MatchPoint - DKFZ translational registration framework // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See mapCopyright.txt or // http://www.dkfz.de/en/sidt/projects/MatchPoint/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) // Subversion HeadURL: $HeadURL: https://svn/sbr/Sources/SBR-Projects/MatchPoint/trunk/Code/IO/include/mapImageReader.tpp $ */ -#ifndef __RTTB_ITK_IMAGE_FILE_DOSE_ACCESSOR_GENERATOR_TPP -#define __RTTB_ITK_IMAGE_FILE_DOSE_ACCESSOR_GENERATOR_TPP +#ifndef __RTTB_ITK_IO_HELPER_TPP +#define __RTTB_ITK_IO_HELPER_TPP -#include "rttbITKImageFileDoseAccessorGenerator.h" +#include "rttbITKImageAccessorConverter.h" #include "rttbInvalidParameterException.h" #include "rttbInvalidDoseException.h" -#include "rttbITKImageDoseAccessor.h" +#include "rttbITKImageAccessor.h" namespace rttb { namespace io { namespace itk { - template ITKDoseImageType::Pointer doCasting(GenericImageReader::GenericOutputImageType* genericImage) + template ITKImageType::Pointer doCasting(GenericImageReader::GenericOutputImageType* genericImage) { - ITKDoseImageType::Pointer itkDoubleImage; + ITKImageType::Pointer itkDoubleImage; typedef ::itk::Image InputImageType; - typedef ITKDoseImageType OutputImageType; + typedef ITKImageType OutputImageType; typename InputImageType::Pointer pCastedInput = dynamic_cast(genericImage); typedef ::itk::CastImageFilter CastFilterType; typename CastFilterType::Pointer castFilter = CastFilterType::New(); castFilter->SetInput(pCastedInput); try { //important to update the filter! castFilter->Update(); itkDoubleImage = castFilter->GetOutput(); } catch (::itk::ExceptionObject& e) { std::cerr << "ITK Error!!!" << std::endl; std::cerr << e << std::endl; } return itkDoubleImage; } } } } #endif diff --git a/code/io/itk/rttbITKImageDoseAccessor.cpp b/code/io/itk/rttbITKImageAccessor.cpp similarity index 55% rename from code/io/itk/rttbITKImageDoseAccessor.cpp rename to code/io/itk/rttbITKImageAccessor.cpp index 51870de..5d02ee6 100644 --- a/code/io/itk/rttbITKImageDoseAccessor.cpp +++ b/code/io/itk/rttbITKImageAccessor.cpp @@ -1,119 +1,118 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) -// @date $Date$ (last change date) -// @author $Author$ (last changed by) +// @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) */ #include -#include "rttbITKImageDoseAccessor.h" +#include "rttbITKImageAccessor.h" #include "rttbException.h" #include "rttbInvalidDoseException.h" namespace rttb { namespace io { namespace itk { - ITKImageDoseAccessor::~ITKImageDoseAccessor() + ITKImageAccessor::~ITKImageAccessor() { } - ITKImageDoseAccessor::ITKImageDoseAccessor(ITKDoseImageType::ConstPointer doseImage): - _doseGridScaling(1.0) + ITKImageAccessor::ITKImageAccessor(ITKImageType::ConstPointer image) { - _dose = doseImage; + _data = image; - if (_dose.IsNull()) + if (_data.IsNull()) { throw core::InvalidDoseException("Dose image = 0!") ; } assembleGeometricInfo(); } - DoseTypeGy ITKImageDoseAccessor::getDoseAt(const VoxelGridID aID) const + GenericValueType ITKImageAccessor::getValueAt(const VoxelGridID aID) const { VoxelGridIndex3D aVoxelGridIndex; if (_geoInfo.convert(aID, aVoxelGridIndex)) { - return getDoseAt(aVoxelGridIndex); + return getValueAt(aVoxelGridIndex); } else { return -1; } } - DoseTypeGy ITKImageDoseAccessor::getDoseAt(const VoxelGridIndex3D& aIndex) const + GenericValueType ITKImageAccessor::getValueAt(const VoxelGridIndex3D& aIndex) const { if (_geoInfo.validIndex(aIndex)) { - const ITKDoseImageType::IndexType pixelIndex = {{aIndex[0], aIndex[1], aIndex[2]}}; - return _dose->GetPixel(pixelIndex) * _doseGridScaling; + const ITKImageType::IndexType pixelIndex = {{aIndex[0], aIndex[1], aIndex[2]}}; + return _data->GetPixel(pixelIndex); } else { return -1; } } - bool ITKImageDoseAccessor::assembleGeometricInfo() + bool ITKImageAccessor::assembleGeometricInfo() { - _geoInfo.setSpacing(SpacingVectorType3D(_dose->GetSpacing()[0], _dose->GetSpacing()[1], - _dose->GetSpacing()[2])); + _geoInfo.setSpacing(SpacingVectorType3D(_data->GetSpacing()[0], _data->GetSpacing()[1], + _data->GetSpacing()[2])); if (_geoInfo.getSpacing()[0] == 0 || _geoInfo.getSpacing()[1] == 0 || _geoInfo.getSpacing()[2] == 0) { throw core::InvalidDoseException("Pixel spacing = 0!"); } - _geoInfo.setImagePositionPatient(WorldCoordinate3D(_dose->GetOrigin()[0], _dose->GetOrigin()[1], - _dose->GetOrigin()[2])); + _geoInfo.setImagePositionPatient(WorldCoordinate3D(_data->GetOrigin()[0], _data->GetOrigin()[1], + _data->GetOrigin()[2])); OrientationMatrix OM(0); for (int col = 0; col < 3; ++col) { for (int row = 0; row < 3; ++row) { - OM(col, row) = _dose->GetDirection()(col, row); + OM(col, row) = _data->GetDirection()(col, row); } } _geoInfo.setOrientationMatrix(OM); - _geoInfo.setNumColumns(_dose->GetLargestPossibleRegion().GetSize()[0]); - _geoInfo.setNumRows(_dose->GetLargestPossibleRegion().GetSize()[1]); - _geoInfo.setNumSlices(_dose->GetLargestPossibleRegion().GetSize()[2]); + _geoInfo.setNumColumns(_data->GetLargestPossibleRegion().GetSize()[0]); + _geoInfo.setNumRows(_data->GetLargestPossibleRegion().GetSize()[1]); + _geoInfo.setNumSlices(_data->GetLargestPossibleRegion().GetSize()[2]); if (_geoInfo.getNumColumns() == 0 || _geoInfo.getNumRows() == 0 || _geoInfo.getNumSlices() == 0) { throw core::InvalidDoseException("Empty dicom dose!") ; } return true; } } } } diff --git a/code/io/itk/rttbITKImageAccessor.h b/code/io/itk/rttbITKImageAccessor.h new file mode 100644 index 0000000..89bbb62 --- /dev/null +++ b/code/io/itk/rttbITKImageAccessor.h @@ -0,0 +1,92 @@ +// ----------------------------------------------------------------------- +// 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: 1066 $ (last changed revision) +// @date $Date: 2015-08-19 11:47:07 +0200 (Mi, 19 Aug 2015) $ (last change date) +// @author $Author: floca $ (last changed by) +*/ +#ifndef __ITK_IMAGE_ACCESSOR_H +#define __ITK_IMAGE_ACCESSOR_H + +#include + +#include + +#include "rttbAccessorWithGeoInfoBase.h" +#include "rttbGeometricInfo.h" +#include "rttbBaseType.h" + +#include "itkImage.h" + +namespace rttb +{ + namespace io + { + namespace itk + { + /*! @class ITKImageAccessor + @brief This class gives access to information stored in an itk image + @details There is no value scaling, i.e., it is assumed that the values in the itkImage are absolute. + */ + class ITKImageAccessor: public core::AccessorWithGeoInfoBase + { + public: + typedef ::itk::Image ITKImageType; + private: + /** @brief The dose as itkImage */ + ITKImageType::ConstPointer _data; + + IDType _UID; + + /*! @brief constructor + @exception InvalidDoseException if _dose is NULL + */ + ITKImageAccessor(); + + /*! @brief get all required data from the itk image contained in _dose + @exception InvalidDoseException if PixelSpacing is 0 or size in any dimension is 0. + */ + bool assembleGeometricInfo(); + + + public: + ~ITKImageAccessor(); + + /*! @brief Constructor. Initialization with a itk image + @pre image must be a valid instance (and not null) + @note the doseImage pixels are assumed absolute + */ + ITKImageAccessor(ITKImageType::ConstPointer image); + + /*! @brief returns the dose for an id + */ + GenericValueType getValueAt(const VoxelGridID aID) const; + + /*! @brief returns the dose for an index + */ + GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const; + + const IDType getUID() const + { + return _UID; + }; + + }; + } + } +} + +#endif diff --git a/code/io/itk/rttbITKImageDoseAccessorConverter.cpp b/code/io/itk/rttbITKImageAccessorConverter.cpp similarity index 74% rename from code/io/itk/rttbITKImageDoseAccessorConverter.cpp rename to code/io/itk/rttbITKImageAccessorConverter.cpp index 0660866..da9d2b4 100644 --- a/code/io/itk/rttbITKImageDoseAccessorConverter.cpp +++ b/code/io/itk/rttbITKImageAccessorConverter.cpp @@ -1,135 +1,135 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) -// @date $Date$ (last change date) -// @author $Author$ (last changed by) +// @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 "rttbITKImageDoseAccessorConverter.h" +#include "rttbITKImageAccessorConverter.h" #include "rttbException.h" #include "rttbInvalidDoseException.h" #include "rttbGeometricInfo.h" #include "itkImageRegionIterator.h" namespace rttb { namespace io { namespace itk { - ITKImageDoseAccessorConverter::ITKImageDoseAccessorConverter(DoseAccessorPointer accessor) + ITKImageAccessorConverter::ITKImageAccessorConverter(DoseAccessorPointer accessor) { setDoseAccessor(accessor); } - bool ITKImageDoseAccessorConverter::process() + bool ITKImageAccessorConverter::process() { //Transfer GeometricInfo to ITK Properties core::GeometricInfo geoInfo = _doseAccessor->getGeometricInfo(); - ITKDoseImageType::RegionType region; - ITKDoseImageType::IndexType start; + ITKImageType::RegionType region; + ITKImageType::IndexType start; for (unsigned int i = 0; i < 3; ++i) { start[i] = 0; } - ITKDoseImageType::SizeType size; + ITKImageType::SizeType size; size[0] = geoInfo.getNumColumns(); size[1] = geoInfo.getNumRows(); size[2] = geoInfo.getNumSlices(); - ITKDoseImageType::SpacingType spacing; + ITKImageType::SpacingType spacing; for (unsigned int i = 0; i < 3; ++i) { spacing[i] = geoInfo.getSpacing()[i]; } - ITKDoseImageType::PointType origin; + ITKImageType::PointType origin; for (unsigned int i = 0; i < 3; ++i) { origin[i] = geoInfo.getImagePositionPatient()[i]; } - ITKDoseImageType::DirectionType direction; + ITKImageType::DirectionType direction; OrientationMatrix OM = geoInfo.getOrientationMatrix(); for (int col = 0; col < 3; ++col) { for (int row = 0; row < 3; ++row) { direction(col, row) = OM(col, row); } } //Create image, assign properties region.SetSize(size); region.SetIndex(start); - _itkImage = ITKDoseImageType::New(); + _itkImage = ITKImageType::New(); _itkImage->SetRegions(region); _itkImage->SetSpacing(spacing); _itkImage->SetDirection(direction); _itkImage->SetOrigin(origin); _itkImage->Allocate(); - ::itk::ImageRegionIterator imageIterator(_itkImage, region); + ::itk::ImageRegionIterator imageIterator(_itkImage, region); VoxelGridID id = 0; //Transfer dose values to itk image //Large advantage: rttbVoxelGridId ordering is the same as itk ordering while (!imageIterator.IsAtEnd()) { VoxelGridIndex3D aIndex; if (_doseAccessor->getGeometricInfo().validID(id)) { // Set the current pixel - imageIterator.Set(_doseAccessor->getDoseAt(id)); + imageIterator.Set(_doseAccessor->getValueAt(id)); } else { if (failsOnInvalidIDs()) { throw core::InvalidDoseException("invalid dose id!"); return false; } else { imageIterator.Set(_invalidDoseValue); } } ++imageIterator; ++id; } return true; } }//end namespace itk }//end namespace io }//end namespace rttb diff --git a/code/io/itk/rttbITKImageDoseAccessorConverter.h b/code/io/itk/rttbITKImageAccessorConverter.h similarity index 55% rename from code/io/itk/rttbITKImageDoseAccessorConverter.h rename to code/io/itk/rttbITKImageAccessorConverter.h index 9f46e27..d05a547 100644 --- a/code/io/itk/rttbITKImageDoseAccessorConverter.h +++ b/code/io/itk/rttbITKImageAccessorConverter.h @@ -1,68 +1,71 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) -// @date $Date$ (last change date) -// @author $Author$ (last changed by) +// @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 __ITK_IMAGE_DOSE_ACCESSOR_CONVERTER_H -#define __ITK_IMAGE_DOSE_ACCESSOR_CONVERTER_H +#ifndef __ITK_IMAGE_ACCESSOR_CONVERTER_H +#define __ITK_IMAGE_ACCESSOR_CONVERTER_H #include #include "rttbDoseAccessorProcessorBase.h" #include "rttbDoseAccessorConversionSettingInterface.h" -#include "rttbITKImageDoseAccessor.h" +#include "rttbITKImageAccessorConverter.h" + +#include "itkImage.h" namespace rttb { namespace io { namespace itk { - /*! @class ITKImageDoseAccessorConverter + /*! @class ITKImageAccessorConverter @brief Class converts/dumps the processed accessor into an itk image @remark DoseAccessorConversionInterface defines how the converter should react on non valid dose values. */ - class ITKImageDoseAccessorConverter: public core::DoseAccessorProcessorBase, + class ITKImageAccessorConverter: public core::DoseAccessorProcessorBase, public core::DoseAccessorConversionSettingInterface { public: + typedef ::itk::Image ITKImageType; typedef core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; bool process(); - ITKDoseImageType::Pointer getITKImage() + ITKImageType::Pointer getITKImage() { return _itkImage; } - ITKImageDoseAccessorConverter(DoseAccessorPointer accessor); - virtual ~ITKImageDoseAccessorConverter() {}; + ITKImageAccessorConverter(DoseAccessorPointer accessor); + virtual ~ITKImageAccessorConverter() {}; private: - ITKImageDoseAccessorConverter(const - ITKImageDoseAccessorConverter&); //not implemented on purpose -> non-copyable - ITKImageDoseAccessorConverter& operator=(const - ITKImageDoseAccessorConverter&);//not implemented on purpose -> non-copyable + ITKImageAccessorConverter(const + ITKImageAccessorConverter&); //not implemented on purpose -> non-copyable + ITKImageAccessorConverter& operator=(const + ITKImageAccessorConverter&);//not implemented on purpose -> non-copyable - ITKDoseImageType::Pointer _itkImage; + ITKImageType::Pointer _itkImage; }; } } } #endif diff --git a/code/io/itk/rttbITKImageDoseAccessorGenerator.cpp b/code/io/itk/rttbITKImageAccessorGenerator.cpp similarity index 64% rename from code/io/itk/rttbITKImageDoseAccessorGenerator.cpp rename to code/io/itk/rttbITKImageAccessorGenerator.cpp index b870a98..5ec5802 100644 --- a/code/io/itk/rttbITKImageDoseAccessorGenerator.cpp +++ b/code/io/itk/rttbITKImageAccessorGenerator.cpp @@ -1,52 +1,59 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) -// @date $Date$ (last change date) -// @author $Author$ (last changed by) +// @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) */ #include #include #include -#include "rttbITKImageDoseAccessorGenerator.h" +#include "rttbITKImageAccessor.h" +#include "rttbITKImageAccessorGenerator.h" #include "rttbException.h" #include "rttbInvalidDoseException.h" -namespace rttb{ - namespace io{ - namespace itk{ +namespace rttb +{ + namespace io + { + namespace itk + { - ITKImageDoseAccessorGenerator::ITKImageDoseAccessorGenerator(const ITKDoseImageType* aDoseImage){ - if (aDoseImage == NULL){ + ITKImageAccessorGenerator::ITKImageAccessorGenerator(const ITKImageType* aDoseImage) + { + if (aDoseImage == NULL) + { throw core::InvalidDoseException("doseImage is NULL"); } _dosePtr = aDoseImage; } - core::DoseAccessorGeneratorBase::DoseAccessorPointer ITKImageDoseAccessorGenerator::generateDoseAccessor(){ - _doseAccessor=boost::make_shared(_dosePtr); + core::DoseAccessorGeneratorBase::DoseAccessorPointer ITKImageAccessorGenerator::generateDoseAccessor() + { + _doseAccessor = boost::make_shared(_dosePtr); return _doseAccessor; } }//end namespace itk }//end namespace io }//end namespace rttb diff --git a/code/io/itk/rttbITKImageDoseAccessorGenerator.h b/code/io/itk/rttbITKImageAccessorGenerator.h similarity index 59% rename from code/io/itk/rttbITKImageDoseAccessorGenerator.h rename to code/io/itk/rttbITKImageAccessorGenerator.h index c040b45..b15677f 100644 --- a/code/io/itk/rttbITKImageDoseAccessorGenerator.h +++ b/code/io/itk/rttbITKImageAccessorGenerator.h @@ -1,73 +1,71 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) -// @date $Date$ (last change date) -// @author $Author$ (last changed by) +// @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 __ITK_IMAGE_DOSE_ACCESSOR_GENERATOR_H -#define __ITK_IMAGE_DOSE_ACCESSOR_GENERATOR_H - -#include -#include +#ifndef __ITK_IMAGE_ACCESSOR_GENERATOR_H +#define __ITK_IMAGE_ACCESSOR_GENERATOR_H #include "rttbDoseAccessorGeneratorBase.h" #include "rttbBaseType.h" -#include "rttbITKImageDoseAccessor.h" +#include "rttbITKImageAccessorConverter.h" #include "itkImage.h" namespace rttb { namespace io { namespace itk { - /*! @class ITKImageDoseAccessorGenerator - @brief Generate ITKImageDoseAccessor wrapping an itk image as object (not as file). - @note it implies that the dose information is stored in absolute Gy values. + /*! @class ITKImageAccessorGenerator + @brief Generate ITKImageAccessor wrapping an itk image as object (not as file). + @note it implies that the information is stored in absolute values. */ - class ITKImageDoseAccessorGenerator: public core::DoseAccessorGeneratorBase + class ITKImageAccessorGenerator: public core::DoseAccessorGeneratorBase { public: + typedef ::itk::Image ITKImageType; typedef DoseAccessorGeneratorBase::DoseAccessorPointer DoseAccessorPointer; private: /** @brief The dose as itkImage */ - ITKDoseImageType::ConstPointer _dosePtr; + ITKImageType::ConstPointer _dosePtr; - ITKImageDoseAccessorGenerator(); + ITKImageAccessorGenerator(); public: - virtual ~ITKImageDoseAccessorGenerator() {}; + virtual ~ITKImageAccessorGenerator() {}; /*! @pre aDoseImage must point to a valid instance. @exception InvalidDoseException Thrown if aDoseImage is invalid. */ - ITKImageDoseAccessorGenerator(const ITKDoseImageType* aDoseImage); + ITKImageAccessorGenerator(const ITKImageType* aDoseImage); /*! @brief Generate DoseAccessor @return Return shared pointer of DoseAccessor. */ DoseAccessorPointer generateDoseAccessor() ; }; } } } #endif diff --git a/code/io/itk/rttbITKImageDoseAccessor.h b/code/io/itk/rttbITKImageDoseAccessor.h deleted file mode 100644 index 85c9255..0000000 --- a/code/io/itk/rttbITKImageDoseAccessor.h +++ /dev/null @@ -1,97 +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$ (last changed revision) -// @date $Date$ (last change date) -// @author $Author$ (last changed by) -*/ -#ifndef __ITK_DOSE_ACCESSOR_H -#define __ITK_DOSE_ACCESSOR_H - -#include - -#include - -#include "rttbDoseAccessorWithGeoInfoBase.h" -#include "rttbGeometricInfo.h" -#include "rttbBaseType.h" - -#include "itkImage.h" - -namespace rttb -{ - namespace io - { - namespace itk - { - typedef ::itk::Image ITKDoseImageType; - typedef ::itk::ImageBase<3> ITKImageBaseType; - /*! @class ITKImageDoseAccessor - @brief This class gives access to dose information stored in an itk image - @details _doseGridScaling is always 1.0. Thus, it is assumed that the values in the itkImage are absolute. - */ - class ITKImageDoseAccessor: public core::DoseAccessorWithGeoInfoBase - { - private: - /** @brief The dose as itkImage */ - ITKDoseImageType::ConstPointer _dose; - - IDType _doseUID; - - /** @brief The dosegridscaling - * @note is always 1.0 - */ - double _doseGridScaling; - - /*! @brief constructor - @exception InvalidDoseException if _dose is NULL - */ - ITKImageDoseAccessor(); - - /*! @brief get all required data from the itk image contained in _dose - @exception InvalidDoseException if PixelSpacing is 0 or size in any dimension is 0. - */ - bool assembleGeometricInfo(); - - - public: - ~ITKImageDoseAccessor(); - - /*! @brief Constructor. Initialization with a itk image containing the dose - @pre doseImage must be a valid instance (and not null) - @note the doseImage pixels are dose (i.e. _doseGridScaling=1.0 is assumed always) - */ - ITKImageDoseAccessor(ITKDoseImageType::ConstPointer doseImage); - - /*! @brief returns the dose for an id - */ - DoseTypeGy getDoseAt(const VoxelGridID aID) const; - - /*! @brief returns the dose for an index - */ - DoseTypeGy getDoseAt(const VoxelGridIndex3D& aIndex) const; - - const IDType getDoseUID() const - { - return _doseUID; - }; - - }; - } - } -} - -#endif diff --git a/code/io/itk/rttbITKImageFileDoseAccessorGenerator.cpp b/code/io/itk/rttbITKImageFileAccessorGenerator.cpp similarity index 57% rename from code/io/itk/rttbITKImageFileDoseAccessorGenerator.cpp rename to code/io/itk/rttbITKImageFileAccessorGenerator.cpp index dd9deee..edd0378 100644 --- a/code/io/itk/rttbITKImageFileDoseAccessorGenerator.cpp +++ b/code/io/itk/rttbITKImageFileAccessorGenerator.cpp @@ -1,60 +1,58 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) -// @date $Date$ (last change date) -// @author $Author$ (last changed by) +// @version $Revision: 995 $ (last changed revision) +// @date $Date: 2015-06-17 12:58:33 +0200 (Mi, 17 Jun 2015) $ (last change date) +// @author $Author: hentsch $ (last changed by) */ #include #include -#include "rttbITKImageFileDoseAccessorGenerator.h" -#include "rttbException.h" -#include "rttbInvalidDoseException.h" -#include "rttbInvalidParameterException.h" +#include "rttbITKImageFileAccessorGenerator.h" +#include "rttbITKImageAccessorConverter.h" #include "rttbITKIOHelper.h" namespace rttb { namespace io { namespace itk { - ITKImageFileDoseAccessorGenerator::~ITKImageFileDoseAccessorGenerator() + ITKImageFileAccessorGenerator::~ITKImageFileAccessorGenerator() { } - ITKImageFileDoseAccessorGenerator::ITKImageFileDoseAccessorGenerator(const FileNameType& fileName) + ITKImageFileAccessorGenerator::ITKImageFileAccessorGenerator(const FileNameType& fileName) { - _dicomDoseFileName = fileName; + _fileName = fileName; } rttb::core::DoseAccessorGeneratorBase::DoseAccessorPointer - ITKImageFileDoseAccessorGenerator::generateDoseAccessor() + ITKImageFileAccessorGenerator::generateDoseAccessor() { - _itkDoubleImage = readITKDoubleImage(_dicomDoseFileName); + _itkDoubleImage = readITKDoubleImage(_fileName); - _doseAccessor = boost::make_shared(_itkDoubleImage.GetPointer()); + _doseAccessor = boost::make_shared(_itkDoubleImage.GetPointer()); return _doseAccessor; } }//end namespace itk }//end namespace io }//end namespace rttb diff --git a/code/io/itk/rttbITKImageFileDoseAccessorGenerator.h b/code/io/itk/rttbITKImageFileAccessorGenerator.h similarity index 63% rename from code/io/itk/rttbITKImageFileDoseAccessorGenerator.h rename to code/io/itk/rttbITKImageFileAccessorGenerator.h index 7edf237..1341322 100644 --- a/code/io/itk/rttbITKImageFileDoseAccessorGenerator.h +++ b/code/io/itk/rttbITKImageFileAccessorGenerator.h @@ -1,82 +1,83 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) -// @date $Date$ (last change date) -// @author $Author$ (last changed by) +// @version $Revision: 995 $ (last changed revision) +// @date $Date: 2015-06-17 12:58:33 +0200 (Mi, 17 Jun 2015) $ (last change date) +// @author $Author: hentsch $ (last changed by) */ -#ifndef __ITK_IMAGE_DOSE_FILE_ACCESSOR_GENERATOR_H -#define __ITK_IMAGE_DOSE_FILE_ACCESSOR_GENERATOR_H +#ifndef __ITK_IMAGE_FILE_ACCESSOR_GENERATOR_H +#define __ITK_IMAGE_FILE_ACCESSOR_GENERATOR_H #include #include #include "rttbDoseAccessorGeneratorBase.h" #include "rttbBaseType.h" -#include "rttbITKImageDoseAccessor.h" +#include "rttbITKImageAccessorConverter.h" #include "rttbGenericImageReader.h" #include "itkImage.h" #include "itkCastImageFilter.h" namespace rttb { namespace io { namespace itk { - /*! @class ITKImageFileDoseAccessorGenerator - @brief Load dose data using the itk loading methods and wraps the resulting itk image in a ITKImageDoseAccessor. - * this is normally used if dose distributions are stored in formats like meta image, nrrd... + /*! @class ITKImageFileAccessorGenerator + @brief Load image data using the itk loading methods and wraps the resulting itk image in a ITKImageAccessor. + * this can be used if dose distributions are stored in formats like meta image, nrrd... * @note it implies that the dose information is stored in absolute Gy values. */ - class ITKImageFileDoseAccessorGenerator: public core::DoseAccessorGeneratorBase + class ITKImageFileAccessorGenerator: public core::DoseAccessorGeneratorBase { public: + typedef ::itk::Image ITKImageType; typedef DoseAccessorGeneratorBase::DoseAccessorPointer DoseAccessorPointer; private: - FileNameType _dicomDoseFileName; + FileNameType _fileName; /** @brief The dose as itkImage */ - ITKDoseImageType::Pointer _itkDoubleImage; + ITKImageType::Pointer _itkDoubleImage; + + ITKImageFileAccessorGenerator(); - ITKImageFileDoseAccessorGenerator(); - public: - ~ITKImageFileDoseAccessorGenerator(); + ~ITKImageFileAccessorGenerator(); - ITKImageFileDoseAccessorGenerator(const FileNameType& fileName); + ITKImageFileAccessorGenerator(const FileNameType& fileName); /*! @brief Generate DoseAccessor @return Return shared pointer of DoseAccessor. @exception InvalidDoseException Thrown if file could not be read @exception InvalidParameterException Thrown if file has imageDimension !=3 or image component type != SCALAR @details is always converted into a itkImage by using a CastImageFilter @sa doCasting, handleGenericImage */ DoseAccessorPointer generateDoseAccessor(); }; }//end namespace itk }//end namespace io }//end namespace rttb #endif diff --git a/code/io/virtuos/rttbVirtuosCubeinfoDoseAccessorGenerator.cpp b/code/io/virtuos/rttbVirtuosCubeinfoDoseAccessorGenerator.cpp index 25901e1..c803c14 100644 --- a/code/io/virtuos/rttbVirtuosCubeinfoDoseAccessorGenerator.cpp +++ b/code/io/virtuos/rttbVirtuosCubeinfoDoseAccessorGenerator.cpp @@ -1,67 +1,73 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include "rttbVirtuosCubeinfoDoseAccessorGenerator.h" #include "rttbVirtuosDoseAccessor.h" #include "rttbNullPointerException.h" #include "rttbInvalidDoseException.h" #include "rttbInvalidParameterException.h" #include "rttbIndexOutOfBoundsException.h" //VIRTUOS #include "pln1file.h" #include "plt_type.h" #include "rtp_type.h" -namespace rttb{ - namespace io{ - namespace virtuos{ +namespace rttb +{ + namespace io + { + namespace virtuos + { - VirtuosCubeinfoDoseAccessorGenerator::~VirtuosCubeinfoDoseAccessorGenerator(){} + VirtuosCubeinfoDoseAccessorGenerator::~VirtuosCubeinfoDoseAccessorGenerator() {} - VirtuosCubeinfoDoseAccessorGenerator::VirtuosCubeinfoDoseAccessorGenerator(Cubeinfo *aPointerOnVirtuosCube, DoseTypeGy normalizationDose, DoseTypeGy prescribedDose): - _pPointerOnVirtuosCube(new Cubeinfo*) + VirtuosCubeinfoDoseAccessorGenerator::VirtuosCubeinfoDoseAccessorGenerator(Cubeinfo* aPointerOnVirtuosCube, + DoseTypeGy normalizationDose, DoseTypeGy prescribedDose): + _pPointerOnVirtuosCube(new Cubeinfo*) { //initialize cube pointer *_pPointerOnVirtuosCube = create_cubeinfo(0); - *_pPointerOnVirtuosCube=aPointerOnVirtuosCube; - _normalizationDose=normalizationDose; - _prescribedDose=prescribedDose; + *_pPointerOnVirtuosCube = aPointerOnVirtuosCube; + _normalizationDose = normalizationDose; + _prescribedDose = prescribedDose; } - VirtuosCubeinfoDoseAccessorGenerator::DoseAccessorPointer VirtuosCubeinfoDoseAccessorGenerator::generateDoseAccessor() { - _doseAccessor=boost::make_shared(*_pPointerOnVirtuosCube, false,_normalizationDose,_prescribedDose); + VirtuosCubeinfoDoseAccessorGenerator::DoseAccessorPointer VirtuosCubeinfoDoseAccessorGenerator::generateDoseAccessor() + { + _doseAccessor = boost::make_shared(*_pPointerOnVirtuosCube, false, _normalizationDose, + _prescribedDose); return _doseAccessor; } } } } diff --git a/code/io/virtuos/rttbVirtuosCubeinfoDoseAccessorGenerator.h b/code/io/virtuos/rttbVirtuosCubeinfoDoseAccessorGenerator.h index 1cc97c4..7e9145f 100644 --- a/code/io/virtuos/rttbVirtuosCubeinfoDoseAccessorGenerator.h +++ b/code/io/virtuos/rttbVirtuosCubeinfoDoseAccessorGenerator.h @@ -1,76 +1,81 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __VIRTUOS_CUBEINFO_DOSE_ACCESSOR_GENERATOR_H #define __VIRTUOS_CUBEINFO_DOSE_ACCESSOR_GENERATOR_H #include #include #include #include "rttbDoseAccessorGeneratorBase.h" +#include "rttbDoseAccessorInterface.h" #include "rttbGeometricInfo.h" #include "rttbBaseType.h" #include "ncfile.h" -namespace rttb{ - namespace io{ - namespace virtuos{ +namespace rttb +{ + namespace io + { + namespace virtuos + { - /*! @class VirtuosCubeinfoDoseAccessorGenerator + /*! @class VirtuosCubeinfoDoseAccessorGenerator @brief Generate DoseAccessor with Virtuos Cubeinfo */ class VirtuosCubeinfoDoseAccessorGenerator: public core::DoseAccessorGeneratorBase { public: typedef core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; - private: - Cubeinfo **_pPointerOnVirtuosCube; + private: + Cubeinfo** _pPointerOnVirtuosCube; DoseTypeGy _normalizationDose; DoseTypeGy _prescribedDose; - + VirtuosCubeinfoDoseAccessorGenerator(); protected: - - public: + + public: ~VirtuosCubeinfoDoseAccessorGenerator(); - /*! @brief Constructor. Initialisation with a Cubeinfo*. + /*! @brief Constructor. Initialisation with a Cubeinfo*. @param normalizationDose is defined as (prescribedDose*1000)/maxDoseInGy. Default is 1 Gy. @param prescribedDose the does that was planned in the reference point in Gy. Default is 1 Gy. */ - VirtuosCubeinfoDoseAccessorGenerator(Cubeinfo *aPointerOnVirtuosCube, DoseTypeGy normalizationDose = 1, DoseTypeGy prescribedDose = 1); - /*! @brief Generate DoseAccessor - @return Return shared pointer of DoseAccessor. + VirtuosCubeinfoDoseAccessorGenerator(Cubeinfo* aPointerOnVirtuosCube, DoseTypeGy normalizationDose = 1, + DoseTypeGy prescribedDose = 1); + /*! @brief Generate DoseAccessor + @return Return shared pointer of DoseAccessor. */ DoseAccessorPointer generateDoseAccessor() ; - + }; } } } #endif diff --git a/code/io/virtuos/rttbVirtuosDoseAccessor.cpp b/code/io/virtuos/rttbVirtuosDoseAccessor.cpp index 84fad28..a66ed42 100644 --- a/code/io/virtuos/rttbVirtuosDoseAccessor.cpp +++ b/code/io/virtuos/rttbVirtuosDoseAccessor.cpp @@ -1,228 +1,228 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbVirtuosDoseAccessor.h" #include "rttbNullPointerException.h" #include "rttbInvalidDoseException.h" #include "rttbInvalidParameterException.h" #include "rttbIndexOutOfBoundsException.h" //VIRTUOS #include "pln1file.h" #include "plt_type.h" #include "rtp_type.h" namespace rttb { - namespace io - { - namespace virtuos - { - - VirtuosDoseAccessor::~VirtuosDoseAccessor() - { - if (_freeVirtuosData) - { - this->freeVirtuosData(); - } - } - - VirtuosDoseAccessor::VirtuosDoseAccessor(Cubeinfo* aPointerOnVirtuosCube, bool freeVirtuosData, - DoseTypeGy normalizationDose, DoseTypeGy prescribedDose): - _pPointerOnVirtuosCube(new Cubeinfo*), _freeVirtuosData(freeVirtuosData), _doseGridScaling(0), - _doseUID(""), _doseScalingFactor(0) - { - //initialize cube pointer - *_pPointerOnVirtuosCube = create_cubeinfo(0); - *_pPointerOnVirtuosCube = aPointerOnVirtuosCube; - - - _prescribedDose = prescribedDose; - _normalizationDose = normalizationDose; - - if (_prescribedDose == 0) - { - _prescribedDose = 1; - } - - if (_normalizationDose == 0) - { - _normalizationDose = 1; - } - - _doseScalingFactor = _prescribedDose / _normalizationDose; - std::cout << "Prescribed dose: " << _prescribedDose << std::endl; - std::cout << "Normalization dose: " << _normalizationDose << std::endl; - - //dose import - this->begin(); - } - - void VirtuosDoseAccessor::begin() - { - if (!_pPointerOnVirtuosCube) - { - throw core::NullPointerException(" *_pPointerOnVirtuosCube must not be NULL!"); - } - - assembleGeometricInfo(); - - //load data - if ((*_pPointerOnVirtuosCube)->data_type == 1) - { - this->importPixelData(); - } - else if ((*_pPointerOnVirtuosCube)->data_type == 2) - { - this->importPixelData(); - } - else - { - throw core::InvalidParameterException(" cube has wrong data type!"); - } - } - - template - void VirtuosDoseAccessor::importPixelData() - { - doseData.clear(); - - int dimX = (*_pPointerOnVirtuosCube)->dimx; - int dimY = (*_pPointerOnVirtuosCube)->dimy; - int dimZ = (*_pPointerOnVirtuosCube)->dimz; - - GridVolumeType pixelSpacing = (*_pPointerOnVirtuosCube)->pixdist; - GridVolumeType sliceThickness = (*_pPointerOnVirtuosCube)->slicedist; - - TPixelType** * access_pointer = (TPixelType***)(*_pPointerOnVirtuosCube)->cube_direct_access; - - for (int k = 0; k < dimZ; k++) - { - for (int j = 0; j < dimY; j++) - { - for (int i = 0; i < dimX; i++) - { - TPixelType voxel_value = access_pointer[k][j][i]; - doseData.push_back(voxel_value * _doseScalingFactor); - } - - }//end for j - }//end for k - } - - void VirtuosDoseAccessor::assembleGeometricInfo() - { - if (!_pPointerOnVirtuosCube) - { - throw core::NullPointerException(" _pPointerOnVirtuosCube must not be NULL!"); - } - - _geoInfo.setNumColumns((*_pPointerOnVirtuosCube)->dimx); - - _geoInfo.setNumRows((*_pPointerOnVirtuosCube)->dimy); - - _geoInfo.setNumSlices((*_pPointerOnVirtuosCube)->dimz); - - if (_geoInfo.getNumColumns() == 0 || _geoInfo.getNumRows() == 0 || _geoInfo.getNumSlices() == 0) - { - throw core::InvalidDoseException("Empty Virtuos dose!") ; - } - - OrientationMatrix orientation; - _geoInfo.setOrientationMatrix(orientation); - - WorldCoordinate3D imagePositionPatient; - imagePositionPatient(0) = (*this->_pPointerOnVirtuosCube)->pixdist / 2; - imagePositionPatient(1) = (*this->_pPointerOnVirtuosCube)->pixdist / 2; - - if (!((*this->_pPointerOnVirtuosCube)->pos_list)) - { - throw core::InvalidDoseException("Empty Virtuos dose!") ; - } - - imagePositionPatient(2) = (*this->_pPointerOnVirtuosCube)->pos_list[0].position; - - _geoInfo.setImagePositionPatient(imagePositionPatient); - - SpacingVectorType3D spacingVector; - spacingVector(0) = (*_pPointerOnVirtuosCube)->pixdist; - spacingVector(1) = (*_pPointerOnVirtuosCube)->pixdist; - _geoInfo.setSpacing(spacingVector); - - if (_geoInfo.getPixelSpacingRow() == 0 || _geoInfo.getPixelSpacingColumn() == 0) - { - throw core::InvalidDoseException("Pixel spacing = 0!"); - } - - spacingVector(2) = (*_pPointerOnVirtuosCube)->slicedist; - - if (spacingVector(2) == 0) - { - std::cerr << "sliceThickness == 0! It will be replaced with pixelSpacingRow=" << - _geoInfo.getPixelSpacingRow() - << "!" << std::endl; - spacingVector(2) = spacingVector(0); - } - - _geoInfo.setSpacing(spacingVector); - } - - - DoseTypeGy VirtuosDoseAccessor::getDoseAt(const VoxelGridID aID) const - { - return doseData.at(aID); - } - - DoseTypeGy VirtuosDoseAccessor::getDoseAt(const VoxelGridIndex3D& aIndex) const - { - VoxelGridID aVoxelGridID; - - if (_geoInfo.convert(aIndex, aVoxelGridID)) - { - return getDoseAt(aVoxelGridID); - } - else - { - return -1; - } - } - - void VirtuosDoseAccessor::freeVirtuosData() - { - if (*(this->_pPointerOnVirtuosCube) != NULL) - { - closecube((*(this->_pPointerOnVirtuosCube))); - nc_free_cubeinfo((*(this->_pPointerOnVirtuosCube))); - delete this->_pPointerOnVirtuosCube; - - // initialize attributes again - //this->_pPointerOnVirtuosCube = new Cubeinfo*; - //*(this->_pPointerOnVirtuosCube) = create_cubeinfo(0); - } - - } - - } - } + namespace io + { + namespace virtuos + { + + VirtuosDoseAccessor::~VirtuosDoseAccessor() + { + if (_freeVirtuosData) + { + this->freeVirtuosData(); + } + } + + VirtuosDoseAccessor::VirtuosDoseAccessor(Cubeinfo* aPointerOnVirtuosCube, bool freeVirtuosData, + DoseTypeGy normalizationDose, DoseTypeGy prescribedDose): + _pPointerOnVirtuosCube(new Cubeinfo*), _freeVirtuosData(freeVirtuosData), _doseGridScaling(0), + _doseUID(""), _doseScalingFactor(0) + { + //initialize cube pointer + *_pPointerOnVirtuosCube = create_cubeinfo(0); + *_pPointerOnVirtuosCube = aPointerOnVirtuosCube; + + + _prescribedDose = prescribedDose; + _normalizationDose = normalizationDose; + + if (_prescribedDose == 0) + { + _prescribedDose = 1; + } + + if (_normalizationDose == 0) + { + _normalizationDose = 1; + } + + _doseScalingFactor = _prescribedDose / _normalizationDose; + std::cout << "Prescribed dose: " << _prescribedDose << std::endl; + std::cout << "Normalization dose: " << _normalizationDose << std::endl; + + //dose import + this->begin(); + } + + void VirtuosDoseAccessor::begin() + { + if (!_pPointerOnVirtuosCube) + { + throw core::NullPointerException(" *_pPointerOnVirtuosCube must not be NULL!"); + } + + assembleGeometricInfo(); + + //load data + if ((*_pPointerOnVirtuosCube)->data_type == 1) + { + this->importPixelData(); + } + else if ((*_pPointerOnVirtuosCube)->data_type == 2) + { + this->importPixelData(); + } + else + { + throw core::InvalidParameterException(" cube has wrong data type!"); + } + } + + template + void VirtuosDoseAccessor::importPixelData() + { + doseData.clear(); + + int dimX = (*_pPointerOnVirtuosCube)->dimx; + int dimY = (*_pPointerOnVirtuosCube)->dimy; + int dimZ = (*_pPointerOnVirtuosCube)->dimz; + + GridVolumeType pixelSpacing = (*_pPointerOnVirtuosCube)->pixdist; + GridVolumeType sliceThickness = (*_pPointerOnVirtuosCube)->slicedist; + + TPixelType** * access_pointer = (TPixelType***)(*_pPointerOnVirtuosCube)->cube_direct_access; + + for (int k = 0; k < dimZ; k++) + { + for (int j = 0; j < dimY; j++) + { + for (int i = 0; i < dimX; i++) + { + TPixelType voxel_value = access_pointer[k][j][i]; + doseData.push_back(voxel_value * _doseScalingFactor); + } + + }//end for j + }//end for k + } + + void VirtuosDoseAccessor::assembleGeometricInfo() + { + if (!_pPointerOnVirtuosCube) + { + throw core::NullPointerException(" _pPointerOnVirtuosCube must not be NULL!"); + } + + _geoInfo.setNumColumns((*_pPointerOnVirtuosCube)->dimx); + + _geoInfo.setNumRows((*_pPointerOnVirtuosCube)->dimy); + + _geoInfo.setNumSlices((*_pPointerOnVirtuosCube)->dimz); + + if (_geoInfo.getNumColumns() == 0 || _geoInfo.getNumRows() == 0 || _geoInfo.getNumSlices() == 0) + { + throw core::InvalidDoseException("Empty Virtuos dose!") ; + } + + OrientationMatrix orientation; + _geoInfo.setOrientationMatrix(orientation); + + WorldCoordinate3D imagePositionPatient; + imagePositionPatient(0) = (*this->_pPointerOnVirtuosCube)->pixdist / 2; + imagePositionPatient(1) = (*this->_pPointerOnVirtuosCube)->pixdist / 2; + + if (!((*this->_pPointerOnVirtuosCube)->pos_list)) + { + throw core::InvalidDoseException("Empty Virtuos dose!") ; + } + + imagePositionPatient(2) = (*this->_pPointerOnVirtuosCube)->pos_list[0].position; + + _geoInfo.setImagePositionPatient(imagePositionPatient); + + SpacingVectorType3D spacingVector; + spacingVector(0) = (*_pPointerOnVirtuosCube)->pixdist; + spacingVector(1) = (*_pPointerOnVirtuosCube)->pixdist; + _geoInfo.setSpacing(spacingVector); + + if (_geoInfo.getPixelSpacingRow() == 0 || _geoInfo.getPixelSpacingColumn() == 0) + { + throw core::InvalidDoseException("Pixel spacing = 0!"); + } + + spacingVector(2) = (*_pPointerOnVirtuosCube)->slicedist; + + if (spacingVector(2) == 0) + { + std::cerr << "sliceThickness == 0! It will be replaced with pixelSpacingRow=" << + _geoInfo.getPixelSpacingRow() + << "!" << std::endl; + spacingVector(2) = spacingVector(0); + } + + _geoInfo.setSpacing(spacingVector); + } + + + GenericValueType VirtuosDoseAccessor::getValueAt(const VoxelGridID aID) const + { + return doseData.at(aID); + } + + GenericValueType VirtuosDoseAccessor::getValueAt(const VoxelGridIndex3D& aIndex) const + { + VoxelGridID aVoxelGridID; + + if (_geoInfo.convert(aIndex, aVoxelGridID)) + { + return getValueAt(aVoxelGridID); + } + else + { + return -1; + } + } + + void VirtuosDoseAccessor::freeVirtuosData() + { + if (*(this->_pPointerOnVirtuosCube) != NULL) + { + closecube((*(this->_pPointerOnVirtuosCube))); + nc_free_cubeinfo((*(this->_pPointerOnVirtuosCube))); + delete this->_pPointerOnVirtuosCube; + + // initialize attributes again + //this->_pPointerOnVirtuosCube = new Cubeinfo*; + //*(this->_pPointerOnVirtuosCube) = create_cubeinfo(0); + } + + } + + } + } } diff --git a/code/io/virtuos/rttbVirtuosDoseAccessor.h b/code/io/virtuos/rttbVirtuosDoseAccessor.h index 36530b2..103891b 100644 --- a/code/io/virtuos/rttbVirtuosDoseAccessor.h +++ b/code/io/virtuos/rttbVirtuosDoseAccessor.h @@ -1,129 +1,129 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __VIRTUOS_DOSE_ACCESSOR_H #define __VIRTUOS_DOSE_ACCESSOR_H #include #include #include -#include "rttbDoseAccessorWithGeoInfoBase.h" +#include "rttbAccessorWithGeoInfoBase.h" #include "rttbGeometricInfo.h" #include "rttbBaseType.h" #include "ncfile.h" namespace rttb { - namespace io - { - namespace virtuos - { + namespace io + { + namespace virtuos + { - /*! @class VirtuosDoseAccessor - @brief This class gives access to dose information from Virtuos Cubeinfo - */ - class VirtuosDoseAccessor : public core::DoseAccessorWithGeoInfoBase - { - private: - Cubeinfo** _pPointerOnVirtuosCube; + /*! @class VirtuosDoseAccessor + @brief This class gives access to dose information from Virtuos Cubeinfo + */ + class VirtuosDoseAccessor : public core::AccessorWithGeoInfoBase + { + private: + Cubeinfo** _pPointerOnVirtuosCube; - /*! absolute Gy dose/doseGridScaling*/ - std::vector doseData; + /*! absolute Gy dose/doseGridScaling*/ + std::vector doseData; - double _doseGridScaling; + double _doseGridScaling; - IDType _doseUID; + IDType _doseUID; - DoseTypeGy _prescribedDose; - DoseTypeGy _normalizationDose; + DoseTypeGy _prescribedDose; + DoseTypeGy _normalizationDose; - DoseTypeGy _doseScalingFactor; + DoseTypeGy _doseScalingFactor; - bool _freeVirtuosData;//if virtuos cube info should be closed + bool _freeVirtuosData;//if virtuos cube info should be closed - /*! close virtuos data cube. - */ - void freeVirtuosData(); + /*! close virtuos data cube. + */ + void freeVirtuosData(); - /*! load actual pixel data from virtuos cube to doseData. TPixelType is usually int but may be float for - special virtuos cubes (data_type = 2). - @pre virtuos cube contains data (dimensions are at least 1) + /*! load actual pixel data from virtuos cube to doseData. TPixelType is usually int but may be float for + special virtuos cubes (data_type = 2). + @pre virtuos cube contains data (dimensions are at least 1) - */ - template - void importPixelData(); + */ + template + void importPixelData(); - protected: - /*! @brief import dose data and relevant geometric information - @throw NullPointerException Thrown if _pPointerOnVirtuosCube is NULL - @throw InvalidDoseException Thrown if one dimension of the virtuos cube is zero - @throw InvalidParameterException Thrown if _pPointerOnVirtuosCube is invalid - */ - void begin(); + protected: + /*! @brief import dose data and relevant geometric information + @throw NullPointerException Thrown if _pPointerOnVirtuosCube is NULL + @throw InvalidDoseException Thrown if one dimension of the virtuos cube is zero + @throw InvalidParameterException Thrown if _pPointerOnVirtuosCube is invalid + */ + void begin(); - /*! @brief get all required geometrical data from virtuos cube - */ - void assembleGeometricInfo(); + /*! @brief get all required geometrical data from virtuos cube + */ + void assembleGeometricInfo(); - public: - ~VirtuosDoseAccessor(); + public: + ~VirtuosDoseAccessor(); - /*! @brief Constructor. Initialisation with a Cubeinfo pointer. - @param normalizationDose is defined as (prescribedDose*1000)/maxDoseInGy. Default is 1 Gy. - @param prescribedDose the does that was planned in the reference point in Gy. Default is 1 Gy. - @param freeVirtuoData If virtuos cube info should be closed, freeVirtuosData should be true. - @throw NullPointerException Thrown if _pPointerOnVirtuosCube is NULL - @throw InvalidDoseException Thrown if one dimension of the virtuos cube is zero - @throw InvalidParameterException Thrown if aPointerOnVirtuosCube is invalid - */ - VirtuosDoseAccessor(Cubeinfo* aPointerOnVirtuosCube, bool freeVirtuosData, - DoseTypeGy normalizationDose = 1, DoseTypeGy prescribedDose = 1); + /*! @brief Constructor. Initialisation with a Cubeinfo pointer. + @param normalizationDose is defined as (prescribedDose*1000)/maxDoseInGy. Default is 1 Gy. + @param prescribedDose the does that was planned in the reference point in Gy. Default is 1 Gy. + @param freeVirtuoData If virtuos cube info should be closed, freeVirtuosData should be true. + @throw NullPointerException Thrown if _pPointerOnVirtuosCube is NULL + @throw InvalidDoseException Thrown if one dimension of the virtuos cube is zero + @throw InvalidParameterException Thrown if aPointerOnVirtuosCube is invalid + */ + VirtuosDoseAccessor(Cubeinfo* aPointerOnVirtuosCube, bool freeVirtuosData, + DoseTypeGy normalizationDose = 1, DoseTypeGy prescribedDose = 1); - DoseTypeGy getDoseAt(const VoxelGridID aID) const; + GenericValueType getValueAt(const VoxelGridID aID) const; - /*! @return dose value at given grid position. If position is invalid return -1 - */ - DoseTypeGy getDoseAt(const VoxelGridIndex3D& aIndex) const; + /*! @return dose value at given grid position. If position is invalid return -1 + */ + GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const; - const IDType getDoseUID() const - { - return _doseUID; - }; + const IDType getUID() const + { + return _doseUID; + }; - const DoseTypeGy getPrescribedDose() const - { - return _prescribedDose; - }; + const DoseTypeGy getPrescribedDose() const + { + return _prescribedDose; + }; - const DoseTypeGy getNormalizationDose() const - { - return _normalizationDose; - }; - }; - } - } + const DoseTypeGy getNormalizationDose() const + { + return _normalizationDose; + }; + }; + } + } } #endif diff --git a/code/io/virtuos/rttbVirtuosDoseFileDoseAccessorGenerator.h b/code/io/virtuos/rttbVirtuosDoseFileDoseAccessorGenerator.h index 10c82cf..5b0b1a0 100644 --- a/code/io/virtuos/rttbVirtuosDoseFileDoseAccessorGenerator.h +++ b/code/io/virtuos/rttbVirtuosDoseFileDoseAccessorGenerator.h @@ -1,92 +1,93 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __VIRTUOS_DOSE_FILE_DOSE_ACCESSOR_GENERATOR_H #define __VIRTUOS_DOSE_FILE_DOSE_ACCESSOR_GENERATOR_H #include #include #include #include "rttbDoseAccessorGeneratorBase.h" +#include "rttbDoseAccessorInterface.h" #include "rttbGeometricInfo.h" #include "rttbBaseType.h" #include "ncfile.h" namespace rttb { namespace io { namespace virtuos { - /*! @class VirtuosDoseFileDoseAccessorGenerator + /*! @class VirtuosDoseFileDoseAccessorGenerator @brief Load dose data from a Virtuos dose file and generate DoseAccessor. @warning Manual dose normalization is done as no virtuos plan file is given! I.e., the DoseAccessor returns pixels having no physical unit (!= Gy) in case of wrong values. It's the responsibility of the user to specify the correct values. Consider using VirtuosPlanFileDoseAccessorGenerator instead! */ class VirtuosDoseFileDoseAccessorGenerator: public core::DoseAccessorGeneratorBase { public: typedef core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; - private: + private: FileNameType _doseFileName; DoseTypeGy _normalizationDose; DoseTypeGy _prescribedDose; - Cubeinfo **_pPointerOnVirtuosCube; + Cubeinfo** _pPointerOnVirtuosCube; /*! prepare virtuos dose cube for data import. Actual data import is performed in importPixelData() and assembleGeometricInfo(). @pre filename needs to point to an existing file. @throw InvalidParameterException Thrown if aVirtuosDoseFileName is invalid or if virtuos cube can not be read */ void initializeVirtuosCube(FileNameType aVirtuosDoseFileName); VirtuosDoseFileDoseAccessorGenerator(); protected: - - public: + + public: ~VirtuosDoseFileDoseAccessorGenerator(); - /*! @brief Constructor. Initialisation with a Virtuos-RT dose file with name aVirtuosDoseFileName. + /*! @brief Constructor. Initialisation with a Virtuos-RT dose file with name aVirtuosDoseFileName. @param normalizationDose is defined as (prescribedDose*1000)/maxDoseInGy. @param prescribedDose the does that was planned in the reference point in Gy. */ VirtuosDoseFileDoseAccessorGenerator(const FileNameType aVirtuosDoseFileName, DoseTypeGy normalizationDose, DoseTypeGy prescribedDose); - /*@brief Generate DoseAccessor - @return Return shared pointer of DoseAccessor. + /*@brief Generate DoseAccessor + @return Return shared pointer of DoseAccessor. @throw InvalidParameterException Thrown if one of the file names is empty. */ DoseAccessorPointer generateDoseAccessor() ; - + }; } } } #endif diff --git a/code/io/virtuos/rttbVirtuosPlanFileDoseAccessorGenerator.h b/code/io/virtuos/rttbVirtuosPlanFileDoseAccessorGenerator.h index e05f79c..7160ad9 100644 --- a/code/io/virtuos/rttbVirtuosPlanFileDoseAccessorGenerator.h +++ b/code/io/virtuos/rttbVirtuosPlanFileDoseAccessorGenerator.h @@ -1,90 +1,87 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __VIRTUOS_PLAN_FILE_DOSE_ACCESSOR_GENERATOR_H #define __VIRTUOS_PLAN_FILE_DOSE_ACCESSOR_GENERATOR_H #include #include #include #include "rttbDoseAccessorGeneratorBase.h" #include "rttbGeometricInfo.h" #include "rttbBaseType.h" #include "ncfile.h" namespace rttb { namespace io { namespace virtuos { - /*! @class VirtuosPlanFileDoseAccessorGenerator + /*! @class VirtuosPlanFileDoseAccessorGenerator @brief Load dose data from a Virtuos dose file and a Virtuos plan file, generate DoseAccessor. @detail Through the use of the plan file, the dose file can be normalized, i.e. the DoseAccessor returns values in Gy. */ class VirtuosPlanFileDoseAccessorGenerator: public core::DoseAccessorGeneratorBase { - public: - typedef core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; - - private: + private: FileNameType _doseFileName; FileNameType _planFileName; - Cubeinfo **_pPointerOnVirtuosCube; + Cubeinfo** _pPointerOnVirtuosCube; /*! prepare virtuos dose cube for data import. Actual data import is performed in importPixelData() and assembleGeometricInfo(). @pre filename needs to point to an existing file. @throw InvalidParameterException Thrown if aVirtuosDoseFileName is invalid or if virtuos cube can not be read */ void initializeVirtuosCube(FileNameType aVirtuosDoseFileName); VirtuosPlanFileDoseAccessorGenerator(); protected: - - public: + + public: ~VirtuosPlanFileDoseAccessorGenerator(); - /*! @brief Constructor. Initialisation with a Virtuos dose file and a Virtuos plan file. Information for dose scaling, + /*! @brief Constructor. Initialisation with a Virtuos dose file and a Virtuos plan file. Information for dose scaling, etc. is taken from the corresponding plan file aVirtuosPlanFileName. - + */ VirtuosPlanFileDoseAccessorGenerator(const FileNameType aVirtuosDoseFileName, const FileNameType aVirtuosPlanFileName); - /*@brief Generate DoseAccessor - @return Return shared pointer of DoseAccessor. + /*@brief Generate DoseAccessor + @return Return shared pointer of DoseAccessor. @throw InvalidParameterException Thrown if one of the file names is empty. @throw InvalidParameterException Thrown if plan file or virtuos cube could not be read. */ - DoseAccessorPointer generateDoseAccessor() ; - + DoseAccessorPointer generateDoseAccessor() override; + }; } } } #endif diff --git a/code/models/files.cmake b/code/models/files.cmake index 7174a52..0deec90 100644 --- a/code/models/files.cmake +++ b/code/models/files.cmake @@ -1,30 +1,29 @@ SET(CPP_FILES rttbBioModel.cpp rttbBioModelCurve.cpp rttbBioModelScatterPlots.cpp rttbNTCPLKBModel.cpp rttbNTCPRSModel.cpp rttbTCPModel.cpp rttbTCPLQModel.cpp rttbDoseBasedModels.cpp rttbDvhBasedModels.cpp rttbIntegration.cpp rttbLQModelAccessor.cpp ) SET(H_FILES rttbBaseTypeModels.h rttbBioModel.h rttbBioModelCurve.h rttbBioModelScatterPlots.h rttbNTCPModel.h rttbNTCPLKBModel.h rttbNTCPRSModel.h rttbTCPModel.h rttbTCPLQModel.h rttbDoseBasedModels.cpp rttbDvhBasedModels.h rttbIntegration.h - rttbBioModelAccessorInterface.h rttbLQModelAccessor.h ) diff --git a/code/models/rttbBioModelAccessorInterface.h b/code/models/rttbBioModelAccessorInterface.h deleted file mode 100644 index d81bb97..0000000 --- a/code/models/rttbBioModelAccessorInterface.h +++ /dev/null @@ -1,82 +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) -*/ -#ifndef __BIO_MODEL_ACCESSOR_INTERFACE_H -#define __BIO_MODEL_ACCESSOR_INTERFACE_H - -#include - -#include "rttbBaseType.h" -#include "rttbBaseTypeModels.h" -#include "rttbGeometricInfo.h" -#include "rttbIndexConversionInterface.h" - -namespace rttb -{ - namespace core - { - - /*! @class BioModelAccessorInterface - @brief Interface for all BioModelAccessor classes - */ - class BioModelAccessorInterface: public IndexConversionInterface - { - public: - typedef boost::shared_ptr BioModelAccessorPointer; - private: - BioModelAccessorInterface(const BioModelAccessorInterface&); //not implemented on purpose -> non-copyable - BioModelAccessorInterface& operator=(const - BioModelAccessorInterface&);//not implemented on purpose -> non-copyable - - public: - BioModelAccessorInterface() {}; - virtual ~BioModelAccessorInterface() {}; - - inline const core::GeometricInfo& getGeometricInfo() const - { - return _geoInfo; - }; - - inline GridSizeType getGridSize() const - { - return _geoInfo.getNumberOfVoxels(); - }; - - virtual models::BioModelValueType getBioModelValueAt(const VoxelGridID aID) const = 0; - - virtual models::BioModelValueType getBioModelValueAt(const VoxelGridIndex3D& aIndex) const = 0; - - /*! @brief is true if dose is on a homogeneous grid - @remarks Inhomogeneous grids are not supported at the moment, but if they will be supported in the future - the interface does not need to change. - */ - virtual bool isGridHomogeneous() const - { - return true; - } - - virtual const IDType getBioModelUID() const = 0; - protected: - core::GeometricInfo _geoInfo; - }; - } -} - -#endif diff --git a/code/models/rttbLQModelAccessor.cpp b/code/models/rttbLQModelAccessor.cpp index 7665d32..ea2c014 100644 --- a/code/models/rttbLQModelAccessor.cpp +++ b/code/models/rttbLQModelAccessor.cpp @@ -1,65 +1,65 @@ // ----------------------------------------------------------------------- // 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) */ #include "rttbLQModelAccessor.h" #include "rttbDoseBasedModels.h" #include "rttbInvalidDoseException.h" namespace rttb { namespace models { LQModelAccessor::~LQModelAccessor() { } LQModelAccessor::LQModelAccessor(DoseAccessorPointer dose, BioModelParamType alpha, BioModelParamType beta) : _dose(dose), _alpha(alpha), _beta(beta) { if (_dose == NULL) { throw core::InvalidDoseException("Dose is NULL"); } assembleGeometricInfo(); } - BioModelValueType LQModelAccessor::getBioModelValueAt(const VoxelGridID aID) const + GenericValueType LQModelAccessor::getValueAt(const VoxelGridID aID) const { - return calcLQ(_dose->getDoseAt(aID), _alpha, _beta); + return calcLQ(_dose->getValueAt(aID), _alpha, _beta); } - BioModelValueType LQModelAccessor::getBioModelValueAt(const VoxelGridIndex3D& aIndex) const + GenericValueType LQModelAccessor::getValueAt(const VoxelGridIndex3D& aIndex) const { - return calcLQ(_dose->getDoseAt(aIndex), _alpha, _beta); + return calcLQ(_dose->getValueAt(aIndex), _alpha, _beta); } bool LQModelAccessor::assembleGeometricInfo() { _geoInfo = _dose->getGeometricInfo(); return true; } } } diff --git a/code/models/rttbLQModelAccessor.h b/code/models/rttbLQModelAccessor.h index f569d65..a559f10 100644 --- a/code/models/rttbLQModelAccessor.h +++ b/code/models/rttbLQModelAccessor.h @@ -1,79 +1,79 @@ // ----------------------------------------------------------------------- // 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 __LQ_MODEL_ACCESSOR_H #define __LQ_MODEL_ACCESSOR_H -#include "rttbBioModelAccessorInterface.h" +#include "rttbAccessorWithGeoInfoBase.h" #include "rttbDoseAccessorInterface.h" #include "rttbBaseTypeModels.h" namespace rttb { namespace models { /*! @class LQModelAccessor @brief This class gives access to the LQ Model information in an image */ - class LQModelAccessor: public core::BioModelAccessorInterface + class LQModelAccessor: public core::AccessorWithGeoInfoBase { public: typedef core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; private: DoseAccessorPointer _dose; BioModelParamType _alpha; BioModelParamType _beta; IDType _bioModelUID; LQModelAccessor(); /*! @brief get all required data from the dose geometric info */ bool assembleGeometricInfo(); public: ~LQModelAccessor(); /*! @brief Constructor. @pre dose must be a valid instance (and not null) @exception InvalidDoseException if _dose is NULL */ LQModelAccessor(DoseAccessorPointer dose, BioModelParamType alpha, BioModelParamType beta); /*! @brief returns the LQ Model value for an id */ - BioModelValueType getBioModelValueAt(const VoxelGridID aID) const; + GenericValueType getValueAt(const VoxelGridID aID) const; /*! @brief returns the LQ Model value for an index */ - BioModelValueType getBioModelValueAt(const VoxelGridIndex3D& aIndex) const; + GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const; - const IDType getBioModelUID() const + const IDType getUID() const { return _bioModelUID; }; }; } } #endif diff --git a/demoapps/BioModelCalc/BioModelCalc.cpp b/demoapps/BioModelCalc/BioModelCalc.cpp new file mode 100644 index 0000000..719d68f --- /dev/null +++ b/demoapps/BioModelCalc/BioModelCalc.cpp @@ -0,0 +1,129 @@ +// ----------------------------------------------------------------------- +// 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: 1066 $ (last changed revision) +// @date $Date: 2015-08-19 11:47:07 +0200 (Mi, 19 Aug 2015) $ (last change date) +// @author $Author: floca $ (last changed by) +*/ + +#include "BioModelCalcApplicationData.h" +#include "BioModelCalcHelper.h" +#include "BioModelCmdLineParser.h" + +#include "boost/shared_ptr.hpp" +#include "boost/make_shared.hpp" + +#include "RTToolboxConfigure.h" + +#include "rttbException.h" + +rttb::apps::bioModelCalc::ApplicationData appData; + +int main(int argc, const char** argv) +{ + int result = 0; + + boost::shared_ptr argParser; + + try + { + std::string appName = "BioModelCalc"; + std::string appVersion = RTT_FULL_VERSION_STRING; + + argParser = boost::make_shared(argc, argv, appName, appVersion); + } + catch (const std::exception& e) + { + std::cerr << e.what() << std::endl; + return -1; + } + + // This is vital. The application needs to exit if the "help" or "version" parameter is set + // because this means the other parameters won't be parsed. + + if (argParser->isSet(argParser->OPTION_HELP) || argParser->isSet(argParser->OPTION_VERSION)) + { + return 0; + } + + rttb::apps::bioModelCalc::populateAppData(argParser, appData); + + std::cout << std::endl << "*******************************************" << std::endl; + std::cout << "Dose file: " << appData._doseFileName << std::endl; + std::cout << "Bio model output file: " << appData._outputFileName << std::endl; + std::cout << "Model: " << appData._model << std::endl; + std::cout << "Model parameters: "; + + for (unsigned int i = 0; i < appData._modelParameters.size(); i++) + { + if (i != 0) + { + std::cout << ", "; + } + + std::cout << appData._modelParameters.at(i); + } + + std::cout << std::endl; + + try + { + appData._dose = rttb::apps::bioModelCalc::loadDose(appData._doseFileName, appData._doseLoadStyle); + } + catch (rttb::core::Exception& e) + { + std::cerr << "RTTB Error!!!" << std::endl; + std::cerr << e.what() << std::endl; + return 1; + } + catch (const std::exception& e) + { + std::cerr << "Error!!!" << std::endl; + std::cerr << e.what() << std::endl; + return 1; + } + catch (...) + { + std::cerr << "Error!!! unknown error while reading input image." << std::endl; + return 1; + } + + try + { + rttb::apps::bioModelCalc::processData(appData); + } + catch (rttb::core::Exception& e) + { + std::cerr << "RTTB Error!!!" << std::endl; + std::cerr << e.what() << std::endl; + return 2; + } + catch (std::exception& e) + { + std::cerr << "Error!!!" << std::endl; + std::cerr << e.what() << std::endl; + return 2; + } + catch (...) + { + std::cerr << "Error!!! unknown error while calculating the bioModel or writing the image." << std::endl; + return 2; + } + + std::cout << "ENDE" << std::endl; + + return result; +} diff --git a/demoapps/BioModelCalc/BioModelCalcApplicationData.cpp b/demoapps/BioModelCalc/BioModelCalcApplicationData.cpp new file mode 100644 index 0000000..dc206e6 --- /dev/null +++ b/demoapps/BioModelCalc/BioModelCalcApplicationData.cpp @@ -0,0 +1,55 @@ +// ----------------------------------------------------------------------- +// 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: 1066 $ (last changed revision) +// @date $Date: 2015-08-19 11:47:07 +0200 (Mi, 19 Aug 2015) $ (last change date) +// @author $Author: floca $ (last changed by) +*/ + +#include "BioModelCalcApplicationData.h" + +namespace rttb +{ + namespace apps + { + namespace bioModelCalc + { + ApplicationData:: + ApplicationData() + { + this->Reset(); + } + + void + ApplicationData:: + Reset() + { + _doseFileName = ""; + _outputFileName = ""; + } + + void populateAppData(boost::shared_ptr argParser, ApplicationData& appData) + { + appData._doseFileName = argParser->get(argParser->OPTION_DOSE_FILE); + appData._doseLoadStyle = argParser->get >(argParser->OPTION_LOAD_STYLE); + appData._outputFileName = argParser->get(argParser->OPTION_OUTPUT_FILE); + appData._model = argParser->get(argParser->OPTION_MODEL); + appData._modelParameters = argParser->get >(argParser->OPTION_MODEL_PARAMETERS); + } + + } + } +} diff --git a/demoapps/BioModelCalc/BioModelCalcApplicationData.h b/demoapps/BioModelCalc/BioModelCalcApplicationData.h new file mode 100644 index 0000000..ddbe1a7 --- /dev/null +++ b/demoapps/BioModelCalc/BioModelCalcApplicationData.h @@ -0,0 +1,67 @@ +// ----------------------------------------------------------------------- +// 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: 1070 $ (last changed revision) +// @date $Date: 2015-08-19 14:50:28 +0200 (Mi, 19 Aug 2015) $ (last change date) +// @author $Author: floca $ (last changed by) +*/ + + +#ifndef __BIO_MODEL_CALC_APPLICATION_DATA_H +#define __BIO_MODEL_CALC_APPLICATION_DATA_H + +#include + +#include "rttbDoseAccessorInterface.h" +#include "BioModelCmdLineParser.h" + +namespace rttb +{ + namespace apps + { + namespace bioModelCalc + { + /*! @class ApplicationData + @brief Class for storing all relevant variables needed in BioModelCalc + */ + class ApplicationData + { + public: + /**Vector of arguments used to specify the loading style (always the first argument) + * and, if needed, additional arguments for the specified loading style (e.g. location of the + * Virtuos plan file for the Virtuos IO style). + */ + typedef std::vector LoadingStyleArgType; + core::DoseAccessorInterface::DoseAccessorPointer _dose; + std::string _doseFileName; + LoadingStyleArgType _doseLoadStyle; + + std::string _outputFileName; + + std::string _model; + std::vector _modelParameters; + + void Reset(); + + ApplicationData(); + }; + /*! @brief Reads the necessary arguments from the BioModelCmdLineParser and writes them in the respective variables of ApplicationData + */ + void populateAppData(boost::shared_ptr argParser, ApplicationData& appData); + } + } +} +#endif diff --git a/demoapps/BioModelCalc/BioModelCalcHelper.cpp b/demoapps/BioModelCalc/BioModelCalcHelper.cpp new file mode 100644 index 0000000..72ef2d4 --- /dev/null +++ b/demoapps/BioModelCalc/BioModelCalcHelper.cpp @@ -0,0 +1,148 @@ +// ----------------------------------------------------------------------- +// 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: 1095 $ (last changed revision) +// @date $Date: 2015-09-11 11:12:40 +0200 (Fr, 11 Sep 2015) $ (last change date) +// @author $Author: hentsch $ (last changed by) +*/ + + +#include "BioModelCalcHelper.h" + +#include "boost/make_shared.hpp" +#include "boost/shared_ptr.hpp" + +#include "rttbExceptionMacros.h" + +#include "rttbVirtuosPlanFileDoseAccessorGenerator.h" +#include "rttbDicomFileDoseAccessorGenerator.h" +#include "rttbDicomHelaxFileDoseAccessorGenerator.h" +#include "rttbITKImageFileAccessorGenerator.h" +#include "rttbITKImageAccessorConverter.h" +#include "rttbImageWriter.h" +#include "rttbLQModelAccessor.h" + +rttb::core::DoseAccessorInterface::DoseAccessorPointer +rttb::apps::bioModelCalc::loadDose(const std::string& fileName, + const rttb::apps::bioModelCalc::ApplicationData::LoadingStyleArgType& args) +{ + rttb::core::DoseAccessorInterface::DoseAccessorPointer result; + + std::cout << std::endl << "read dose file... "; + + if (args.empty() || args[0] == "dicom") + { + std::cout << "use RTTB dicom IO... "; + result = loadDicomDose(fileName); + } + else if (args[0] == "helax") + { + std::cout << "use RTTB Helax IO... "; + result = loadHelaxDose(fileName); + } + else if (args[0] == "itk") + { + std::cout << "use RTTB itk IO... "; + result = loadITKDose(fileName); + } + else if (args[0] == "virtuos") + { + if (args.size() < 2) + { + rttbDefaultExceptionStaticMacro( << + "Cannot load virtuos dose. Plan file is missing. Specify plan file as 2nd io stlye argument."); + } + + std::cout << "use RTTB virtuos IO... " << std::endl; + std::cout << " virtuos plan file: " << args[1] << " ... "; + result = loadVirtuosDose(fileName, args[1]); + } + else + { + rttbDefaultExceptionStaticMacro( << "Unknown io style selected. Cannot load data. Selected style: " + << args[0]); + } + + std::cout << "done." << std::endl; + + return result; +}; + +rttb::core::DoseAccessorInterface::DoseAccessorPointer +rttb::apps::bioModelCalc::loadDicomDose(const std::string& fileName) +{ + rttb::io::dicom::DicomFileDoseAccessorGenerator generator(fileName); + return generator.generateDoseAccessor(); +}; + +rttb::core::DoseAccessorInterface::DoseAccessorPointer +rttb::apps::bioModelCalc::loadHelaxDose(const std::string& path) +{ + rttb::io::helax::DicomHelaxFileDoseAccessorGenerator generator(path); + return generator.generateDoseAccessor(); +}; + +rttb::core::DoseAccessorInterface::DoseAccessorPointer +rttb::apps::bioModelCalc::loadITKDose(const std::string& fileName) +{ + rttb::io::itk::ITKImageFileAccessorGenerator generator(fileName); + return generator.generateDoseAccessor(); +}; + +rttb::core::DoseAccessorInterface::DoseAccessorPointer +rttb::apps::bioModelCalc::loadVirtuosDose(const std::string& fileName, const std::string& planFileName) +{ + rttb::io::virtuos::VirtuosPlanFileDoseAccessorGenerator generator(fileName, planFileName); + return generator.generateDoseAccessor(); +}; + + +void +rttb::apps::bioModelCalc::processData(rttb::apps::bioModelCalc::ApplicationData& appData) +{ + rttb::core::DoseAccessorInterface::DoseAccessorPointer outputAccessor; + + std::cout << std::endl << "generate biomodel... "; + auto bioModelAccessor = generateBioModel(appData._dose, appData._model, appData._modelParameters); + std::cout << "done." << std::endl; + std::cout << std::endl << "generate output image... "; + io::itk::ITKImageAccessorConverter converter(bioModelAccessor); + converter.setFailOnInvalidIDs(true); + converter.process(); + io::itk::ITKImageAccessorConverter::ITKImageType::Pointer itkImage = converter.getITKImage(); + std::cout << "done." << std::endl; + std::cout << std::endl << "write output image... "; + io::itk::ImageWriter writer(appData._outputFileName, itkImage); + writer.writeFile(); + std::cout << "done." << std::endl; +}; + + +rttb::core::AccessorInterface::AccessorPointer rttb::apps::bioModelCalc::generateBioModel( + rttb::core::DoseAccessorInterface::DoseAccessorPointer dose, const std::string& model, + const std::vector& modelParameters) +{ + if (model == "LQ") + { + return boost::make_shared(dose, modelParameters.at(0), modelParameters.at(1)); + } + else + { + rttbDefaultExceptionStaticMacro( << "Unknown model selected. Cannot load data. Selected model: " + << model); + } +} + diff --git a/demoapps/BioModelCalc/BioModelCalcHelper.h b/demoapps/BioModelCalc/BioModelCalcHelper.h new file mode 100644 index 0000000..d136f2c --- /dev/null +++ b/demoapps/BioModelCalc/BioModelCalcHelper.h @@ -0,0 +1,75 @@ +// ----------------------------------------------------------------------- +// 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: 1066 $ (last changed revision) +// @date $Date: 2015-08-19 11:47:07 +0200 (Mi, 19 Aug 2015) $ (last change date) +// @author $Author: floca $ (last changed by) +*/ + +#ifndef __BIO_MODEL_CALC_HELPER_H +#define __BIO_MODEL_CALC_HELPER_H + +#include "BioModelCalcApplicationData.h" +#include "rttbAccessorInterface.h" + +namespace rttb +{ + namespace apps + { + namespace bioModelCalc + { + /*! @brief loads a dose from a file based on the loadingStyle. + @details Throws an rttb::Exception if loading fails + */ + core::DoseAccessorInterface::DoseAccessorPointer loadDose(const std::string& fileName, + const rttb::apps::bioModelCalc::ApplicationData::LoadingStyleArgType& args); + /*! @brief loads a dicom dose from a file. + @details Throws an rttb::Exception if loading fails + @sa DicomFileDoseAccessorGenerator + */ + core::DoseAccessorInterface::DoseAccessorPointer loadDicomDose(const std::string& fileName); + /*! @brief loads a helax dose from a file. + @details Throws an rttb::Exception if loading fails + @sa DicomHelaxFileDoseAccessorGenerator + */ + core::DoseAccessorInterface::DoseAccessorPointer loadHelaxDose(const std::string& path); + /*! @brief loads an itk dose from a file. + @details Throws an rttb::Exception if loading fails. Might be of all formats that ITK know (*.mhd, *.nrrd, ...). The absolute image values are taken as dose. + @sa ITKImageFileAccessorGenerator + */ + core::DoseAccessorInterface::DoseAccessorPointer loadITKDose(const std::string& fileName); + /*! @brief loads a virtuos dose from a file. + @details Throws an rttb::Exception if loading fails + @sa VirtuosPlanFileDoseAccessorGenerator + */ + core::DoseAccessorInterface::DoseAccessorPointer loadVirtuosDose(const std::string& fileName, + const std::string& planFileName); + + /*! @brief Contains the business logic of processing all information to calculate a bioModel from the dose and writing it back to an image. + @details Uses appData for the input data and the correct configuration. + */ + void processData(ApplicationData& appData); + + core::AccessorInterface::AccessorPointer generateBioModel( + core::DoseAccessorInterface::DoseAccessorPointer dose, const std::string& model, + const std::vector& modelParameters); + + } + } +} + + +#endif diff --git a/demoapps/BioModelCalc/BioModelCmdLineParser.cpp b/demoapps/BioModelCalc/BioModelCmdLineParser.cpp new file mode 100644 index 0000000..fe304fc --- /dev/null +++ b/demoapps/BioModelCalc/BioModelCmdLineParser.cpp @@ -0,0 +1,90 @@ +#include "BioModelCmdLineParser.h" + +namespace rttb +{ + namespace apps + { + namespace bioModelCalc + { + + BioModelCmdLineParser::BioModelCmdLineParser(int argc, const char** argv, const std::string& name, + const std::string& version) : + CmdLineParserBase(name, version) + { + addOption(OPTION_DOSE_FILE, OPTION_GROUP_REQUIRED, + "The name of the dose file. Can be omitted if used as " + "positional argument (see above).", 'd', true); + addOption(OPTION_OUTPUT_FILE, OPTION_GROUP_REQUIRED, + "The name of the output file. Can be omitted if used as " + "positional argument (see above).", 'o', true); + addPositionalOption(OPTION_DOSE_FILE, 1); + addPositionalOption(OPTION_OUTPUT_FILE, 1); + addOptionWithDefaultValue(OPTION_MODEL, OPTION_GROUP_REQUIRED, + "The used radiobiological model the dose should be analyzed with. Available models are:\n \"LQ\"", "LQ", "LQ", 'm'); + addOption >(OPTION_MODEL_PARAMETERS, OPTION_GROUP_REQUIRED, + "The parameters for the radiobiological model.", 'p', false, true); + std::vector defaultLoadingStyle; + defaultLoadingStyle.push_back("itk"); + addOptionWithDefaultValue >(OPTION_LOAD_STYLE, OPTION_GROUP_REQUIRED, + "The loading style for the dose. Available styles are:\n" + "\"dicom\": normal dicom dose\n" + "\"virtuos\": load of a virtuos dose (This style is a multi argument. The second argument specifies the virtuos plan file, e.g. : \"--loadStyle virtuos myFavorite.pln\")\n" + "\"itk\": use itk image loading\n\"helax\": load a helax dose (choosing this style, the dose path should only be a directory).", + defaultLoadingStyle, defaultLoadingStyle.at(0), + 's', true, true); + + parse(argc, argv); + } + + void BioModelCmdLineParser::validateInput() const + { + std::string model = get(OPTION_MODEL); + + if (model != "LQ") + { + throw cmdlineparsing::InvalidConstraintException("Unknown model: " + model + + ".\nPlease refer to the help for valid models."); + } + else + { + if (get >(OPTION_MODEL_PARAMETERS).size() != 2) + { + throw cmdlineparsing::InvalidConstraintException("The LQ Model requires two parameters!"); + } + } + + std::vector loadStyle = get >(OPTION_LOAD_STYLE); + std::string loadStyleAbbreviation = loadStyle.at(0); + + if (loadStyleAbbreviation != "dicom" && loadStyleAbbreviation != "virtuos" && loadStyleAbbreviation != "itk" + && loadStyleAbbreviation != "helax") + { + throw cmdlineparsing::InvalidConstraintException("Unknown load style:" + loadStyleAbbreviation + + ".\nPlease refer to the help for valid loading style settings."); + } + + if (loadStyleAbbreviation == "virtuos") + { + if (loadStyle.size() < 2) + { + throw cmdlineparsing::InvalidConstraintException("Cannot load virtuos dose. Plan file is missing. Specify plan file as 2nd io style argument."); + } + } + } + + void BioModelCmdLineParser::printHelp() const + { + cmdlineparsing::CmdLineParserBase::printHelp(); + std::cout << "Example:" << std::endl << std::endl; + std::cout << m_programName << + " dose.mhd result.mhd -s itk -m LQ -p 0.2 0.02" << + std::endl << std::endl; + std::cout << + "This will calculate the Linear quadratic (LQ) BioModel from \"dose.mhd\" and will write the result to \"result.mhd\". " + "The alpha and beta parameters for the LQ model are 0.2 and 0.02, respectively." + << std::endl; + } + + } + } +} diff --git a/demoapps/BioModelCalc/BioModelCmdLineParser.h b/demoapps/BioModelCalc/BioModelCmdLineParser.h new file mode 100644 index 0000000..915aafd --- /dev/null +++ b/demoapps/BioModelCalc/BioModelCmdLineParser.h @@ -0,0 +1,38 @@ +#ifndef __BIO_MODEL_CMD_LINE_PARSER +#define __BIO_MODEL_CMD_LINE_PARSER + +#include "CmdLineParserBase.h" +namespace rttb +{ + namespace apps + { + namespace bioModelCalc + { + /*! @class BioModelCmdLineParser + @brief Argument parsing is parametrized here based on ArgParserLib + @see cmdlineparsing::CmdLineParserBase + */ + class BioModelCmdLineParser : public cmdlineparsing::CmdLineParserBase + { + public: + BioModelCmdLineParser(int argc, const char** argv, const std::string& name, const std::string& version); + void validateInput() const; + void printHelp() const; + + // Option groups + const std::string OPTION_GROUP_REQUIRED = "Required Arguments"; + const std::string OPTION_GROUP_OPTIONAL = "Optional Arguments"; + + // Parameters + const std::string OPTION_DOSE_FILE = "dose"; + const std::string OPTION_OUTPUT_FILE = "outputFile"; + const std::string OPTION_MODEL = "model"; + const std::string OPTION_MODEL_PARAMETERS = "modelParameters"; + const std::string OPTION_LOAD_STYLE = "loadStyle"; + }; + + } + } +} + +#endif \ No newline at end of file diff --git a/demoapps/BioModelCalc/CMakeLists.txt b/demoapps/BioModelCalc/CMakeLists.txt new file mode 100644 index 0000000..9b9da15 --- /dev/null +++ b/demoapps/BioModelCalc/CMakeLists.txt @@ -0,0 +1,3 @@ +MESSAGE (STATUS "generating demo app: BioModelCalc - calculating the radiobiological effect based on dose") + +RTTB_CREATE_APPLICATION(BioModelCalc DEPENDS RTTBCore RTTBITKIO RTTBVirtuosIO RTTBDicomIO RTTBHelaxIO RTTBModels PACKAGE_DEPENDS ArgumentParsingLib) \ No newline at end of file diff --git a/demoapps/BioModelCalc/files.cmake b/demoapps/BioModelCalc/files.cmake new file mode 100644 index 0000000..2ab3e9b --- /dev/null +++ b/demoapps/BioModelCalc/files.cmake @@ -0,0 +1,12 @@ +SET(CPP_FILES +BioModelCalc.cpp +BioModelCalcHelper.cpp +BioModelCalcApplicationData.cpp +BioModelCmdLineParser.cpp +) + +SET(H_FILES +BioModelCalcHelper.h +BioModelCalcApplicationData.h +BioModelCmdLineParser.h +) diff --git a/demoapps/CMakeLists.txt b/demoapps/CMakeLists.txt index f9a355e..64d7a2f 100644 --- a/demoapps/CMakeLists.txt +++ b/demoapps/CMakeLists.txt @@ -1,11 +1,16 @@ MESSAGE(STATUS "processing RTToolbox demo apps") OPTION(BUILD_DemoApp_DoseAcc "Determine if the demo application DoseAcc will be generated." OFF) IF(BUILD_DemoApp_DoseAcc) ADD_SUBDIRECTORY(DoseAcc) ENDIF(BUILD_DemoApp_DoseAcc) OPTION(BUILD_DemoApp_DoseMap "Determine if the demo application DoseMap will be generated." OFF) IF(BUILD_DemoApp_DoseMap) ADD_SUBDIRECTORY(DoseMap) ENDIF(BUILD_DemoApp_DoseMap) + +OPTION(BUILD_DemoApp_BioModelCalc "Determine if the demo application BioModelCalc will be generated." OFF) +IF(BUILD_DemoApp_BioModelCalc) +ADD_SUBDIRECTORY(BioModelCalc) +ENDIF(BUILD_DemoApp_BioModelCalc) diff --git a/demoapps/DoseAcc/DoseAccHelper.cpp b/demoapps/DoseAcc/DoseAccHelper.cpp index 0e20089..4f49d68 100644 --- a/demoapps/DoseAcc/DoseAccHelper.cpp +++ b/demoapps/DoseAcc/DoseAccHelper.cpp @@ -1,265 +1,265 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "DoseAccHelper.h" #include "mapRegistrationFileReader.h" #include "itkImageFileWriter.h" #include "rttbExceptionMacros.h" #include "rttbVirtuosPlanFileDoseAccessorGenerator.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomHelaxFileDoseAccessorGenerator.h" -#include "rttbITKImageFileDoseAccessorGenerator.h" +#include "rttbITKImageAccessorConverter.h" #include "rttbSimpleMappableDoseAccessor.h" #include "rttbMatchPointTransformation.h" #include "rttbLinearInterpolation.h" #include "rttbNearestNeighborInterpolation.h" #include "rttbRosuMappableDoseAccessor.h" -#include "rttbITKImageDoseAccessorConverter.h" +#include "rttbITKImageFileAccessorGenerator.h" #include "rttbArithmetic.h" -#include "rttbBinaryFunctorDoseAccessor.h" +#include "rttbBinaryFunctorAccessor.h" rttb::core::DoseAccessorInterface::DoseAccessorPointer rttb::apps::doseAcc::loadDose(const std::string& fileName, const rttb::apps::doseAcc::ApplicationData::LoadingStyleArgType& args) { rttb::core::DoseAccessorInterface::DoseAccessorPointer result; std::cout << std::endl << "read dose file... "; if (args.empty() || args[0] == "dicom") { std::cout << "use RTTB dicom IO... "; result = loadDicomDose(fileName); } else if (args[0] == "helax") { std::cout << "use RTTB Helax IO... "; result = loadHelaxDose(fileName); } else if (args[0] == "itk") { std::cout << "use RTTB itk IO... "; result = loadITKDose(fileName); } else if (args[0] == "virtuos") { if (args.size() < 2) { rttbDefaultExceptionStaticMacro( << "Cannot load virtuos dose. Plan file is missing. Specify plan file as 2nd io stlye argument."); } std::cout << "use RTTB virtuos IO... " << std::endl; std::cout << " virtuos plan file: " << args[1] << " ... "; result = loadVirtuosDose(fileName, args[1]); } else { rttbDefaultExceptionStaticMacro( << "Unknown io style selected. Cannot load data. Selected style: " << args[0]); } std::cout << "done." << std::endl; return result; }; rttb::core::DoseAccessorInterface::DoseAccessorPointer rttb::apps::doseAcc::loadDicomDose(const std::string& fileName) { rttb::io::dicom::DicomFileDoseAccessorGenerator generator(fileName); return generator.generateDoseAccessor(); }; rttb::core::DoseAccessorInterface::DoseAccessorPointer rttb::apps::doseAcc::loadHelaxDose(const std::string& path) { rttb::io::helax::DicomHelaxFileDoseAccessorGenerator generator(path); return generator.generateDoseAccessor(); }; rttb::core::DoseAccessorInterface::DoseAccessorPointer rttb::apps::doseAcc::loadITKDose(const std::string& fileName) { - rttb::io::itk::ITKImageFileDoseAccessorGenerator generator(fileName); + rttb::io::itk::ITKImageFileAccessorGenerator generator(fileName); return generator.generateDoseAccessor(); }; rttb::core::DoseAccessorInterface::DoseAccessorPointer rttb::apps::doseAcc::loadVirtuosDose(const std::string& fileName, const std::string& planFileName) { rttb::io::virtuos::VirtuosPlanFileDoseAccessorGenerator generator(fileName, planFileName); return generator.generateDoseAccessor(); }; rttb::apps::doseAcc::ApplicationData::RegistrationType::Pointer rttb::apps::doseAcc::loadRegistration(const std::string& fileName) { map::io::RegistrationFileReader::Pointer spRegReader = map::io::RegistrationFileReader::New(); map::io::RegistrationFileReader::LoadedRegistrationPointer spReg; std::cout << std::endl << "read registration file... "; spReg = spRegReader->read(fileName); std::cout << "done." << std::endl; ApplicationData::RegistrationType::Pointer resultPtr = dynamic_cast(spReg.GetPointer()); if (resultPtr.IsNull()) { rttbDefaultExceptionStaticMacro( << "Loaded registration cannot be used. Only 3D 3D registrations are allowed."); } return resultPtr; }; rttb::core::DoseAccessorInterface::DoseAccessorPointer generateNNMappableAccessor( const rttb::core::GeometricInfo& geoInfoTargetImage, const rttb::core::DoseAccessorInterface::DoseAccessorPointer doseMovingImage, const rttb::interpolation::TransformationInterface::Pointer aTransformation) { rttb::interpolation::InterpolationBase::Pointer interpolate = rttb::interpolation::NearestNeighborInterpolation::Pointer(new rttb::interpolation::NearestNeighborInterpolation()); return rttb::core::DoseAccessorInterface::DoseAccessorPointer( new rttb::interpolation::SimpleMappableDoseAccessor(geoInfoTargetImage, doseMovingImage, aTransformation, interpolate)); } rttb::core::DoseAccessorInterface::DoseAccessorPointer generateLinearMappableAccessor( const rttb::core::GeometricInfo& geoInfoTargetImage, const rttb::core::DoseAccessorInterface::DoseAccessorPointer doseMovingImage, const rttb::interpolation::TransformationInterface::Pointer aTransformation) { rttb::interpolation::InterpolationBase::Pointer interpolate = rttb::interpolation::LinearInterpolation::Pointer(new rttb::interpolation::LinearInterpolation()); return rttb::core::DoseAccessorInterface::DoseAccessorPointer( new rttb::interpolation::SimpleMappableDoseAccessor(geoInfoTargetImage, doseMovingImage, aTransformation, interpolate)); } rttb::core::DoseAccessorInterface::DoseAccessorPointer generateRosuMappableAccessor( const rttb::core::GeometricInfo& geoInfoTargetImage, const rttb::core::DoseAccessorInterface::DoseAccessorPointer doseMovingImage, const rttb::interpolation::TransformationInterface::Pointer aTransformation) { return rttb::core::DoseAccessorInterface::DoseAccessorPointer( new rttb::interpolation::RosuMappableDoseAccessor(geoInfoTargetImage, doseMovingImage, aTransformation)); } /**Private helper function for processData(). Generates a suitable output accessor * (depending on the configuration in appData a suitable accessor pipeline is established) * which performs the accumulation of the doses and returns the output.to */ rttb::core::DoseAccessorInterface::DoseAccessorPointer assembleOutputAccessor(rttb::apps::doseAcc::ApplicationData& appData) { rttb::core::DoseAccessorInterface::DoseAccessorPointer dose2Accessor = appData._Dose2; if (appData._spReg.IsNotNull()) { rttb::interpolation::TransformationInterface::Pointer transform = rttb::interpolation::TransformationInterface::Pointer(new rttb::interpolation::MatchPointTransformation(appData._spReg)); if (appData._interpolatorName == "rosu") { dose2Accessor = generateRosuMappableAccessor(appData._Dose1->getGeometricInfo(), appData._Dose2, transform); } else if (appData._interpolatorName == "nn") { dose2Accessor = generateNNMappableAccessor(appData._Dose1->getGeometricInfo(), appData._Dose2, transform); } else if (appData._interpolatorName == "linear") { dose2Accessor = generateLinearMappableAccessor(appData._Dose1->getGeometricInfo(), appData._Dose2, transform); } else { rttbDefaultExceptionStaticMacro( << "Unkown interpolation type selected. Cannot map dose. Interpolation type: " << appData._interpolatorName); } } rttb::core::DoseAccessorInterface::DoseAccessorPointer outputAccessor; if (appData._operator == "+") { rttb::algorithms::arithmetic::doseOp::AddWeighted addOp(appData._weightDose1, appData._weightDose2); - outputAccessor = + rttb::core::DoseAccessorInterface::DoseAccessorPointer outputAccessor = rttb::core::DoseAccessorInterface::DoseAccessorPointer(new - rttb::algorithms::BinaryFunctorDoseAccessor + rttb::algorithms::BinaryFunctorAccessor (appData._Dose1, dose2Accessor, addOp)); } else if (appData._operator == "*") { outputAccessor = rttb::core::DoseAccessorInterface::DoseAccessorPointer(new - rttb::algorithms::BinaryFunctorDoseAccessor + rttb::algorithms::BinaryFunctorAccessor (appData._Dose1, dose2Accessor, rttb::algorithms::arithmetic::doseOp::Multiply())); } else { rttbDefaultExceptionStaticMacro( << "Unkown operator selected. Cannot map dose. Operator: " << appData._interpolatorName); } return outputAccessor; } void rttb::apps::doseAcc::processData(rttb::apps::doseAcc::ApplicationData& appData) { rttb::core::DoseAccessorInterface::DoseAccessorPointer outputAccessor = assembleOutputAccessor( appData); std::cout << std::endl << "generate output image... "; - io::itk::ITKImageDoseAccessorConverter converter(outputAccessor); + io::itk::ITKImageAccessorConverter converter(outputAccessor); converter.setFailOnInvalidIDs(true); converter.process(); - io::itk::ITKDoseImageType::Pointer itkImage = converter.getITKImage(); + io::itk::ITKImageAccessorConverter::ITKImageType::Pointer itkImage = converter.getITKImage(); std::cout << "done." << std::endl; - typedef ::itk::ImageFileWriter WriterType; + typedef ::itk::ImageFileWriter WriterType; std::cout << std::endl << "write output image... "; WriterType::Pointer writer = WriterType::New(); writer->SetInput(itkImage); writer->SetFileName(appData._outputFileName); writer->Write(); std::cout << "done." << std::endl; }; diff --git a/demoapps/DoseMap/DoseMapHelper.cpp b/demoapps/DoseMap/DoseMapHelper.cpp index 51bb0f0..f5d5513 100644 --- a/demoapps/DoseMap/DoseMapHelper.cpp +++ b/demoapps/DoseMap/DoseMapHelper.cpp @@ -1,209 +1,209 @@ // ----------------------------------------------------------------------- // 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: 741 $ (last changed revision) // @date $Date: 2014-09-16 16:34:22 +0200 (Di, 16 Sep 2014) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "DoseMapHelper.h" #include "mapRegistrationFileReader.h" #include "itkImageFileWriter.h" #include "rttbVirtuosPlanFileDoseAccessorGenerator.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomHelaxFileDoseAccessorGenerator.h" -#include "rttbITKImageFileDoseAccessorGenerator.h" +#include "rttbITKImageAccessorConverter.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbSimpleMappableDoseAccessor.h" #include "rttbMatchPointTransformation.h" #include "rttbLinearInterpolation.h" #include "rttbNearestNeighborInterpolation.h" #include "rttbRosuMappableDoseAccessor.h" -#include "rttbITKImageDoseAccessorConverter.h" +#include "rttbITKImageFileAccessorGenerator.h" #include "rttbArithmetic.h" -#include "rttbBinaryFunctorDoseAccessor.h" +#include "rttbBinaryFunctorAccessor.h" #include "rttbExceptionMacros.h" rttb::core::DoseAccessorInterface::DoseAccessorPointer rttb::apps::doseMap::loadDose(const std::string& fileName, const rttb::apps::doseMap::ApplicationData::LoadingStyleArgType& args) { - rttb::core::DoseAccessorInterface::DoseAccessorPointer result; - - std::cout << std::endl << "read dose file... "; - - if (args.empty() || args[0] == "dicom") - { - std::cout << "use RTTB dicom IO... "; - result = loadDicomDose(fileName); - } - else if (args[0] == "helax") - { - std::cout << "use RTTB Helax IO... "; - result = loadHelaxDose(fileName); - } - else if (args[0] == "itk") - { - std::cout << "use RTTB itk IO... "; - result = loadITKDose(fileName); - } - else if (args[0] == "virtuos") - { - if (args.size() < 2) - { - rttbDefaultExceptionStaticMacro( << - "Cannot load virtuos dose. Plan file is missing. Specify plan file as 2nd io stlye argument."); - } - - std::cout << "use RTTB virtuos IO... " << std::endl; - std::cout << " virtuos plan file: " << args[1] << " ... "; - result = loadVirtuosDose(fileName, args[1]); - } - else - { - rttbDefaultExceptionStaticMacro( << "Unknown io style selected. Cannot load data. Selected style: " - << args[0]); - } - - std::cout << "done." << std::endl; - - return result; + rttb::core::DoseAccessorInterface::DoseAccessorPointer result; + + std::cout << std::endl << "read dose file... "; + + if (args.empty() || args[0] == "dicom") + { + std::cout << "use RTTB dicom IO... "; + result = loadDicomDose(fileName); + } + else if (args[0] == "helax") + { + std::cout << "use RTTB Helax IO... "; + result = loadHelaxDose(fileName); + } + else if (args[0] == "itk") + { + std::cout << "use RTTB itk IO... "; + result = loadITKDose(fileName); + } + else if (args[0] == "virtuos") + { + if (args.size() < 2) + { + rttbDefaultExceptionStaticMacro( << + "Cannot load virtuos dose. Plan file is missing. Specify plan file as 2nd io stlye argument."); + } + + std::cout << "use RTTB virtuos IO... " << std::endl; + std::cout << " virtuos plan file: " << args[1] << " ... "; + result = loadVirtuosDose(fileName, args[1]); + } + else + { + rttbDefaultExceptionStaticMacro( << "Unknown io style selected. Cannot load data. Selected style: " + << args[0]); + } + + std::cout << "done." << std::endl; + + return result; }; rttb::core::DoseAccessorInterface::DoseAccessorPointer rttb::apps::doseMap::loadDicomDose(const std::string& fileName) { - rttb::io::dicom::DicomFileDoseAccessorGenerator generator(fileName); - return generator.generateDoseAccessor(); + rttb::io::dicom::DicomFileDoseAccessorGenerator generator(fileName); + return generator.generateDoseAccessor(); }; rttb::core::DoseAccessorInterface::DoseAccessorPointer rttb::apps::doseMap::loadHelaxDose(const std::string& path) { - rttb::io::helax::DicomHelaxFileDoseAccessorGenerator generator(path); - return generator.generateDoseAccessor(); + rttb::io::helax::DicomHelaxFileDoseAccessorGenerator generator(path); + return generator.generateDoseAccessor(); }; rttb::core::DoseAccessorInterface::DoseAccessorPointer rttb::apps::doseMap::loadITKDose(const std::string& fileName) { - rttb::io::itk::ITKImageFileDoseAccessorGenerator generator(fileName); - return generator.generateDoseAccessor(); + rttb::io::itk::ITKImageFileAccessorGenerator generator(fileName); + return generator.generateDoseAccessor(); }; rttb::core::DoseAccessorInterface::DoseAccessorPointer rttb::apps::doseMap::loadVirtuosDose(const std::string& fileName, const std::string& planFileName) { - rttb::io::virtuos::VirtuosPlanFileDoseAccessorGenerator generator(fileName, planFileName); - return generator.generateDoseAccessor(); + rttb::io::virtuos::VirtuosPlanFileDoseAccessorGenerator generator(fileName, planFileName); + return generator.generateDoseAccessor(); }; rttb::apps::doseMap::ApplicationData::RegistrationType::Pointer rttb::apps::doseMap::loadRegistration(const std::string& fileName) { - map::io::RegistrationFileReader::Pointer spRegReader = map::io::RegistrationFileReader::New(); + map::io::RegistrationFileReader::Pointer spRegReader = map::io::RegistrationFileReader::New(); - map::io::RegistrationFileReader::LoadedRegistrationPointer spReg; + map::io::RegistrationFileReader::LoadedRegistrationPointer spReg; - std::cout << std::endl << "read registration file... "; - spReg = spRegReader->read(fileName); - std::cout << "done." << std::endl; + std::cout << std::endl << "read registration file... "; + spReg = spRegReader->read(fileName); + std::cout << "done." << std::endl; - ApplicationData::RegistrationType::Pointer resultPtr = - dynamic_cast(spReg.GetPointer()); + ApplicationData::RegistrationType::Pointer resultPtr = + dynamic_cast(spReg.GetPointer()); - if (resultPtr.IsNull()) - { - mapDefaultExceptionStaticMacro( << - "Loaded registration cannot be used. Only 3D 3D registrations are allowed."); - } + if (resultPtr.IsNull()) + { + mapDefaultExceptionStaticMacro( << + "Loaded registration cannot be used. Only 3D 3D registrations are allowed."); + } - return resultPtr; + return resultPtr; }; /**Private helper function for processData(). Generates a suitable output accessor * (depending on the configuration in appData a suitable accessor pipeline is established) * which performs the accumulation of the doses and returns the output.to */ rttb::core::DoseAccessorInterface::DoseAccessorPointer assembleOutputAccessor(rttb::apps::doseMap::ApplicationData& appData) { - rttb::core::DoseAccessorInterface::DoseAccessorPointer outputAccessor = appData._inputDose; - - rttb::interpolation::TransformationInterface::Pointer transform = - rttb::interpolation::TransformationInterface::Pointer(new - rttb::interpolation::MatchPointTransformation(appData._spReg)); - - if (appData._interpolatorName == "rosu") - { - outputAccessor = rttb::core::DoseAccessorInterface::DoseAccessorPointer( - new rttb::interpolation::RosuMappableDoseAccessor(appData._refDose->getGeometricInfo(), - appData._inputDose, transform)); - } - else - { - rttb::interpolation::InterpolationBase::Pointer interpolate = - rttb::interpolation::LinearInterpolation::Pointer(new - rttb::interpolation::LinearInterpolation()); - - if (appData._interpolatorName == "nn") - { - interpolate = rttb::interpolation::NearestNeighborInterpolation::Pointer(new - rttb::interpolation::NearestNeighborInterpolation()); - } - else if (appData._interpolatorName != "linear") - { - mapDefaultExceptionStaticMacro( << - "Unkown interpolation type selected. Cannot map dose. Interpolation type: " << - appData._interpolatorName); - } - - outputAccessor = rttb::core::DoseAccessorInterface::DoseAccessorPointer( - new rttb::interpolation::SimpleMappableDoseAccessor(appData._refDose->getGeometricInfo(), - appData._inputDose, transform, interpolate)); - } - - return outputAccessor; + rttb::core::DoseAccessorInterface::DoseAccessorPointer outputAccessor = appData._inputDose; + + rttb::interpolation::TransformationInterface::Pointer transform = + rttb::interpolation::TransformationInterface::Pointer(new + rttb::interpolation::MatchPointTransformation(appData._spReg)); + + if (appData._interpolatorName == "rosu") + { + outputAccessor = rttb::core::DoseAccessorInterface::DoseAccessorPointer( + new rttb::interpolation::RosuMappableDoseAccessor(appData._refDose->getGeometricInfo(), + appData._inputDose, transform)); + } + else + { + rttb::interpolation::InterpolationBase::Pointer interpolate = + rttb::interpolation::LinearInterpolation::Pointer(new + rttb::interpolation::LinearInterpolation()); + + if (appData._interpolatorName == "nn") + { + interpolate = rttb::interpolation::NearestNeighborInterpolation::Pointer(new + rttb::interpolation::NearestNeighborInterpolation()); + } + else if (appData._interpolatorName != "linear") + { + mapDefaultExceptionStaticMacro( << + "Unkown interpolation type selected. Cannot map dose. Interpolation type: " << + appData._interpolatorName); + } + + outputAccessor = rttb::core::DoseAccessorInterface::DoseAccessorPointer( + new rttb::interpolation::SimpleMappableDoseAccessor(appData._refDose->getGeometricInfo(), + appData._inputDose, transform, interpolate)); + } + + return outputAccessor; } void rttb::apps::doseMap::processData(rttb::apps::doseMap::ApplicationData& appData) { - rttb::core::DoseAccessorInterface::DoseAccessorPointer outputAccessor = assembleOutputAccessor( - appData); - - std::cout << std::endl << "generate output image... "; - io::itk::ITKImageDoseAccessorConverter converter(outputAccessor); - converter.setFailOnInvalidIDs(true); - converter.process(); - io::itk::ITKDoseImageType::Pointer itkImage = converter.getITKImage(); - std::cout << "done." << std::endl; - - typedef ::itk::ImageFileWriter WriterType; - - std::cout << std::endl << "write output image... "; - WriterType::Pointer writer = WriterType::New(); - writer->SetInput(itkImage); - writer->SetFileName(appData._outputFileName); - writer->Write(); - std::cout << "done." << std::endl; + rttb::core::DoseAccessorInterface::DoseAccessorPointer outputAccessor = assembleOutputAccessor( + appData); + + std::cout << std::endl << "generate output image... "; + io::itk::ITKImageAccessorConverter converter(outputAccessor); + converter.setFailOnInvalidIDs(true); + converter.process(); + io::itk::ITKImageAccessorConverter::ITKImageType::Pointer itkImage = converter.getITKImage(); + std::cout << "done." << std::endl; + + typedef ::itk::ImageFileWriter WriterType; + + std::cout << std::endl << "write output image... "; + WriterType::Pointer writer = WriterType::New(); + writer->SetInput(itkImage); + writer->SetFileName(appData._outputFileName); + writer->Write(); + std::cout << "done." << std::endl; }; diff --git a/testing/algorithms/ArithmeticTest.cpp b/testing/algorithms/ArithmeticTest.cpp index 3a52489..bf70e70 100644 --- a/testing/algorithms/ArithmeticTest.cpp +++ b/testing/algorithms/ArithmeticTest.cpp @@ -1,363 +1,363 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "../core/DummyDoseAccessor.h" #include "../core/DummyMaskAccessor.h" #include "../core/DummyMutableDoseAccessor.h" #include "rttbDoseAccessorInterface.h" #include "rttbMutableDoseAccessorInterface.h" #include "rttbMutableMaskAccessorInterface.h" #include "rttbArithmetic.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "rttbGenericMutableMaskAccessor.h" #include "rttbMaskAccessorInterface.h" namespace rttb { namespace testing { typedef core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; typedef core::MutableDoseAccessorInterface::MutableDoseAccessorPointer MutableDoseAccessorPointer; typedef DummyMaskAccessor::MaskVoxelListPointer MaskVoxelListPointer; typedef DummyMaskAccessor::MaskVoxelList MaskVoxelList; typedef core::MaskAccessorInterface::MaskAccessorPointer MaskAccessorPointer; typedef core::MutableMaskAccessorInterface::MutableMaskAccessorPointer MutableMaskAccessorPointer; /*! @brief ArithmeticTest - tests arithmetic combinations of accessors 1) test dose-dose operations 2) test dose-mask operations 3) test mask-mask operations 4) test convenience functions */ int ArithmeticTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; // initialize accessors for arithmetic //DOSE: //Null pointers DoseAccessorPointer spDoseNull; MutableDoseAccessorPointer spMutableDoseNull; //dose with random values between 0 and 100 boost::shared_ptr spTestDoseAccessor1 = boost::make_shared(); DoseAccessorPointer spDoseAccessor1(spTestDoseAccessor1); //generate a 2nd dose with fixed values core::GeometricInfo geoInfo = spDoseAccessor1->getGeometricInfo(); DoseTypeGy valFix = 101; // to ensure values are larger than 100 on adding std::vector dose2Vals(geoInfo.getNumberOfVoxels(), valFix); boost::shared_ptr spTestDoseAccessor2 = boost::make_shared (dose2Vals, geoInfo); DoseAccessorPointer spDoseAccessor2(spTestDoseAccessor2); //generate result acessor std::vector doseResultVals(geoInfo.getNumberOfVoxels(), -1); boost::shared_ptr spTestMutableDoseAccessor = boost::make_shared(doseResultVals, geoInfo); MutableDoseAccessorPointer spMutableDoseAccessor(spTestMutableDoseAccessor); // different geometricInfo core::GeometricInfo geoInfo2 = geoInfo; geoInfo2.setNumColumns(5); geoInfo2.setNumRows(5); geoInfo2.setNumSlices(5); std::vector dose3Vals(geoInfo2.getNumberOfVoxels(), valFix); boost::shared_ptr spTestDoseAccessor3 = boost::make_shared (dose3Vals, geoInfo2); DoseAccessorPointer spDoseAccessorDiffGeoInfo(spTestDoseAccessor3); boost::shared_ptr spTestMutableDoseAccessor2 = boost::make_shared(dose3Vals, geoInfo2); MutableDoseAccessorPointer spMutableDoseAccessorDiffGeoInfo(spTestMutableDoseAccessor2); //MASK: //null pointer MaskAccessorPointer spMaskAccessorNull; MutableMaskAccessorPointer spMutableMaskAccessorNull; MaskVoxelList voxelList; FractionType aVolumeFraction = 1; VoxelGridID aVoxelGridID = 10; //generate a dummy mask while (aVoxelGridID < geoInfo.getNumberOfVoxels() && aVoxelGridID <= 30) { voxelList.push_back(core::MaskVoxel(aVoxelGridID, aVolumeFraction)); ++aVoxelGridID; } MaskVoxelListPointer voxelListPtr = boost::make_shared(voxelList); boost::shared_ptr dummyMask1 = boost::make_shared(geoInfo, voxelListPtr); MaskAccessorPointer spMaskAccessor1(dummyMask1); MaskVoxelList voxelList2; aVoxelGridID = 20; //generate a 2nd dummy mask that partly overlaps with the 1st one while (aVoxelGridID < geoInfo.getNumberOfVoxels() && aVoxelGridID <= 40) { voxelList2.push_back(core::MaskVoxel(aVoxelGridID, aVolumeFraction)); ++aVoxelGridID; } MaskVoxelListPointer voxelListPtr2 = boost::make_shared(voxelList2); boost::shared_ptr dummyMask2 = boost::make_shared(geoInfo, voxelListPtr2); MaskAccessorPointer spMaskAccessor2(dummyMask2); // result accessor boost::shared_ptr mMask1 = boost::make_shared(geoInfo); MutableMaskAccessorPointer spMutableMask(mMask1); // different geometricInfo boost::shared_ptr spDummyMaskDiffGeoInfo = boost::make_shared (geoInfo2, voxelListPtr2); MaskAccessorPointer spMaskAccessorDiffGeoInfo(spDummyMaskDiffGeoInfo); boost::shared_ptr mMask2 = boost::make_shared(geoInfo2); MutableMaskAccessorPointer spMutableMaskDiffGeoInfo(mMask2); // 1) test dose-dose operations //ADD algorithms::arithmetic::doseOp::Add addOP; CHECK_NO_THROW(algorithms::arithmetic::arithmetic(spDoseAccessor1, spDoseAccessor2, spMutableDoseAccessor, addOP)); VoxelGridID id = 5; - CHECK(spMutableDoseAccessor->getDoseAt(id) > 100); - CHECK_EQUAL(spDoseAccessor1->getDoseAt(id) + valFix, spMutableDoseAccessor->getDoseAt(id)); + CHECK(spMutableDoseAccessor->getValueAt(id) > 100); + CHECK_EQUAL(spDoseAccessor1->getValueAt(id) + valFix, spMutableDoseAccessor->getValueAt(id)); id = 10; - CHECK(spMutableDoseAccessor->getDoseAt(id) > 100); - CHECK_EQUAL(spDoseAccessor1->getDoseAt(id) + valFix, spMutableDoseAccessor->getDoseAt(id)); + CHECK(spMutableDoseAccessor->getValueAt(id) > 100); + CHECK_EQUAL(spDoseAccessor1->getValueAt(id) + valFix, spMutableDoseAccessor->getValueAt(id)); //@todo add MappableDoseAccessor Tests //handling exceptions is tested once for dose-dose operations, because this does not change if the operation changes. //handling null pointers CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor1, spDoseNull, spMutableDoseAccessor, addOP), core::NullPointerException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseNull, spDoseAccessor2, spMutableDoseAccessor, addOP), core::NullPointerException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor1, spDoseAccessor2, spMutableDoseNull, addOP), core::NullPointerException); //handle different geometricInfos CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor1, spDoseAccessorDiffGeoInfo, spMutableDoseAccessor, addOP), core::InvalidParameterException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessorDiffGeoInfo, spDoseAccessor2, spMutableDoseAccessor, addOP), core::InvalidParameterException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor1, spDoseAccessor2, spMutableDoseAccessorDiffGeoInfo, addOP), core::InvalidParameterException); //ADD_WEIGHTED algorithms::arithmetic::doseOp::AddWeighted addWOP(1, 2); CHECK_NO_THROW(algorithms::arithmetic::arithmetic(spDoseAccessor1, spDoseAccessor2, spMutableDoseAccessor, addWOP)); id = 5; - CHECK(spMutableDoseAccessor->getDoseAt(id) > 201); - CHECK_EQUAL(spDoseAccessor1->getDoseAt(id) + 2 * valFix, spMutableDoseAccessor->getDoseAt(id)); + CHECK(spMutableDoseAccessor->getValueAt(id) > 201); + CHECK_EQUAL(spDoseAccessor1->getValueAt(id) + 2 * valFix, spMutableDoseAccessor->getValueAt(id)); id = 10; - CHECK(spMutableDoseAccessor->getDoseAt(id) > 201); - CHECK_EQUAL(spDoseAccessor1->getDoseAt(id) + 2 * valFix, spMutableDoseAccessor->getDoseAt(id)); + CHECK(spMutableDoseAccessor->getValueAt(id) > 201); + CHECK_EQUAL(spDoseAccessor1->getValueAt(id) + 2 * valFix, spMutableDoseAccessor->getValueAt(id)); //MULTIPLY algorithms::arithmetic::doseOp::Multiply multiplyOP; CHECK_NO_THROW(algorithms::arithmetic::arithmetic(spDoseAccessor1, spDoseAccessor2, spMutableDoseAccessor, multiplyOP)); id = 5; - CHECK(spMutableDoseAccessor->getDoseAt(id) > 201); - CHECK_EQUAL(spDoseAccessor1->getDoseAt(id) * valFix, spMutableDoseAccessor->getDoseAt(id)); + CHECK(spMutableDoseAccessor->getValueAt(id) > 201); + CHECK_EQUAL(spDoseAccessor1->getValueAt(id) * valFix, spMutableDoseAccessor->getValueAt(id)); id = 10; - CHECK(spMutableDoseAccessor->getDoseAt(id) > 201); - CHECK_EQUAL(spDoseAccessor1->getDoseAt(id) * valFix, spMutableDoseAccessor->getDoseAt(id)); + CHECK(spMutableDoseAccessor->getValueAt(id) > 201); + CHECK_EQUAL(spDoseAccessor1->getValueAt(id) * valFix, spMutableDoseAccessor->getValueAt(id)); //@todo add MappableDoseAccessor Tests // 2) test dose-mask operations //MULTIPLY algorithms::arithmetic::doseMaskOp::Multiply multOP; CHECK_NO_THROW(algorithms::arithmetic::arithmetic(spDoseAccessor2, spMaskAccessor1, spMutableDoseAccessor, multOP)); core::MaskVoxel mVoxel(0); id = 5; - CHECK_EQUAL(0, spMutableDoseAccessor->getDoseAt(id)); + CHECK_EQUAL(0, spMutableDoseAccessor->getValueAt(id)); spMaskAccessor1->getMaskAt(id, mVoxel); - CHECK_EQUAL(spMutableDoseAccessor->getDoseAt(id), mVoxel.getRelevantVolumeFraction()); + CHECK_EQUAL(spMutableDoseAccessor->getValueAt(id), mVoxel.getRelevantVolumeFraction()); id = 15; - CHECK_EQUAL(valFix, spMutableDoseAccessor->getDoseAt(id)); + CHECK_EQUAL(valFix, spMutableDoseAccessor->getValueAt(id)); id = 35; - CHECK_EQUAL(0, spMutableDoseAccessor->getDoseAt(id)); + CHECK_EQUAL(0, spMutableDoseAccessor->getValueAt(id)); //@todo add MappableDoseAccessor Tests //handling exceptions is tested once for dose-dose operations, because this does not change if the operation changes. //handling null pointers CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor1, spMaskAccessorNull, spMutableDoseAccessor, multOP), core::NullPointerException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseNull, spDoseAccessor2, spMutableDoseAccessor, multOP), core::NullPointerException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor2, spMaskAccessor1, spMutableDoseNull, multOP), core::NullPointerException); //handle different geometricInfos CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor2, spMaskAccessorDiffGeoInfo, spMutableDoseAccessor, multOP), core::InvalidParameterException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessorDiffGeoInfo, spMaskAccessor1, spMutableDoseAccessor, multOP), core::InvalidParameterException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor2, spMaskAccessor1, spMutableDoseAccessorDiffGeoInfo, multOP), core::InvalidParameterException); // 3) test mask-mask operations //ADD algorithms::arithmetic::maskOp::Add maskAddOP; CHECK_NO_THROW(algorithms::arithmetic::arithmetic(spMaskAccessor1, spMaskAccessor2, spMutableMask, maskAddOP)); id = 5; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); id = 15; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(1, mVoxel.getRelevantVolumeFraction()); id = 35; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(1, mVoxel.getRelevantVolumeFraction()); id = 45; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); //handling exceptions is tested once for dose-dose operations, because this does not change if the operation changes. //handling null pointers CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spMaskAccessor1, spMaskAccessorNull, spMutableMask, maskAddOP), core::NullPointerException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spMaskAccessorNull, spMaskAccessor2, spMutableMask, maskAddOP), core::NullPointerException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spMaskAccessor1, spMaskAccessor1, spMutableMaskAccessorNull, maskAddOP), core::NullPointerException); //handle different geometricInfos CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spMaskAccessor1, spMaskAccessorDiffGeoInfo, spMutableMask, maskAddOP), core::InvalidParameterException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spMaskAccessorDiffGeoInfo, spMaskAccessor2, spMutableMask, maskAddOP), core::InvalidParameterException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spMaskAccessor1, spMaskAccessor1, spMutableMaskDiffGeoInfo, maskAddOP), core::InvalidParameterException); //SUBTRACT algorithms::arithmetic::maskOp::Subtract maskSubOP; CHECK_NO_THROW(algorithms::arithmetic::arithmetic(spMaskAccessor1, spMaskAccessor2, spMutableMask, maskSubOP)); id = 5; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); id = 15; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(1, mVoxel.getRelevantVolumeFraction()); id = 35; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); id = 45; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); // 4) test convenience functions // tests are similar to explicit calls //@todo if convenience functions are implemented: add MappableDoseAccessor Tests CHECK_NO_THROW(algorithms::arithmetic::add(spDoseAccessor1, spDoseAccessor2, spMutableDoseAccessor)); id = 5; - CHECK(spMutableDoseAccessor->getDoseAt(id) > 100); - CHECK_EQUAL(spDoseAccessor1->getDoseAt(id) + valFix, spMutableDoseAccessor->getDoseAt(id)); + CHECK(spMutableDoseAccessor->getValueAt(id) > 100); + CHECK_EQUAL(spDoseAccessor1->getValueAt(id) + valFix, spMutableDoseAccessor->getValueAt(id)); id = 10; - CHECK(spMutableDoseAccessor->getDoseAt(id) > 100); - CHECK_EQUAL(spDoseAccessor1->getDoseAt(id) + valFix, spMutableDoseAccessor->getDoseAt(id)); + CHECK(spMutableDoseAccessor->getValueAt(id) > 100); + CHECK_EQUAL(spDoseAccessor1->getValueAt(id) + valFix, spMutableDoseAccessor->getValueAt(id)); CHECK_NO_THROW(algorithms::arithmetic::add(spMaskAccessor1, spMaskAccessor2, spMutableMask)); id = 5; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); id = 15; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(1, mVoxel.getRelevantVolumeFraction()); id = 35; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(1, mVoxel.getRelevantVolumeFraction()); id = 45; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); CHECK_NO_THROW(algorithms::arithmetic::subtract(spMaskAccessor1, spMaskAccessor2, spMutableMask)); id = 5; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); id = 15; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(1, mVoxel.getRelevantVolumeFraction()); id = 35; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); id = 45; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); CHECK_NO_THROW(algorithms::arithmetic::multiply(spDoseAccessor2, spMaskAccessor1, spMutableDoseAccessor)); id = 5; - CHECK_EQUAL(0, spMutableDoseAccessor->getDoseAt(id)); + CHECK_EQUAL(0, spMutableDoseAccessor->getValueAt(id)); spMaskAccessor1->getMaskAt(id, mVoxel); - CHECK_EQUAL(spMutableDoseAccessor->getDoseAt(id), mVoxel.getRelevantVolumeFraction()); + CHECK_EQUAL(spMutableDoseAccessor->getValueAt(id), mVoxel.getRelevantVolumeFraction()); id = 15; - CHECK_EQUAL(valFix, spMutableDoseAccessor->getDoseAt(id)); + CHECK_EQUAL(valFix, spMutableDoseAccessor->getValueAt(id)); id = 35; - CHECK_EQUAL(0, spMutableDoseAccessor->getDoseAt(id)); + CHECK_EQUAL(0, spMutableDoseAccessor->getValueAt(id)); RETURN_AND_REPORT_TEST_SUCCESS; } } } \ No newline at end of file diff --git a/testing/algorithms/BinaryFunctorDoseAccessorTest.cpp b/testing/algorithms/BinaryFunctorAccessorTest.cpp similarity index 54% rename from testing/algorithms/BinaryFunctorDoseAccessorTest.cpp rename to testing/algorithms/BinaryFunctorAccessorTest.cpp index d987a80..fac249d 100644 --- a/testing/algorithms/BinaryFunctorDoseAccessorTest.cpp +++ b/testing/algorithms/BinaryFunctorAccessorTest.cpp @@ -1,134 +1,134 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) -// @date $Date$ (last change date) -// @author $Author$ (last changed by) +// @version $Revision: 741 $ (last changed revision) +// @date $Date: 2014-09-16 16:34:22 +0200 (Di, 16 Sep 2014) $ (last change date) +// @author $Author: hentsch $ (last changed by) */ #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbDoseAccessorInterface.h" #include "rttbDicomDoseAccessor.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbArithmetic.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" -#include "rttbBinaryFunctorDoseAccessor.h" +#include "rttbBinaryFunctorAccessor.h" namespace rttb { namespace testing { typedef core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; - typedef algorithms::BinaryFunctorDoseAccessor - BinaryFunctorDoseAccessorAddType; - typedef algorithms::BinaryFunctorDoseAccessor - BinaryFunctorDoseAccessorAddWeightedType; + typedef algorithms::BinaryFunctorAccessor + BinaryFunctorAccessorAddType; + typedef algorithms::BinaryFunctorAccessor + BinaryFunctorAccessorAddWeightedType; - /*! @brief BinaryFunctorDoseAccessorTest - tests functors of dose-dose accessors + /*! @brief BinaryFunctorAccessorTest - tests functors of two accessors 1) test constructor 2) test getDoseAt */ - int BinaryFunctorDoseAccessorTest(int argc, char* argv[]) + int BinaryFunctorAccessorTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; std::string RTDOSE_FILENAME; std::string RTDOSE2_FILENAME; if (argc > 1) { RTDOSE_FILENAME = argv[1]; } if (argc > 2) { RTDOSE2_FILENAME = argv[2]; } DoseAccessorPointer spDoseAccessorNull; DoseAccessorPointer spDoseAccessor = io::dicom::DicomFileDoseAccessorGenerator( RTDOSE_FILENAME.c_str()).generateDoseAccessor(); DoseAccessorPointer spDoseAccessor2 = io::dicom::DicomFileDoseAccessorGenerator( RTDOSE2_FILENAME.c_str()).generateDoseAccessor(); algorithms::arithmetic::doseOp::Add addOP; algorithms::arithmetic::doseOp::AddWeighted addWeightedOP(1.0, 10.0); algorithms::arithmetic::doseOp::AddWeighted addWeightedTwoOP(2.0, 2.0); //1) Check constructor - CHECK_THROW_EXPLICIT(BinaryFunctorDoseAccessorAddType(spDoseAccessorNull, spDoseAccessor, addOP), + CHECK_THROW_EXPLICIT(BinaryFunctorAccessorAddType(spDoseAccessorNull, spDoseAccessor, addOP), core::NullPointerException); - CHECK_THROW_EXPLICIT(BinaryFunctorDoseAccessorAddType(spDoseAccessor, spDoseAccessorNull, addOP), + CHECK_THROW_EXPLICIT(BinaryFunctorAccessorAddType(spDoseAccessor, spDoseAccessorNull, addOP), core::NullPointerException); - CHECK_THROW_EXPLICIT(BinaryFunctorDoseAccessorAddType(spDoseAccessorNull, spDoseAccessorNull, + CHECK_THROW_EXPLICIT(BinaryFunctorAccessorAddType(spDoseAccessorNull, spDoseAccessorNull, addOP), core::NullPointerException); - CHECK_THROW_EXPLICIT(BinaryFunctorDoseAccessorAddType(spDoseAccessor, spDoseAccessor2, addOP), + CHECK_THROW_EXPLICIT(BinaryFunctorAccessorAddType(spDoseAccessor, spDoseAccessor2, addOP), core::InvalidParameterException); - CHECK_NO_THROW(BinaryFunctorDoseAccessorAddType(spDoseAccessor, spDoseAccessor, addOP)); - CHECK_NO_THROW(BinaryFunctorDoseAccessorAddWeightedType(spDoseAccessor, spDoseAccessor, + CHECK_NO_THROW(BinaryFunctorAccessorAddType(spDoseAccessor, spDoseAccessor, addOP)); + CHECK_NO_THROW(BinaryFunctorAccessorAddWeightedType(spDoseAccessor, spDoseAccessor, addWeightedOP)); - boost::shared_ptr spBinaryFunctorDoseAccessorAdd( - new BinaryFunctorDoseAccessorAddType(spDoseAccessor, spDoseAccessor, addOP)); - boost::shared_ptr spBinaryFunctorDoseAccessorAddWeighted( - new BinaryFunctorDoseAccessorAddWeightedType(spDoseAccessor, spDoseAccessor, addWeightedOP)); - boost::shared_ptr - spBinaryFunctorDoseAccessorAddWeightedTwo(new BinaryFunctorDoseAccessorAddWeightedType( + boost::shared_ptr spBinaryFunctorDoseAccessorAdd( + new BinaryFunctorAccessorAddType(spDoseAccessor, spDoseAccessor, addOP)); + boost::shared_ptr spBinaryFunctorDoseAccessorAddWeighted( + new BinaryFunctorAccessorAddWeightedType(spDoseAccessor, spDoseAccessor, addWeightedOP)); + boost::shared_ptr + spBinaryFunctorDoseAccessorAddWeightedTwo(new BinaryFunctorAccessorAddWeightedType( spDoseAccessor, spDoseAccessor, addWeightedTwoOP)); //2) Test getDoseAt() VoxelGridID aId[3] = {5, 6067, spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumberOfVoxels() - 1}; VoxelGridIndex3D aIndex[3] = {VoxelGridIndex3D(5, 0, 0), VoxelGridIndex3D(37, 0, 2), VoxelGridIndex3D(spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumColumns() - 1, spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumRows() - 1, spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumSlices() - 1)}; for (int i = 0; i < 3; ++i) { - CHECK_EQUAL(spBinaryFunctorDoseAccessorAdd->getDoseAt(aId[i]), 4.0); - CHECK_EQUAL(spBinaryFunctorDoseAccessorAddWeighted->getDoseAt(aId[i]), 22.0); - CHECK_EQUAL(spBinaryFunctorDoseAccessorAdd->getDoseAt(aIndex[i]), - spBinaryFunctorDoseAccessorAdd->getDoseAt(aId[i])); - CHECK_EQUAL(spBinaryFunctorDoseAccessorAddWeighted->getDoseAt(aIndex[i]), - spBinaryFunctorDoseAccessorAddWeighted->getDoseAt(aId[i])); - CHECK_EQUAL(spBinaryFunctorDoseAccessorAdd->getDoseAt(aId[i]) * 2.0, - spBinaryFunctorDoseAccessorAddWeightedTwo->getDoseAt(aId[i])); + CHECK_EQUAL(spBinaryFunctorDoseAccessorAdd->getValueAt(aId[i]), 4.0); + CHECK_EQUAL(spBinaryFunctorDoseAccessorAddWeighted->getValueAt(aId[i]), 22.0); + CHECK_EQUAL(spBinaryFunctorDoseAccessorAdd->getValueAt(aIndex[i]), + spBinaryFunctorDoseAccessorAdd->getValueAt(aId[i])); + CHECK_EQUAL(spBinaryFunctorDoseAccessorAddWeighted->getValueAt(aIndex[i]), + spBinaryFunctorDoseAccessorAddWeighted->getValueAt(aId[i])); + CHECK_EQUAL(spBinaryFunctorDoseAccessorAdd->getValueAt(aId[i]) * 2.0, + spBinaryFunctorDoseAccessorAddWeightedTwo->getValueAt(aId[i])); } VoxelGridID aIdInvalid(spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumberOfVoxels()); VoxelGridIndex3D aIndexInvalid(spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumColumns(), spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumRows(), spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumSlices()); - CHECK_EQUAL(spBinaryFunctorDoseAccessorAdd->getDoseAt(aIdInvalid), -1.0); - CHECK_EQUAL(spBinaryFunctorDoseAccessorAdd->getDoseAt(aIndexInvalid), -1.0); - CHECK_EQUAL(spBinaryFunctorDoseAccessorAddWeighted->getDoseAt(aIdInvalid), -1.0); - CHECK_EQUAL(spBinaryFunctorDoseAccessorAddWeighted->getDoseAt(aIndexInvalid), -1.0); + CHECK_EQUAL(spBinaryFunctorDoseAccessorAdd->getValueAt(aIdInvalid), -1.0); + CHECK_EQUAL(spBinaryFunctorDoseAccessorAdd->getValueAt(aIndexInvalid), -1.0); + CHECK_EQUAL(spBinaryFunctorDoseAccessorAddWeighted->getValueAt(aIdInvalid), -1.0); + CHECK_EQUAL(spBinaryFunctorDoseAccessorAddWeighted->getValueAt(aIndexInvalid), -1.0); RETURN_AND_REPORT_TEST_SUCCESS; } } } \ No newline at end of file diff --git a/testing/algorithms/CMakeLists.txt b/testing/algorithms/CMakeLists.txt index 4a106e5..912e5bd 100644 --- a/testing/algorithms/CMakeLists.txt +++ b/testing/algorithms/CMakeLists.txt @@ -1,21 +1,21 @@ #----------------------------------------------------------------------------- # Setup the system information test. Write out some basic failsafe # information in case the test doesn't run. #----------------------------------------------------------------------------- SET(ALGORITHMS_TESTS ${EXECUTABLE_OUTPUT_PATH}/rttbAlgorithmsTests) SET(ALGORITHMS_HEADER_TEST ${EXECUTABLE_OUTPUT_PATH}/rttbAlgorithmsHeaderTest) SET(TEST_DATA_ROOT ${RTTBTesting_SOURCE_DIR}/data) SET(TEMP ${RTTBTesting_BINARY_DIR}/temporary) #----------------------------------------------------------------------------- ADD_TEST(DoseStatisticsTest ${ALGORITHMS_TESTS} DoseStatisticsTest) ADD_TEST(ArithmeticTest ${ALGORITHMS_TESTS} ArithmeticTest) -ADD_TEST(BinaryFunctorDoseAccessorTest ${ALGORITHMS_TESTS} BinaryFunctorDoseAccessorTest "${TEST_DATA_ROOT}/DICOM/TestDose/ConstantTwo.dcm" "${TEST_DATA_ROOT}/DICOM/TestDose/dicompylerTestDose.dcm") +ADD_TEST(BinaryFunctorAccessorTest ${ALGORITHMS_TESTS} BinaryFunctorAccessorTest "${TEST_DATA_ROOT}/DICOM/TestDose/ConstantTwo.dcm" "${TEST_DATA_ROOT}/DICOM/TestDose/dicompylerTestDose.dcm") RTTB_CREATE_TEST_MODULE(rttbAlgorithms DEPENDS RTTBAlgorithms RTTBMasks RTTBDicomIO PACKAGE_DEPENDS Boost Litmus DCMTK) diff --git a/testing/algorithms/files.cmake b/testing/algorithms/files.cmake index e056ae8..01b0cac 100644 --- a/testing/algorithms/files.cmake +++ b/testing/algorithms/files.cmake @@ -1,20 +1,20 @@ SET(CPP_FILES DoseStatisticsTest.cpp DoseStatisticsCalculatorTest.cpp ArithmeticTest.cpp - BinaryFunctorDoseAccessorTest.cpp + BinaryFunctorAccessorTest.cpp rttbAlgorithmsTests.cpp #include dummy accessor files ../core/DummyDoseAccessor.cpp ../core/DummyMaskAccessor.cpp ../core/DummyMutableDoseAccessor.cpp ) SET(H_FILES #include dummy accessor files ../core/DummyDoseAccessor.h ../core/DummyMaskAccessor.h ../core/DummyMutableDoseAccessor.h ) diff --git a/testing/algorithms/rttbAlgorithmsTests.cpp b/testing/algorithms/rttbAlgorithmsTests.cpp index 69263f6..e73def6 100644 --- a/testing/algorithms/rttbAlgorithmsTests.cpp +++ b/testing/algorithms/rttbAlgorithmsTests.cpp @@ -1,66 +1,66 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ // this file defines the rttbAlgorithmsTests for the test driver // and all it expects is that you have a function called RegisterTests #if defined(_MSC_VER) #pragma warning ( disable : 4786 ) #endif #include "litMultiTestsMain.h" namespace rttb { namespace testing { void registerTests() { LIT_REGISTER_TEST(DoseStatisticsTest); LIT_REGISTER_TEST(DoseStatisticsCalculatorTest); LIT_REGISTER_TEST(ArithmeticTest); - LIT_REGISTER_TEST(BinaryFunctorDoseAccessorTest); + LIT_REGISTER_TEST(BinaryFunctorAccessorTest); } } } int main(int argc, char* argv[]) { int result = 0; rttb::testing::registerTests(); try { result = lit::multiTestsMain(argc, argv); } catch (const std::exception& /*e*/) { result = -1; } catch (...) { result = -1; } return result; } diff --git a/testing/core/DVHCalculatorTest.cpp b/testing/core/DVHCalculatorTest.cpp index d60ed41..c772f62 100644 --- a/testing/core/DVHCalculatorTest.cpp +++ b/testing/core/DVHCalculatorTest.cpp @@ -1,117 +1,127 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (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 "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbDVHCalculator.h" #include "rttbGenericMaskedDoseIterator.h" #include "rttbGenericDoseIterator.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "DummyDoseAccessor.h" #include "DummyMaskAccessor.h" -namespace rttb{ +namespace rttb +{ - namespace testing{ - typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; - typedef core::GenericMaskedDoseIterator::MaskAccessorPointer MaskAccessorPointer; - typedef core::DVHCalculator::DoseIteratorPointer DoseIteratorPointer; - typedef core::DVHCalculator::MaskedDoseIteratorPointer MaskedDoseIteratorPointer; - + namespace testing + { + typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; + typedef core::GenericMaskedDoseIterator::MaskAccessorPointer MaskAccessorPointer; + typedef core::DVHCalculator::DoseIteratorPointer DoseIteratorPointer; + typedef core::DVHCalculator::MaskedDoseIteratorPointer MaskedDoseIteratorPointer; - /*!@brief DVHTest - test the API of DVH + + /*!@brief DVHTest - test the API of DVH 1) test constructors (values as expected?) - */ - - int DVHCalculatorTest(int argc, char* argv[] ) - { - PREPARE_DEFAULT_TEST_REPORTING; - - //create null pointer to DoseIterator - DoseIteratorPointer spDoseIteratorNull; - - const IDType structureID = "myStructure"; - const IDType doseIDNull = "myDose"; - - - //1) test constructors (values as expected?) - CHECK_THROW_EXPLICIT(core::DVHCalculator myDVHCalc(spDoseIteratorNull, structureID, doseIDNull), core::NullPointerException); - - - //create dummy DoseAccessor - boost::shared_ptr spTestDoseAccessor = boost::make_shared(); - DoseAccessorPointer spDoseAccessor(spTestDoseAccessor); - const std::vector* doseVals = spTestDoseAccessor->getDoseVector(); - //create corresponding DoseIterator - boost::shared_ptr spTestDoseIterator = - boost::make_shared(spDoseAccessor); - DoseIteratorPointer spDoseIterator (spTestDoseIterator); - - const IDType doseID = spDoseAccessor->getDoseUID(); - - CHECK_NO_THROW(core::DVHCalculator myDVHCalc(spDoseIterator, structureID, doseID)); - CHECK_THROW_EXPLICIT(core::DVHCalculator myDVHCalc(spDoseIterator, structureID, doseID, -1), core::InvalidParameterException); - - int numBins = 21; - DoseTypeGy binSize = 0; - DoseStatisticType maximum = 0; - std::vector::const_iterator doseIt = doseVals->begin(); - while(doseIt != doseVals->end()){ - if (maximum < *doseIt){ - maximum = *doseIt; - } - doseIt++; - } - binSize = maximum*1.5/numBins; - - CHECK_NO_THROW(core::DVHCalculator myDVHCalc(spDoseIterator, structureID, doseID, binSize, numBins)); - CHECK_THROW_EXPLICIT(core::DVHCalculator myDVHCalc(spDoseIterator, structureID, doseID, 0, 0), - core::InvalidParameterException);//aNumberOfBins must be >=0 - core::DVHCalculator myDVHCalc(spDoseIterator, structureID, doseID, binSize, 1); - CHECK_THROW_EXPLICIT(myDVHCalc.generateDVH(), core::InvalidParameterException);//_numberOfBins must be > max(aDoseIterator)/aDeltaD! - - //create dummy MaskAccessor - boost::shared_ptr spTestMaskAccessor = - boost::make_shared(spDoseAccessor->getGeometricInfo()); - MaskAccessorPointer spMaskAccessor(spTestMaskAccessor); - //create corresponding MaskedDoseIterator - boost::shared_ptr spTestMaskedDoseIterator = - boost::make_shared(spMaskAccessor, spDoseAccessor); - DoseIteratorPointer spMaskedDoseIterator (spTestMaskedDoseIterator); - - CHECK_NO_THROW(core::DVHCalculator myDVHCalc(spMaskedDoseIterator, structureID, doseID)); - - //actual calculation is still missing - - - RETURN_AND_REPORT_TEST_SUCCESS; - } - - }//end namespace testing + */ + + int DVHCalculatorTest(int argc, char* argv[]) + { + PREPARE_DEFAULT_TEST_REPORTING; + + //create null pointer to DoseIterator + DoseIteratorPointer spDoseIteratorNull; + + const IDType structureID = "myStructure"; + const IDType doseIDNull = "myDose"; + + + //1) test constructors (values as expected?) + CHECK_THROW_EXPLICIT(core::DVHCalculator myDVHCalc(spDoseIteratorNull, structureID, doseIDNull), + core::NullPointerException); + + + //create dummy DoseAccessor + boost::shared_ptr spTestDoseAccessor = boost::make_shared(); + DoseAccessorPointer spDoseAccessor(spTestDoseAccessor); + const std::vector* doseVals = spTestDoseAccessor->getDoseVector(); + //create corresponding DoseIterator + boost::shared_ptr spTestDoseIterator = + boost::make_shared(spDoseAccessor); + DoseIteratorPointer spDoseIterator(spTestDoseIterator); + + const IDType doseID = spDoseAccessor->getUID(); + + CHECK_NO_THROW(core::DVHCalculator myDVHCalc(spDoseIterator, structureID, doseID)); + CHECK_THROW_EXPLICIT(core::DVHCalculator myDVHCalc(spDoseIterator, structureID, doseID, -1), + core::InvalidParameterException); + + int numBins = 21; + DoseTypeGy binSize = 0; + DoseStatisticType maximum = 0; + std::vector::const_iterator doseIt = doseVals->begin(); + + while (doseIt != doseVals->end()) + { + if (maximum < *doseIt) + { + maximum = *doseIt; + } + + doseIt++; + } + + binSize = maximum * 1.5 / numBins; + + CHECK_NO_THROW(core::DVHCalculator myDVHCalc(spDoseIterator, structureID, doseID, binSize, numBins)); + CHECK_THROW_EXPLICIT(core::DVHCalculator myDVHCalc(spDoseIterator, structureID, doseID, 0, 0), + core::InvalidParameterException);//aNumberOfBins must be >=0 + core::DVHCalculator myDVHCalc(spDoseIterator, structureID, doseID, binSize, 1); + CHECK_THROW_EXPLICIT(myDVHCalc.generateDVH(), + core::InvalidParameterException);//_numberOfBins must be > max(aDoseIterator)/aDeltaD! + + //create dummy MaskAccessor + boost::shared_ptr spTestMaskAccessor = + boost::make_shared(spDoseAccessor->getGeometricInfo()); + MaskAccessorPointer spMaskAccessor(spTestMaskAccessor); + //create corresponding MaskedDoseIterator + boost::shared_ptr spTestMaskedDoseIterator = + boost::make_shared(spMaskAccessor, spDoseAccessor); + DoseIteratorPointer spMaskedDoseIterator(spTestMaskedDoseIterator); + + CHECK_NO_THROW(core::DVHCalculator myDVHCalc(spMaskedDoseIterator, structureID, doseID)); + + //actual calculation is still missing + + + RETURN_AND_REPORT_TEST_SUCCESS; + } + + }//end namespace testing }//end namespace rttb diff --git a/testing/core/DummyDoseAccessor.cpp b/testing/core/DummyDoseAccessor.cpp index b74adba..0eca971 100644 --- a/testing/core/DummyDoseAccessor.cpp +++ b/testing/core/DummyDoseAccessor.cpp @@ -1,96 +1,96 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include #include "DummyDoseAccessor.h" #include "rttbNullPointerException.h" #include "rttbInvalidDoseException.h" #include "rttbIndexOutOfBoundsException.h" namespace rttb { namespace testing { DummyDoseAccessor::~DummyDoseAccessor() {} DummyDoseAccessor::DummyDoseAccessor() { boost::uuids::uuid id; boost::uuids::random_generator generator; id = generator(); std::stringstream ss; ss << id; _doseUID = "DummyDoseAccessor_" + ss.str(); SpacingVectorType3D aVector(2.5); _geoInfo.setSpacing(aVector); WorldCoordinate3D anOtherVector(-25, -2, 35); _geoInfo.setImagePositionPatient(anOtherVector); _geoInfo.setNumRows(11); _geoInfo.setNumColumns(10); _geoInfo.setNumSlices(5); OrientationMatrix unit = OrientationMatrix(); _geoInfo.setOrientationMatrix(unit); for (int i = 0; i < _geoInfo.getNumberOfVoxels(); i++) { doseData.push_back((double(rand()) / RAND_MAX) * 1000); } } DummyDoseAccessor::DummyDoseAccessor(const std::vector& aDoseVector, const core::GeometricInfo& geoInfo) { boost::uuids::uuid id; boost::uuids::random_generator generator; id = generator(); std::stringstream ss; ss << id; _doseUID = "DummyDoseAccessor_" + ss.str(); doseData = aDoseVector; _geoInfo = geoInfo; } - DoseTypeGy DummyDoseAccessor::getDoseAt(const VoxelGridID aID) const + GenericValueType DummyDoseAccessor::getValueAt(const VoxelGridID aID) const { if (!_geoInfo.validID(aID)) { throw core::IndexOutOfBoundsException("Not a valid Position!"); } return doseData.at(aID); } - DoseTypeGy DummyDoseAccessor::getDoseAt(const VoxelGridIndex3D& aIndex) const + GenericValueType DummyDoseAccessor::getValueAt(const VoxelGridIndex3D& aIndex) const { VoxelGridID gridID = 0; _geoInfo.convert(aIndex, gridID); - return getDoseAt(gridID); + return getValueAt(gridID); } }//end namespace testing }//end namespace rttb \ No newline at end of file diff --git a/testing/core/DummyDoseAccessor.h b/testing/core/DummyDoseAccessor.h index 241695a..f73fea2 100644 --- a/testing/core/DummyDoseAccessor.h +++ b/testing/core/DummyDoseAccessor.h @@ -1,80 +1,80 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DUMMY_DOSE_ACCESSOR_H #define __DUMMY_DOSE_ACCESSOR_H #include -#include "rttbDoseAccessorWithGeoInfoBase.h" +#include "rttbAccessorWithGeoInfoBase.h" #include "rttbGeometricInfo.h" #include "rttbBaseType.h" namespace rttb { - namespace testing - { + namespace testing + { - /*! @class DummyDoseAccessor - @brief A dummy DoseAccessor for testing filled with random dose values between 0 and 100. - The default grid size is [11,10,5] - */ - class DummyDoseAccessor: public core::DoseAccessorWithGeoInfoBase - { + /*! @class DummyDoseAccessor + @brief A dummy DoseAccessor for testing filled with random dose values between 0 and 100. + The default grid size is [11,10,5] + */ + class DummyDoseAccessor: public core::AccessorWithGeoInfoBase + { - private: - /*! vector of dose data(absolute Gy dose/doseGridScaling)*/ - std::vector doseData; + private: + /*! vector of dose data(absolute Gy dose/doseGridScaling)*/ + std::vector doseData; - IDType _doseUID; + IDType _doseUID; - public: - ~DummyDoseAccessor(); + public: + ~DummyDoseAccessor(); - /*! @brief A dummy DoseAccessor for testing filled with random dose values between 0 and 100. - The default grid size is [11,10,5] - */ - DummyDoseAccessor(); + /*! @brief A dummy DoseAccessor for testing filled with random dose values between 0 and 100. + The default grid size is [11,10,5] + */ + DummyDoseAccessor(); - /*! @brief Constructor. - Initialisation of dose with a given vector. - */ - DummyDoseAccessor(const std::vector& aDoseVector, const core::GeometricInfo& geoInfo); + /*! @brief Constructor. + Initialisation of dose with a given vector. + */ + DummyDoseAccessor(const std::vector& aDoseVector, const core::GeometricInfo& geoInfo); - const std::vector* getDoseVector() const - { - return &doseData; - }; + const std::vector* getDoseVector() const + { + return &doseData; + }; - DoseTypeGy getDoseAt(const VoxelGridID aID) const; + GenericValueType getValueAt(const VoxelGridID aID) const; - DoseTypeGy getDoseAt(const VoxelGridIndex3D& aIndex) const; + GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const; - const IDType getDoseUID() const - { - return _doseUID; - }; - }; - } + const IDType getUID() const + { + return _doseUID; + }; + }; + } } #endif diff --git a/testing/core/DummyMutableDoseAccessor.cpp b/testing/core/DummyMutableDoseAccessor.cpp index 3c4502b..12de4c3 100644 --- a/testing/core/DummyMutableDoseAccessor.cpp +++ b/testing/core/DummyMutableDoseAccessor.cpp @@ -1,120 +1,120 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include #include "DummyMutableDoseAccessor.h" #include "rttbNullPointerException.h" #include "rttbInvalidDoseException.h" #include "rttbIndexOutOfBoundsException.h" namespace rttb { - namespace testing - { - - DummyMutableDoseAccessor::~DummyMutableDoseAccessor() {} - - DummyMutableDoseAccessor::DummyMutableDoseAccessor() - { - boost::uuids::uuid id; - boost::uuids::random_generator generator; - id = generator(); - std::stringstream ss; - ss << id; - _doseUID = "DummyMutableDoseAccessor_" + ss.str(); - - SpacingVectorType3D aVector(2.5); - _geoInfo.setSpacing(aVector); - WorldCoordinate3D anOtherVector(-25, -2, 35); - _geoInfo.setImagePositionPatient(anOtherVector); - _geoInfo.setNumRows(11); - _geoInfo.setNumColumns(10); - _geoInfo.setNumSlices(5); - - OrientationMatrix unit = OrientationMatrix(); - _geoInfo.setOrientationMatrix(unit); - - for (int i = 0; i < _geoInfo.getNumberOfVoxels(); i++) - { - doseData.push_back((double(rand()) / RAND_MAX) * 1000); - } - } - - DummyMutableDoseAccessor::DummyMutableDoseAccessor(const std::vector& aDoseVector, - const core::GeometricInfo& geoInfo) - { - boost::uuids::uuid id; - boost::uuids::random_generator generator; - id = generator(); - std::stringstream ss; - ss << id; - _doseUID = "DummyMutableDoseAccessor_" + ss.str(); - - doseData = aDoseVector; - _geoInfo = geoInfo; - } - - const core::GeometricInfo& - DummyMutableDoseAccessor:: - getGeometricInfo() const - { - return _geoInfo; - } - - DoseTypeGy DummyMutableDoseAccessor::getDoseAt(const VoxelGridID aID) const - { - if (!_geoInfo.validID(aID)) - { - throw core::IndexOutOfBoundsException("Not a valid Position!"); - } - - return doseData.at(aID); - } - - DoseTypeGy DummyMutableDoseAccessor::getDoseAt(const VoxelGridIndex3D& aIndex) const - { - VoxelGridID gridID = 0; - _geoInfo.convert(aIndex, gridID); - return getDoseAt(gridID); - } - - void DummyMutableDoseAccessor::setDoseAt(const VoxelGridID aID, DoseTypeGy value) - { - if (!_geoInfo.validID(aID)) - { - throw core::IndexOutOfBoundsException("Not a valid Position!"); - } - - doseData.at(aID) = value; - } - - void DummyMutableDoseAccessor::setDoseAt(const VoxelGridIndex3D& aIndex, DoseTypeGy value) - { - VoxelGridID gridID = 0; - _geoInfo.convert(aIndex, gridID); - setDoseAt(gridID, value); - } - - }//end namespace testing + namespace testing + { + + DummyMutableDoseAccessor::~DummyMutableDoseAccessor() {} + + DummyMutableDoseAccessor::DummyMutableDoseAccessor() + { + boost::uuids::uuid id; + boost::uuids::random_generator generator; + id = generator(); + std::stringstream ss; + ss << id; + _doseUID = "DummyMutableDoseAccessor_" + ss.str(); + + SpacingVectorType3D aVector(2.5); + _geoInfo.setSpacing(aVector); + WorldCoordinate3D anOtherVector(-25, -2, 35); + _geoInfo.setImagePositionPatient(anOtherVector); + _geoInfo.setNumRows(11); + _geoInfo.setNumColumns(10); + _geoInfo.setNumSlices(5); + + OrientationMatrix unit = OrientationMatrix(); + _geoInfo.setOrientationMatrix(unit); + + for (int i = 0; i < _geoInfo.getNumberOfVoxels(); i++) + { + doseData.push_back((double(rand()) / RAND_MAX) * 1000); + } + } + + DummyMutableDoseAccessor::DummyMutableDoseAccessor(const std::vector& aDoseVector, + const core::GeometricInfo& geoInfo) + { + boost::uuids::uuid id; + boost::uuids::random_generator generator; + id = generator(); + std::stringstream ss; + ss << id; + _doseUID = "DummyMutableDoseAccessor_" + ss.str(); + + doseData = aDoseVector; + _geoInfo = geoInfo; + } + + const core::GeometricInfo& + DummyMutableDoseAccessor:: + getGeometricInfo() const + { + return _geoInfo; + } + + GenericValueType DummyMutableDoseAccessor::getValueAt(const VoxelGridID aID) const + { + if (!_geoInfo.validID(aID)) + { + throw core::IndexOutOfBoundsException("Not a valid Position!"); + } + + return doseData.at(aID); + } + + GenericValueType DummyMutableDoseAccessor::getValueAt(const VoxelGridIndex3D& aIndex) const + { + VoxelGridID gridID = 0; + _geoInfo.convert(aIndex, gridID); + return getValueAt(gridID); + } + + void DummyMutableDoseAccessor::setDoseAt(const VoxelGridID aID, DoseTypeGy value) + { + if (!_geoInfo.validID(aID)) + { + throw core::IndexOutOfBoundsException("Not a valid Position!"); + } + + doseData.at(aID) = value; + } + + void DummyMutableDoseAccessor::setDoseAt(const VoxelGridIndex3D& aIndex, DoseTypeGy value) + { + VoxelGridID gridID = 0; + _geoInfo.convert(aIndex, gridID); + setDoseAt(gridID, value); + } + + }//end namespace testing }//end namespace rttb \ No newline at end of file diff --git a/testing/core/DummyMutableDoseAccessor.h b/testing/core/DummyMutableDoseAccessor.h index 496451e..5dbdae9 100644 --- a/testing/core/DummyMutableDoseAccessor.h +++ b/testing/core/DummyMutableDoseAccessor.h @@ -1,88 +1,88 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DUMMY_MUTABLE_DOSE_ACCESSOR_H #define __DUMMY_MUTABLE_DOSE_ACCESSOR_H #include #include "rttbMutableDoseAccessorInterface.h" #include "rttbGeometricInfo.h" #include "rttbBaseType.h" namespace rttb { - namespace testing - { + namespace testing + { - /*! @class DummyMutableDoseAccessor - @brief A dummy MutableDoseAccessor for testing filled with random dose values between 0 and 100. - The default grid size is [11,10,5] - */ - class DummyMutableDoseAccessor: public core::MutableDoseAccessorInterface - { + /*! @class DummyMutableDoseAccessor + @brief A dummy MutableDoseAccessor for testing filled with random dose values between 0 and 100. + The default grid size is [11,10,5] + */ + class DummyMutableDoseAccessor: public core::MutableDoseAccessorInterface + { - private: - /*! vector of dose data(absolute Gy dose/doseGridScaling)*/ - std::vector doseData; + private: + /*! vector of dose data(absolute Gy dose/doseGridScaling)*/ + std::vector doseData; - IDType _doseUID; + IDType _doseUID; - core::GeometricInfo _geoInfo; + core::GeometricInfo _geoInfo; - public: - ~DummyMutableDoseAccessor(); + public: + ~DummyMutableDoseAccessor(); - /*! @brief A dummy DummyMutableDoseAccessor for testing filled with random dose values between 0 and 100. - The default grid size is [11,10,5] - */ - DummyMutableDoseAccessor(); + /*! @brief A dummy DummyMutableDoseAccessor for testing filled with random dose values between 0 and 100. + The default grid size is [11,10,5] + */ + DummyMutableDoseAccessor(); - /*! @brief Constructor. - Initialisation of dose with a given vector. - */ - DummyMutableDoseAccessor(const std::vector& aDoseVector, - const core::GeometricInfo& geoInfo); + /*! @brief Constructor. + Initialisation of dose with a given vector. + */ + DummyMutableDoseAccessor(const std::vector& aDoseVector, + const core::GeometricInfo& geoInfo); - const std::vector* getDoseVector() const - { - return &doseData; - }; + const std::vector* getDoseVector() const + { + return &doseData; + }; - virtual const core::GeometricInfo& getGeometricInfo() const; + virtual const core::GeometricInfo& getGeometricInfo() const; - DoseTypeGy getDoseAt(const VoxelGridID aID) const; + GenericValueType getValueAt(const VoxelGridID aID) const; - DoseTypeGy getDoseAt(const VoxelGridIndex3D& aIndex) const; + GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const; - void setDoseAt(const VoxelGridID aID, DoseTypeGy value); + void setDoseAt(const VoxelGridID aID, DoseTypeGy value); - void setDoseAt(const VoxelGridIndex3D& aIndex, DoseTypeGy value); + void setDoseAt(const VoxelGridIndex3D& aIndex, DoseTypeGy value); - const IDType getDoseUID() const - { - return _doseUID; - }; - }; - } + const IDType getUID() const + { + return _doseUID; + }; + }; + } } #endif diff --git a/testing/examples/DVHCalculatorComparisonTest.cpp b/testing/examples/DVHCalculatorComparisonTest.cpp index 9d4ef91..8fa933b 100644 --- a/testing/examples/DVHCalculatorComparisonTest.cpp +++ b/testing/examples/DVHCalculatorComparisonTest.cpp @@ -1,365 +1,365 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (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 "rttbDVHCalculator.h" #include "rttbGenericMaskedDoseIterator.h" #include "rttbGenericDoseIterator.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "rttbDicomDoseAccessor.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomFileStructureSetGenerator.h" #include "rttbOTBMaskAccessor.h" #include "rttbDVHTxtFileReader.h" namespace rttb { namespace testing { /*! @brief DVHCalculatorTest. Test if calculation in new architecture returns similar results to the original implementation. WARNING: The values for comparison need to be adjusted if the input files are changed! This test can be used to get more detailed information, but it will always fail, because differences in voxelization accuracy, especially the ones caused by the change from double to float precission will not cause considerable deviations in the structure sizes, which correspond to considerable differences in the calculated DVHs. Even in double precission differences up to 0.005 between values from old and new implementation can occure. */ int DVHCalculatorComparisonTest(int argc, char* argv[]) { typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; typedef core::GenericMaskedDoseIterator::MaskAccessorPointer MaskAccessorPointer; typedef core::DVHCalculator::DoseIteratorPointer DoseIteratorPointer; typedef core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: 1: structure file name // 2: dose1 file name // 3: dose2 file name // 4: dose3 file name std::string RTSTRUCT_FILENAME; std::string RTDOSE_FILENAME; std::string RTDOSE2_FILENAME; std::string RTDOSE3_FILENAME; std::string COMPARISON_DVH_FOLDER; if (argc > 1) { RTSTRUCT_FILENAME = argv[1]; } if (argc > 2) { RTDOSE_FILENAME = argv[2]; } if (argc > 3) { RTDOSE2_FILENAME = argv[3]; } if (argc > 4) { RTDOSE3_FILENAME = argv[4]; } if (argc > 5) { COMPARISON_DVH_FOLDER = argv[5]; } OFCondition status; DcmFileFormat fileformat; /* read dicom-rt dose */ io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1(RTDOSE_FILENAME.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); //create a vector of MaskAccessors (one for each structure) StructureSetPointer rtStructureSet = io::dicom::DicomFileStructureSetGenerator( RTSTRUCT_FILENAME.c_str()).generateStructureSet(); std::vector rtStructSetMaskAccessorVec; ::DRTDoseIOD rtdose2; io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator2(RTDOSE2_FILENAME.c_str()); DoseAccessorPointer doseAccessor2(doseAccessorGenerator2.generateDoseAccessor()); ::DRTDoseIOD rtdose3; io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator3(RTDOSE3_FILENAME.c_str()); DoseAccessorPointer doseAccessor3(doseAccessorGenerator3.generateDoseAccessor()); double maxDifference = 0; double difference = 0; double minDifference = 1000; clock_t start(clock()); if (rtStructureSet->getNumberOfStructures() > 0) { for (int j = 0; j < rtStructureSet->getNumberOfStructures(); j++) { //create MaskAccessor ::boost::shared_ptr spOTBMaskAccessor = ::boost::make_shared(rtStructureSet->getStructure(j), doseAccessor1->getGeometricInfo()); spOTBMaskAccessor->updateMask(); MaskAccessorPointer spMaskAccessor(spOTBMaskAccessor); //create corresponding MaskedDoseIterator ::boost::shared_ptr spMaskedDoseIteratorTmp = ::boost::make_shared(spMaskAccessor, doseAccessor1); DoseIteratorPointer spMaskedDoseIterator(spMaskedDoseIteratorTmp); //store MaskAccessor rtStructSetMaskAccessorVec.push_back(spMaskAccessor); rttb::core::DVHCalculator calc(spMaskedDoseIterator, (rtStructureSet->getStructure(j))->getUID(), - doseAccessor1->getDoseUID()); + doseAccessor1->getUID()); std::string dvhFileName = "dvh1"; std::string label = (rtStructureSet->getStructure(j))->getLabel(); dvhFileName.append(label); if (dvhFileName.find("/") != std::string::npos) { dvhFileName.replace(dvhFileName.find("/"), 1, ""); } std::cout << "=== Dose 1: " << label << "===" << std::endl; rttb::io::other::DVHTxtFileReader dvhOriginalReader = rttb::io::other::DVHTxtFileReader( COMPARISON_DVH_FOLDER + dvhFileName + ".txt"); rttb::core::DVH dvhOrig = *(dvhOriginalReader.generateDVH()); rttb::core::DVH::DataDifferentialType dvhOrigData = dvhOrig.getDataDifferential(); rttb::core::DVH dvh = *(calc.generateDVH()); rttb::core::DVH::DataDifferentialType dvhData = dvh.getDataDifferential(); CHECK_EQUAL(dvhOrig, dvh); CHECK_CLOSE(dvhOrig.getMaximum(), dvh.getMaximum(), errorConstant); CHECK_CLOSE(dvhOrig.getMinimum(), dvh.getMinimum(), errorConstant); CHECK_CLOSE(dvhOrig.getMean(), dvh.getMean(), errorConstant); rttb::core::DVH::DataDifferentialType::iterator it; rttb::core::DVH::DataDifferentialType::iterator itOrig; itOrig = dvhOrigData.begin(); for (it = dvhData.begin(); it != dvhData.end() || itOrig != dvhOrigData.end(); ++it, ++itOrig) { CHECK_CLOSE(*(itOrig), *(it), errorConstant); std::cout << std::setprecision(20) << "difference: " << abs(*(itOrig) - * (it)) << std::endl; difference = abs(*(itOrig) - * (it)); if (difference < minDifference) { minDifference = difference; } if (difference > maxDifference) { maxDifference = difference; } } } } clock_t finish(clock()); std::cout << std::setprecision(20) << "max(difference): " << maxDifference << std::endl; std::cout << std::setprecision(20) << "min(difference): " << minDifference << std::endl; std::cout << "DVH Calculation time: " << finish - start << " ms" << std::endl; maxDifference = 0; minDifference = 1000; clock_t start2(clock()); for (int j = 0; j < rtStructSetMaskAccessorVec.size(); j++) { //create corresponding MaskedDoseIterator ::boost::shared_ptr spMaskedDoseIteratorTmp = ::boost::make_shared(rtStructSetMaskAccessorVec.at(j), doseAccessor2); DoseIteratorPointer spMaskedDoseIterator(spMaskedDoseIteratorTmp); rttb::core::DVHCalculator calc(spMaskedDoseIterator, (rtStructureSet->getStructure(j))->getUID(), - doseAccessor2->getDoseUID()); + doseAccessor2->getUID()); std::string dvhFileName = "dvh2"; std::string label = (rtStructureSet->getStructure(j))->getLabel(); dvhFileName.append(label); if (dvhFileName.find("/") != std::string::npos) { dvhFileName.replace(dvhFileName.find("/"), 1, ""); } std::cout << "=== Dose 2: " << label << "===" << std::endl; rttb::io::other::DVHTxtFileReader dvhOriginalReader = rttb::io::other::DVHTxtFileReader( COMPARISON_DVH_FOLDER + dvhFileName + ".txt"); rttb::core::DVH dvhOrig = *(dvhOriginalReader.generateDVH()); rttb::core::DVH::DataDifferentialType dvhOrigData = dvhOrig.getDataDifferential(); rttb::core::DVH dvh = *(calc.generateDVH()); rttb::core::DVH::DataDifferentialType dvhData = dvh.getDataDifferential(); CHECK_EQUAL(dvhOrig, dvh); CHECK_CLOSE(dvhOrig.getMaximum(), dvh.getMaximum(), errorConstant); CHECK_CLOSE(dvhOrig.getMinimum(), dvh.getMinimum(), errorConstant); CHECK_CLOSE(dvhOrig.getMean(), dvh.getMean(), errorConstant); rttb::core::DVH::DataDifferentialType::iterator it; rttb::core::DVH::DataDifferentialType::iterator itOrig; itOrig = dvhOrigData.begin(); for (it = dvhData.begin(); it != dvhData.end() || itOrig != dvhOrigData.end(); ++it, ++itOrig) { CHECK_CLOSE(*(itOrig), *(it), errorConstant); std::cout << std::setprecision(20) << "difference: " << abs(*(itOrig) - * (it)) << std::endl; difference = abs(*(itOrig) - * (it)); if (difference > 10) { std::cout << "large difference: " << abs(*(itOrig) - * (it)) << " = " << *(itOrig) << " - " << * (it) << std::endl; } if (difference < minDifference) { minDifference = difference; } if (difference > maxDifference) { maxDifference = difference; } } } clock_t finish2(clock()); std::cout << std::setprecision(20) << "max(difference): " << maxDifference << std::endl; std::cout << std::setprecision(20) << "min(difference): " << minDifference << std::endl; std::cout << "Reset dose 2, DVH Calculation time: " << finish2 - start2 << " ms" << std::endl; maxDifference = 0; minDifference = 1000; clock_t start3(clock()); for (int j = 0; j < rtStructSetMaskAccessorVec.size(); j++) { //create corresponding MaskedDoseIterator ::boost::shared_ptr spMaskedDoseIteratorTmp = ::boost::make_shared(rtStructSetMaskAccessorVec.at(j), doseAccessor3); DoseIteratorPointer spMaskedDoseIterator(spMaskedDoseIteratorTmp); rttb::core::DVHCalculator calc(spMaskedDoseIterator, (rtStructureSet->getStructure(j))->getUID(), - doseAccessor3->getDoseUID()); + doseAccessor3->getUID()); std::string dvhFileName = "dvh3"; std::string label = (rtStructureSet->getStructure(j))->getLabel(); dvhFileName.append(label); if (dvhFileName.find("/") != std::string::npos) { dvhFileName.replace(dvhFileName.find("/"), 1, ""); } std::cout << "=== Dose 3: " << label << "===" << std::endl; rttb::io::other::DVHTxtFileReader dvhOriginalReader = rttb::io::other::DVHTxtFileReader( COMPARISON_DVH_FOLDER + dvhFileName + ".txt"); rttb::core::DVH dvhOrig = *(dvhOriginalReader.generateDVH()); rttb::core::DVH::DataDifferentialType dvhOrigData = dvhOrig.getDataDifferential(); rttb::core::DVH dvh = *(calc.generateDVH()); rttb::core::DVH::DataDifferentialType dvhData = dvh.getDataDifferential(); CHECK_EQUAL(dvhOrig, dvh); CHECK_CLOSE(dvhOrig.getMaximum(), dvh.getMaximum(), errorConstant); CHECK_CLOSE(dvhOrig.getMinimum(), dvh.getMinimum(), errorConstant); CHECK_CLOSE(dvhOrig.getMean(), dvh.getMean(), errorConstant); rttb::core::DVH::DataDifferentialType::iterator it; rttb::core::DVH::DataDifferentialType::iterator itOrig; itOrig = dvhOrigData.begin(); for (it = dvhData.begin(); it != dvhData.end() || itOrig != dvhOrigData.end(); ++it, ++itOrig) { CHECK_CLOSE(*(itOrig), *(it), errorConstant); std::cout << std::setprecision(20) << "difference: " << abs(*(itOrig) - * (it)) << std::endl; if (difference > 10) { std::cout << "large difference: " << abs(*(itOrig) - * (it)) << " = " << *(itOrig) << " - " << * (it) << std::endl; } difference = abs(*(itOrig) - * (it)); if (difference < minDifference) { minDifference = difference; } if (difference > maxDifference) { maxDifference = difference; } } } clock_t finish3(clock()); std::cout << std::setprecision(20) << "max(difference): " << maxDifference << std::endl; std::cout << std::setprecision(20) << "min(difference): " << minDifference << std::endl; std::cout << "Reset dose 3, DVH Calculation time: " << finish3 - start3 << " ms" << std::endl; RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/examples/DVHCalculatorExampleTest.cpp b/testing/examples/DVHCalculatorExampleTest.cpp index ad1a195..6685f09 100644 --- a/testing/examples/DVHCalculatorExampleTest.cpp +++ b/testing/examples/DVHCalculatorExampleTest.cpp @@ -1,306 +1,305 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (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 "rttbDVHCalculator.h" #include "rttbGenericMaskedDoseIterator.h" #include "rttbGenericDoseIterator.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "rttbDicomDoseAccessor.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomFileStructureSetGenerator.h" #include "rttbOTBMaskAccessor.h" namespace rttb { namespace testing { /*! @brief DVHCalculatorTest. Test if calculation in new architecture returns similar results to the original implementation. WARNING: The values for comparison need to be adjusted if the input files are changed! */ int DVHCalculatorExampleTest(int argc, char* argv[]) { typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; typedef core::GenericMaskedDoseIterator::MaskAccessorPointer MaskAccessorPointer; typedef core::DVHCalculator::DoseIteratorPointer DoseIteratorPointer; typedef core::DVHCalculator::MaskedDoseIteratorPointer MaskedDoseIteratorPointer; typedef masks::legacy::OTBMaskAccessor::StructTypePointer StructTypePointer; typedef core::DVH::DVHPointer DVHPointer; typedef core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: 1: structure file name // 2: dose1 file name // 3: dose2 file name // 4: dose3 file name std::string RTSTRUCT_FILENAME; std::string RTDOSE_FILENAME; std::string RTDOSE2_FILENAME; std::string RTDOSE3_FILENAME; if (argc > 1) { RTSTRUCT_FILENAME = argv[1]; } if (argc > 2) { RTDOSE_FILENAME = argv[2]; } if (argc > 3) { RTDOSE2_FILENAME = argv[3]; } if (argc > 4) { RTDOSE3_FILENAME = argv[4]; } - OFCondition status; DcmFileFormat fileformat; // read dicom-rt dose io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1(RTDOSE_FILENAME.c_str()); + DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); //create a vector of MaskAccessors (one for each structure) StructureSetPointer rtStructureSet = io::dicom::DicomFileStructureSetGenerator( RTSTRUCT_FILENAME.c_str()).generateStructureSet(); //storeage for mask accessors to reduce time spent on voxelization (perform only once) std::vector rtStructSetMaskAccessorVec; ::DRTDoseIOD rtdose2; io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator2(RTDOSE2_FILENAME.c_str()); DoseAccessorPointer doseAccessor2(doseAccessorGenerator2.generateDoseAccessor()); ::DRTDoseIOD rtdose3; io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator3(RTDOSE3_FILENAME.c_str()); DoseAccessorPointer doseAccessor3(doseAccessorGenerator3.generateDoseAccessor()); - //start evaluation clock_t start(clock()); if (rtStructureSet->getNumberOfStructures() > 0) { for (int j = 0; j < rtStructureSet->getNumberOfStructures(); j++) { std::cout << rtStructureSet->getStructure(j)->getLabel() << std::endl; //create MaskAccessor for each structure ::boost::shared_ptr spOTBMaskAccessor = ::boost::make_shared(rtStructureSet->getStructure(j), doseAccessor1->getGeometricInfo()); spOTBMaskAccessor->updateMask(); MaskAccessorPointer spMaskAccessor(spOTBMaskAccessor); - + //create corresponding MaskedDoseIterator ::boost::shared_ptr spMaskedDoseIteratorTmp = ::boost::make_shared(spMaskAccessor, doseAccessor1); DoseIteratorPointer spMaskedDoseIterator(spMaskedDoseIteratorTmp); //store MaskAccessor for each structure (later reuse) rtStructSetMaskAccessorVec.push_back(spMaskAccessor); //calculate DVH rttb::core::DVHCalculator calc(spMaskedDoseIterator, (rtStructureSet->getStructure(j))->getUID(), - doseAccessor1->getDoseUID()); + doseAccessor1->getUID()); rttb::core::DVH dvh = *(calc.generateDVH()); //DEBUG OUTPUT - std::cout << "=== Dose 1 Structure "< spMaskedDoseIteratorTmp = ::boost::make_shared(rtStructSetMaskAccessorVec.at(j), doseAccessor2); DoseIteratorPointer spMaskedDoseIterator(spMaskedDoseIteratorTmp); //calculate DVH rttb::core::DVHCalculator calc(spMaskedDoseIterator, (rtStructureSet->getStructure(j))->getUID(), - doseAccessor2->getDoseUID()); + doseAccessor2->getUID()); rttb::core::DVH dvh = *(calc.generateDVH()); if (j == 0) { CHECK_CLOSE(1.8423272053074631, dvh.getMaximum(), 1e-1); CHECK_CLOSE(0.0069001018925373145, dvh.getMinimum(), errorConstant); CHECK_CLOSE(0.5534586388640208, dvh.getMean(), errorConstant); CHECK_CLOSE(0.42090621544477619, dvh.getMedian(), errorConstant); CHECK_CLOSE(0.075901120817910464, dvh.getModal(), errorConstant); CHECK_CLOSE(0.44688344565881616, dvh.getStdDeviation(), 1e-4); CHECK_CLOSE(0.19970481400389611, dvh.getVariance(), 1e-4); CHECK_CLOSE(89230.858052685187, dvh.getNumberOfVoxels(), 1e-1); } if (j == 4) { CHECK_CLOSE(1.6264736515373135, dvh.getMaximum(), 1e-3); CHECK_CLOSE(0.10433981915522389, dvh.getMinimum(), errorConstant); CHECK_CLOSE(0.70820073085773427, dvh.getMean(), errorConstant); CHECK_CLOSE(0.71810346124477609, dvh.getMedian(), errorConstant); CHECK_CLOSE(0.23936782041492538, dvh.getModal(), errorConstant); CHECK_CLOSE(0.36355099006842068, dvh.getStdDeviation(), errorConstant); CHECK_CLOSE(0.13216932237972889, dvh.getVariance(), errorConstant); CHECK_CLOSE(2299.7105030728999, dvh.getNumberOfVoxels(), 1e-3); } } clock_t finish2(clock()); std::cout << "Reset dose 2, DVH Calculation time: " << finish2 - start2 << " ms" << std::endl; clock_t start3(clock()); for (int j = 0; j < rtStructSetMaskAccessorVec.size(); j++) { //create corresponding MaskedDoseIterator ::boost::shared_ptr spMaskedDoseIteratorTmp = ::boost::make_shared(rtStructSetMaskAccessorVec.at(j), doseAccessor3); DoseIteratorPointer spMaskedDoseIterator(spMaskedDoseIteratorTmp); //calculate DVH rttb::core::DVHCalculator calc(spMaskedDoseIterator, (rtStructureSet->getStructure(j))->getUID(), - doseAccessor3->getDoseUID()); + doseAccessor3->getUID()); rttb::core::DVH dvh = *(calc.generateDVH()); if (j == 1) { CHECK_CLOSE(0.0010765085705970151, dvh.getMaximum(), 1e-3); CHECK_CLOSE(0.00087641404074626872, dvh.getMinimum(), errorConstant); CHECK_CLOSE(0.0009788401527774486, dvh.getMean(), errorConstant); CHECK_CLOSE(0.00098846697746268666, dvh.getMedian(), errorConstant); CHECK_CLOSE(0.00098846697746268666, dvh.getModal(), errorConstant); CHECK_CLOSE(3.2977969280849566e-005, dvh.getStdDeviation(), errorConstant); CHECK_CLOSE(1.0875464578886574e-009, dvh.getVariance(), errorConstant); CHECK_CLOSE(595.30645355716683, dvh.getNumberOfVoxels(), 1e-3); } if (j == 6) { CHECK_CLOSE(0.0016589942782835824, dvh.getMaximum(), 1e-3); CHECK_CLOSE(0.00027960577723880602, dvh.getMinimum(), errorConstant); CHECK_CLOSE(0.0010389077643351956, dvh.getMean(), errorConstant); CHECK_CLOSE(0.0011246365706716419, dvh.getMedian(), errorConstant); CHECK_CLOSE(0.0013856019627611941, dvh.getModal(), errorConstant); CHECK_CLOSE(0.00036431958148461669, dvh.getStdDeviation(), errorConstant); CHECK_CLOSE(1.3272875745312625e-007, dvh.getVariance(), errorConstant); CHECK_CLOSE(8034.8878045085003, dvh.getNumberOfVoxels(), 1e-2); } } clock_t finish3(clock()); std::cout << "Reset dose 3, DVH Calculation time: " << finish3 - start3 << " ms" << std::endl; RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/examples/VoxelizationValidationTest.cpp b/testing/examples/VoxelizationValidationTest.cpp index 08e4018..77a6021 100644 --- a/testing/examples/VoxelizationValidationTest.cpp +++ b/testing/examples/VoxelizationValidationTest.cpp @@ -1,195 +1,195 @@ // ----------------------------------------------------------------------- // 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: 929 $ (last changed revision) // @date $Date: 2015-04-08 14:50:57 +0200 (Mi, 08 Apr 2015) $ (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 "rttbDVHCalculator.h" #include "rttbGenericMaskedDoseIterator.h" #include "rttbGenericDoseIterator.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "rttbDicomDoseAccessor.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomFileStructureSetGenerator.h" #include "rttbOTBMaskAccessor.h" #include "rttbDVHTxtFileReader.h" #include "rttbBoostMaskAccessor.h" //#include "rttbITKImageMaskAccessorConverter.h" //#include "rttbImageWriter.h" namespace rttb { namespace testing { /*! @brief VoxelizationValidationTest. Compare two differnt voxelizations: OTB and Boost. Check dvh maximum and minimum for each structure. Check write mask to itk file for further validation. */ int VoxelizationValidationTest(int argc, char* argv[]) { typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; typedef core::GenericMaskedDoseIterator::MaskAccessorPointer MaskAccessorPointer; typedef core::DVHCalculator::DoseIteratorPointer DoseIteratorPointer; typedef core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: 1: structure file name // 2: dose1 file name // 3: directory name to write boost mask of all structures // 4: directory name to write OTB mask of all structures std::string RTSTRUCT_FILENAME ; std::string RTDOSE_FILENAME; std::string BoostMask_DIRNAME; std::string OTBMask_DIRNAME; if (argc > 4) { RTSTRUCT_FILENAME = argv[1]; RTDOSE_FILENAME = argv[2]; BoostMask_DIRNAME = argv[3]; OTBMask_DIRNAME = argv[4]; } OFCondition status; DcmFileFormat fileformat; /* read dicom-rt dose */ io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1(RTDOSE_FILENAME.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); //create a vector of MaskAccessors (one for each structure) StructureSetPointer rtStructureSet = io::dicom::DicomFileStructureSetGenerator( RTSTRUCT_FILENAME.c_str()).generateStructureSet(); std::vector rtStructSetMaskAccessorVec; if (rtStructureSet->getNumberOfStructures() > 0) { for (int j = 0; j < rtStructureSet->getNumberOfStructures(); j++) { std::cout << j << ": " << rtStructureSet->getStructure(j)->getLabel() << std::endl; clock_t start(clock()); //create OTB MaskAccessor ::boost::shared_ptr spOTBMaskAccessor = ::boost::make_shared(rtStructureSet->getStructure(j), doseAccessor1->getGeometricInfo()); spOTBMaskAccessor->updateMask(); MaskAccessorPointer spMaskAccessor(spOTBMaskAccessor); ::boost::shared_ptr spMaskedDoseIteratorTmp = ::boost::make_shared(spMaskAccessor, doseAccessor1); DoseIteratorPointer spMaskedDoseIterator(spMaskedDoseIteratorTmp); rttb::core::DVHCalculator calc(spMaskedDoseIterator, (rtStructureSet->getStructure(j))->getUID(), - doseAccessor1->getDoseUID()); + doseAccessor1->getUID()); rttb::core::DVH dvh = *(calc.generateDVH()); clock_t finish(clock()); std::cout << "OTB Mask Calculation time: " << finish - start << " ms" << std::endl; //Write the mask image to a file. /*! It takes a long time to write all mask files so that RUN_TESTS causes a timeout error. To write all mask files, please use the outcommented code and call the .exe directly! */ /*rttb::io::itk::ITKImageMaskAccessorConverter itkConverter(spOTBMaskAccessor); CHECK(itkConverter.process()); std::stringstream fileNameSstr; fileNameSstr< (rtStructureSet->getStructure(j), doseAccessor1->getGeometricInfo()); CHECK_NO_THROW(boostMaskAccessorPtr->updateMask()); ::boost::shared_ptr spMaskedDoseIteratorTmp2 = ::boost::make_shared(boostMaskAccessorPtr, doseAccessor1); DoseIteratorPointer spMaskedDoseIterator2(spMaskedDoseIteratorTmp2); rttb::core::DVHCalculator calc2(spMaskedDoseIterator2, (rtStructureSet->getStructure(j))->getUID(), - doseAccessor1->getDoseUID()); + doseAccessor1->getUID()); rttb::core::DVH dvh2 = *(calc2.generateDVH()); clock_t finish2(clock()); std::cout << "Boost Mask Calculation and write file time: " << finish2 - start2 << " ms" << std::endl; //Write the mask image to a file. /*! It takes a long time to write all mask files so that RUN_TESTS causes a timeout error. To write all mask files, please use the outcommented code and call the .exe directly! */ /*rttb::io::itk::ITKImageMaskAccessorConverter itkConverter2(boostMaskAccessorPtr); CHECK(itkConverter2.process()); std::stringstream fileNameSstr2; fileNameSstr2< TranslationTransformType; /*! @brief SimpleMappableDoseAccessorWithITKTest - test the API of SimpleMappableDoseAccessor with ITK transformation 1) Test constructor 2) test getDoseAt() a) with Identity transform b) with translation transform */ int SimpleMappableDoseAccessorWithITKTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; std::string RTDOSE_FILENAME_CONSTANT_TWO; std::string RTDOSE_FILENAME_INCREASE_X; if (argc > 2) { RTDOSE_FILENAME_CONSTANT_TWO = argv[1]; RTDOSE_FILENAME_INCREASE_X = argv[2]; } else { std::cout << "at least two parameters for SimpleMappableDoseAccessorWithITKTest are expected" << std::endl; return -1; } const double doseGridScaling = 2.822386e-005; rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1( RTDOSE_FILENAME_CONSTANT_TWO.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator2( RTDOSE_FILENAME_INCREASE_X.c_str()); DoseAccessorPointer doseAccessor2(doseAccessorGenerator2.generateDoseAccessor()); core::GeometricInfo doseAccessor1GeometricInfo = doseAccessor1->getGeometricInfo(); NearestNeighborInterpolation::Pointer interpolationNN = NearestNeighborInterpolation::Pointer(new NearestNeighborInterpolation()); LinearInterpolation::Pointer interpolationLinear = LinearInterpolation::Pointer - (new LinearInterpolation()); + (new LinearInterpolation()); //auto transformITKIdentity = TransformationInterface::Pointer(new ITKTransformation( // IdentityTransformType::New())); TranslationTransformType::Pointer transformITKIdentityTemporary = TranslationTransformType::New(); TranslationTransformType::OutputVectorType translationIdentity; translationIdentity[0] = 0.0; translationIdentity[1] = 0.0; translationIdentity[2] = 0.0; transformITKIdentityTemporary->Translate(translationIdentity); TransformationInterface::Pointer transformITKIdentity = TransformationInterface::Pointer(new ITKTransformation( - transformITKIdentityTemporary)); + transformITKIdentityTemporary)); TranslationTransformType::Pointer transformITKTranslationTemporary = TranslationTransformType::New(); TranslationTransformType::OutputVectorType translation; translation[0] = 5.0; translation[1] = 5.0; translation[2] = 5.0; transformITKTranslationTemporary->Translate(translation); TransformationInterface::Pointer transformITKTranslation = TransformationInterface::Pointer(new ITKTransformation( - transformITKTranslationTemporary)); + transformITKTranslationTemporary)); - SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorITKIdentity = SimpleMappableDoseAccessor::Pointer(new SimpleMappableDoseAccessor( - doseAccessor1GeometricInfo, doseAccessor2, transformITKIdentity, interpolationLinear)); - SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorITKTranslation = SimpleMappableDoseAccessor::Pointer(new SimpleMappableDoseAccessor( - doseAccessor1GeometricInfo, doseAccessor2, transformITKTranslation, interpolationLinear)); + SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorITKIdentity = SimpleMappableDoseAccessor::Pointer( + new SimpleMappableDoseAccessor( + doseAccessor1GeometricInfo, doseAccessor2, transformITKIdentity, interpolationLinear)); + SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorITKTranslation = SimpleMappableDoseAccessor::Pointer( + new SimpleMappableDoseAccessor( + doseAccessor1GeometricInfo, doseAccessor2, transformITKTranslation, interpolationLinear)); //1) Test constructor CHECK_NO_THROW(SimpleMappableDoseAccessor( doseAccessor1GeometricInfo, doseAccessor2, transformITKIdentity, interpolationLinear)); CHECK_NO_THROW(SimpleMappableDoseAccessor( doseAccessor1GeometricInfo, doseAccessor2, transformITKTranslation, interpolationLinear)); CHECK_NO_THROW(ITKTransformation(transformITKTranslationTemporary.GetPointer())); CHECK_THROW_EXPLICIT(ITKTransformation(NULL), core::NullPointerException); //2) test getDoseAt() // a) with Identity transform //test valid voxels std::vector voxelsAsIndexToTest; std::vector expectedValues; voxelsAsIndexToTest.push_back(VoxelGridIndex3D(5, 9, 8)); voxelsAsIndexToTest.push_back(VoxelGridIndex3D(22, 15, 10)); voxelsAsIndexToTest.push_back(VoxelGridIndex3D(30, 20, 7)); expectedValues.push_back(5.0 * doseGridScaling); expectedValues.push_back(22.0 * doseGridScaling); expectedValues.push_back(30.0 * doseGridScaling); //convert VoxelGridIndex3D to VoxelGridID for (int i = 0; i < voxelsAsIndexToTest.size(); i++) { VoxelGridID currentId; doseAccessor1GeometricInfo.convert(voxelsAsIndexToTest.at(i), currentId); //test if the expected interpolation values are computed - CHECK_EQUAL(aSimpleMappableDoseAccessorITKIdentity->getDoseAt(voxelsAsIndexToTest.at(i)), + CHECK_EQUAL(aSimpleMappableDoseAccessorITKIdentity->getValueAt(voxelsAsIndexToTest.at(i)), expectedValues.at(i)); //test if getDoseAt(VoxelGridIndex3D) and getDoseAt(VoxelGridD) lead to the same results - CHECK_EQUAL(aSimpleMappableDoseAccessorITKIdentity->getDoseAt(voxelsAsIndexToTest.at(i)), - aSimpleMappableDoseAccessorITKIdentity->getDoseAt(currentId)); + CHECK_EQUAL(aSimpleMappableDoseAccessorITKIdentity->getValueAt(voxelsAsIndexToTest.at(i)), + aSimpleMappableDoseAccessorITKIdentity->getValueAt(currentId)); } //no tests with invalid IDs, this has been done already tested in SimpleMappableDoseAccessorTest //b) with translation transform //translation of one voxel in each direction expectedValues.clear(); expectedValues.push_back(6.0 * doseGridScaling); expectedValues.push_back(23.0 * doseGridScaling); expectedValues.push_back(31.0 * doseGridScaling); for (int i = 0; i < voxelsAsIndexToTest.size(); i++) { VoxelGridID currentId; doseAccessor1GeometricInfo.convert(voxelsAsIndexToTest.at(i), currentId); //test if the expected interpolation values are computed - CHECK_EQUAL(aSimpleMappableDoseAccessorITKTranslation->getDoseAt(voxelsAsIndexToTest.at(i)), + CHECK_EQUAL(aSimpleMappableDoseAccessorITKTranslation->getValueAt(voxelsAsIndexToTest.at(i)), expectedValues.at(i)); //test if getDoseAt(VoxelGridIndex3D) and getDoseAt(VoxelGridD) lead to the same results - CHECK_EQUAL(aSimpleMappableDoseAccessorITKTranslation->getDoseAt(voxelsAsIndexToTest.at(i)), - aSimpleMappableDoseAccessorITKTranslation->getDoseAt(currentId)); + CHECK_EQUAL(aSimpleMappableDoseAccessorITKTranslation->getValueAt(voxelsAsIndexToTest.at(i)), + aSimpleMappableDoseAccessorITKTranslation->getValueAt(currentId)); } RETURN_AND_REPORT_TEST_SUCCESS; } }//end namespace testing }//end namespace rttb diff --git a/testing/interpolation/InterpolationTest.cpp b/testing/interpolation/InterpolationTest.cpp index 8ee3dfe..00edec9 100644 --- a/testing/interpolation/InterpolationTest.cpp +++ b/testing/interpolation/InterpolationTest.cpp @@ -1,224 +1,224 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbNearestNeighborInterpolation.h" #include "rttbLinearInterpolation.h" #include "rttbDicomDoseAccessor.h" #include "rttbGenericDoseIterator.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbNullPointerException.h" #include "rttbMappingOutsideOfImageException.h" namespace rttb { namespace testing { typedef rttb::interpolation::NearestNeighborInterpolation NearestNeighborInterpolation; typedef rttb::interpolation::LinearInterpolation LinearInterpolation; typedef rttb::core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; /*! @brief InterpolationTest - tests only interpolation 1) test both interpolation types with simple image (Dose = 2) 2) test both interpolation types with increasing x image values image (Dose = y value) 3) test exception handling */ int InterpolationTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; std::string RTDOSE_FILENAME_CONSTANT_TWO; std::string RTDOSE_FILENAME_INCREASE_X; if (argc > 2) { RTDOSE_FILENAME_CONSTANT_TWO = argv[1]; RTDOSE_FILENAME_INCREASE_X = argv[2]; } else { std::cout << "at least two parameters for InterpolationTest expected" << std::endl; return -1; } rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1( RTDOSE_FILENAME_CONSTANT_TWO.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); DoseAccessorPointer doseAccessorNull; rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator2( RTDOSE_FILENAME_INCREASE_X.c_str()); DoseAccessorPointer doseAccessor2(doseAccessorGenerator2.generateDoseAccessor()); //doseAccessor1 is used as dose image boost::shared_ptr interpolationNN = boost::shared_ptr(new NearestNeighborInterpolation()); - interpolationNN->setDoseAccessorPointer(doseAccessor1); + interpolationNN->setAccessorPointer(doseAccessor1); boost::shared_ptr interpolationLinear = boost::shared_ptr (new LinearInterpolation()); - interpolationLinear->setDoseAccessorPointer(doseAccessor1); + interpolationLinear->setAccessorPointer(doseAccessor1); //doseAccessor2 is used as dose image. //RTDOSE_FILENAME_INCREASE_X and RTDOSE_FILENAME_CONSTANT_TWO have the same GeometricInfo boost::shared_ptr interpolationNN2 = boost::shared_ptr(new NearestNeighborInterpolation()); - interpolationNN2->setDoseAccessorPointer(doseAccessor2); + interpolationNN2->setAccessorPointer(doseAccessor2); boost::shared_ptr interpolationLinear2 = boost::shared_ptr(new LinearInterpolation()); - interpolationLinear2->setDoseAccessorPointer(doseAccessor2); + interpolationLinear2->setAccessorPointer(doseAccessor2); boost::shared_ptr interpolationNullNN = boost::shared_ptr(new NearestNeighborInterpolation()); boost::shared_ptr interpolationNullLinear = boost::shared_ptr(new LinearInterpolation()); rttb::WorldCoordinate3D imagePositionPatient = doseAccessor1->getGeometricInfo().getImagePositionPatient(); rttb::SpacingVectorType3D pixelSpacing = doseAccessor1->getGeometricInfo().getSpacing(); int size[] = {doseAccessor1->getGeometricInfo().getNumColumns(), doseAccessor1->getGeometricInfo().getNumRows(), doseAccessor1->getGeometricInfo().getNumSlices()}; //check position [0 0 0], [max/2, max/2, max/2], [max max max] and combinations (as pixel positions are given at middle, correct with PixelSpacing/2) //outermost position of the image max_x = (coordinatesZeroAndMaxX.at(0) + (size[0]*pixelSpacing.x()) can't be used, because this is already outside of the image, thus test max-0.001. std::vector coordinatesZeroAndMaxX; coordinatesZeroAndMaxX.push_back(imagePositionPatient.x() - (pixelSpacing.x() * 0.5)); coordinatesZeroAndMaxX.push_back(coordinatesZeroAndMaxX.at(0) + (size[0] *pixelSpacing.x() - 0.001)); coordinatesZeroAndMaxX.push_back(coordinatesZeroAndMaxX.at(0) + ((size[0] - 1)*pixelSpacing.x() * 0.5)); std::vector coordinatesZeroAndMaxY; coordinatesZeroAndMaxY.push_back(imagePositionPatient.y() - (pixelSpacing.y() * 0.5)); coordinatesZeroAndMaxY.push_back(coordinatesZeroAndMaxY.at(0) + (size[1] *pixelSpacing.y() - 0.001)); coordinatesZeroAndMaxY.push_back(coordinatesZeroAndMaxY.at(0) + ((size[1] - 1)*pixelSpacing.y() * 0.5)); std::vector coordinatesZeroAndMaxZ; coordinatesZeroAndMaxZ.push_back(imagePositionPatient.z() - (pixelSpacing.z() * 0.5)); coordinatesZeroAndMaxZ.push_back(coordinatesZeroAndMaxZ.at(0) + (size[2] *pixelSpacing.z() - 0.001)); coordinatesZeroAndMaxZ.push_back(coordinatesZeroAndMaxZ.at(0) + ((size[2] - 1)*pixelSpacing.z() * 0.5)); std::vector coordinatesToCheck; for (int x = 0; x < coordinatesZeroAndMaxX.size(); x++) { for (int y = 0; y < coordinatesZeroAndMaxY.size(); y++) { for (int z = 0; z < coordinatesZeroAndMaxZ.size(); z++) { coordinatesToCheck.push_back(rttb::WorldCoordinate3D(coordinatesZeroAndMaxX.at(x), coordinatesZeroAndMaxY.at(y), coordinatesZeroAndMaxZ.at(z))); } } } rttb::WorldCoordinate3D positionOutsideOfImageLeft = imagePositionPatient - rttb::WorldCoordinate3D( pixelSpacing.x() * 2.0, pixelSpacing.y() * 2.0, pixelSpacing.z() * 2.0); rttb::WorldCoordinate3D positionOutsideOfImageRight = imagePositionPatient + rttb::WorldCoordinate3D(size[0] * pixelSpacing.x(), size[1] * pixelSpacing.y(), size[2] * pixelSpacing.z()) + rttb::WorldCoordinate3D(pixelSpacing.x() * 2.0, pixelSpacing.y() * 2.0, pixelSpacing.z() * 2.0); //precomputed values for Nearest neighbor + Linear interpolator double expectedDoseIncreaseXNearest[27]; double expectedDoseIncreaseXLinear[27]; for (int i = 0; i < 27; i++) { if (i < 9) { expectedDoseIncreaseXNearest[i] = 0.0; expectedDoseIncreaseXLinear[i] = 0.0; } else if (i < 18) { expectedDoseIncreaseXNearest[i] = 0.00186277; expectedDoseIncreaseXLinear[i] = 0.00186277; } else { expectedDoseIncreaseXNearest[i] = 0.000931387; expectedDoseIncreaseXLinear[i] = 0.000931387; } } //TEST 1) RTDOSE_FILENAME_CONSTANT_TWO contains Dose 2.0 Gy for each pixel, so for every interpolation, 2.0 has to be the result std::vector::const_iterator iterCoordinates = coordinatesToCheck.cbegin(); while (iterCoordinates != coordinatesToCheck.cend()) { CHECK_EQUAL(interpolationNN->getValue(*iterCoordinates), 2.0); CHECK_EQUAL(interpolationLinear->getValue(*iterCoordinates), 2.0); ++iterCoordinates; } //TEST 2) RTDOSE_FILENAME_INCREASE_X contains a Dose gradient file, correct interpolation values have been computed manually. To avoid floating point inaccuracy, CHECK_CLOSE is used iterCoordinates = coordinatesToCheck.cbegin(); unsigned int index = 0; while (iterCoordinates != coordinatesToCheck.cend() && index < 27) { CHECK_CLOSE(interpolationNN2->getValue(*iterCoordinates), expectedDoseIncreaseXNearest[index], errorConstant); CHECK_CLOSE(interpolationLinear2->getValue(*iterCoordinates), expectedDoseIncreaseXLinear[index], errorConstant); ++iterCoordinates; ++index; } //TEST 3) Exception handling //Check that core::MappingOutOfImageException is thrown if requested position is outside image CHECK_THROW_EXPLICIT(interpolationNN->getValue(positionOutsideOfImageLeft), core::MappingOutsideOfImageException); CHECK_THROW_EXPLICIT(interpolationNN->getValue(positionOutsideOfImageRight), core::MappingOutsideOfImageException); CHECK_THROW_EXPLICIT(interpolationLinear->getValue(positionOutsideOfImageLeft), core::MappingOutsideOfImageException); CHECK_THROW_EXPLICIT(interpolationLinear->getValue(positionOutsideOfImageRight), core::MappingOutsideOfImageException); //Check that core::NullPointerException is thrown if Null Pointers are given to interpolator - CHECK_THROW_EXPLICIT(interpolationNullLinear->setDoseAccessorPointer(doseAccessorNull), + CHECK_THROW_EXPLICIT(interpolationNullLinear->setAccessorPointer(doseAccessorNull), core::NullPointerException); - CHECK_THROW_EXPLICIT(interpolationNullNN->setDoseAccessorPointer(doseAccessorNull), + CHECK_THROW_EXPLICIT(interpolationNullNN->setAccessorPointer(doseAccessorNull), core::NullPointerException); CHECK_THROW_EXPLICIT(interpolationNullLinear->getValue(coordinatesToCheck.front()), core::NullPointerException); CHECK_THROW_EXPLICIT(interpolationNullNN->getValue(coordinatesToCheck.front()), core::NullPointerException); //Check that no exception is thrown otherwise CHECK_NO_THROW(boost::shared_ptr(new NearestNeighborInterpolation())); CHECK_NO_THROW(boost::shared_ptr(new LinearInterpolation())); RETURN_AND_REPORT_TEST_SUCCESS; } } } diff --git a/testing/interpolation/MatchPointBinding/SimpleMappableDoseAccessorWithMatchPointTest.cpp b/testing/interpolation/MatchPointBinding/SimpleMappableDoseAccessorWithMatchPointTest.cpp index 562725e..446f5ef 100644 --- a/testing/interpolation/MatchPointBinding/SimpleMappableDoseAccessorWithMatchPointTest.cpp +++ b/testing/interpolation/MatchPointBinding/SimpleMappableDoseAccessorWithMatchPointTest.cpp @@ -1,248 +1,252 @@ // ----------------------------------------------------------------------- // 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: 741 $ (last changed revision) // @date $Date: 2014-09-16 16:34:22 +0200 (Di, 16 Sep 2014) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbGenericDoseIterator.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbSimpleMappableDoseAccessor.h" #include "rttbNearestNeighborInterpolation.h" #include "rttbLinearInterpolation.h" #include "rttbGeometricInfo.h" #include "rttbTransformationInterface.h" #include "rttbMatchPointTransformation.h" #include "rttbNullPointerException.h" #include "registrationTest.h" #include "simpleRegistrationWorkflow.h" namespace rttb { namespace testing { static const unsigned int TargetDimension3D = 3; static const unsigned int MovingDimension3D = 3; typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; typedef rttb::interpolation::SimpleMappableDoseAccessor SimpleMappableDoseAccessor; typedef map::core::RegistrationTest Registration3D3DTypeTest; typedef Registration3D3DTypeTest::Pointer Registration3D3DTypeTestPointer; typedef map::core::Registration Registration3D3DType; typedef Registration3D3DType::Pointer Registration3D3DPointer; typedef rttb::interpolation::NearestNeighborInterpolation NearestNeighborInterpolation; typedef rttb::interpolation::LinearInterpolation LinearInterpolation; typedef rttb::interpolation::TransformationInterface TransformationInterface; typedef rttb::interpolation::MatchPointTransformation MatchPointTransformation; /*! @brief SimpleMappableDoseAccessorWithMatchPointTest - test the API of SimpleMappableDoseAccessor with MatchPoint transform 1) Test constructor 2) test getDoseAt() a) with Identity transform b) with translation transform [3) test with rigid registration optional (if filenames are given as argument)] */ int SimpleMappableDoseAccessorWithMatchPointTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; std::string RTDOSE_FILENAME_CONSTANT_TWO; std::string RTDOSE_FILENAME_INCREASE_X; std::string RTDOSE_FILENAME_REALISTIC = ""; std::string CT_PLANNING = ""; std::string CT_FRACTION = ""; if (argc > 2) { RTDOSE_FILENAME_CONSTANT_TWO = argv[1]; RTDOSE_FILENAME_INCREASE_X = argv[2]; } else { std::cout << "at least two parameters for SimpleMappableDoseAccessorWithMatchPointTest are expected" << std::endl; return -1; } if (argc > 5) { RTDOSE_FILENAME_REALISTIC = argv[3]; CT_PLANNING = argv[4]; CT_FRACTION = argv[5]; } rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1( RTDOSE_FILENAME_CONSTANT_TWO.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); DoseAccessorPointer doseAccessorNull; rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator2( RTDOSE_FILENAME_INCREASE_X.c_str()); DoseAccessorPointer doseAccessor2(doseAccessorGenerator2.generateDoseAccessor()); core::GeometricInfo doseAccessor1GeometricInfo = doseAccessor1->getGeometricInfo(); Registration3D3DTypeTestPointer registration = Registration3D3DTypeTest::New(); double translation[] = {0.0, 0.0, 0.0}; registration->_translation = translation; registration->_limitedTarget = false; NearestNeighborInterpolation::Pointer interpolationNN = NearestNeighborInterpolation::Pointer(new NearestNeighborInterpolation()); LinearInterpolation::Pointer interpolationLinear = LinearInterpolation::Pointer - (new LinearInterpolation()); + (new LinearInterpolation()); NearestNeighborInterpolation::Pointer interpolationNull; TransformationInterface::Pointer transformMP = TransformationInterface::Pointer(new MatchPointTransformation( - registration.GetPointer())); + registration.GetPointer())); - SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorMPIdentityLinear = SimpleMappableDoseAccessor::Pointer(new SimpleMappableDoseAccessor( - doseAccessor1GeometricInfo, doseAccessor2, transformMP, interpolationLinear)); - SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorMPIdentityNN = SimpleMappableDoseAccessor::Pointer(new SimpleMappableDoseAccessor( - doseAccessor1GeometricInfo, doseAccessor2, transformMP, interpolationNN)); + SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorMPIdentityLinear = SimpleMappableDoseAccessor::Pointer( + new SimpleMappableDoseAccessor( + doseAccessor1GeometricInfo, doseAccessor2, transformMP, interpolationLinear)); + SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorMPIdentityNN = SimpleMappableDoseAccessor::Pointer( + new SimpleMappableDoseAccessor( + doseAccessor1GeometricInfo, doseAccessor2, transformMP, interpolationNN)); //1) Test constructor CHECK_NO_THROW(SimpleMappableDoseAccessor( doseAccessor1GeometricInfo, doseAccessor2, transformMP, interpolationLinear)); CHECK_NO_THROW(SimpleMappableDoseAccessor( doseAccessor1GeometricInfo, doseAccessor2, transformMP, interpolationNN)); CHECK_NO_THROW(MatchPointTransformation(registration.GetPointer())); CHECK_THROW_EXPLICIT(MatchPointTransformation(NULL), core::NullPointerException); //2) test getDoseAt() // a) with Identity transform double vectorDoseAccessorStartEnd = 0.0; while (vectorDoseAccessorStartEnd <= 1.0) { VoxelGridID runningID = (VoxelGridID)(vectorDoseAccessorStartEnd * (double)aSimpleMappableDoseAccessorMPIdentityLinear->getGridSize()); - CHECK_EQUAL(aSimpleMappableDoseAccessorMPIdentityLinear->getDoseAt(runningID), - doseAccessor2->getDoseAt(runningID)); - CHECK_EQUAL(aSimpleMappableDoseAccessorMPIdentityNN->getDoseAt(runningID), - doseAccessor2->getDoseAt(runningID)); + CHECK_EQUAL(aSimpleMappableDoseAccessorMPIdentityLinear->getValueAt(runningID), + doseAccessor2->getValueAt(runningID)); + CHECK_EQUAL(aSimpleMappableDoseAccessorMPIdentityNN->getValueAt(runningID), + doseAccessor2->getValueAt(runningID)); vectorDoseAccessorStartEnd += 0.1; } // b) with translation transform //Second: Translation (5mm/5mm/5mm) --> in voxel: (1/1/1) as pixelspacing = 5 mm translation[0] = translation[1] = translation[2] = 5.0; registration->_translation = translation; - SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorMPTranslationLinear = SimpleMappableDoseAccessor::Pointer(new SimpleMappableDoseAccessor( - doseAccessor1GeometricInfo, doseAccessor2, transformMP, interpolationLinear)); - SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorMPTranslationNN = SimpleMappableDoseAccessor::Pointer(new SimpleMappableDoseAccessor( - doseAccessor1GeometricInfo, doseAccessor2, transformMP, interpolationNN)); + SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorMPTranslationLinear = + SimpleMappableDoseAccessor::Pointer(new SimpleMappableDoseAccessor( + doseAccessor1GeometricInfo, doseAccessor2, transformMP, interpolationLinear)); + SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorMPTranslationNN = SimpleMappableDoseAccessor::Pointer( + new SimpleMappableDoseAccessor( + doseAccessor1GeometricInfo, doseAccessor2, transformMP, interpolationNN)); rttb::VoxelGridIndex3D aIndexBeforeTransformation(0, 0, 0); rttb::VoxelGridIndex3D aIndexAfterTransformation(1, 1, 1); - CHECK_EQUAL(aSimpleMappableDoseAccessorMPTranslationLinear->getDoseAt(aIndexBeforeTransformation), - doseAccessor2->getDoseAt(aIndexAfterTransformation)); - CHECK_EQUAL(aSimpleMappableDoseAccessorMPTranslationNN->getDoseAt(aIndexBeforeTransformation), - doseAccessor2->getDoseAt(aIndexAfterTransformation)); + CHECK_EQUAL(aSimpleMappableDoseAccessorMPTranslationLinear->getValueAt(aIndexBeforeTransformation), + doseAccessor2->getValueAt(aIndexAfterTransformation)); + CHECK_EQUAL(aSimpleMappableDoseAccessorMPTranslationNN->getValueAt(aIndexBeforeTransformation), + doseAccessor2->getValueAt(aIndexAfterTransformation)); rttb::VoxelGridIndex3D aIndexBeforeTransformation2(20, 10, 10); rttb::VoxelGridIndex3D aIndexAfterTransformation2(21, 11, 11); - CHECK_EQUAL(aSimpleMappableDoseAccessorMPTranslationLinear->getDoseAt(aIndexBeforeTransformation2), - doseAccessor2->getDoseAt(aIndexAfterTransformation2)); - CHECK_EQUAL(aSimpleMappableDoseAccessorMPTranslationNN->getDoseAt(aIndexBeforeTransformation2), - doseAccessor2->getDoseAt(aIndexAfterTransformation2)); + CHECK_EQUAL(aSimpleMappableDoseAccessorMPTranslationLinear->getValueAt(aIndexBeforeTransformation2), + doseAccessor2->getValueAt(aIndexAfterTransformation2)); + CHECK_EQUAL(aSimpleMappableDoseAccessorMPTranslationNN->getValueAt(aIndexBeforeTransformation2), + doseAccessor2->getValueAt(aIndexAfterTransformation2)); rttb::VoxelGridIndex3D aIndexBeforeTransformation3( aSimpleMappableDoseAccessorMPTranslationLinear->getGeometricInfo().getNumColumns() - 2, aSimpleMappableDoseAccessorMPTranslationLinear->getGeometricInfo().getNumRows() - 2, aSimpleMappableDoseAccessorMPTranslationLinear->getGeometricInfo().getNumSlices() - 2); rttb::VoxelGridIndex3D aIndexAfterTransformation3( aSimpleMappableDoseAccessorMPTranslationLinear->getGeometricInfo().getNumColumns() - 1, aSimpleMappableDoseAccessorMPTranslationLinear->getGeometricInfo().getNumRows() - 1, aSimpleMappableDoseAccessorMPTranslationLinear->getGeometricInfo().getNumSlices() - 1); - CHECK_EQUAL(aSimpleMappableDoseAccessorMPTranslationLinear->getDoseAt(aIndexBeforeTransformation3), - doseAccessor2->getDoseAt(aIndexAfterTransformation3)); - CHECK_EQUAL(aSimpleMappableDoseAccessorMPTranslationNN->getDoseAt(aIndexBeforeTransformation3), - doseAccessor2->getDoseAt(aIndexAfterTransformation3)); + CHECK_EQUAL(aSimpleMappableDoseAccessorMPTranslationLinear->getValueAt(aIndexBeforeTransformation3), + doseAccessor2->getValueAt(aIndexAfterTransformation3)); + CHECK_EQUAL(aSimpleMappableDoseAccessorMPTranslationNN->getValueAt(aIndexBeforeTransformation3), + doseAccessor2->getValueAt(aIndexAfterTransformation3)); if (RTDOSE_FILENAME_REALISTIC != "" && CT_FRACTION != "" && CT_PLANNING != "") { //3) test with rigid registration //realistic background: registration from BP-CT to fraction CT, apply on planning dose that is based on BP-CT (proof of concept) //Target image: fraction CT, Moving image: planning CT simpleRegistrationWorkflow prepareRegistrationRealisticScenario(CT_FRACTION, CT_PLANNING, true); Registration3D3DPointer registrationRealisticScenario = prepareRegistrationRealisticScenario.getRegistration(); TransformationInterface::Pointer transformRealistic = TransformationInterface::Pointer(new MatchPointTransformation( - registrationRealisticScenario)); + registrationRealisticScenario)); io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator3(RTDOSE_FILENAME_REALISTIC.c_str()); DoseAccessorPointer doseAccessor3(doseAccessorGenerator3.generateDoseAccessor()); core::GeometricInfo geoInfoRealistic; geoInfoRealistic.setNumColumns( prepareRegistrationRealisticScenario.getTargetImage()->GetLargestPossibleRegion().GetSize()[0]); geoInfoRealistic.setNumRows( prepareRegistrationRealisticScenario.getTargetImage()->GetLargestPossibleRegion().GetSize()[1]); geoInfoRealistic.setNumSlices( prepareRegistrationRealisticScenario.getTargetImage()->GetLargestPossibleRegion().GetSize()[2]); //Dose is related to BP-CT, map dose to fraction CT geometry SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorRealisticScenarioLinear = SimpleMappableDoseAccessor::Pointer(new SimpleMappableDoseAccessor(geoInfoRealistic, - doseAccessor3, transformRealistic, interpolationLinear)); + doseAccessor3, transformRealistic, interpolationLinear)); //combination of 0, size/2 and size to check as coordinates std::vector coordinatesToCheckX, coordinatesToCheckY, coordinatesToCheckZ; coordinatesToCheckX.push_back(0); coordinatesToCheckX.push_back(geoInfoRealistic.getNumColumns() / 2); coordinatesToCheckX.push_back(geoInfoRealistic.getNumColumns() - 1); coordinatesToCheckY.push_back(0); coordinatesToCheckY.push_back(geoInfoRealistic.getNumRows() / 2); coordinatesToCheckY.push_back(geoInfoRealistic.getNumRows() - 1); coordinatesToCheckZ.push_back(0); coordinatesToCheckZ.push_back(geoInfoRealistic.getNumSlices() / 2); coordinatesToCheckZ.push_back(geoInfoRealistic.getNumSlices() - 1); //Pixels are inside the fraction CT image and mapping should work (even if they map outside of doseAccessor3) for (unsigned int i = 0; i < coordinatesToCheckX.size(); ++i) { for (unsigned int j = 0; j < coordinatesToCheckY.size(); ++j) { for (unsigned int k = 0; k < coordinatesToCheckZ.size(); ++k) { - CHECK_NO_THROW(aSimpleMappableDoseAccessorRealisticScenarioLinear->getDoseAt(VoxelGridIndex3D( + CHECK_NO_THROW(aSimpleMappableDoseAccessorRealisticScenarioLinear->getValueAt(VoxelGridIndex3D( coordinatesToCheckX.at(i), coordinatesToCheckY.at(j), coordinatesToCheckZ.at(k)))); } } } } RETURN_AND_REPORT_TEST_SUCCESS; } }//end namespace testing }//end namespace rttb diff --git a/testing/interpolation/RosuMappableDoseAccessorTest.cpp b/testing/interpolation/RosuMappableDoseAccessorTest.cpp index fd9dc90..fa9b3d8 100644 --- a/testing/interpolation/RosuMappableDoseAccessorTest.cpp +++ b/testing/interpolation/RosuMappableDoseAccessorTest.cpp @@ -1,153 +1,153 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbGenericDoseIterator.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbRosuMappableDoseAccessor.h" #include "DummyTransformation.h" #include "rttbNullPointerException.h" #include "rttbMappingOutsideOfImageException.h" namespace rttb { namespace testing { typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; typedef rttb::interpolation::RosuMappableDoseAccessor RosuMappableDoseAccessor; typedef rttb::interpolation::TransformationInterface TransformationInterface; /*! @brief RosuMappableDoseAccessorTest - test the API of RosuMappableDoseAccessor 1) Constructor 2) test getDoseAt() */ int RosuMappableDoseAccessorTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; std::string RTDOSE_FILENAME_CONSTANT_TWO; std::string RTDOSE_FILENAME_INCREASE_X; if (argc > 2) { RTDOSE_FILENAME_CONSTANT_TWO = argv[1]; RTDOSE_FILENAME_INCREASE_X = argv[2]; } else { std::cout << "at least two parameters for RosuMappableDoseAccessorTest are expected" << std::endl; return -1; } const double doseGridScaling = 2.822386e-005; rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1( RTDOSE_FILENAME_CONSTANT_TWO.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator2( RTDOSE_FILENAME_INCREASE_X.c_str()); DoseAccessorPointer doseAccessor2(doseAccessorGenerator2.generateDoseAccessor()); DoseAccessorPointer doseAccessorNull; auto transformDummy = TransformationInterface::Pointer(new DummyTransformation()); TransformationInterface::Pointer transformNull; auto aRosuMappableDoseAccessorDefault = RosuMappableDoseAccessor::Pointer(new RosuMappableDoseAccessor( doseAccessor1->getGeometricInfo(), doseAccessor2, transformDummy)); auto aRosuMappableDoseAccessorNoPadding = RosuMappableDoseAccessor::Pointer(new RosuMappableDoseAccessor( doseAccessor1->getGeometricInfo(), doseAccessor2, transformDummy, false)); //1) Constructor CHECK_NO_THROW(RosuMappableDoseAccessor test(doseAccessor1->getGeometricInfo(), doseAccessor2, transformDummy)); CHECK_NO_THROW(RosuMappableDoseAccessor test(doseAccessor1->getGeometricInfo(), doseAccessor2, transformDummy, false)); CHECK_NO_THROW(RosuMappableDoseAccessor test(doseAccessor1->getGeometricInfo(), doseAccessor2, transformDummy, true, 5.0)); CHECK_THROW_EXPLICIT(RosuMappableDoseAccessor test(doseAccessor1->getGeometricInfo(), doseAccessorNull, transformDummy), core::NullPointerException); CHECK_THROW_EXPLICIT(RosuMappableDoseAccessor test(doseAccessor1->getGeometricInfo(), doseAccessor2, transformNull), core::NullPointerException); CHECK_THROW_EXPLICIT(RosuMappableDoseAccessor test(doseAccessor1->getGeometricInfo(), doseAccessorNull, transformNull), core::NullPointerException); //2) test getDoseAt() std::vector voxelsAsIndexToTest; std::vector voxelsAsIdToTest; std::vector expectedValues; voxelsAsIndexToTest.push_back(VoxelGridIndex3D(5, 9, 8)); voxelsAsIndexToTest.push_back(VoxelGridIndex3D(22, 15, 10)); voxelsAsIndexToTest.push_back(VoxelGridIndex3D(30, 20, 7)); expectedValues.push_back(5.0 * doseGridScaling); expectedValues.push_back(22.0 * doseGridScaling); expectedValues.push_back(30.0 * doseGridScaling); //convert VoxelGridIndex3D to VoxelGridID for (int i = 0; i < voxelsAsIndexToTest.size(); i++) { VoxelGridID currentId; doseAccessor1->getGeometricInfo().convert(voxelsAsIndexToTest.at(i), currentId); voxelsAsIdToTest.push_back(currentId); } for (int i = 0; i < voxelsAsIndexToTest.size(); i++) { //test if the expected interpolation values are computed - CHECK_CLOSE(aRosuMappableDoseAccessorDefault->getDoseAt(voxelsAsIndexToTest.at(i)), + CHECK_CLOSE(aRosuMappableDoseAccessorDefault->getValueAt(voxelsAsIndexToTest.at(i)), expectedValues.at(i), errorConstant); //test if getDoseAt(VoxelGridIndex3D) and getDoseAt(VoxelGridD) lead to the same results - CHECK_EQUAL(aRosuMappableDoseAccessorDefault->getDoseAt(voxelsAsIndexToTest.at(i)), - aRosuMappableDoseAccessorDefault->getDoseAt(voxelsAsIdToTest.at(i))); + CHECK_EQUAL(aRosuMappableDoseAccessorDefault->getValueAt(voxelsAsIndexToTest.at(i)), + aRosuMappableDoseAccessorDefault->getValueAt(voxelsAsIdToTest.at(i))); } //test invalid voxels VoxelGridID invalidID(doseAccessor1->getGeometricInfo().getNumberOfVoxels() + 1); VoxelGridIndex3D invalidIndex(doseAccessor1->getGeometricInfo().getNumColumns() + 1, doseAccessor1->getGeometricInfo().getNumRows() + 1, doseAccessor1->getGeometricInfo().getNumSlices() + 1); - CHECK_EQUAL(aRosuMappableDoseAccessorDefault->getDoseAt(invalidID), 0.0); - CHECK_EQUAL(aRosuMappableDoseAccessorDefault->getDoseAt(invalidIndex), 0.0); - CHECK_THROW_EXPLICIT(aRosuMappableDoseAccessorNoPadding->getDoseAt(invalidID), + CHECK_EQUAL(aRosuMappableDoseAccessorDefault->getValueAt(invalidID), 0.0); + CHECK_EQUAL(aRosuMappableDoseAccessorDefault->getValueAt(invalidIndex), 0.0); + CHECK_THROW_EXPLICIT(aRosuMappableDoseAccessorNoPadding->getValueAt(invalidID), core::MappingOutsideOfImageException); - CHECK_THROW_EXPLICIT(aRosuMappableDoseAccessorNoPadding->getDoseAt(invalidIndex), + CHECK_THROW_EXPLICIT(aRosuMappableDoseAccessorNoPadding->getValueAt(invalidIndex), core::MappingOutsideOfImageException); RETURN_AND_REPORT_TEST_SUCCESS; } }//end namespace testing }//end namespace rttb diff --git a/testing/interpolation/SimpleMappableDoseAccessorTest.cpp b/testing/interpolation/SimpleMappableDoseAccessorTest.cpp index 4df9b43..1ec7c42 100644 --- a/testing/interpolation/SimpleMappableDoseAccessorTest.cpp +++ b/testing/interpolation/SimpleMappableDoseAccessorTest.cpp @@ -1,164 +1,166 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbGenericDoseIterator.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbSimpleMappableDoseAccessor.h" #include "rttbNearestNeighborInterpolation.h" #include "rttbLinearInterpolation.h" #include "rttbTransformationInterface.h" #include "DummyTransformation.h" #include "rttbNullPointerException.h" #include "rttbMappingOutsideOfImageException.h" namespace rttb { namespace testing { typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; typedef rttb::interpolation::SimpleMappableDoseAccessor SimpleMappableDoseAccessor; typedef rttb::interpolation::TransformationInterface TransformationInterface; typedef rttb::interpolation::LinearInterpolation LinearInterpolation; typedef rttb::interpolation::NearestNeighborInterpolation NearestNeighborInterpolation; /*! @brief SimpleMappableDoseAccessorTest - test the API of SimpleMappableDoseAccessor 1) Test constructor 2) test getDoseAt() */ int SimpleMappableDoseAccessorTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; std::string RTDOSE_FILENAME_CONSTANT_TWO; std::string RTDOSE_FILENAME_INCREASE_X; if (argc > 2) { RTDOSE_FILENAME_CONSTANT_TWO = argv[1]; RTDOSE_FILENAME_INCREASE_X = argv[2]; } else { std::cout << "at least two parameters for SimpleMappableDoseAccessorTest are expected" << std::endl; return -1; } const double doseGridScaling = 2.822386e-005; rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1( RTDOSE_FILENAME_CONSTANT_TWO.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); core::GeometricInfo doseAccessor1GeometricInfo = doseAccessor1->getGeometricInfo(); rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator2( RTDOSE_FILENAME_INCREASE_X.c_str()); DoseAccessorPointer doseAccessor2(doseAccessorGenerator2.generateDoseAccessor()); DoseAccessorPointer doseAccessorNull; TransformationInterface::Pointer transformDummy = TransformationInterface::Pointer(new DummyTransformation()); TransformationInterface::Pointer transformNull; NearestNeighborInterpolation::Pointer interpolationNN = NearestNeighborInterpolation::Pointer(new NearestNeighborInterpolation()); LinearInterpolation::Pointer interpolationLinear = LinearInterpolation::Pointer(new LinearInterpolation()); boost::shared_ptr interpolationNull; - SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorDefault = SimpleMappableDoseAccessor::Pointer(new SimpleMappableDoseAccessor( - doseAccessor1->getGeometricInfo(), doseAccessor2, transformDummy, interpolationLinear)); - SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorNoPadding = SimpleMappableDoseAccessor::Pointer(new SimpleMappableDoseAccessor( - doseAccessor1->getGeometricInfo(), doseAccessor2, transformDummy, interpolationLinear, false)); + SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorDefault = SimpleMappableDoseAccessor::Pointer( + new SimpleMappableDoseAccessor( + doseAccessor1->getGeometricInfo(), doseAccessor2, transformDummy, interpolationLinear)); + SimpleMappableDoseAccessor::Pointer aSimpleMappableDoseAccessorNoPadding = SimpleMappableDoseAccessor::Pointer( + new SimpleMappableDoseAccessor( + doseAccessor1->getGeometricInfo(), doseAccessor2, transformDummy, interpolationLinear, false)); //1) Test constructor CHECK_NO_THROW(SimpleMappableDoseAccessor test(doseAccessor1->getGeometricInfo(), doseAccessor2, transformDummy, interpolationLinear)); CHECK_NO_THROW(SimpleMappableDoseAccessor test(doseAccessor1->getGeometricInfo(), doseAccessor2, transformDummy, interpolationLinear, false)); CHECK_NO_THROW(SimpleMappableDoseAccessor test(doseAccessor1->getGeometricInfo(), doseAccessor2, transformDummy, interpolationLinear, true, 5.0)); CHECK_NO_THROW(SimpleMappableDoseAccessor(doseAccessor1GeometricInfo, doseAccessor2, transformDummy, interpolationNN)); CHECK_THROW_EXPLICIT(SimpleMappableDoseAccessor test(doseAccessor1->getGeometricInfo(), doseAccessorNull, transformDummy, interpolationLinear), core::NullPointerException); CHECK_THROW_EXPLICIT(SimpleMappableDoseAccessor test(doseAccessor1->getGeometricInfo(), doseAccessor2, transformNull, interpolationLinear), core::NullPointerException); CHECK_THROW_EXPLICIT(SimpleMappableDoseAccessor test(doseAccessor1->getGeometricInfo(), doseAccessorNull, transformNull, interpolationLinear), core::NullPointerException); CHECK_THROW_EXPLICIT(SimpleMappableDoseAccessor(doseAccessor1GeometricInfo, doseAccessor2, transformDummy, interpolationNull), core::NullPointerException); //2) test getGeometricInfo(), getGridSize(), getDoseUID() function CHECK_EQUAL(aSimpleMappableDoseAccessorDefault->getGeometricInfo(), doseAccessor1->getGeometricInfo()); CHECK_EQUAL(aSimpleMappableDoseAccessorDefault->getGridSize(), doseAccessor1->getGeometricInfo().getNumberOfVoxels()); - CHECK_EQUAL(aSimpleMappableDoseAccessorDefault->getDoseUID(), doseAccessor2->getDoseUID()); + CHECK_EQUAL(aSimpleMappableDoseAccessorDefault->getUID(), doseAccessor2->getUID()); //3) test getDoseAt() //test valid voxels std::vector voxelsAsIndexToTest; std::vector expectedValues; voxelsAsIndexToTest.push_back(VoxelGridIndex3D(5, 9, 8)); voxelsAsIndexToTest.push_back(VoxelGridIndex3D(22, 15, 10)); voxelsAsIndexToTest.push_back(VoxelGridIndex3D(30, 20, 7)); expectedValues.push_back(5.0 * doseGridScaling); expectedValues.push_back(22.0 * doseGridScaling); expectedValues.push_back(30.0 * doseGridScaling); for (int i = 0; i < voxelsAsIndexToTest.size(); i++) { VoxelGridID currentId; doseAccessor1GeometricInfo.convert(voxelsAsIndexToTest.at(i), currentId); //test if the expected interpolation values are computed - CHECK_EQUAL(aSimpleMappableDoseAccessorDefault->getDoseAt(currentId), + CHECK_EQUAL(aSimpleMappableDoseAccessorDefault->getValueAt(currentId), expectedValues.at(i)); //test if getDoseAt(VoxelGridIndex3D) and getDoseAt(VoxelGridD) lead to the same results - CHECK_EQUAL(aSimpleMappableDoseAccessorDefault->getDoseAt(currentId), - aSimpleMappableDoseAccessorDefault->getDoseAt(voxelsAsIndexToTest.at(i))); + CHECK_EQUAL(aSimpleMappableDoseAccessorDefault->getValueAt(currentId), + aSimpleMappableDoseAccessorDefault->getValueAt(voxelsAsIndexToTest.at(i))); } //test invalid voxels VoxelGridID invalidID(doseAccessor1GeometricInfo.getNumberOfVoxels() + 1); VoxelGridIndex3D invalidIndex(doseAccessor1GeometricInfo.getNumColumns() + 1, doseAccessor1GeometricInfo.getNumRows() + 1, doseAccessor1GeometricInfo.getNumSlices() + 1); - CHECK_EQUAL(aSimpleMappableDoseAccessorDefault->getDoseAt(invalidID), 0.0); - CHECK_EQUAL(aSimpleMappableDoseAccessorDefault->getDoseAt(invalidIndex), 0.0); - CHECK_THROW_EXPLICIT(aSimpleMappableDoseAccessorNoPadding->getDoseAt(invalidID), + CHECK_EQUAL(aSimpleMappableDoseAccessorDefault->getValueAt(invalidID), 0.0); + CHECK_EQUAL(aSimpleMappableDoseAccessorDefault->getValueAt(invalidIndex), 0.0); + CHECK_THROW_EXPLICIT(aSimpleMappableDoseAccessorNoPadding->getValueAt(invalidID), core::MappingOutsideOfImageException); - CHECK_THROW_EXPLICIT(aSimpleMappableDoseAccessorNoPadding->getDoseAt(invalidIndex), + CHECK_THROW_EXPLICIT(aSimpleMappableDoseAccessorNoPadding->getValueAt(invalidIndex), core::MappingOutsideOfImageException); RETURN_AND_REPORT_TEST_SUCCESS; } }//end namespace testing }//end namespace rttb diff --git a/testing/io/dicom/DicomDoseAccessorConverterTest.cpp b/testing/io/dicom/DicomDoseAccessorConverterTest.cpp index 51db803..7748401 100644 --- a/testing/io/dicom/DicomDoseAccessorConverterTest.cpp +++ b/testing/io/dicom/DicomDoseAccessorConverterTest.cpp @@ -1,132 +1,149 @@ // ----------------------------------------------------------------------- // 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 "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(); + DoseAccessorPointer doseAccessor_r = io::dicom::DicomFileDoseAccessorGenerator( + RTDOSE_FILENAME_R.c_str()).generateDoseAccessor(); 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_NO_THROW(doseConverter.setFileName(RTDOSE_FILENAME_W)); CHECK_EQUAL(doseConverter.process(), true); - - DoseAccessorPointer doseAccessor_w = io::dicom::DicomFileDoseAccessorGenerator(RTDOSE_FILENAME_W).generateDoseAccessor(); + + 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_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); + 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->getValueAt(index), doseAccessor_w->getValueAt(index), errorConstant); + + if (size / 2 - index >= 0 && size / 2 - index < size) + { + CHECK_CLOSE(doseAccessor_r->getValueAt(size / 2 - index), doseAccessor_w->getValueAt(size / 2 - index), errorConstant); } - CHECK_CLOSE(doseAccessor_r->getDoseAt(size-index-1), doseAccessor_w->getDoseAt(size-index-1), errorConstant); + + CHECK_CLOSE(doseAccessor_r->getValueAt(size - index - 1), doseAccessor_w->getValueAt(size - index - 1), errorConstant); } RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/dicom/DicomIOTest.cpp b/testing/io/dicom/DicomIOTest.cpp index e89cfc2..77b693e 100644 --- a/testing/io/dicom/DicomIOTest.cpp +++ b/testing/io/dicom/DicomIOTest.cpp @@ -1,240 +1,241 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (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 "rttbGeometricInfo.h" #include "rttbDoseIteratorInterface.h" #include "rttbDicomDoseAccessor.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomIODDoseAccessorGenerator.h" #include "rttbDicomFileStructureSetGenerator.h" namespace rttb { namespace testing { /*!@brief DicomIOTest - test the IO for dicom data 1) test dicom dose import if geometric info was set correctly 2) test dicom dose import accessing dose data and converting 3) check if dicom tags are correctly read 4) test structure import WARNING: The values for comparison need to be adjusted if the input files are changed! */ int DicomIOTest(int argc, char* argv[]) { typedef core::DoseIteratorInterface::DoseAccessorPointer DoseAccessorPointer; typedef core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: 1: structure file name // 2: dose1 file name // 3: dose2 file name // 4: dose3 file name // 5: dose4 file name // 6: dose5 file name std::string RTSTRUCT_FILENAME; std::string RTDOSE_FILENAME; std::string RTDOSE2_FILENAME; std::string RTDOSE3_FILENAME; std::string RTDOSE4_FILENAME; std::string RTDOSE5_FILENAME; if (argc > 1) { RTSTRUCT_FILENAME = argv[1]; } if (argc > 2) { RTDOSE_FILENAME = argv[2]; } if (argc > 3) { RTDOSE2_FILENAME = argv[3]; } if (argc > 4) { RTDOSE3_FILENAME = argv[4]; } if (argc > 5) { RTDOSE4_FILENAME = argv[5]; } - if(argc > 6) + + if (argc > 6) { RTDOSE5_FILENAME = argv[6]; } OFCondition status; DcmFileFormat fileformat; /* read dicom-rt dose */ io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1(RTDOSE_FILENAME.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); //1) test dicom dose import if geometric info was set correctly core::GeometricInfo geoInfo = doseAccessor1->getGeometricInfo(); CHECK_EQUAL(45, geoInfo.getNumRows()); CHECK_EQUAL(67, geoInfo.getNumColumns()); CHECK_EQUAL(64, geoInfo.getNumSlices()); CHECK_EQUAL(OrientationMatrix(), geoInfo.getOrientationMatrix()); SpacingVectorType3D pixelSpacing(5, 5, 5); CHECK_EQUAL(pixelSpacing, geoInfo.getSpacing()); WorldCoordinate3D imagePositionPatient(-170.556642, -273.431642, -674); CHECK_EQUAL(imagePositionPatient, geoInfo.getImagePositionPatient()); //test geometric info of an inhomogeneous dose grid io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator5(RTDOSE5_FILENAME.c_str()); DoseAccessorPointer doseAccessor5(doseAccessorGenerator5.generateDoseAccessor()); - SpacingVectorType3D pixelSpacing5(2,3,2); + SpacingVectorType3D pixelSpacing5(2, 3, 2); CHECK_EQUAL(pixelSpacing5, doseAccessor5->getGeometricInfo().getSpacing()); const VoxelGridID start = 0; const VoxelGridIndex3D start3D(0); VoxelGridID end, inbetween; VoxelGridIndex3D end3D, inbetween3D; //2) test dicom dose import accessing dose data and converting - CHECK_EQUAL(2, doseAccessor1->getDoseAt(start)); - CHECK_EQUAL(2, doseAccessor1-> getDoseAt(start3D)); - CHECK_EQUAL(doseAccessor1->getDoseAt(start), doseAccessor1-> getDoseAt(start3D)); + CHECK_EQUAL(2, doseAccessor1->getValueAt(start)); + CHECK_EQUAL(2, doseAccessor1-> getValueAt(start3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(start), doseAccessor1-> getValueAt(start3D)); inbetween = int(std::floor(doseAccessor1->getGridSize() / 2.0)); doseAccessor1->getGeometricInfo().convert(inbetween, inbetween3D); - CHECK_EQUAL(2, doseAccessor1->getDoseAt(inbetween)); - CHECK_EQUAL(2, doseAccessor1-> getDoseAt(inbetween3D)); - CHECK_EQUAL(doseAccessor1->getDoseAt(inbetween), doseAccessor1-> getDoseAt(inbetween3D)); + CHECK_EQUAL(2, doseAccessor1->getValueAt(inbetween)); + CHECK_EQUAL(2, doseAccessor1-> getValueAt(inbetween3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(inbetween), doseAccessor1-> getValueAt(inbetween3D)); end = doseAccessor1->getGridSize() - 1; doseAccessor1->getGeometricInfo().convert(end, end3D); - CHECK_EQUAL(2, doseAccessor1->getDoseAt(end)); - CHECK_EQUAL(2, doseAccessor1-> getDoseAt(end3D)); - CHECK_EQUAL(doseAccessor1->getDoseAt(end), doseAccessor1-> getDoseAt(end3D)); + CHECK_EQUAL(2, doseAccessor1->getValueAt(end)); + CHECK_EQUAL(2, doseAccessor1-> getValueAt(end3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(end), doseAccessor1-> getValueAt(end3D)); ::DRTDoseIOD rtdose2; io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator2(RTDOSE2_FILENAME.c_str()); DoseAccessorPointer doseAccessor2(doseAccessorGenerator2.generateDoseAccessor()); //2) test dicom dose import accessing dose data and converting - CHECK_EQUAL(50, doseAccessor2->getDoseAt(start)); - CHECK_EQUAL(50, doseAccessor2-> getDoseAt(start3D)); - CHECK_EQUAL(doseAccessor2->getDoseAt(start), doseAccessor2-> getDoseAt(start3D)); + CHECK_EQUAL(50, doseAccessor2->getValueAt(start)); + CHECK_EQUAL(50, doseAccessor2-> getValueAt(start3D)); + CHECK_EQUAL(doseAccessor2->getValueAt(start), doseAccessor2-> getValueAt(start3D)); inbetween = int(std::floor(doseAccessor2->getGridSize() / 2.0)); doseAccessor2->getGeometricInfo().convert(inbetween, inbetween3D); - CHECK_EQUAL(50, doseAccessor2->getDoseAt(inbetween)); - CHECK_EQUAL(50, doseAccessor2-> getDoseAt(inbetween3D)); - CHECK_EQUAL(doseAccessor2->getDoseAt(inbetween), doseAccessor2-> getDoseAt(inbetween3D)); + CHECK_EQUAL(50, doseAccessor2->getValueAt(inbetween)); + CHECK_EQUAL(50, doseAccessor2-> getValueAt(inbetween3D)); + CHECK_EQUAL(doseAccessor2->getValueAt(inbetween), doseAccessor2-> getValueAt(inbetween3D)); end = doseAccessor2->getGridSize() - 1; doseAccessor2->getGeometricInfo().convert(end, end3D); - CHECK_EQUAL(50, doseAccessor2->getDoseAt(end)); - CHECK_EQUAL(50, doseAccessor2-> getDoseAt(end3D)); - CHECK_EQUAL(doseAccessor2->getDoseAt(end), doseAccessor2-> getDoseAt(end3D)); + CHECK_EQUAL(50, doseAccessor2->getValueAt(end)); + CHECK_EQUAL(50, doseAccessor2-> getValueAt(end3D)); + CHECK_EQUAL(doseAccessor2->getValueAt(end), doseAccessor2-> getValueAt(end3D)); ::DRTDoseIOD rtdose3; io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator3(RTDOSE3_FILENAME.c_str()); DoseAccessorPointer doseAccessor3(doseAccessorGenerator3.generateDoseAccessor()); //2) test dicom dose import accessing dose data and converting - CHECK_EQUAL(0, doseAccessor3->getDoseAt(start)); - CHECK_EQUAL(0, doseAccessor3-> getDoseAt(start3D)); - CHECK_EQUAL(doseAccessor3->getDoseAt(start), doseAccessor3-> getDoseAt(start3D)); + CHECK_EQUAL(0, doseAccessor3->getValueAt(start)); + CHECK_EQUAL(0, doseAccessor3-> getValueAt(start3D)); + CHECK_EQUAL(doseAccessor3->getValueAt(start), doseAccessor3-> getValueAt(start3D)); inbetween = int(std::floor(doseAccessor3->getGridSize() / 2.0)); doseAccessor3->getGeometricInfo().convert(inbetween, inbetween3D); - CHECK_EQUAL(0, doseAccessor3->getDoseAt(inbetween)); - CHECK_EQUAL(0, doseAccessor3-> getDoseAt(inbetween3D)); - CHECK_EQUAL(doseAccessor3->getDoseAt(inbetween), doseAccessor3-> getDoseAt(inbetween3D)); + CHECK_EQUAL(0, doseAccessor3->getValueAt(inbetween)); + CHECK_EQUAL(0, doseAccessor3-> getValueAt(inbetween3D)); + CHECK_EQUAL(doseAccessor3->getValueAt(inbetween), doseAccessor3-> getValueAt(inbetween3D)); end = doseAccessor3->getGridSize() - 1; doseAccessor3->getGeometricInfo().convert(end, end3D); - CHECK_CLOSE(1.46425, doseAccessor3->getDoseAt(end), errorConstant); - CHECK_CLOSE(1.46425, doseAccessor3-> getDoseAt(end3D), errorConstant); - CHECK_EQUAL(doseAccessor3->getDoseAt(end), doseAccessor3-> getDoseAt(end3D)); + CHECK_CLOSE(1.46425, doseAccessor3->getValueAt(end), errorConstant); + CHECK_CLOSE(1.46425, doseAccessor3-> getValueAt(end3D), errorConstant); + CHECK_EQUAL(doseAccessor3->getValueAt(end), doseAccessor3-> getValueAt(end3D)); /* structure set */ StructureSetPointer rtStructureSet = io::dicom::DicomFileStructureSetGenerator( RTSTRUCT_FILENAME.c_str()).generateStructureSet(); //4) test structure import CHECK_EQUAL(10, rtStructureSet->getNumberOfStructures()); CHECK_EQUAL("Aussenkontur", (rtStructureSet->getStructure(0))->getLabel()); CHECK_EQUAL("Rueckenmark", (rtStructureSet->getStructure(1))->getLabel()); CHECK_EQUAL("Niere re.", (rtStructureSet->getStructure(2))->getLabel()); CHECK_EQUAL("Niere li.", (rtStructureSet->getStructure(3))->getLabel()); CHECK_EQUAL("Magen/DD", (rtStructureSet->getStructure(4))->getLabel()); CHECK_EQUAL("Leber", (rtStructureSet->getStructure(5))->getLabel()); CHECK_EQUAL("Darm", (rtStructureSet->getStructure(6))->getLabel()); CHECK_EQUAL("Ref.Pkt.", (rtStructureSet->getStructure(7))->getLabel()); CHECK_EQUAL("PTV", (rtStructureSet->getStructure(8))->getLabel()); CHECK_EQUAL("Boost", (rtStructureSet->getStructure(9))->getLabel()); //4) Test other tags (GridFrameOffsetVector(3004,000c) and PixelSpacingBetweenSlices(0018, 0088)) to compute dose slicing io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator4(RTDOSE4_FILENAME.c_str()); DoseAccessorPointer doseAccessor4(doseAccessorGenerator4.generateDoseAccessor()); rttb::SpacingVectorType3D spacingVec = doseAccessor4->getGeometricInfo().getSpacing(); CHECK_EQUAL(2.5, spacingVec.x()); CHECK_EQUAL(2.5, spacingVec.y()); CHECK_EQUAL(3, spacingVec.z()); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/helax/DicomHelaxIOTest.cpp b/testing/io/helax/DicomHelaxIOTest.cpp index 62d4b3b..761b35c 100644 --- a/testing/io/helax/DicomHelaxIOTest.cpp +++ b/testing/io/helax/DicomHelaxIOTest.cpp @@ -1,128 +1,128 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (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 "rttbGeometricInfo.h" #include "rttbDoseIteratorInterface.h" #include "rttbDicomHelaxFileDoseAccessorGenerator.h" #include "rttbDicomHelaxIODVecDoseAccessorGenerator.h" #include "rttbDicomHelaxDoseAccessor.h" #include "rttbDicomFileStructureSetGenerator.h" namespace rttb { namespace testing { /*!@brief DicomHelaxIOTest - test the IO for dicom helax data 1) test dicom helax dose import if geometric info was set correctly 2) test dicom helax dose import accessing dose data and converting 3) test dicom helax structure import WARNING: The values for comparison need to be adjusted if the input files are changed! */ int DicomHelaxIOTest(int argc, char* argv[]) { typedef core::DoseIteratorInterface::DoseAccessorPointer DoseAccessorPointer; typedef core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: 1: directory name std::string RT_DIRNAME; if (argc > 1) { RT_DIRNAME = argv[1]; } OFCondition status; DcmFileFormat fileformat; /* read dicom-rt dose */ io::helax::DicomHelaxFileDoseAccessorGenerator doseAccessorGenerator1(RT_DIRNAME.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); //1) test dicom dose import if geometric info was set correctly core::GeometricInfo geoInfo = doseAccessor1->getGeometricInfo(); CHECK_EQUAL(64, geoInfo.getNumRows()); CHECK_EQUAL(54, geoInfo.getNumColumns()); CHECK_EQUAL(52, geoInfo.getNumSlices()); CHECK_EQUAL(OrientationMatrix(), geoInfo.getOrientationMatrix()); const VoxelGridID start = 0; const VoxelGridIndex3D start3D(0); VoxelGridID end, inbetween; VoxelGridIndex3D end3D, inbetween3D; //2) test dicom dose import accessing dose data and converting - CHECK_EQUAL(doseAccessor1->getDoseAt(start), doseAccessor1-> getDoseAt(start3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(start), doseAccessor1-> getValueAt(start3D)); inbetween = int(std::floor(doseAccessor1->getGridSize() / 2.0)); doseAccessor1->getGeometricInfo().convert(inbetween, inbetween3D); - CHECK_EQUAL(doseAccessor1->getDoseAt(inbetween), doseAccessor1-> getDoseAt(inbetween3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(inbetween), doseAccessor1-> getValueAt(inbetween3D)); end = doseAccessor1->getGridSize() - 1; doseAccessor1->getGeometricInfo().convert(end, end3D); - CHECK_EQUAL(doseAccessor1->getDoseAt(end), doseAccessor1-> getDoseAt(end3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(end), doseAccessor1-> getValueAt(end3D)); /* structure set */ StructureSetPointer rtStructureSet = io::dicom::DicomFileStructureSetGenerator( RT_DIRNAME.c_str()).generateStructureSet(); //3) test structure import CHECK_EQUAL(8, rtStructureSet->getNumberOfStructures()); CHECK_EQUAL("Patient outline", (rtStructureSet->getStructure(0))->getLabel()); CHECK_EQUAL("boost", (rtStructureSet->getStructure(1))->getLabel()); CHECK_EQUAL("Chiasma", (rtStructureSet->getStructure(2))->getLabel()); CHECK_EQUAL("Sehnerv li.", (rtStructureSet->getStructure(3))->getLabel()); CHECK_EQUAL("Sehnerv re.", (rtStructureSet->getStructure(4))->getLabel()); CHECK_EQUAL("Auge li.", (rtStructureSet->getStructure(5))->getLabel()); CHECK_EQUAL("Auge re.", (rtStructureSet->getStructure(6))->getLabel()); CHECK_EQUAL("Hirnstamm", (rtStructureSet->getStructure(7))->getLabel()); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/itk/CMakeLists.txt b/testing/io/itk/CMakeLists.txt index bd3bea9..45b04ef 100644 --- a/testing/io/itk/CMakeLists.txt +++ b/testing/io/itk/CMakeLists.txt @@ -1,32 +1,35 @@ #----------------------------------------------------------------------------- # Setup the system information test. Write out some basic failsafe # information in case the test doesn't run. #----------------------------------------------------------------------------- SET(ITKIO_TEST ${EXECUTABLE_OUTPUT_PATH}/rttbITKIOTests) SET(TEST_DATA_ROOT ${RTTBTesting_SOURCE_DIR}/data) SET(TEMP ${RTTBTesting_BINARY_DIR}/temporary) #----------------------------------------------------------------------------- ADD_TEST(ITKDoseAccessorGeneratorTest ${ITKIO_TEST} ITKDoseAccessorGeneratorTest "${TEST_DATA_ROOT}/MatchPointLogo.mhd") ADD_TEST(ITKIOTest ${ITKIO_TEST} ITKIOTest "${TEST_DATA_ROOT}/MatchPointLogo.mhd") ADD_TEST(ITKDoseAccessorConverterTest ${ITKIO_TEST} ITKDoseAccessorConverterTest "${TEST_DATA_ROOT}/DICOM/TestDose/ConstantTwo.dcm" "${TEST_DATA_ROOT}/MatchPointLogo.mhd" ) + + ADD_TEST(ITKBioModelAccessorConverterTest ${ITKIO_TEST} ITKBioModelAccessorConverterTest + "${TEST_DATA_ROOT}/DICOM/TestDose/ConstantTwo.dcm") ADD_TEST(ITKMaskAccessorGeneratorTest ${ITKIO_TEST} ITKMaskAccessorGeneratorTest "${TEST_DATA_ROOT}/MatchPointLogo.mhd") ADD_TEST(ITKMaskAccessorConverterTest ${ITKIO_TEST} ITKMaskAccessorConverterTest "${TEST_DATA_ROOT}/DICOM/StructureSet/RS1.3.6.1.4.1.2452.6.841242143.1311652612.1170940299.4217870819.dcm" "${TEST_DATA_ROOT}/DICOM/TestDose/ConstantTwo.dcm" "${TEST_DATA_ROOT}/MatchPointLogo.mhd") -RTTB_CREATE_TEST_MODULE(rttbITKIO DEPENDS RTTBITKIO RTTBDicomIO RTTBMasks RTTBOTBMask PACKAGE_DEPENDS Boost Litmus MatchPoint ITK DCMTK) +RTTB_CREATE_TEST_MODULE(rttbITKIO DEPENDS RTTBITKIO RTTBDicomIO RTTBMasks RTTBOTBMask RTTBModels PACKAGE_DEPENDS Boost Litmus MatchPoint ITK DCMTK) diff --git a/testing/io/itk/ITKDoseAccessorConverterTest.cpp b/testing/io/itk/ITKBioModelAccessorConverterTest.cpp similarity index 51% copy from testing/io/itk/ITKDoseAccessorConverterTest.cpp copy to testing/io/itk/ITKBioModelAccessorConverterTest.cpp index 2b24bdb..93895f4 100644 --- a/testing/io/itk/ITKDoseAccessorConverterTest.cpp +++ b/testing/io/itk/ITKBioModelAccessorConverterTest.cpp @@ -1,136 +1,109 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) -// @date $Date$ (last change date) -// @author $Author$ (last changed by) +// @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) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include "litCheckMacros.h" #include "litImageTester.h" #include "litTestImageIO.h" #include "itkImage.h" #include "itkImageFileReader.h" #include "rttbBaseType.h" #include "rttbDoseIteratorInterface.h" +#include "rttbAccessorInterface.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomDoseAccessor.h" -#include "rttbITKImageDoseAccessor.h" -#include "rttbITKImageFileDoseAccessorGenerator.h" -#include "rttbITKImageDoseAccessorGenerator.h" -#include "rttbITKImageDoseAccessorConverter.h" +#include "rttbLQModelAccessor.h" +#include "rttbITKImageAccessor.h" +#include "rttbITKImageFileAccessorGenerator.h" +#include "rttbITKImageAccessorGenerator.h" +#include "rttbITKImageAccessorConverter.h" #include "rttbDoseAccessorProcessorBase.h" #include "rttbDoseAccessorConversionSettingInterface.h" #include "rttbInvalidDoseException.h" namespace rttb { namespace testing { - /*!@brief ITKDoseAccessorConverterTest - test the conversion rttb dose accessor ->itk + /*!@brief ITKBioModelAccessorConverterTest - test the conversion rttb BioModel accessor ->itk 1) test with dicom file (DicomDoseAccessorGenerator) - 2) test with mhd file (ITKImageFileDoseAccessorGenerator) */ - int ITKDoseAccessorConverterTest(int argc, char* argv[]) + int ITKBioModelAccessorConverterTest(int argc, char* argv[]) { - typedef core::DoseIteratorInterface::DoseAccessorPointer DoseAccessorPointer; + typedef core::AccessorInterface::AccessorPointer AccessorPointer; PREPARE_DEFAULT_TEST_REPORTING; - //ARGUMENTS: - // 1: dose1 file name - // 2: dose2 file name std::string RTDOSE_FILENAME; - std::string RTDOSE2_FILENAME; if (argc > 1) { RTDOSE_FILENAME = argv[1]; } - if (argc > 2) - { - RTDOSE2_FILENAME = argv[2]; - } - - //1) Read dicomFile and test getITKImage() + //1) Read dicomFile and test process() and getITKImage() io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator(RTDOSE_FILENAME.c_str()); - DoseAccessorPointer doseAccessor(doseAccessorGenerator.generateDoseAccessor()); + auto doseAccessor(doseAccessorGenerator.generateDoseAccessor()); - io::itk::ITKImageDoseAccessorConverter itkConverter(doseAccessor); + AccessorPointer LQWithConstantDose = boost::make_shared(doseAccessor, 0.2, 0.02); + + io::itk::ITKImageAccessorConverter itkConverter(LQWithConstantDose); CHECK_NO_THROW(itkConverter.process()); CHECK_NO_THROW(itkConverter.getITKImage()); - io::itk::ITKDoseImageType::IndexType itkIndex; + io::itk::ITKImageAccessor::ITKImageType::IndexType itkIndex; itkIndex[0] = itkIndex[1] = itkIndex[2] = 0; VoxelGridIndex3D rttbIndex(0, 0, 0); - CHECK_EQUAL(itkConverter.getITKImage()->GetPixel(itkIndex), doseAccessor->getDoseAt(rttbIndex)); + CHECK_EQUAL(itkConverter.getITKImage()->GetPixel(itkIndex), LQWithConstantDose->getValueAt(rttbIndex)); itkIndex[0] = rttbIndex[0] = doseAccessor->getGeometricInfo().getNumColumns() / 2; itkIndex[1] = rttbIndex[1] = doseAccessor->getGeometricInfo().getNumRows() / 2; itkIndex[2] = rttbIndex[2] = doseAccessor->getGeometricInfo().getNumSlices() / 2; - CHECK_EQUAL(itkConverter.getITKImage()->GetPixel(itkIndex), doseAccessor->getDoseAt(rttbIndex)); + CHECK_EQUAL(itkConverter.getITKImage()->GetPixel(itkIndex), LQWithConstantDose->getValueAt(rttbIndex)); itkIndex[0] = rttbIndex[0] = doseAccessor->getGeometricInfo().getNumColumns() - 1; itkIndex[1] = rttbIndex[1] = doseAccessor->getGeometricInfo().getNumRows() - 1; itkIndex[2] = rttbIndex[2] = doseAccessor->getGeometricInfo().getNumSlices() - 1; - CHECK_EQUAL(itkConverter.getITKImage()->GetPixel(itkIndex), doseAccessor->getDoseAt(rttbIndex)); - - //2) Read mhdFile and test getITKImage() with Litmus TestImageIO - - io::itk::ITKImageFileDoseAccessorGenerator doseAccessorGenerator2(RTDOSE2_FILENAME.c_str()); - DoseAccessorPointer doseAccessor2(doseAccessorGenerator2.generateDoseAccessor()); - - io::itk::ITKImageDoseAccessorConverter itkConverter2(doseAccessor2); - - CHECK_NO_THROW(itkConverter2.process()); - CHECK_NO_THROW(itkConverter2.getITKImage()); - - io::itk::ITKDoseImageType::Pointer expectedImage = - lit::TestImageIO::readImage( - RTDOSE2_FILENAME); - - ::lit::ImageTester - tester; - tester.setExpectedImage(expectedImage); - tester.setActualImage(itkConverter2.getITKImage()); - - CHECK_TESTER(tester); + CHECK_EQUAL(itkConverter.getITKImage()->GetPixel(itkIndex), LQWithConstantDose->getValueAt(rttbIndex)); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/itk/ITKDoseAccessorConverterTest.cpp b/testing/io/itk/ITKDoseAccessorConverterTest.cpp index 2b24bdb..464ff41 100644 --- a/testing/io/itk/ITKDoseAccessorConverterTest.cpp +++ b/testing/io/itk/ITKDoseAccessorConverterTest.cpp @@ -1,136 +1,134 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (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 "litCheckMacros.h" #include "litImageTester.h" #include "litTestImageIO.h" #include "itkImage.h" #include "itkImageFileReader.h" #include "rttbBaseType.h" #include "rttbDoseIteratorInterface.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomDoseAccessor.h" -#include "rttbITKImageDoseAccessor.h" -#include "rttbITKImageFileDoseAccessorGenerator.h" -#include "rttbITKImageDoseAccessorGenerator.h" -#include "rttbITKImageDoseAccessorConverter.h" +#include "rttbITKImageAccessorConverter.h" +#include "rttbITKImageFileAccessorGenerator.h" #include "rttbDoseAccessorProcessorBase.h" #include "rttbDoseAccessorConversionSettingInterface.h" #include "rttbInvalidDoseException.h" namespace rttb { namespace testing { /*!@brief ITKDoseAccessorConverterTest - test the conversion rttb dose accessor ->itk 1) test with dicom file (DicomDoseAccessorGenerator) 2) test with mhd file (ITKImageFileDoseAccessorGenerator) */ int ITKDoseAccessorConverterTest(int argc, char* argv[]) { typedef core::DoseIteratorInterface::DoseAccessorPointer DoseAccessorPointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: // 1: dose1 file name // 2: dose2 file name std::string RTDOSE_FILENAME; std::string RTDOSE2_FILENAME; if (argc > 1) { RTDOSE_FILENAME = argv[1]; } if (argc > 2) { RTDOSE2_FILENAME = argv[2]; } //1) Read dicomFile and test getITKImage() io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator(RTDOSE_FILENAME.c_str()); DoseAccessorPointer doseAccessor(doseAccessorGenerator.generateDoseAccessor()); - io::itk::ITKImageDoseAccessorConverter itkConverter(doseAccessor); + io::itk::ITKImageAccessorConverter itkConverter(doseAccessor); CHECK_NO_THROW(itkConverter.process()); CHECK_NO_THROW(itkConverter.getITKImage()); - io::itk::ITKDoseImageType::IndexType itkIndex; + io::itk::ITKImageAccessorConverter::ITKImageType::IndexType itkIndex; itkIndex[0] = itkIndex[1] = itkIndex[2] = 0; VoxelGridIndex3D rttbIndex(0, 0, 0); - CHECK_EQUAL(itkConverter.getITKImage()->GetPixel(itkIndex), doseAccessor->getDoseAt(rttbIndex)); + CHECK_EQUAL(itkConverter.getITKImage()->GetPixel(itkIndex), doseAccessor->getValueAt(rttbIndex)); itkIndex[0] = rttbIndex[0] = doseAccessor->getGeometricInfo().getNumColumns() / 2; itkIndex[1] = rttbIndex[1] = doseAccessor->getGeometricInfo().getNumRows() / 2; itkIndex[2] = rttbIndex[2] = doseAccessor->getGeometricInfo().getNumSlices() / 2; - CHECK_EQUAL(itkConverter.getITKImage()->GetPixel(itkIndex), doseAccessor->getDoseAt(rttbIndex)); + CHECK_EQUAL(itkConverter.getITKImage()->GetPixel(itkIndex), doseAccessor->getValueAt(rttbIndex)); itkIndex[0] = rttbIndex[0] = doseAccessor->getGeometricInfo().getNumColumns() - 1; itkIndex[1] = rttbIndex[1] = doseAccessor->getGeometricInfo().getNumRows() - 1; itkIndex[2] = rttbIndex[2] = doseAccessor->getGeometricInfo().getNumSlices() - 1; - CHECK_EQUAL(itkConverter.getITKImage()->GetPixel(itkIndex), doseAccessor->getDoseAt(rttbIndex)); + CHECK_EQUAL(itkConverter.getITKImage()->GetPixel(itkIndex), doseAccessor->getValueAt(rttbIndex)); //2) Read mhdFile and test getITKImage() with Litmus TestImageIO - io::itk::ITKImageFileDoseAccessorGenerator doseAccessorGenerator2(RTDOSE2_FILENAME.c_str()); + io::itk::ITKImageFileAccessorGenerator doseAccessorGenerator2(RTDOSE2_FILENAME.c_str()); DoseAccessorPointer doseAccessor2(doseAccessorGenerator2.generateDoseAccessor()); - io::itk::ITKImageDoseAccessorConverter itkConverter2(doseAccessor2); + io::itk::ITKImageAccessorConverter itkConverter2(doseAccessor2); CHECK_NO_THROW(itkConverter2.process()); CHECK_NO_THROW(itkConverter2.getITKImage()); - io::itk::ITKDoseImageType::Pointer expectedImage = - lit::TestImageIO::readImage( + io::itk::ITKImageAccessorConverter::ITKImageType::Pointer expectedImage = + lit::TestImageIO::readImage( RTDOSE2_FILENAME); - ::lit::ImageTester + ::lit::ImageTester tester; tester.setExpectedImage(expectedImage); tester.setActualImage(itkConverter2.getITKImage()); CHECK_TESTER(tester); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/itk/ITKDoseAccessorGeneratorTest.cpp b/testing/io/itk/ITKDoseAccessorGeneratorTest.cpp index 2172089..d3523a4 100644 --- a/testing/io/itk/ITKDoseAccessorGeneratorTest.cpp +++ b/testing/io/itk/ITKDoseAccessorGeneratorTest.cpp @@ -1,95 +1,95 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (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 "litCheckMacros.h" #include "itkImage.h" #include "itkImageFileReader.h" #include "rttbBaseType.h" -#include "rttbITKImageDoseAccessor.h" -#include "rttbITKImageFileDoseAccessorGenerator.h" -#include "rttbITKImageDoseAccessorGenerator.h" +#include "rttbITKImageAccessorConverter.h" +#include "rttbITKImageAccessorGenerator.h" +#include "rttbITKImageFileAccessorGenerator.h" #include "rttbInvalidDoseException.h" namespace rttb { namespace testing { /*!@brief ITKDoseAccessorGeneratorTest - test the generators for dicom data 1) test itk file generator generateDoseAccessor() 2) test itk generator generateDoseAccessor() */ int ITKDoseAccessorGeneratorTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: // 1: mhd/raw file name std::string RTDOSE_FILENAME; if (argc > 1) { RTDOSE_FILENAME = argv[1]; } /* test ITKFileDoseAccessorGenerator generateDoseAccessor()*/ - CHECK_THROW_EXPLICIT(io::itk::ITKImageFileDoseAccessorGenerator("test.test").generateDoseAccessor(), + CHECK_THROW_EXPLICIT(io::itk::ITKImageFileAccessorGenerator("test.test").generateDoseAccessor(), core::InvalidDoseException); - CHECK_NO_THROW(io::itk::ITKImageFileDoseAccessorGenerator( + CHECK_NO_THROW(io::itk::ITKImageFileAccessorGenerator( RTDOSE_FILENAME.c_str()).generateDoseAccessor()); /* test ITKDoseAccessorGenerator generateDoseAccessor()*/ typedef itk::Image< DoseTypeGy, 3 > DoseImageType; typedef itk::ImageFileReader ReaderType; DoseImageType::Pointer invalidDose = DoseImageType::New(); ReaderType::Pointer reader = ReaderType::New(); - CHECK_THROW_EXPLICIT(io::itk::ITKImageDoseAccessorGenerator( + CHECK_THROW_EXPLICIT(io::itk::ITKImageAccessorGenerator( invalidDose.GetPointer()).generateDoseAccessor(), core::InvalidDoseException); reader->SetFileName(RTDOSE_FILENAME); //important to update the reader (won't work without) reader->Update(); - CHECK_NO_THROW(io::itk::ITKImageDoseAccessorGenerator(reader->GetOutput()).generateDoseAccessor()); + CHECK_NO_THROW(io::itk::ITKImageAccessorGenerator(reader->GetOutput()).generateDoseAccessor()); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/itk/ITKIOTest.cpp b/testing/io/itk/ITKIOTest.cpp index ee9e044..c0eccbf 100644 --- a/testing/io/itk/ITKIOTest.cpp +++ b/testing/io/itk/ITKIOTest.cpp @@ -1,167 +1,167 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (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 "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbGeometricInfo.h" #include "rttbDoseIteratorInterface.h" -#include "rttbITKImageDoseAccessor.h" -#include "rttbITKImageFileDoseAccessorGenerator.h" -#include "rttbITKImageDoseAccessorGenerator.h" +#include "rttbITKImageAccessorConverter.h" +#include "rttbITKImageAccessorGenerator.h" +#include "rttbITKImageFileAccessorGenerator.h" namespace rttb { namespace testing { /*!@brief ITKIOTest - test the IO for ITK data 1) test ITK dose import if geometric info was set correctly 2) test ITKImageFileDoseAccessorGenerator accessing dose data and converting (*.mhd file) 3) test ITKImageDoseAccessorGenerator accessing dose data and converting (*.mhd file) WARNING: The values for comparison need to be adjusted if the input files are changed! */ int ITKIOTest(int argc, char* argv[]) { typedef core::DoseIteratorInterface::DoseAccessorPointer DoseAccessorPointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: // 1: mhd file name std::string RTDOSE_FILENAME; if (argc > 1) { RTDOSE_FILENAME = argv[1]; } /* read dose in *.mhd file */ - io::itk::ITKImageFileDoseAccessorGenerator doseAccessorGenerator1(RTDOSE_FILENAME.c_str()); + io::itk::ITKImageFileAccessorGenerator doseAccessorGenerator1(RTDOSE_FILENAME.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); //1) test ITK dose import if geometric info was set correctly core::GeometricInfo geoInfo = doseAccessor1->getGeometricInfo(); CHECK_EQUAL(100, geoInfo.getNumRows()); CHECK_EQUAL(100, geoInfo.getNumColumns()); CHECK_EQUAL(60, geoInfo.getNumSlices()); //orientation matrix equals identity matrix CHECK_EQUAL(OrientationMatrix(), geoInfo.getOrientationMatrix()); const VoxelGridID start = 0; const VoxelGridIndex3D start3D(0); VoxelGridID end, inbetween, inbetween2; VoxelGridIndex3D end3D, inbetween3D, inbetween23D; //2) test ITK dose import accessing dose data and converting (*.mhd file) CHECK(doseAccessor1->getGeometricInfo().validID(start)); CHECK(doseAccessor1->getGeometricInfo().validIndex(start3D)); CHECK(!(doseAccessor1->getGeometricInfo().validID(doseAccessor1->getGridSize()))); CHECK(!(doseAccessor1->getGeometricInfo().validIndex(VoxelGridIndex3D( doseAccessor1->getGridSize())))); - CHECK_EQUAL(0, doseAccessor1->getDoseAt(start)); - CHECK_EQUAL(doseAccessor1->getDoseAt(start), doseAccessor1-> getDoseAt(start3D)); + CHECK_EQUAL(0, doseAccessor1->getValueAt(start)); + CHECK_EQUAL(doseAccessor1->getValueAt(start), doseAccessor1-> getValueAt(start3D)); inbetween = 204837; doseAccessor1->getGeometricInfo().convert(inbetween, inbetween3D); CHECK(doseAccessor1->getGeometricInfo().validID(inbetween)); CHECK(doseAccessor1->getGeometricInfo().validIndex(inbetween3D)); - CHECK_EQUAL(242.0, doseAccessor1->getDoseAt(inbetween)); - CHECK_EQUAL(doseAccessor1->getDoseAt(inbetween), doseAccessor1-> getDoseAt(inbetween3D)); + CHECK_EQUAL(242.0, doseAccessor1->getValueAt(inbetween)); + CHECK_EQUAL(doseAccessor1->getValueAt(inbetween), doseAccessor1-> getValueAt(inbetween3D)); inbetween2 = 283742; doseAccessor1->getGeometricInfo().convert(inbetween2, inbetween23D); CHECK(doseAccessor1->getGeometricInfo().validID(inbetween2)); CHECK(doseAccessor1->getGeometricInfo().validIndex(inbetween23D)); - CHECK_EQUAL(111.0, doseAccessor1->getDoseAt(inbetween2)); - CHECK_EQUAL(doseAccessor1->getDoseAt(inbetween2), doseAccessor1-> getDoseAt(inbetween23D)); + CHECK_EQUAL(111.0, doseAccessor1->getValueAt(inbetween2)); + CHECK_EQUAL(doseAccessor1->getValueAt(inbetween2), doseAccessor1-> getValueAt(inbetween23D)); end = doseAccessor1->getGridSize() - 1; doseAccessor1->getGeometricInfo().convert(end, end3D); CHECK(doseAccessor1->getGeometricInfo().validID(end)); CHECK(doseAccessor1->getGeometricInfo().validIndex(end3D)); - CHECK_EQUAL(0, doseAccessor1->getDoseAt(end)); - CHECK_EQUAL(doseAccessor1->getDoseAt(end), doseAccessor1-> getDoseAt(end3D)); + CHECK_EQUAL(0, doseAccessor1->getValueAt(end)); + CHECK_EQUAL(doseAccessor1->getValueAt(end), doseAccessor1-> getValueAt(end3D)); typedef itk::Image< DoseTypeGy, 3 > DoseImageType; typedef itk::ImageFileReader ReaderType; ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(RTDOSE_FILENAME); //important to update the reader (won't work without) reader->Update(); - io::itk::ITKImageDoseAccessorGenerator doseAccessorGenerator2(reader->GetOutput()); + io::itk::ITKImageAccessorGenerator doseAccessorGenerator2(reader->GetOutput()); DoseAccessorPointer doseAccessor2(doseAccessorGenerator2.generateDoseAccessor()); //3) test ITK dose import accessing dose data and converting (ITKImageDoseAccessor) CHECK(doseAccessor2->getGeometricInfo().validID(start)); CHECK(doseAccessor2->getGeometricInfo().validIndex(start3D)); CHECK(!(doseAccessor2->getGeometricInfo().validID(doseAccessor2->getGridSize()))); CHECK(!(doseAccessor2->getGeometricInfo().validIndex(VoxelGridIndex3D( doseAccessor2->getGridSize())))); - CHECK_EQUAL(0, doseAccessor2->getDoseAt(start)); - CHECK_EQUAL(doseAccessor2->getDoseAt(start), doseAccessor2->getDoseAt(start3D)); + CHECK_EQUAL(0, doseAccessor2->getValueAt(start)); + CHECK_EQUAL(doseAccessor2->getValueAt(start), doseAccessor2->getValueAt(start3D)); CHECK(doseAccessor2->getGeometricInfo().validID(inbetween)); CHECK(doseAccessor2->getGeometricInfo().validIndex(inbetween3D)); - CHECK_EQUAL(242.0, doseAccessor2->getDoseAt(inbetween)); - CHECK_EQUAL(doseAccessor2->getDoseAt(inbetween), doseAccessor2->getDoseAt(inbetween3D)); + CHECK_EQUAL(242.0, doseAccessor2->getValueAt(inbetween)); + CHECK_EQUAL(doseAccessor2->getValueAt(inbetween), doseAccessor2->getValueAt(inbetween3D)); CHECK(doseAccessor2->getGeometricInfo().validID(inbetween2)); CHECK(doseAccessor2->getGeometricInfo().validIndex(inbetween23D)); - CHECK_EQUAL(111.0, doseAccessor2->getDoseAt(inbetween2)); - CHECK_EQUAL(doseAccessor2->getDoseAt(inbetween2), doseAccessor2->getDoseAt(inbetween23D)); + CHECK_EQUAL(111.0, doseAccessor2->getValueAt(inbetween2)); + CHECK_EQUAL(doseAccessor2->getValueAt(inbetween2), doseAccessor2->getValueAt(inbetween23D)); end = doseAccessor2->getGridSize() - 1; doseAccessor2->getGeometricInfo().convert(end, end3D); CHECK(doseAccessor2->getGeometricInfo().validID(end)); CHECK(doseAccessor2->getGeometricInfo().validIndex(end3D)); - CHECK_EQUAL(0, doseAccessor2->getDoseAt(end)); - CHECK_EQUAL(doseAccessor2->getDoseAt(end), doseAccessor2-> getDoseAt(end3D)); + CHECK_EQUAL(0, doseAccessor2->getValueAt(end)); + CHECK_EQUAL(doseAccessor2->getValueAt(end), doseAccessor2-> getValueAt(end3D)); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/itk/files.cmake b/testing/io/itk/files.cmake index b8458a7..d11daae 100644 --- a/testing/io/itk/files.cmake +++ b/testing/io/itk/files.cmake @@ -1,11 +1,12 @@ SET(CPP_FILES ITKDoseAccessorGeneratorTest.cpp ITKDoseAccessorConverterTest.cpp + ITKBioModelAccessorConverterTest.cpp ITKMaskAccessorGeneratorTest.cpp ITKMaskAccessorConverterTest.cpp ITKIOTest.cpp rttbITKIOTests.cpp ) SET(H_FILES ) diff --git a/testing/io/itk/rttbITKIOTests.cpp b/testing/io/itk/rttbITKIOTests.cpp index e9e2a37..c05d662 100644 --- a/testing/io/itk/rttbITKIOTests.cpp +++ b/testing/io/itk/rttbITKIOTests.cpp @@ -1,62 +1,65 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #if defined(_MSC_VER) #pragma warning ( disable : 4786 ) #endif -#include "litMultiTestsMain.h" +#include "litMultiTestsMain.h" -namespace rttb{ - namespace testing{ +namespace rttb +{ + namespace testing + { void registerTests() - { - LIT_REGISTER_TEST(ITKDoseAccessorGeneratorTest); - LIT_REGISTER_TEST(ITKDoseAccessorConverterTest); - LIT_REGISTER_TEST(ITKIOTest); - LIT_REGISTER_TEST(ITKMaskAccessorGeneratorTest); - LIT_REGISTER_TEST(ITKMaskAccessorConverterTest); - } + { + LIT_REGISTER_TEST(ITKDoseAccessorGeneratorTest); + LIT_REGISTER_TEST(ITKDoseAccessorConverterTest); + LIT_REGISTER_TEST(ITKBioModelAccessorConverterTest); + LIT_REGISTER_TEST(ITKIOTest); + LIT_REGISTER_TEST(ITKMaskAccessorGeneratorTest); + LIT_REGISTER_TEST(ITKMaskAccessorConverterTest); } } +} int main(int argc, char* argv[]) - { +{ int result = 0; rttb::testing::registerTests(); try - { - result = lit::multiTestsMain(argc,argv); - } + { + result = lit::multiTestsMain(argc, argv); + } - catch(...) - { + catch (...) + { result = -1; - } + } return result; - } +} diff --git a/testing/io/rttbDoseAccessorTester.cpp b/testing/io/rttbDoseAccessorTester.cpp index c371b95..5085f7d 100644 --- a/testing/io/rttbDoseAccessorTester.cpp +++ b/testing/io/rttbDoseAccessorTester.cpp @@ -1,152 +1,152 @@ // ----------------------------------------------------------------------- // 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 $ (last changed revision) // @date $Date $ (last change date) // @author $Author $ (last changed by) */ #include #include "rttbGeometricInfo.h" #include "rttbDoseAccessorTester.h" namespace rttb { namespace testing { DoseAccessorTester::DoseAccessorTester(DoseAccessorPointer aReferenceDose, DoseAccessorPointer aCompareDose) : _referenceDose(aReferenceDose), _compareDose(aCompareDose), _geometryIsSimilar(false), _sameGridSize(false), _conversionFailed(false), _numDifference(0) {} void DoseAccessorTester::setReferenceDose(const DoseAccessorPointer aReferenceDose) { _referenceDose = aReferenceDose; } void DoseAccessorTester::setCompareDose(const DoseAccessorPointer aCompareDose) { _compareDose = aCompareDose; } lit::StringType DoseAccessorTester::getTestDescription(void) const { return "Compare two DoseAccessors and determine if the contained doses are equal."; }; bool DoseAccessorTester::doCheck(void) const { _pResults->onTestStart(getCurrentTestLabel()); _geometryIsSimilar = (_referenceDose->getGeometricInfo() == _compareDose->getGeometricInfo()); if (!_geometryIsSimilar) { return false; } _sameGridSize = (_referenceDose->getGridSize() == _compareDose->getGridSize()); if (!_sameGridSize) { return false; } _numDifference = 0; _maxDifference = 0; VoxelGridIndex3D id3D; for (VoxelGridID id = 0; id < _referenceDose->getGridSize(); id++) { _compareDose->getGeometricInfo().convert(id, id3D); if (!_compareDose->getGeometricInfo().validIndex(id3D)) { _conversionFailed = true; _failedID = id; return false; } - if ((_referenceDose-> getDoseAt(id) != _referenceDose-> getDoseAt(id3D)) - || (_compareDose->getDoseAt(id) != _compareDose-> getDoseAt(id3D))) + if ((_referenceDose-> getValueAt(id) != _referenceDose-> getValueAt(id3D)) + || (_compareDose->getValueAt(id) != _compareDose-> getValueAt(id3D))) { _conversionFailed = true; _failedID = id; return false; } - if ((_referenceDose->getDoseAt(id) != _compareDose->getDoseAt(id)) - || (_referenceDose->getDoseAt(id3D) != _compareDose->getDoseAt(id3D))) + if ((_referenceDose->getValueAt(id) != _compareDose->getValueAt(id)) + || (_referenceDose->getValueAt(id3D) != _compareDose->getValueAt(id3D))) { - float tmpDifference = abs(_referenceDose->getDoseAt(id) - _compareDose->getDoseAt(id)); + float tmpDifference = abs(_referenceDose->getValueAt(id) - _compareDose->getValueAt(id)); if (tmpDifference > _maxDifference) { _maxDifference = tmpDifference; } _numDifference++; } }//end for(VoxelGridID id = 0; id < _referenceDose->getGridSize(); id++) return (_numDifference == 0); } void DoseAccessorTester::handleSuccess(void) const { std::ostringstream stream; stream << "Both doses are equal" << std::endl; _pResults->onTestSuccess(getCurrentTestLabel(), stream.str()); } void DoseAccessorTester::handleFailure(void) const { std::ostringstream stream; stream << "Doses are different" << std::endl; if (_geometryIsSimilar) { if (_sameGridSize) { stream << std::endl << "Error voxel count: " << _numDifference << std::endl; stream << std::endl << "Maximum difference: " << _maxDifference << std::endl; if (_conversionFailed) { stream << std::endl << "Index conversion failed in: " << _failedID << std::endl; } } else { stream << "Doses have different grid sizes" << std::endl; stream << "Reference dose contains " << _referenceDose->getGridSize() << " voxels and comparison dose " << _compareDose->getGridSize() << std::endl; } } else { stream << "Doses have different geometry" << std::endl; } _pResults->onTestFailure(getCurrentTestLabel(), stream.str()); } } } \ No newline at end of file diff --git a/testing/io/virtuos/TripDoseIOTest.cpp b/testing/io/virtuos/TripDoseIOTest.cpp index d79191c..23a981b 100644 --- a/testing/io/virtuos/TripDoseIOTest.cpp +++ b/testing/io/virtuos/TripDoseIOTest.cpp @@ -1,234 +1,234 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (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 "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbGeometricInfo.h" #include "rttbDoseIteratorInterface.h" #include "rttbVirtuosPlanFileDoseAccessorGenerator.h" #include "rttbVirtuosDoseFileDoseAccessorGenerator.h" #include "rttbVirtuosDoseAccessor.h" #include "rttbVirtuosFileStructureSetGenerator.h" #include "rttbNullPointerException.h" #include "rttbInvalidDoseException.h" #include "rttbInvalidParameterException.h" #include "rttbIndexOutOfBoundsException.h" #include "../rttbDoseAccessorTester.h" namespace rttb { namespace testing { /*! @brief TripDoseIOTest - test the IO for virtuos data 2) test virtuos dose import if geometric info was set correctly 3) test trip dose import accessing dose data and converting Since the same class is used for the import of VIRTUOS structures, the constructors are tested more thoroughly in VirtuosDoseIOTest. WARNING: The values for comparison need to be adjusted if the input files are changed! @see VirtuosDoseIOTest */ int TripDoseIOTest(int argc, char* argv[]) { typedef core::DoseIteratorInterface::DoseAccessorPointer DoseAccessorPointer; PREPARE_DEFAULT_TEST_REPORTING; // 1: plan file name (virtuos) .../testing/data/Virtuos/NHH030101.pln // 2: dose1 file name (virtuos) .../testing/data/Virtuos/NHH030101.dos.gz // 3: dose2 file name (trip): .../testing/data/Virtuos/trip/NHH030101.dos // WARNING: Test will fail if dose2 does not contain the same dose as dose1! std::string RTPLAN_FILENAME; std::string RTDOSE_FILENAME; std::string RTDOSE2_FILENAME; if (argc > 1) { RTPLAN_FILENAME = argv[1]; } if (argc > 2) { RTDOSE_FILENAME = argv[2]; } if (argc > 3) { RTDOSE2_FILENAME = argv[3]; } /* import VIRTUOS dose */ io::virtuos::VirtuosPlanFileDoseAccessorGenerator doseAccessorGenerator1(RTDOSE_FILENAME.c_str(), RTPLAN_FILENAME.c_str()); boost::shared_ptr doseAccessor1 = boost::static_pointer_cast (doseAccessorGenerator1.generateDoseAccessor()); //CHECK_EQUAL(76.0,spDoseAccessor1->getPrescribedDose()); //CHECK_EQUAL(885.0,spDoseAccessor1->getNormalizationDose()); //2) test dose import if geometric info was set correctly core::GeometricInfo geoInfo = doseAccessor1->getGeometricInfo(); CHECK_EQUAL(256, geoInfo.getNumRows()); CHECK_EQUAL(256, geoInfo.getNumColumns()); CHECK_EQUAL(165, geoInfo.getNumSlices()); CHECK_EQUAL(256 * 256 * 165, doseAccessor1->getGridSize()); CHECK_EQUAL(OrientationMatrix(), geoInfo.getOrientationMatrix()); const VoxelGridID start = 0; const VoxelGridIndex3D start3D(0); VoxelGridID end, inbetween; VoxelGridIndex3D end3D, inbetween3D; //3) test dose import accessing dose data and converting - CHECK_EQUAL(0, doseAccessor1->getDoseAt(start)); - CHECK_EQUAL(0, doseAccessor1-> getDoseAt(start3D)); - CHECK_EQUAL(doseAccessor1->getDoseAt(start), doseAccessor1-> getDoseAt(start3D)); + CHECK_EQUAL(0, doseAccessor1->getValueAt(start)); + CHECK_EQUAL(0, doseAccessor1-> getValueAt(start3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(start), doseAccessor1-> getValueAt(start3D)); inbetween = int(std::floor(doseAccessor1->getGridSize() / 2.0)); doseAccessor1->getGeometricInfo().convert(inbetween, inbetween3D); - CHECK_EQUAL(0, doseAccessor1->getDoseAt(inbetween)); - CHECK_EQUAL(0, doseAccessor1-> getDoseAt(inbetween3D)); - CHECK_EQUAL(doseAccessor1->getDoseAt(inbetween), doseAccessor1-> getDoseAt(inbetween3D)); + CHECK_EQUAL(0, doseAccessor1->getValueAt(inbetween)); + CHECK_EQUAL(0, doseAccessor1-> getValueAt(inbetween3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(inbetween), doseAccessor1-> getValueAt(inbetween3D)); end = doseAccessor1->getGridSize() - 1; doseAccessor1->getGeometricInfo().convert(end, end3D); - CHECK_EQUAL(0, doseAccessor1->getDoseAt(end)); - CHECK_EQUAL(0, doseAccessor1-> getDoseAt(end3D)); - CHECK_EQUAL(doseAccessor1->getDoseAt(end), doseAccessor1-> getDoseAt(end3D)); + CHECK_EQUAL(0, doseAccessor1->getValueAt(end)); + CHECK_EQUAL(0, doseAccessor1-> getValueAt(end3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(end), doseAccessor1-> getValueAt(end3D)); /* Dose without plan */ io::virtuos::VirtuosDoseFileDoseAccessorGenerator doseAccessorGenerator2(RTDOSE2_FILENAME.c_str(), doseAccessor1->getNormalizationDose(), doseAccessor1->getPrescribedDose()); boost::shared_ptr doseAccessor2 = boost::static_pointer_cast (doseAccessorGenerator2.generateDoseAccessor()); CHECK_EQUAL(doseAccessor1->getPrescribedDose(), doseAccessor2->getPrescribedDose()); CHECK_EQUAL(doseAccessor1->getNormalizationDose(), doseAccessor2->getNormalizationDose()); //2) test dose import if geometric info was set correctly core::GeometricInfo geoInfo2 = doseAccessor2->getGeometricInfo(); CHECK_EQUAL(geoInfo.getNumRows(), geoInfo2.getNumRows()); CHECK_EQUAL(geoInfo.getNumColumns(), geoInfo2.getNumColumns()); CHECK_EQUAL(geoInfo.getNumSlices(), geoInfo2.getNumSlices()); CHECK_EQUAL(doseAccessor1->getGridSize(), doseAccessor2->getGridSize()); CHECK_EQUAL(geoInfo.getOrientationMatrix(), geoInfo2.getOrientationMatrix()); //3) test dose import accessing dose data and converting - CHECK_EQUAL(doseAccessor1->getDoseAt(start), doseAccessor2->getDoseAt(start)); - CHECK_EQUAL(doseAccessor1-> getDoseAt(start3D), doseAccessor2-> getDoseAt(start3D)); - CHECK_EQUAL(doseAccessor2->getDoseAt(start), doseAccessor2-> getDoseAt(start3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(start), doseAccessor2->getValueAt(start)); + CHECK_EQUAL(doseAccessor1-> getValueAt(start3D), doseAccessor2-> getValueAt(start3D)); + CHECK_EQUAL(doseAccessor2->getValueAt(start), doseAccessor2-> getValueAt(start3D)); inbetween = int(std::floor(doseAccessor2->getGridSize() / 2.0)); doseAccessor2->getGeometricInfo().convert(inbetween, inbetween3D); - CHECK_EQUAL(doseAccessor1->getDoseAt(inbetween), doseAccessor2->getDoseAt(inbetween)); - CHECK_EQUAL(doseAccessor1-> getDoseAt(inbetween3D), doseAccessor2-> getDoseAt(inbetween3D)); - CHECK_EQUAL(doseAccessor2->getDoseAt(inbetween), doseAccessor2-> getDoseAt(inbetween3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(inbetween), doseAccessor2->getValueAt(inbetween)); + CHECK_EQUAL(doseAccessor1-> getValueAt(inbetween3D), doseAccessor2-> getValueAt(inbetween3D)); + CHECK_EQUAL(doseAccessor2->getValueAt(inbetween), doseAccessor2-> getValueAt(inbetween3D)); end = doseAccessor2->getGridSize() - 1; doseAccessor2->getGeometricInfo().convert(end, end3D); - CHECK_EQUAL(doseAccessor1->getDoseAt(end), doseAccessor2->getDoseAt(end)); - CHECK_EQUAL(doseAccessor1-> getDoseAt(end3D), doseAccessor2-> getDoseAt(end3D)); - CHECK_EQUAL(doseAccessor2->getDoseAt(end), doseAccessor2-> getDoseAt(end3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(end), doseAccessor2->getValueAt(end)); + CHECK_EQUAL(doseAccessor1-> getValueAt(end3D), doseAccessor2-> getValueAt(end3D)); + CHECK_EQUAL(doseAccessor2->getValueAt(end), doseAccessor2-> getValueAt(end3D)); /* Import Trip dose */ io::virtuos::VirtuosDoseFileDoseAccessorGenerator doseAccessorGenerator3(RTDOSE2_FILENAME.c_str(), doseAccessor1->getNormalizationDose(), doseAccessor1->getPrescribedDose()); boost::shared_ptr doseAccessor3 = boost::static_pointer_cast (doseAccessorGenerator3.generateDoseAccessor()); CHECK_EQUAL(doseAccessor1->getPrescribedDose(), doseAccessor3->getPrescribedDose()); CHECK_EQUAL(doseAccessor1->getNormalizationDose(), doseAccessor3->getNormalizationDose()); //2) test dose import if geometric info was set correctly core::GeometricInfo geoInfo3 = doseAccessor3->getGeometricInfo(); CHECK_EQUAL(geoInfo.getNumRows(), geoInfo3.getNumRows()); CHECK_EQUAL(geoInfo.getNumColumns(), geoInfo3.getNumColumns()); CHECK_EQUAL(geoInfo.getNumSlices(), geoInfo3.getNumSlices()); CHECK_EQUAL(doseAccessor1->getGridSize(), doseAccessor3->getGridSize()); CHECK_EQUAL(geoInfo.getOrientationMatrix(), geoInfo3.getOrientationMatrix()); //3) test dose import accessing dose data and converting - CHECK_EQUAL(doseAccessor1->getDoseAt(start), doseAccessor3->getDoseAt(start)); - CHECK_EQUAL(doseAccessor1-> getDoseAt(start3D), doseAccessor3-> getDoseAt(start3D)); - CHECK_EQUAL(doseAccessor3->getDoseAt(start), doseAccessor3-> getDoseAt(start3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(start), doseAccessor3->getValueAt(start)); + CHECK_EQUAL(doseAccessor1-> getValueAt(start3D), doseAccessor3-> getValueAt(start3D)); + CHECK_EQUAL(doseAccessor3->getValueAt(start), doseAccessor3-> getValueAt(start3D)); inbetween = int(std::floor(doseAccessor3->getGridSize() / 2.0)); doseAccessor3->getGeometricInfo().convert(inbetween, inbetween3D); - CHECK_EQUAL(doseAccessor1->getDoseAt(inbetween), doseAccessor3->getDoseAt(inbetween)); - CHECK_EQUAL(doseAccessor1-> getDoseAt(inbetween3D), doseAccessor3-> getDoseAt(inbetween3D)); - CHECK_EQUAL(doseAccessor3->getDoseAt(inbetween), doseAccessor3-> getDoseAt(inbetween3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(inbetween), doseAccessor3->getValueAt(inbetween)); + CHECK_EQUAL(doseAccessor1-> getValueAt(inbetween3D), doseAccessor3-> getValueAt(inbetween3D)); + CHECK_EQUAL(doseAccessor3->getValueAt(inbetween), doseAccessor3-> getValueAt(inbetween3D)); io::virtuos::VirtuosPlanFileDoseAccessorGenerator doseAccessorGenerator4(RTDOSE2_FILENAME.c_str(), RTPLAN_FILENAME.c_str()); boost::shared_ptr spDoseAccessor4 = boost::static_pointer_cast (doseAccessorGenerator4.generateDoseAccessor()); DoseAccessorPointer doseAccessor4(spDoseAccessor4); DoseAccessorTester doseCompare(doseAccessor1, doseAccessor2); CHECK_TESTER(doseCompare); DoseAccessorTester doseCompare2(doseAccessor3, doseAccessor4); CHECK_TESTER(doseCompare2); DoseAccessorTester doseCompare3(doseAccessor1, doseAccessor3); CHECK_TESTER(doseCompare3); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/virtuos/VirtuosDVHCalculatorExampleTest.cpp b/testing/io/virtuos/VirtuosDVHCalculatorExampleTest.cpp index 7944d97..93d13dc 100644 --- a/testing/io/virtuos/VirtuosDVHCalculatorExampleTest.cpp +++ b/testing/io/virtuos/VirtuosDVHCalculatorExampleTest.cpp @@ -1,183 +1,183 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (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 "rttbDVHCalculator.h" #include "rttbGenericMaskedDoseIterator.h" #include "rttbGenericDoseIterator.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "rttbOTBMaskAccessor.h" #include "rttbVirtuosPlanFileDoseAccessorGenerator.h" #include "rttbVirtuosDoseAccessor.h" #include "rttbVirtuosFileStructureSetGenerator.h" namespace rttb { namespace testing { /*! @brief VirtuosDVHCalculatorExampleTest. Test if calculation in new architecture returns similar results to the original implementation. WARNING: The values for comparison need to be adjusted if the input files are changed! */ int VirtuosDVHCalculatorExampleTest(int argc, char* argv[]) { typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; typedef core::GenericMaskedDoseIterator::MaskAccessorPointer MaskAccessorPointer; typedef core::DVHCalculator::DoseIteratorPointer DoseIteratorPointer; typedef core::DVHCalculator::MaskedDoseIteratorPointer MaskedDoseIteratorPointer; typedef masks::legacy::OTBMaskAccessor::StructTypePointer StructTypePointer; typedef core::DVH::DVHPointer DVHPointer; typedef core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: 1: virtuos dose file name // 2: virtuos structure file name // 3: virtuos plan file name // 4: virtuos CT file name std::string Virtuos_Dose_File; std::string Virtuos_Structure_File; std::string Virtuos_Plan_File; std::string Virtuos_CT_File; if (argc > 1) { Virtuos_Dose_File = argv[1]; } if (argc > 2) { Virtuos_Structure_File = argv[2]; } if (argc > 3) { Virtuos_Plan_File = argv[3]; } if (argc > 4) { Virtuos_CT_File = argv[4]; } //Virtuos DVH Test io::virtuos::VirtuosPlanFileDoseAccessorGenerator doseAccessorGeneratorVirtuos(Virtuos_Dose_File, Virtuos_Plan_File); DoseAccessorPointer doseAccessorVirtuos(doseAccessorGeneratorVirtuos.generateDoseAccessor()); StructureSetPointer rtStructureSetVirtuos = io::virtuos::VirtuosFileStructureSetGenerator( Virtuos_Structure_File, Virtuos_CT_File).generateStructureSet(); for (int i = 1; i < rtStructureSetVirtuos->getNumberOfStructures(); i++) { //if(i=6 || i==8){//todo: assertion bug! if (i == 8) { //create MaskAccessor for each structure boost::shared_ptr spOTBMaskAccessorVirtuos = boost::make_shared(rtStructureSetVirtuos->getStructure(i), doseAccessorVirtuos->getGeometricInfo()); spOTBMaskAccessorVirtuos->updateMask(); MaskAccessorPointer spMaskAccessor(spOTBMaskAccessorVirtuos); //create corresponding MaskedDoseIterator boost::shared_ptr spMaskedDoseIteratorTmp = boost::make_shared(spMaskAccessor, doseAccessorVirtuos); DoseIteratorPointer spMaskedDoseIterator(spMaskedDoseIteratorTmp); std::cout << "dvh calc" << std::endl; rttb::core::DVHCalculator* calc; if (i == 6) { calc = new rttb::core::DVHCalculator(spMaskedDoseIterator, - (rtStructureSetVirtuos->getStructure(i))->getUID(), doseAccessorVirtuos->getDoseUID(), 0.367944); + (rtStructureSetVirtuos->getStructure(i))->getUID(), doseAccessorVirtuos->getUID(), 0.367944); } else { calc = new rttb::core::DVHCalculator(spMaskedDoseIterator, - (rtStructureSetVirtuos->getStructure(i))->getUID(), doseAccessorVirtuos->getDoseUID(), 0.510107); + (rtStructureSetVirtuos->getStructure(i))->getUID(), doseAccessorVirtuos->getUID(), 0.510107); } DVHPointer dvhPtr = calc->generateDVH(); if (i == 6) { CHECK_CLOSE(42.497532, dvhPtr->getMaximum(), errorConstant); CHECK_CLOSE(2.7595800000000001, dvhPtr->getMinimum(), errorConstant); CHECK_CLOSE(7.4752642058590695, dvhPtr->getMean(), errorConstant); CHECK_CLOSE(6.4390200000000002, dvhPtr->getMedian(), errorConstant); CHECK_CLOSE(5.7031320000000001, dvhPtr->getModal(), errorConstant); CHECK_CLOSE(3.5065188466477824, dvhPtr->getStdDeviation(), errorConstant); CHECK_CLOSE(12.295674421896095, dvhPtr->getVariance(), errorConstant); CHECK_CLOSE(177218.04900734947, dvhPtr->getNumberOfVoxels(), 1e-2); } if (i == 8) { CHECK_CLOSE(68.099284499999996, dvhPtr->getMaximum(), errorConstant); CHECK_CLOSE(24.7401895, dvhPtr->getMinimum(), errorConstant); CHECK_CLOSE(54.384709827101481, dvhPtr->getMean(), errorConstant); CHECK_CLOSE(54.836502499999995, dvhPtr->getMedian(), errorConstant); CHECK_CLOSE(54.836502499999995, dvhPtr->getModal(), errorConstant); CHECK_CLOSE(3.3345924130915088, dvhPtr->getStdDeviation(), errorConstant); CHECK_CLOSE(11.119506561447452, dvhPtr->getVariance(), errorConstant); CHECK_CLOSE(338856.04793872859, dvhPtr->getNumberOfVoxels(), 1e-2); } } } RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/virtuos/VirtuosDoseIOTest.cpp b/testing/io/virtuos/VirtuosDoseIOTest.cpp index 7872039..cd52bd7 100644 --- a/testing/io/virtuos/VirtuosDoseIOTest.cpp +++ b/testing/io/virtuos/VirtuosDoseIOTest.cpp @@ -1,227 +1,227 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (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 "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbGeometricInfo.h" #include "rttbDoseIteratorInterface.h" #include "rttbVirtuosCubeinfoDoseAccessorGenerator.h" #include "rttbVirtuosDoseFileDoseAccessorGenerator.h" #include "rttbVirtuosPlanFileDoseAccessorGenerator.h" #include "rttbVirtuosDoseAccessor.h" #include "rttbNullPointerException.h" #include "rttbInvalidDoseException.h" #include "rttbInvalidParameterException.h" #include "rttbIndexOutOfBoundsException.h" #include "../rttbDoseAccessorTester.h" namespace rttb { namespace testing { /*! @brief VirtuosDoseIOTest - test the IO for virtuos data 1) test getPrescribedDose() and getNormalizationDose() 2) test virtuos dose import if geometric info was set correctly 3) test virtuos dose import accessing dose data and converting WARNING: The values for comparison need to be adjusted if the input files are changed! */ int VirtuosDoseIOTest(int argc, char* argv[]) { typedef core::DoseIteratorInterface::DoseAccessorPointer DoseAccessorPointer; PREPARE_DEFAULT_TEST_REPORTING; // 1: plan file name (virtuos) .../testing/data/Virtuos/prostate_ac/prostate_ac101.pln // 2: dose1 file name (virtuos) .../testing/data/Virtuos/prostate_ac/prostate_ac101.dos.gz // 3: dose2 file name (trip): .../testing/data/Virtuos/prostate_ac/prostate_ac101.dos // WARNING: Test will fail if dose2 does not contain the same dose as dose1! std::string RTPLAN_FILENAME; std::string RTDOSE_FILENAME; std::string RTDOSE2_FILENAME; if (argc > 1) { RTPLAN_FILENAME = argv[1]; } if (argc > 2) { RTDOSE_FILENAME = argv[2]; } if (argc > 3) { RTDOSE2_FILENAME = argv[3]; } //1) test getPrescribedDose() and getNormalizationDose() io::virtuos::VirtuosDoseFileDoseAccessorGenerator doseAccessorGeneratorTest3( RTDOSE_FILENAME.c_str(), 885.0, 76.0); boost::shared_ptr virtuosTest3 = boost::static_pointer_cast (doseAccessorGeneratorTest3.generateDoseAccessor()); CHECK_EQUAL(76.0, virtuosTest3->getPrescribedDose()); CHECK_EQUAL(885.0, virtuosTest3->getNormalizationDose()); io::virtuos::VirtuosDoseFileDoseAccessorGenerator doseAccessorGeneratorTest4( RTDOSE_FILENAME.c_str(), 0, 0); boost::shared_ptr virtuosTest4 = boost::static_pointer_cast (doseAccessorGeneratorTest4.generateDoseAccessor()); CHECK_EQUAL(1, virtuosTest4->getPrescribedDose()); CHECK_EQUAL(1, virtuosTest4->getNormalizationDose()); io::virtuos::VirtuosPlanFileDoseAccessorGenerator doseAccessorGenerator1(RTDOSE_FILENAME.c_str(), RTPLAN_FILENAME.c_str()); boost::shared_ptr doseAccessor1 = boost::static_pointer_cast (doseAccessorGenerator1.generateDoseAccessor()); CHECK_EQUAL(76.0, doseAccessor1->getPrescribedDose()); CHECK_EQUAL(885.0, doseAccessor1->getNormalizationDose()); //2) test dose import if geometric info was set correctly core::GeometricInfo geoInfo = doseAccessor1->getGeometricInfo(); CHECK_EQUAL(256, geoInfo.getNumRows()); CHECK_EQUAL(256, geoInfo.getNumColumns()); CHECK_EQUAL(144, geoInfo.getNumSlices()); CHECK_EQUAL(256 * 256 * 144, doseAccessor1->getGridSize()); CHECK_EQUAL(OrientationMatrix(), geoInfo.getOrientationMatrix()); const VoxelGridID start = 0; const VoxelGridIndex3D start3D(0); VoxelGridID end, inbetween; VoxelGridIndex3D end3D, inbetween3D; //3) test dose import accessing dose data and converting - CHECK_EQUAL(0, doseAccessor1->getDoseAt(start)); - CHECK_EQUAL(0, doseAccessor1-> getDoseAt(start3D)); + CHECK_EQUAL(0, doseAccessor1->getValueAt(start)); + CHECK_EQUAL(0, doseAccessor1-> getValueAt(start3D)); inbetween = int(doseAccessor1->getGridSize() / 2.0); doseAccessor1->getGeometricInfo().convert(inbetween, inbetween3D); - CHECK_EQUAL(0, doseAccessor1->getDoseAt(inbetween)); - CHECK_EQUAL(0, doseAccessor1-> getDoseAt(inbetween3D)); + CHECK_EQUAL(0, doseAccessor1->getValueAt(inbetween)); + CHECK_EQUAL(0, doseAccessor1-> getValueAt(inbetween3D)); end = doseAccessor1->getGridSize() - 1; doseAccessor1->getGeometricInfo().convert(end, end3D); - CHECK_EQUAL(0, doseAccessor1->getDoseAt(end)); - CHECK_EQUAL(0, doseAccessor1-> getDoseAt(end3D)); + CHECK_EQUAL(0, doseAccessor1->getValueAt(end)); + CHECK_EQUAL(0, doseAccessor1-> getValueAt(end3D)); /* Dose without plan */ io::virtuos::VirtuosDoseFileDoseAccessorGenerator doseAccessorGenerator2(RTDOSE2_FILENAME.c_str(), doseAccessor1->getNormalizationDose(), doseAccessor1->getPrescribedDose()); boost::shared_ptr doseAccessor2 = boost::static_pointer_cast (doseAccessorGenerator2.generateDoseAccessor()); CHECK_EQUAL(doseAccessor1->getPrescribedDose(), doseAccessor2->getPrescribedDose()); CHECK_EQUAL(doseAccessor1->getNormalizationDose(), doseAccessor2->getNormalizationDose()); //2) test dose import if geometric info was set correctly core::GeometricInfo geoInfo2 = doseAccessor2->getGeometricInfo(); CHECK_EQUAL(geoInfo.getNumRows(), geoInfo2.getNumRows()); CHECK_EQUAL(geoInfo.getNumColumns(), geoInfo2.getNumColumns()); CHECK_EQUAL(geoInfo.getNumSlices(), geoInfo2.getNumSlices()); CHECK_EQUAL(doseAccessor1->getGridSize(), doseAccessor2->getGridSize()); CHECK_EQUAL(geoInfo.getOrientationMatrix(), geoInfo2.getOrientationMatrix()); //3) test dose import accessing dose data and converting - CHECK_EQUAL(doseAccessor1->getDoseAt(start), doseAccessor2->getDoseAt(start)); - CHECK_EQUAL(doseAccessor1-> getDoseAt(start3D), doseAccessor2-> getDoseAt(start3D)); - CHECK_EQUAL(doseAccessor2->getDoseAt(start), doseAccessor2-> getDoseAt(start3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(start), doseAccessor2->getValueAt(start)); + CHECK_EQUAL(doseAccessor1-> getValueAt(start3D), doseAccessor2-> getValueAt(start3D)); + CHECK_EQUAL(doseAccessor2->getValueAt(start), doseAccessor2-> getValueAt(start3D)); inbetween = int(doseAccessor2->getGridSize() / 2.0); doseAccessor2->getGeometricInfo().convert(inbetween, inbetween3D); - CHECK_EQUAL(doseAccessor1->getDoseAt(inbetween), doseAccessor2->getDoseAt(inbetween)); - CHECK_EQUAL(doseAccessor1-> getDoseAt(inbetween3D), doseAccessor2-> getDoseAt(inbetween3D)); - CHECK_EQUAL(doseAccessor2->getDoseAt(inbetween), doseAccessor2-> getDoseAt(inbetween3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(inbetween), doseAccessor2->getValueAt(inbetween)); + CHECK_EQUAL(doseAccessor1-> getValueAt(inbetween3D), doseAccessor2-> getValueAt(inbetween3D)); + CHECK_EQUAL(doseAccessor2->getValueAt(inbetween), doseAccessor2-> getValueAt(inbetween3D)); end = doseAccessor2->getGridSize() - 1; doseAccessor2->getGeometricInfo().convert(end, end3D); - CHECK_EQUAL(doseAccessor1->getDoseAt(end), doseAccessor2->getDoseAt(end)); - CHECK_EQUAL(doseAccessor1-> getDoseAt(end3D), doseAccessor2-> getDoseAt(end3D)); - CHECK_EQUAL(doseAccessor2->getDoseAt(end), doseAccessor2-> getDoseAt(end3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(end), doseAccessor2->getValueAt(end)); + CHECK_EQUAL(doseAccessor1-> getValueAt(end3D), doseAccessor2-> getValueAt(end3D)); + CHECK_EQUAL(doseAccessor2->getValueAt(end), doseAccessor2-> getValueAt(end3D)); /* Import Trip dose */ io::virtuos::VirtuosDoseFileDoseAccessorGenerator doseAccessorGenerator3(RTDOSE2_FILENAME.c_str(), doseAccessor1->getNormalizationDose(), doseAccessor1->getPrescribedDose()); boost::shared_ptr doseAccessor3 = boost::static_pointer_cast (doseAccessorGenerator3.generateDoseAccessor()); CHECK_EQUAL(doseAccessor1->getPrescribedDose(), doseAccessor3->getPrescribedDose()); CHECK_EQUAL(doseAccessor1->getNormalizationDose(), doseAccessor3->getNormalizationDose()); //2) test dose import if geometric info was set correctly core::GeometricInfo geoInfo3 = doseAccessor3->getGeometricInfo(); CHECK_EQUAL(geoInfo.getNumRows(), geoInfo3.getNumRows()); CHECK_EQUAL(geoInfo.getNumColumns(), geoInfo3.getNumColumns()); CHECK_EQUAL(geoInfo.getNumSlices(), geoInfo3.getNumSlices()); CHECK_EQUAL(doseAccessor1->getGridSize(), doseAccessor3->getGridSize()); CHECK_EQUAL(geoInfo.getOrientationMatrix(), geoInfo3.getOrientationMatrix()); //3) test dose import accessing dose data and converting - CHECK_EQUAL(doseAccessor1->getDoseAt(start), doseAccessor3->getDoseAt(start)); - CHECK_EQUAL(doseAccessor1-> getDoseAt(start3D), doseAccessor3-> getDoseAt(start3D)); - CHECK_EQUAL(doseAccessor3->getDoseAt(start), doseAccessor3-> getDoseAt(start3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(start), doseAccessor3->getValueAt(start)); + CHECK_EQUAL(doseAccessor1-> getValueAt(start3D), doseAccessor3-> getValueAt(start3D)); + CHECK_EQUAL(doseAccessor3->getValueAt(start), doseAccessor3-> getValueAt(start3D)); inbetween = int(doseAccessor3->getGridSize() / 2.0); doseAccessor3->getGeometricInfo().convert(inbetween, inbetween3D); - CHECK_EQUAL(doseAccessor1->getDoseAt(inbetween), doseAccessor3->getDoseAt(inbetween)); - CHECK_EQUAL(doseAccessor1-> getDoseAt(inbetween3D), doseAccessor3-> getDoseAt(inbetween3D)); - CHECK_EQUAL(doseAccessor3->getDoseAt(inbetween), doseAccessor3-> getDoseAt(inbetween3D)); + CHECK_EQUAL(doseAccessor1->getValueAt(inbetween), doseAccessor3->getValueAt(inbetween)); + CHECK_EQUAL(doseAccessor1-> getValueAt(inbetween3D), doseAccessor3-> getValueAt(inbetween3D)); + CHECK_EQUAL(doseAccessor3->getValueAt(inbetween), doseAccessor3-> getValueAt(inbetween3D)); DoseAccessorTester doseCompare(doseAccessor1, doseAccessor3); CHECK_TESTER(doseCompare); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/models/LQModelAccessorTest.cpp b/testing/models/LQModelAccessorTest.cpp index b7c3c3c..cadb7ce 100644 --- a/testing/models/LQModelAccessorTest.cpp +++ b/testing/models/LQModelAccessorTest.cpp @@ -1,114 +1,114 @@ // ----------------------------------------------------------------------- // 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: 4047 $ (last changed revision) // @date $Date: 2012-10-29 16:19:15 +0100 (Mo, 29 Okt 2012) $ (last change date) // @author $Author: mang $ (last changed by) */ #include "litCheckMacros.h" #include #include "rttbLQModelAccessor.h" #include "rttbGenericDoseIterator.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbInvalidDoseException.h" namespace rttb { namespace testing { /*! @brief LQModelAccessorTest. 1) Test constructor 2) Test getGeometricInfo() - 3) Test getBioModelValueAt() + 3) Test getValueAt() */ int LQModelAccessorTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; std::string RTDOSE_FILENAME_CONSTANT_TWO; std::string RTDOSE_FILENAME_INCREASE_X; if (argc > 2) { RTDOSE_FILENAME_CONSTANT_TWO = argv[1]; RTDOSE_FILENAME_INCREASE_X = argv[2]; } else { std::cout << "at least two parameters for LQModelAccessorTest are expected" << std::endl; return -1; } typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1( RTDOSE_FILENAME_CONSTANT_TWO.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator2( RTDOSE_FILENAME_INCREASE_X.c_str()); DoseAccessorPointer doseAccessor2(doseAccessorGenerator2.generateDoseAccessor()); core::GeometricInfo doseAccessor1GeometricInfo = doseAccessor1->getGeometricInfo(); core::GeometricInfo doseAccessor2GeometricInfo = doseAccessor2->getGeometricInfo(); DoseAccessorPointer doseAccessorNull; - core::BioModelAccessorInterface::BioModelAccessorPointer LQWithConstantDose; - core::BioModelAccessorInterface::BioModelAccessorPointer LQWithIncreaseXDose; + core::AccessorInterface::AccessorPointer LQWithConstantDose; + core::AccessorInterface::AccessorPointer LQWithIncreaseXDose; //1) test constructor CHECK_THROW_EXPLICIT(models::LQModelAccessor(doseAccessorNull, 0, 0), core::InvalidDoseException); CHECK_NO_THROW(LQWithConstantDose = boost::make_shared(doseAccessor1, 0.2, 0.02)); CHECK_NO_THROW(LQWithIncreaseXDose = boost::make_shared(doseAccessor2, 0.3, 0.01)); //2) Test getGeometricInfo() CHECK_EQUAL(LQWithConstantDose->getGeometricInfo(), doseAccessor1GeometricInfo); CHECK_EQUAL(LQWithIncreaseXDose->getGeometricInfo(), doseAccessor2GeometricInfo); - //3) Test getBioModelValueAt() + //3) Test getValueAt() models::BioModelParamType expectedLQWithDoseTwo = exp(-(0.2 * 2 + (0.02 * 2 * 2))); - CHECK_EQUAL(LQWithConstantDose->getBioModelValueAt(0), expectedLQWithDoseTwo); - CHECK_EQUAL(LQWithConstantDose->getBioModelValueAt(LQWithConstantDose->getGridSize() - 1), expectedLQWithDoseTwo); - CHECK_EQUAL(LQWithConstantDose->getBioModelValueAt(VoxelGridIndex3D(1, 2, 6)), expectedLQWithDoseTwo); - CHECK_EQUAL(LQWithConstantDose->getBioModelValueAt(VoxelGridIndex3D(65, 40, 60)), expectedLQWithDoseTwo); - CHECK_EQUAL(LQWithIncreaseXDose->getBioModelValueAt(0), 1); + CHECK_EQUAL(LQWithConstantDose->getValueAt(0), expectedLQWithDoseTwo); + CHECK_EQUAL(LQWithConstantDose->getValueAt(LQWithConstantDose->getGridSize() - 1), expectedLQWithDoseTwo); + CHECK_EQUAL(LQWithConstantDose->getValueAt(VoxelGridIndex3D(1, 2, 6)), expectedLQWithDoseTwo); + CHECK_EQUAL(LQWithConstantDose->getValueAt(VoxelGridIndex3D(65, 40, 60)), expectedLQWithDoseTwo); + CHECK_EQUAL(LQWithIncreaseXDose->getValueAt(0), 1); models::BioModelParamType expectedLQWithIncreaseX = exp(-(0.3 * 66 * 2.822386e-5 + (0.01 * 66 * 2.822386e-5 * 66 * 2.822386e-5))); - CHECK_CLOSE(LQWithIncreaseXDose->getBioModelValueAt(LQWithIncreaseXDose->getGridSize() - 1), expectedLQWithIncreaseX, + CHECK_CLOSE(LQWithIncreaseXDose->getValueAt(LQWithIncreaseXDose->getGridSize() - 1), expectedLQWithIncreaseX, errorConstant); expectedLQWithIncreaseX = exp(-(0.3 * 1 * 2.822386e-5 + (0.01 * 1 * 2.822386e-5 * 1 * 2.822386e-5))); - CHECK_CLOSE(LQWithIncreaseXDose->getBioModelValueAt(VoxelGridIndex3D(1, 2, 6)), expectedLQWithIncreaseX, errorConstant); + CHECK_CLOSE(LQWithIncreaseXDose->getValueAt(VoxelGridIndex3D(1, 2, 6)), expectedLQWithIncreaseX, errorConstant); expectedLQWithIncreaseX = exp(-(0.3 * 45 * 2.822386e-5 + (0.01 * 45 * 2.822386e-5 * 45 * 2.822386e-5))); - CHECK_CLOSE(LQWithIncreaseXDose->getBioModelValueAt(VoxelGridIndex3D(45, 40, 60)), expectedLQWithIncreaseX, + CHECK_CLOSE(LQWithIncreaseXDose->getValueAt(VoxelGridIndex3D(45, 40, 60)), expectedLQWithIncreaseX, errorConstant); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb \ No newline at end of file