diff --git a/code/masks/files.cmake b/code/masks/files.cmake index 0cc43df..370758b 100644 --- a/code/masks/files.cmake +++ b/code/masks/files.cmake @@ -1,7 +1,9 @@ SET(CPP_FILES rttbGenericMutableMaskAccessor.cpp + rttbVOIindexIdentifier.cpp ) SET(H_FILES rttbGenericMutableMaskAccessor.h + rttbVOIindexIdentifier.h ) diff --git a/code/masks/rttbGenericMutableMaskAccessor.h b/code/masks/rttbGenericMutableMaskAccessor.h index 71153a1..038e555 100644 --- a/code/masks/rttbGenericMutableMaskAccessor.h +++ b/code/masks/rttbGenericMutableMaskAccessor.h @@ -1,108 +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 __GENERIC_MUTABLE_MASK_ACCESSOR_H #define __GENERIC_MUTABLE_MASK_ACCESSOR_H #include "rttbMutableMaskAccessorInterface.h" #include "rttbBaseType.h" #include "rttbMaskVoxel.h" namespace rttb { - namespace masks - { + namespace masks + { - /*! @class GenericMutableMaskAccessor - @brief Default implementation of MutableMaskAccessorInterface. - @see MutableMaskAccessorInterface - */ - class GenericMutableMaskAccessor: public core::MutableMaskAccessorInterface - { - public: - typedef core::MutableMaskAccessorInterface::MaskVoxelList MaskVoxelList; - typedef core::MutableMaskAccessorInterface::MaskVoxelListPointer MaskVoxelListPointer; + /*! @class GenericMutableMaskAccessor + @brief Default implementation of MutableMaskAccessorInterface. + @see MutableMaskAccessorInterface + */ + class GenericMutableMaskAccessor: public core::MutableMaskAccessorInterface + { + public: + typedef core::MutableMaskAccessorInterface::MaskVoxelList MaskVoxelList; + typedef core::MutableMaskAccessorInterface::MaskVoxelListPointer MaskVoxelListPointer; - private: - core::GeometricInfo _geoInfo; + private: + core::GeometricInfo _geoInfo; - /*! vector containing list of mask voxels*/ - MaskVoxelListPointer _spRelevantVoxelVector; + /*! vector containing list of mask voxels*/ + MaskVoxelListPointer _spRelevantVoxelVector; - IDType _maskUID; + IDType _maskUID; - GenericMutableMaskAccessor(const - GenericMutableMaskAccessor&); //not implemented on purpose -> non-copyable - GenericMutableMaskAccessor& operator=(const - GenericMutableMaskAccessor&);//not implemented on purpose -> non-copyable + GenericMutableMaskAccessor(const + GenericMutableMaskAccessor&); //not implemented on purpose -> non-copyable + GenericMutableMaskAccessor& operator=(const + GenericMutableMaskAccessor&);//not implemented on purpose -> non-copyable - public: - ~GenericMutableMaskAccessor(); + public: + ~GenericMutableMaskAccessor(); - GenericMutableMaskAccessor(const core::GeometricInfo& aGeometricInfo); + GenericMutableMaskAccessor(const core::GeometricInfo& aGeometricInfo); - /*! @brief initialize mask structure if _spRelevantVoxelVector was not previously initialized*/ - void updateMask(); + /*! @brief initialize mask structure if _spRelevantVoxelVector was not previously initialized*/ + void updateMask(); - /*! @brief get vector containing all relevant voxels that are inside the given structure*/ - MaskVoxelListPointer getRelevantVoxelVector(); - /*! @brief get vector containing all relevant voxels that have a relevant volume above the given threshold and are inside the given structure*/ - MaskVoxelListPointer getRelevantVoxelVector(float lowerThreshold); + /*! @brief get vector containing all relevant voxels that are inside the given structure*/ + MaskVoxelListPointer getRelevantVoxelVector(); + /*! @brief get vector containing all relevant voxels that have a relevant volume above the given threshold and are inside the given structure*/ + MaskVoxelListPointer getRelevantVoxelVector(float lowerThreshold); - /*!@brief determine how a given voxel on the dose grid is masked - * @param aID ID of the voxel in grid. - * @param voxel Reference to the voxel. - * @post after a valid call voxel contains the information of the specified grid voxel. If aID is not valid, voxel values are undefined. - * The relevant volume fraction will be set to zero. - * @return Indicates if the voxel exists and therefore if parameter voxel contains valid values.*/ - bool getMaskAt(const VoxelGridID aID, core::MaskVoxel& voxel) const; + /*!@brief determine how a given voxel on the dose grid is masked + * @param aID ID of the voxel in grid. + * @param voxel Reference to the voxel. + * @post after a valid call voxel contains the information of the specified grid voxel. If aID is not valid, voxel values are undefined. + * The relevant volume fraction will be set to zero. + * @return Indicates if the voxel exists and therefore if parameter voxel contains valid values.*/ + bool getMaskAt(const VoxelGridID aID, core::MaskVoxel& voxel) const; - bool getMaskAt(const VoxelGridIndex3D& aIndex, core::MaskVoxel& voxel) const; + bool getMaskAt(const VoxelGridIndex3D& aIndex, core::MaskVoxel& voxel) const; - /* @ brief is true if dose is on a homogeneous grid */ - // Inhomogeneous grids are not supported at the moment, but if they will - // be supported in the future the interface does not need to change. - bool isGridHomogeneous() const - { - return true; - }; + /* @ brief is true if dose is on a homogeneous grid */ + // Inhomogeneous grids are not supported at the moment, but if they will + // be supported in the future the interface does not need to change. + bool isGridHomogeneous() const + { + return true; + }; - /*! @brief give access to GeometricInfo*/ - inline const core::GeometricInfo& getGeometricInfo() const - { - return _geoInfo; - }; + /*! @brief give access to GeometricInfo*/ + inline const core::GeometricInfo& getGeometricInfo() const + { + return _geoInfo; + }; - IDType getMaskUID() const - { - return _maskUID; - }; + IDType getMaskUID() const + { + return _maskUID; + }; - void setMaskAt(VoxelGridID aID, const core::MaskVoxel& voxel); + void setMaskAt(VoxelGridID aID, const core::MaskVoxel& voxel); - void setMaskAt(const VoxelGridIndex3D& gridIndex, const core::MaskVoxel& voxel); + void setMaskAt(const VoxelGridIndex3D& gridIndex, const core::MaskVoxel& voxel); - void setRelevantVoxelVector(MaskVoxelListPointer aVoxelListPointer); + void setRelevantVoxelVector(MaskVoxelListPointer aVoxelListPointer); - }; - } + }; + } } #endif \ No newline at end of file diff --git a/code/masks/rttbVOIindexIdentifier.cpp b/code/masks/rttbVOIindexIdentifier.cpp new file mode 100644 index 0000000..cb98659 --- /dev/null +++ b/code/masks/rttbVOIindexIdentifier.cpp @@ -0,0 +1,147 @@ +// ----------------------------------------------------------------------- +// 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: +// @date $Date: +// @author $Author: +*/ + + +#include "rttbVOIindexIdentifier.h" +#include "rttbStructureSet.h" +#include "rttbStructure.h" +#include "rttbExceptionMacros.h" +#include +#include + + + +namespace rttb +{ + namespace masks + { + + const unsigned int VOIindexIdentifier::getIndexByVoiName(StructSetTypePointer spStructSet, + const std::string& name) + { + + if (!spStructSet) + { + std::ostringstream message; + message << "Exception: "<< "invalid method call spStructSet invalid"; + ::rttb::core::Exception e_(message.str().c_str()); + throw e_; + } + + + VoiLabelList voiLabelList; + + for (int i = 0; i < spStructSet->getNumberOfStructures(); i++) + { + voiLabelList.push_back(spStructSet->getStructure(i)->getLabel()); + } + + + + int returnValue = -1; + + if (voiLabelList.empty()) + { + std::ostringstream message; + message << "Exception: "<< "invalid method call, object state invalid, voiLabelList empty"; + ::rttb::core::Exception e_(message.str().c_str()); + throw e_; + } + + + ::boost::regex optionalNamesREG("([^\|]*)([\|\|][^\|]*)+"); + ::boost::smatch what; + + typedef std::vector< std::string > OptionalVectorType; + OptionalVectorType optionalVois; + ::boost::split(optionalVois, name, ::boost::is_any_of("||")); + + for (OptionalVectorType::iterator i = optionalVois.begin(); i != optionalVois.end(); i++) + { + int counter = 0; + + /* + Searches for valid entries in the voi list. + Takes the first matching entry! + */ + for (VoiLabelList::const_iterator iter = voiLabelList.begin(); + iter != voiLabelList.end(); iter++) + { + if ((*iter).compare(*i) == 0) + { + returnValue = counter; + } + + counter++; + } + + } + + if (returnValue == -1) + { + std::ostringstream message; + message << "Exception: "<< "specified voi name not found!"; + ::rttb::core::Exception e_(message.str().c_str()); + throw e_; + } + + return returnValue; + } + + const std::string VOIindexIdentifier::getVoiNameByIndex(StructSetTypePointer spStructSet, + const unsigned int& index) + { + if (!spStructSet) + { + std::ostringstream message; + message << "Exception: "<< "invalid method call spStructSet invalid"; + ::rttb::core::Exception e_(message.str().c_str()); + throw e_; + } + + VoiLabelList voiLabelList; + + for (int i = 0; i < spStructSet->getNumberOfStructures(); i++) + { + voiLabelList.push_back(spStructSet->getStructure(i)->getLabel()); + } + + if (voiLabelList.empty()) + { + std::ostringstream message; + message << "Exception: "<< "invalid method call, object state invalid, voiLabelList empty"; + ::rttb::core::Exception e_(message.str().c_str()); + throw e_; + } + + if (index >= voiLabelList.size()) + { + std::ostringstream message; + message << "Exception: "<< "invalid index, index out of range"; + ::rttb::core::Exception e_(message.str().c_str()); + throw e_; + } + + return voiLabelList[index]; + } + } +} + diff --git a/code/masks/rttbVOIindexIdentifier.h b/code/masks/rttbVOIindexIdentifier.h new file mode 100644 index 0000000..13875bf --- /dev/null +++ b/code/masks/rttbVOIindexIdentifier.h @@ -0,0 +1,86 @@ +// ----------------------------------------------------------------------- +// 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: +// @date $Date: +// @author $Author: +*/ + + + + +#ifndef __VOI_INDEX_IDENTIFIER_H +#define __VOI_INDEX_IDENTIFIER_H + +#include "rttbStructureSet.h" +#include "rttbStructure.h" +#include + + + + +namespace rttb +{ + namespace masks + { + class VOIindexIdentifier + { + + public: + typedef ::boost::shared_ptr Pointer; + typedef ::rttb::core::StructureSet StructSetType; + typedef ::boost::shared_ptr StructSetTypePointer; + typedef ::rttb::core::Structure StructType; + typedef StructType::StructTypePointer StructTypePointer; + typedef std::vector VoiLabelList; + + + public: + + VOIindexIdentifier(){} + virtual ~VOIindexIdentifier() {} + + + /*!@brief get the index of the corresponding VOI + * @pre name must contain a valid voi name + * @pre spStructSet must point to a valid structure set. + * @param spStructSet Pointer to the structur set that should be checked for the named VOI. + * @param name Name of the VOI + * @exception ::rttb::core::Exception on invalid spStructSet + ::rttb::core::Exception on invalid spStructSet + * @return the index */ + static const unsigned int getIndexByVoiName(StructSetTypePointer spStructSet, + const std::string& name); + + + /*!@brief get the VOI of the corresponding index + * @pre index must specify a valid index value + * @pre spStructSet must point to a valid structure set. + * @param spStructSet Pointer to the structur set that should be checked for the named VOI. + * @param name Index of the VOI + * @exception ::rttb::core::Exception on invalid spStructSet + ::rttb::core::Exception on invalid spStructSet + * @return voi name */ + static const std::string getVoiNameByIndex(StructSetTypePointer spStructSet, + const unsigned int& index); + + + }; + + } +} + +#endif __VOI_INDEX_IDENTIFIER_H diff --git a/testing/masks/CMakeLists.txt b/testing/masks/CMakeLists.txt index efaff83..4dbe0cf 100644 --- a/testing/masks/CMakeLists.txt +++ b/testing/masks/CMakeLists.txt @@ -1,17 +1,37 @@ MESSAGE (STATUS "Process All Mask Tests...") #----------------------------------------------------------------------------- # Include sub directories #----------------------------------------------------------------------------- IF(BUILD_Masks_Boost) ADD_SUBDIRECTORY(boost) ENDIF() IF(BUILD_Masks_OTB) ADD_SUBDIRECTORY(legacy) ENDIF() + +#----------------------------------------------------------------------------- +# Setup the system information test. Write out some basic failsafe +# information in case the test doesn't run. +#----------------------------------------------------------------------------- + + +SET(Masks_TESTS ${EXECUTABLE_OUTPUT_PATH}/rttbMasksTests) + +SET(TEST_DATA_ROOT ${RTTBTesting_SOURCE_DIR}/data) + +SET(TEMP ${RTTBTesting_BINARY_DIR}/temporary) + + +#----------------------------------------------------------------------------- +ADD_TEST(VOIindexIdentifierTest ${Mask_TESTS} VOIindexIdentifierTest +"${TEST_DATA_ROOT}/DICOM/StructureSet/RS1.3.6.1.4.1.2452.6.841242143.1311652612.1170940299.4217870819.dcm" ) + + +RTTB_CREATE_TEST_MODULE(rttbMasks DEPENDS RTTBDicomIO RTTBMasks PACKAGE_DEPENDS Boost Litmus DCMTK) diff --git a/testing/masks/VOIindexIdentifierTest.cpp b/testing/masks/VOIindexIdentifierTest.cpp new file mode 100644 index 0000000..21fb0b1 --- /dev/null +++ b/testing/masks/VOIindexIdentifierTest.cpp @@ -0,0 +1,100 @@ +// ----------------------------------------------------------------------- +// 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: +// @date $Date: +// @author $Author: +*/ + +// 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 "rttbDicomFileStructureSetGenerator.h" +#include "rttbDicomIODStructureSetGenerator.h" +#include "rttbDcmrtException.h" +#include "rttbInvalidParameterException.h" +#include "rttbVOIindexIdentifier.h" + +namespace rttb +{ + + namespace testing + { + + int VOIindexIdentifierTest(int argc, char* argv[]) + { + typedef core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; + //typedef boost::shared_ptr DRTStrSetIODPtr; + + PREPARE_DEFAULT_TEST_REPORTING; + //ARGUMENTS: 1: structure file name + + + std::string RTSTRUCT_FILENAME; + + + if (argc > 1) + { + RTSTRUCT_FILENAME = argv[1]; + } + else + { + RTSTRUCT_FILENAME = "D:\\ajaeger\\Packages\\NotMeVisLab\\SBR\\RTToolbox\\AVIDIntegration\\testing\\data\\DICOM\\StructureSet\\RS1.3.6.1.4.1.2452.6.841242143.1311652612.1170940299.4217870819.dcm"; + } + + StructureSetPointer rtStructureSet = io::dicom::DicomFileStructureSetGenerator( + RTSTRUCT_FILENAME.c_str()).generateStructureSet(); + + StructureSetPointer emptyPointer = StructureSetPointer(); + + /* getIndexByVoiName */ + CHECK_NO_THROW(::rttb::masks::VOIindexIdentifier testVOIindexId = ::rttb::masks::VOIindexIdentifier()); + ::rttb::masks::VOIindexIdentifier testVOIindexId = ::rttb::masks::VOIindexIdentifier(); + CHECK_THROW_EXPLICIT(testVOIindexId.getIndexByVoiName(emptyPointer,"Leber"), + ::rttb::core::Exception); + + CHECK_NO_THROW(testVOIindexId.getIndexByVoiName(rtStructureSet,"Leber")); + int intVoi = 5; + CHECK_EQUAL(testVOIindexId.getIndexByVoiName(rtStructureSet,"Leber"),intVoi); + + CHECK_NO_THROW(testVOIindexId.getIndexByVoiName(rtStructureSet,"Leber||Leb")); + + CHECK_EQUAL(testVOIindexId.getIndexByVoiName(rtStructureSet,"Leber"),intVoi); + CHECK_EQUAL(testVOIindexId.getIndexByVoiName(rtStructureSet,"Leber||Leb"),intVoi); + + CHECK_THROW_EXPLICIT(testVOIindexId.getIndexByVoiName(rtStructureSet,"Herz"),::rttb::core::Exception); + + /* getVoiNameByIndex */ + CHECK_THROW_EXPLICIT(testVOIindexId.getVoiNameByIndex(emptyPointer, 5), + ::rttb::core::Exception); + CHECK_EQUAL(testVOIindexId.getVoiNameByIndex(rtStructureSet,5), "Leber"); + std::string voiName = "Herz"; + CHECK_THROW_EXPLICIT(testVOIindexId.getVoiNameByIndex(rtStructureSet,20), ::rttb::core::Exception); + + RETURN_AND_REPORT_TEST_SUCCESS; + } + + }//testing +}//rttb + diff --git a/testing/masks/files.cmake b/testing/masks/files.cmake new file mode 100644 index 0000000..b5c92ab --- /dev/null +++ b/testing/masks/files.cmake @@ -0,0 +1,7 @@ +SET(CPP_FILES + VOIindexIdentifierTest.cpp + rttbMasksTests.cpp + ) + +SET(H_FILES +) diff --git a/testing/masks/rttbMasksTests.cpp b/testing/masks/rttbMasksTests.cpp index b55efc5..c13bce8 100644 --- a/testing/masks/rttbMasksTests.cpp +++ b/testing/masks/rttbMasksTests.cpp @@ -1,63 +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) */ // 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" namespace rttb { namespace testing { void registerTests() { - LIT_REGISTER_TEST(OTBMaskAccessorTest); + LIT_REGISTER_TEST(VOIindexIdentifierTest); } } } 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; }