diff --git a/README.md b/README.md index 0956754..e1db17e 100644 --- a/README.md +++ b/README.md @@ -1,271 +1,271 @@ # RTToolbox RTToolbox is a software library to support quantitative analysis of treatment outcome for radiotherapy. The RTToolbox was designed following object-oriented design (OOD) principles and was implemented in the language C++. Features include: * import of radiotherapy data (e.g. dose distributions and structure sets) from DICOM-RT format and other standard image processing formats * DVH calculation * Dose statistic calculation * arithmetic operations on dose distributions * structure relationship analyses (e.g. fully-contained, partially-contained) * Calculation of dose comparison indices such as Conformity Index (CI), Homogeneity Index (HI) and Conformation Number (CN) * Calculation of biological models including TCP, NTCP, EUD and BED Also, the RTToolbox provides apps e.g. for DVH/Dose Statistic calculation or Dose accumulation that provides a convenient access of RT scenarios without computer-science knowledge. ## Getting Started These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. ### Prerequisites #### Build system * [CMake](https://cmake.org), version 3.1 or higher #### Compiler * Visual Studio 2013 * Visual Studio 2015 * Visual Studio 2017 * GCC 5.4 * GCC 7.3 Other compilers may work as well, but are not tested. #### Linking Static/Dynamic library support Can be changed with advanced option `BUILD_SHARED_LIBS` :warning: building RTToolbox as dynamic library under Windows and as static library under Linux is an experimental feature. #### Third party libraries * [boost](http://www.boost.org ), version 1.64.0 or higher * [DCMTK](http://dicom.offis.de/dcmtk.php.en ), with RT support - 3.6.1_20121102 or newer * [ITK](https://itk.org ), version 4.4 or higher (*optional*) * for DoseInterpolation support with ITK transformation or ITK File IO support * [MatchPoint](http://mitk.org/download/thirdparty/MatchPoint_rev1610.tar.gz ), version 0.12 or higher (*optional*) * for DoseInterpolation support with MatchPoint registration objects :information_source: To make sure everything runs smoothly, please make sure that all libraries and the RTToolbox are either compiled with `/MD` or `/MT` flags. ##### Boost In case you work with Windows, we recommend using the [pre-build versions of boost](https://sourceforge.net/projects/boost/files/boost-binaries/). If you want to build the library yourself, consider the following: Build (using the same compiler options as RTToolbox, usually `STATIC LINKING` and `x64` architecture). The following components are needed: * `filesystem`, * `system` and * `program_options` * if you plan to build the apps (*optional*) :information_source: eventually, it might be needed to add the CMake variable `BOOST_LIBRARYDIR` and set it to the respective library path of boost. For Windows: To build Boost open a command prompt, change to your boost source directory and copy following command(s): Debug: `b2 -j12 --with-filesystem --with-system --with-thread --with-program_options --with-date_time --with-atomic --with-chrono toolset=msvc-14.1 address-model=64 variant=debug threading=multi link=shared define=_BIND_TO_CURRENT_VCLIBS_VERSION` Release: `b2 -j12 --with-filesystem --with-system --with-thread --with-program_options --with-date_time --with-atomic --with-chrono toolset=msvc-14.1 address-model=64 variant=release threading=multi link=shared` If you don´t require `program_options` delete `--with-program_options` from the command before executing it. ##### DCMTK For Windows: To compile DCMTK with `/MD` flags (standard for all other libs), you need to patch the CMAKE options of DCMTK (`PathToDCMTK\CMake\dcmtkPrepare.cmake`), either by replacing `"/MT"` with `"/MD"` or by explicitly replacing lines 135 to 171 with the following lines: ``` IF(DCMTK_OVERWRITE_WIN32_COMPILER_FLAGS AND NOT BUILD_SHARED_LIBS) # settings for Microsoft Visual Studio IF(CMAKE_GENERATOR MATCHES "Visual Studio .*") # get Visual Studio Version STRING(REGEX REPLACE "Visual Studio ([0-9]+).*" "\\1" VS_VERSION "${CMAKE_GENERATOR}") # these settings never change even for C or C++ SET(CMAKE_C_FLAGS_DEBUG "/MDd /Z7 /Od") SET(CMAKE_C_FLAGS_RELEASE "/DNDEBUG /MD /O2") SET(CMAKE_C_FLAGS_MINSIZEREL "/DNDEBUG /MD /O2") SET(CMAKE_C_FLAGS_RELWITHDEBINFO "/DNDEBUG /MDd /Z7 /Od") SET(CMAKE_CXX_FLAGS_DEBUG "/MDd /Z7 /Od") SET(CMAKE_CXX_FLAGS_RELEASE "/DNDEBUG /MD /O2") SET(CMAKE_CXX_FLAGS_MINSIZEREL "/DNDEBUG /MD /O2") SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/DNDEBUG /MDd /Z7 /Od") # specific settings for the various Visual Studio versions IF(VS_VERSION EQUAL 6) SET(CMAKE_C_FLAGS "/nologo /W3 /GX /Gy /YX") SET(CMAKE_CXX_FLAGS "/nologo /W3 /GX /Gy /YX /Zm500") # /Zm500 increments heap size which is needed on some system to compile templates in dcmimgle ENDIF(VS_VERSION EQUAL 6) IF(VS_VERSION EQUAL 7) SET(CMAKE_C_FLAGS "/nologo /W3 /Gy") SET(CMAKE_CXX_FLAGS "/nologo /W3 /Gy") ENDIF(VS_VERSION EQUAL 7) IF(VS_VERSION GREATER 7) SET(CMAKE_C_FLAGS "/nologo /W3 /Gy /EHsc") SET(CMAKE_CXX_FLAGS "/nologo /W3 /Gy /EHsc") ENDIF(VS_VERSION GREATER 7) ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio .*") ENDIF(DCMTK_OVERWRITE_WIN32_COMPILER_FLAGS AND NOT BUILD_SHARED_LIBS) ``` `BUILD_APPS` can be switched off. Then build DCMTK. For Linux: install required dependencies (Ubuntu 18.04 and newer): `sudo apt-get install libpng-dev libtiff5-dev libxml2-dev libjpeg8-dev zlib1g-dev libwrap0-dev libssl-dev` install required dependencies (Ubuntu 17.10 and older): `sudo apt-get install libpng12-dev libtiff5-dev libxml2-dev libjpeg8-dev zlib1g-dev libwrap0-dev libssl-dev` Enable `BUILD_SHARED_LIBS`. `BUILD_APPS` can be switched off. ##### ITK Build ITK with default options. :warning: ensure that compiler enables C++11 features by setting `CMAKE_CXX_STANDARD=11` (default for supported compilers) :warning: if you use ITK 5, turn on `RTTB_ITK5_SUPPORT` :warning: Only use one ITK version consistently throughout all libraries and RTToolbox! Otherwise, linker errors will occur. ##### MatchPoint Configure MatchPoint. Please disable `BUILD_TESTING` before building it. :warning: ensure that compiler enables C++11 features by setting `CMAKE_CXX_STANDARD=11` (default for supported compilers) :warning: Only use one ITK version consistently throughout all libraries and RTToolbox! Otherwise, linker errors will occur. :warning: MatchPoint currently does not support ITK 5 ### Building RT-Toolbox * Configure with CMake * Set `BOOST_INCLUDE_DIR` to the main boost directory. Eventually set `BOOST_LIBRARYDIR` to the respective path (e.g. `/lib64-msvc-14.1\` for Visual Studio 2017 and 64-bit) * Select all packages you like to build (Parameters `BUILD_*` ; e.g. `BUILD_IO_Dicom`). * `BUILD_IO_Dicom`: Reading and writing of DICOM-RT files * `BUILD_IO_HELAX`: Reading of Helax DICOM files * `BUILD_IO_ITK`: Generic reading/writing with ITK * `BUILD_Interpolation`: Dose Interpolation * `BUILD_InterpolationMatchPointTransformation`: Dose Interpolation with Match Point registration support. * `BUILD_Masks`: Voxelization support * `BUILD_Models`: Calculation of dosimetrical models like TCP, NTCP etc. * `BUILD_Apps`: To build the RTTB command line apps (five available) * `BioModelCalc`: calculate the radiobiological effect based on dose * `DoseAcc`: Do dose accumulation * `DoseMap`: Do dose mapping * `DoseTool`: Compute Dose statistics and DVH * `VoxelizerTool`: Voxelize an RTSTRUCT file Some modules of RT-Toolbox are mandatory (e.g. `RTTBCore`) and build automatically. :information_source: enabling `BUILD_All_Modules` builds all modules (except Apps and Testing modules). :information_source: if you build RTTB with VS dynamic, you must ensure that code that uses RTTB DLLs uses the same STL Set `DCMTK_DIR` to your dcmtk binary file directory and `DCMTK_SOURCE_DIR` to your dcmtk source directory. If you want to build RT-Toolbox with ITK and/or MatchPoint set your `ITK_DIR` to your itk binary file directory and/or `MatchPoint_DIR` to your binary matchpoint directory. All directory entries left empty do not require a manual input. Finally, Generate the compilation files for your environment and built it. ### Examples Some examples can be found in ´testing/examples´: * `RTBioModelExampleTest`: Computation of Biological model indices (TCP/NTCP) from a given DVH -* `RTDoseIndexTest`: Computation of dose indices (Conformation Number, Conformal Index, Conformity index) from a given DVH * `RTDoseStatisticsDicomTest`: Computation of dose statistics (max dose/mean dose/min dose/Dx/Vx) based on dose data for a specified structure * `RTDVHTest`: Computation of statistics (max value/mean value/min value/Dx/Vx) based on a DVH Other examples include: * `DVHCalculatorTest` (`testing/core`): Computation of a DVH from dose and structure * `VoxelizationValidationTest` (`testing/validation`): Computation of a voxelization * `ITKDoseAccessorConverterTest`: (`testing/io/itk`): Saving image RTToolbox image data as an ITK file +* `DoseIndex tests`: (`testing/indices`): Computation of different dose indices (e.g. Conformation Number, Conformal Index, Conformity index) ## Running the tests [CTest](https://cmake.org/Wiki/CMake/Testing_With_CTest) is used as testing framework. See their documentation for general testing questions. :information_source: The used testing library Litmus is build automatically. :warning: currently, you have access to testing data only with ssh. That means that a [phabricator](https://phabricator.mitk.org/) account and access to `RTTB-data` repository is mandatory. Please contact rttb(at)dkfz.de for further information. Enabling testing is done as follows: * Enable `BUILD_TESTING` * Configure with CMake * Enable tests of interest * Generate CMake configuration * Build RT-Toolbox * Run tests (build `RUN_TESTS` project or call `ctest` in commandline) to ensure that everything is correct. :information_source: `BUILD_Tester_All` builds all test modules. ## Contributing Please add a github issue and send a pull request if you want to contribute. ## Versioning We use the Ubuntu Release versioning scheme. v2017.02 was released in February 2017. We aim at releasing stable versions once a year. For the versions available, see the [tags on this repository](https://github.com/MIC-DKFZ/RTTB/tags). ## Authors See the list of [contributors](https://github.com/MIC-DKFZ/RTTB/contributors) who participated in this project. ## License This project is licensed under the BSD License - see the [LICENSE](LICENSE) file for details ## Contact Software Development for Integrated Diagnostics and Therapy (SIDT), German Cancer Research Center (DKFZ), Heidelberg, Germany. Web: https://www.dkfz-heidelberg.de/en/mic/research/SIDT/sidt_projects.html E-mail: rttb(at)dkfz.de ## Acknowledgments * **Billie Thompson** - *Template of the readme* - [PurpleBooth](https://github.com/PurpleBooth) diff --git a/cmake/rttbMacroCreateModule.cmake b/cmake/rttbMacroCreateModule.cmake index 34217c7..7ca3219 100644 --- a/cmake/rttbMacroCreateModule.cmake +++ b/cmake/rttbMacroCreateModule.cmake @@ -1,115 +1,118 @@ ################################################################## # # RTTB_CREATE_MODULE # #! Creates a module for the automatic module dependency system within RTTB. #! Configurations are generated in the moduleConf directory. #! #! USAGE: #! #! \code #! RTTB_CREATE_MODULE( #! [INCLUDE_DIRS ] #! [INTERNAL_INCLUDE_DIRS ] #! [DEPENDS ] #! [PROVIDES ] #! [PACKAGE_DEPENDS ] #! [EXPORT_DEFINE ] #! \endcode #! #! \param MODULE_NAME_IN The name for the new module # ################################################################## MACRO(RTTB_CREATE_MODULE MODULE_NAME_IN) MACRO_PARSE_ARGUMENTS(MODULE "INCLUDE_DIRS;INTERNAL_INCLUDE_DIRS;DEPENDS;DEPENDS_INTERNAL;PROVIDES;PACKAGE_DEPENDS;EXPORT_DEFINE;ADDITIONAL_LIBS" "FORCE_STATIC;HEADERS_ONLY" ${ARGN}) SET(MODULE_NAME ${MODULE_NAME_IN}) # assume worst case SET(MODULE_IS_ENABLED 0) # first we check if we have an explicit module build list IF(RTTB_MODULES_TO_BUILD) LIST(FIND RTTB_MODULES_TO_BUILD ${MODULE_NAME} _MOD_INDEX) IF(_MOD_INDEX EQUAL -1) SET(MODULE_IS_EXCLUDED 1) ENDIF() ENDIF() IF(NOT MODULE_IS_EXCLUDED) MESSAGE(STATUS "configuring Module ${MODULE_NAME}...") # first of all we check for the dependencies RTTB_CHECK_MODULE(_MISSING_DEP ${MODULE_DEPENDS}) IF(_MISSING_DEP) MESSAGE("Module ${MODULE_NAME} won't be built, missing dependency: ${_MISSING_DEP}") SET(MODULE_IS_ENABLED 0) ELSE(_MISSING_DEP) SET(MODULE_IS_ENABLED 1) # now check for every package if it is enabled. This overlaps a bit with # RTTB_CHECK_MODULE ... FOREACH(_package ${MODULE_PACKAGE_DEPENDS}) IF((DEFINED RTTB_USE_${_package}) AND NOT (RTTB_USE_${_package})) MESSAGE("Module ${MODULE_NAME} won't be built. Turn on RTTB_USE_${_package} if you want to use it.") SET(MODULE_IS_ENABLED 0) ENDIF() ENDFOREACH() IF(MODULE_IS_ENABLED) SET(MODULE_IS_ENABLED 1) _RTTB_CREATE_MODULE_CONF() IF(NOT MODULE_EXPORT_DEFINE) SET(MODULE_EXPORT_DEFINE ${MODULE_NAME}_EXPORT) ENDIF(NOT MODULE_EXPORT_DEFINE) CONFIGURE_FILE(${RTToolbox_SOURCE_DIR}/cmake/moduleExports.h.in ${RTTB_MODULES_CONF_DIR}/${MODULE_NAME}Exports.h @ONLY) SET(DEPENDS "${MODULE_DEPENDS}") SET(DEPENDS_BEFORE "not initialized") SET(PACKAGE_DEPENDS "${MODULE_PACKAGE_DEPENDS}") RTTB_USE_MODULE("${MODULE_DEPENDS}") # ok, now create the module itself INCLUDE_DIRECTORIES(. ${ALL_INCLUDE_DIRECTORIES}) INCLUDE(files.cmake) ORGANIZE_SOURCES(SOURCE ${CPP_FILES} HEADER ${H_FILES} TXX ${TXX_FILES} DOC ${DOX_FILES} ) IF(MODULE_FORCE_STATIC) SET(_STATIC ${RTTB_WIN32_FORCE_STATIC}) ENDIF(MODULE_FORCE_STATIC) IF(NOT MODULE_HEADERS_ONLY) IF(ALL_LIBRARY_DIRS) # LINK_DIRECTORIES applies only to targets which are added after the call to LINK_DIRECTORIES LINK_DIRECTORIES(${ALL_LIBRARY_DIRS}) ENDIF(ALL_LIBRARY_DIRS) SET(coverage_sources ${CPP_FILES} ${H_FILES} ${TXX_FILES}) SET_PROPERTY(SOURCE ${coverage_sources} APPEND PROPERTY LABELS ${MODULE_SUBPROJECTS}) ADD_LIBRARY(${MODULE_PROVIDES} ${_STATIC} ${coverage_sources} ${CPP_FILES_GENERATED}) SET_TARGET_PROPERTIES(${MODULE_PROVIDES} PROPERTIES ${RTToolbox_LIBRARY_PROPERTIES} OUTPUT_NAME ${MODULE_PROVIDES}-${RTToolbox_VERSION_MAJOR}.${RTToolbox_VERSION_MINOR} OUTPUT_NAME_DEBUG ${MODULE_PROVIDES}-D-${RTToolbox_VERSION_MAJOR}.${RTToolbox_VERSION_MINOR}) EXPORT(TARGETS ${MODULE_PROVIDES} APPEND FILE ${RTToolbox_TARGETS_FILE}) - INSTALL(TARGETS ${MODULE_PROVIDES} EXPORT RTToolboxExport LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) + INSTALL(TARGETS ${MODULE_PROVIDES} EXPORT RTToolboxExport + RUNTIME DESTINATION ${RTTOOLBOX_INSTALL_BIN_DIR} COMPONENT RuntimeLibraries + LIBRARY DESTINATION ${RTTOOLBOX_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries + ARCHIVE DESTINATION ${RTTOOLBOX_INSTALL_LIB_DIR} COMPONENT Development) IF(ALL_LIBRARIES) TARGET_LINK_LIBRARIES(${MODULE_PROVIDES} ${ALL_LIBRARIES}) ENDIF(ALL_LIBRARIES) ENDIF() ENDIF(MODULE_IS_ENABLED) ENDIF(_MISSING_DEP) ENDIF(NOT MODULE_IS_EXCLUDED) IF(NOT MODULE_IS_ENABLED) _RTTB_CREATE_MODULE_CONF() ENDIF(NOT MODULE_IS_ENABLED) ENDMACRO(RTTB_CREATE_MODULE) diff --git a/code/core/rttbGenericMaskedDoseIterator.h b/code/core/rttbGenericMaskedDoseIterator.h index 2af24e0..fed89b0 100644 --- a/code/core/rttbGenericMaskedDoseIterator.h +++ b/code/core/rttbGenericMaskedDoseIterator.h @@ -1,109 +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. // //------------------------------------------------------------------------ #ifndef __GENERIC_MASKED_DOSE_ITERATOR_NEW_H #define __GENERIC_MASKED_DOSE_ITERATOR_NEW_H #include #include "rttbBaseType.h" #include "rttbMaskedDoseIteratorInterface.h" #include "rttbMaskAccessorInterface.h" #include "RTTBCoreExports.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class GenericMaskedDoseIterator @brief This is a templated class representing a generic masked dose iterator for a VoxelizationPolicy. @see testing/GenericMaskedDoseIteratorTest.cpp for more information. */ class RTTBCore_EXPORT GenericMaskedDoseIterator : public MaskedDoseIteratorInterface { public: using MaskVoxelListPointer = MaskAccessorInterface::MaskVoxelListPointer; using MaskVoxelList = MaskAccessorInterface::MaskVoxelList; using MaskAccessorPointer = MaskedDoseIteratorInterface::MaskAccessorPointer; using DoseAccessorPointer = MaskedDoseIteratorInterface::DoseAccessorPointer; private: using MaskVoxelListIterator = MaskVoxelList::const_iterator; /*! The current index position of the vector _maskVoxelVec*/ MaskVoxelListIterator _currentMaskPos; /*! vector of MaskVoxel, as defined in the voxelization*/ MaskVoxelListPointer _maskVoxelVec; /*! the volume in cm^3 of the current dose voxel*/ - DoseVoxelVolumeType _currentVoxelVolume; - + DoseVoxelVolumeType _currentVoxelVolume = 0.; public: GenericMaskedDoseIterator(MaskAccessorPointer aSpMask, DoseAccessorPointer aDoseAccessor) : MaskedDoseIteratorInterface(aSpMask, aDoseAccessor) {}; /*! @brief Set the position on the first index. Use also as initialization. */ bool reset() override; /*! move to next mask position. The validity of the position is not checked here. */ void next() override; /*! @brief Volume of one voxel (in cm3) @exception InvalidParameterException if a inhomogeneous grid is defined in the dose accessors, because these grids are currently not supported. */ DoseVoxelVolumeType getCurrentVoxelVolume() const override; FractionType getCurrentRelevantVolumeFraction() const override; inline MaskVoxelListPointer getMaskVoxelVec() const { return _maskVoxelVec; }; /*! Check first if the position inside the maskedVoxelVector is valid. If so, check if the gridID at the current position in the MaskedVoxelVector is valid in the dose and mask grid. */ bool isPositionValid() const override; /*! @brief get current VoxelGridID (on dose voxel grid)*/ VoxelGridID getCurrentVoxelGridID() const override; /*! @return current dose value multiplied by current volume fraction*/ DoseTypeGy getCurrentMaskedDoseValue() const override; /*! @return current dose value without masking*/ DoseTypeGy getCurrentDoseValue() const override; }; } } #ifdef _MSC_VER #pragma warning(pop) #endif #endif diff --git a/testing/CMakeLists.txt b/testing/CMakeLists.txt index e3c392f..ec2a5cc 100644 --- a/testing/CMakeLists.txt +++ b/testing/CMakeLists.txt @@ -1,113 +1,118 @@ MESSAGE(STATUS "processing RTToolbox testing code") # Testing branch PROJECT(RTTBTesting) #----------------------------------------------------------------------------- # extract and build Litmus #----------------------------------------------------------------------------- include(ExternalProject) message(STATUS "Litmus will be automatically downloaded and built.") set(LITMUS_SOURCE_DIR "${CMAKE_BINARY_DIR}/external/Litmus-src") set(LITMUS_BUILD_DIR "${CMAKE_BINARY_DIR}/external/Litmus-build") set(LITMUS_CMAKE_DIR "${CMAKE_BINARY_DIR}/external/Litmus-cmake") IF (BUILD_Tester_All OR (BUILD_Tester_Interpolation AND BUILD_InterpolationMatchPointTransformation) OR (BUILD_Tester_IO AND BUILD_IO_ITK) OR (BUILD_Tester_Apps)) set(ENABLE_ITK "-DLIT_ENABLE_ITK_SUPPORT:BOOL=ON") set(ITK_DIRECTORY "-DITK_DIR:PATH=${ITK_DIR}") IF (RTTB_USE_SYSTEM_HDF5) set(SYSTEM_HDF5 "-DLIT_USE_SYSTEM_HDF5:BOOL=ON") set(LITMUS_HDF5_DIR "-DHDF5_DIR:PATH=${HDF5_DIR}") ENDIF() ENDIF() #extract and build Litmus ExternalProject_Add( Litmus URL ${RTToolbox_SOURCE_DIR}/utilities/Litmus/Litmus.tar.gz URL_HASH SHA1=73CE5302C35D984090B70B4A44644DA916A5E0A3 SOURCE_DIR ${LITMUS_SOURCE_DIR} BINARY_DIR ${LITMUS_BUILD_DIR} PREFIX ${LITMUS_CMAKE_DIR} INSTALL_COMMAND "" UPDATE_COMMAND "" # Don't update SVN on every build CMAKE_ARGS -DBUILD_TESTING:BOOL=OFF -DCMAKE_CXX_STANDARD=11 ${ENABLE_ITK} ${ITK_DIRECTORY} ${SYSTEM_HDF5} ${LITMUS_HDF5_DIR} ) set(RTTBDATA_DIR "${CMAKE_BINARY_DIR}/external/RTTBData") set(TEST_DATA_ROOT ${RTTBDATA_DIR}) #download RTTB data message(STATUS "RTTBdata will be automatically downloaded.") ExternalProject_Add( RTTBData SOURCE_DIR ${RTTBDATA_DIR} GIT_REPOSITORY "https://phabricator.mitk.org/source/rttb-data.git" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" ) #----------------------------------------------------------------------------- # Configure Testing branch #----------------------------------------------------------------------------- MAKE_DIRECTORY(${RTTBTesting_BINARY_DIR}/Temporary) OPTION(BUILD_Tester_All "All testing modules will be built" OFF) MESSAGE(STATUS "Process All Tests...") #----------------------------------------------------------------------------- # Include sub directories #----------------------------------------------------------------------------- OPTION(BUILD_Tester_Core "build project on/off" OFF) OPTION(BUILD_Tester_Examples "build project on/off" OFF) OPTION(BUILD_Tester_Algorithms "build project on/off" OFF) +OPTION(BUILD_Tester_Indices "build project on/off" OFF) OPTION(BUILD_Tester_Models "build project on/off" OFF) OPTION(BUILD_Tester_IO "build project on/off" OFF) OPTION(BUILD_Tester_Masks "build project on/off" OFF) OPTION(BUILD_Tester_Interpolation "build project on/off" OFF) OPTION(BUILD_Tester_Apps "build project on/off" OFF) OPTION(BUILD_Tester_Validation "build project on/off" OFF) IF(BUILD_Tester_All OR BUILD_Tester_Core) ADD_SUBDIRECTORY(core) ENDIF() IF(BUILD_Tester_All OR BUILD_Tester_Examples) ADD_SUBDIRECTORY(examples) ENDIF() IF(BUILD_Tester_All OR BUILD_Tester_Algorithms) ADD_SUBDIRECTORY(algorithms) ENDIF() +IF(BUILD_Tester_All OR BUILD_Tester_Indices) + ADD_SUBDIRECTORY(indices) +ENDIF() + IF(BUILD_Tester_All OR BUILD_Tester_Models) ADD_SUBDIRECTORY(models) ENDIF() IF(BUILD_Tester_All OR BUILD_Tester_IO) ADD_SUBDIRECTORY(io) ENDIF() IF(BUILD_Tester_All OR BUILD_Tester_Masks) ADD_SUBDIRECTORY(masks) ENDIF() IF(BUILD_Tester_All OR BUILD_Tester_Interpolation) ADD_SUBDIRECTORY(interpolation) ENDIF() IF(BUILD_Tester_All OR BUILD_Tester_Validation) ADD_SUBDIRECTORY(validation) ENDIF() IF(BUILD_Tester_All OR BUILD_Tester_Apps) ADD_SUBDIRECTORY(apps) ENDIF() diff --git a/testing/core/DVHCalculatorTest.cpp b/testing/core/DVHCalculatorTest.cpp index 53f1d7f..cd973b1 100644 --- a/testing/core/DVHCalculatorTest.cpp +++ b/testing/core/DVHCalculatorTest.cpp @@ -1,148 +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. // //------------------------------------------------------------------------ // 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 "rttbGeometricInfo.h" #include "rttbGenericDoseIterator.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "DummyDoseAccessor.h" #include "DummyMaskAccessor.h" namespace rttb { 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 1) test constructors (values as expected?) */ - int DVHCalculatorTest(int argc, char* argv[]) + 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! //generateDVH (only test basic functionality here and test it in RTTBDicomIOTests and RTTBITKIOTests) //create dummy DoseAccessor with values 0 to check if _deltaD is set to 0.1 std::vector zeros(1000, 0); core::GeometricInfo geoInfo; geoInfo.setNumColumns(10); geoInfo.setNumRows(10); geoInfo.setNumSlices(10); geoInfo.setSpacing({1.0, 1.0, 1.0}); boost::shared_ptr spTestDoseAccessorZeros = boost::make_shared(zeros, geoInfo); DoseAccessorPointer spDoseAccessorZeros(spTestDoseAccessorZeros); boost::shared_ptr spTestDoseIteratorZeros = boost::make_shared(spDoseAccessorZeros); DoseIteratorPointer spDoseIteratorZeros(spTestDoseIteratorZeros); CHECK_NO_THROW(core::DVHCalculator myDVHCalc2(spDoseIteratorZeros, structureID, doseID, 0, numBins)); core::DVHCalculator myDVHCalc2(spDoseIteratorZeros, structureID, doseID, 0, numBins); core::DVH::Pointer dvh; CHECK_NO_THROW(dvh = myDVHCalc2.generateDVH()); CHECK(dvh); CHECK_CLOSE(dvh->getDeltaD(), 0.1, errorConstant); //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); MaskedDoseIteratorPointer spMaskedDoseIterator(spTestMaskedDoseIterator); CHECK_NO_THROW(core::DVHCalculator myDVHCalc3(spMaskedDoseIterator, structureID, doseID)); core::DVHCalculator myDVHCalc3(spMaskedDoseIterator, structureID, doseID); CHECK_NO_THROW(dvh = myDVHCalc3.generateDVH()); CHECK(dvh); RETURN_AND_REPORT_TEST_SUCCESS; } }//end namespace testing }//end namespace rttb diff --git a/testing/core/GenericDoseIteratorTest.cpp b/testing/core/GenericDoseIteratorTest.cpp index 7894dbc..46b688e 100644 --- a/testing/core/GenericDoseIteratorTest.cpp +++ b/testing/core/GenericDoseIteratorTest.cpp @@ -1,106 +1,106 @@ // ----------------------------------------------------------------------- // 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. // //------------------------------------------------------------------------ #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbGenericDoseIterator.h" #include "DummyDoseAccessor.h" #include "DummyInhomogeneousDoseAccessor.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace testing { typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; /*! @brief GenericDoseIteratorTest - test the API of GenericDoseIterator 1) test constructor (values as expected?) 2) test reset/next/get current values/isPositionValid 3) test DoseIteratorInterface functions */ - int GenericDoseIteratorTest(int argc, char* argv[]) + int GenericDoseIteratorTest(int /*argc*/, char* /*argv*/[]) { PREPARE_DEFAULT_TEST_REPORTING; //create dummy DoseAccessor boost::shared_ptr spTestDoseAccessor = boost::make_shared(); DoseAccessorPointer spDoseAccessor(spTestDoseAccessor); boost::shared_ptr spTestDoseAccessorInhomo = boost::make_shared(); DoseAccessorPointer spDoseAccessorInhomo(spTestDoseAccessorInhomo); //1) test constructor (values as expected?) CHECK_NO_THROW(core::GenericDoseIterator genDoseIterator(spDoseAccessor)); core::GenericDoseIterator genDoseIterator(spDoseAccessor); const VoxelGridID defaultDoseVoxelGridID = 0; const DoseVoxelVolumeType defaultVoxelVolume = 0; CHECK_EQUAL(defaultDoseVoxelGridID, genDoseIterator.getCurrentVoxelGridID()); CHECK_EQUAL(defaultVoxelVolume, genDoseIterator.getCurrentVoxelVolume()); core::GenericDoseIterator genDoseIteratorInhomo(spDoseAccessorInhomo); //2) test reset/next genDoseIterator.reset(); const DoseVoxelVolumeType homogeneousVoxelVolume = genDoseIterator.getCurrentVoxelVolume(); CHECK_EQUAL(defaultDoseVoxelGridID, genDoseIterator.getCurrentVoxelGridID()); CHECK(!(defaultVoxelVolume == genDoseIterator.getCurrentVoxelVolume())); core::GeometricInfo geoInfo = spTestDoseAccessor->getGeometricInfo(); SpacingVectorType3D spacing = geoInfo.getSpacing(); CHECK_EQUAL(spacing(0)*spacing(1)*spacing(2) / 1000, genDoseIterator.getCurrentVoxelVolume()); CHECK_THROW_EXPLICIT(genDoseIteratorInhomo.reset(), core::InvalidParameterException); //check if the correct voxels are accessed const std::vector* doseVals = spTestDoseAccessor->getDoseVector(); genDoseIterator.reset(); VoxelGridID position = 0; while (genDoseIterator.isPositionValid()) { CHECK_EQUAL(genDoseIterator.getCurrentDoseValue(), doseVals->at(position)); CHECK_EQUAL(homogeneousVoxelVolume, genDoseIterator.getCurrentVoxelVolume()); CHECK_EQUAL(1, genDoseIterator.getCurrentRelevantVolumeFraction()); CHECK_EQUAL(position, genDoseIterator.getCurrentVoxelGridID()); genDoseIterator.next(); position++; } CHECK_EQUAL(spTestDoseAccessor->getGridSize(), spTestDoseAccessor->getGeometricInfo().getNumberOfVoxels()); //check isPositionValid() in invalid positions CHECK(!(genDoseIterator.isPositionValid())); //after end of dose CHECK_EQUAL(genDoseIterator.getCurrentDoseValue(), 0); genDoseIterator.reset(); CHECK_EQUAL(defaultDoseVoxelGridID, genDoseIterator.getCurrentVoxelGridID()); CHECK(genDoseIterator.isPositionValid());//before start of dose //3) test DoseIteratorInterface functions CHECK_EQUAL(genDoseIterator.getVoxelizationID(), ""); CHECK_EQUAL(genDoseIterator.getDoseUID(), spTestDoseAccessor->getUID()); CHECK_THROW_EXPLICIT(genDoseIteratorInhomo.getCurrentVoxelVolume(), core::InvalidParameterException); RETURN_AND_REPORT_TEST_SUCCESS; } }//end namespace testing }//end namespace rttb diff --git a/testing/core/GenericMaskedDoseIteratorTest.cpp b/testing/core/GenericMaskedDoseIteratorTest.cpp index 6ba9097..8ffb148 100644 --- a/testing/core/GenericMaskedDoseIteratorTest.cpp +++ b/testing/core/GenericMaskedDoseIteratorTest.cpp @@ -1,137 +1,137 @@ // ----------------------------------------------------------------------- // 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. // //------------------------------------------------------------------------ #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbGenericMaskedDoseIterator.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "rttbException.h" #include "DummyDoseAccessor.h" #include "DummyInhomogeneousDoseAccessor.h" #include "DummyMaskAccessor.h" namespace rttb { namespace testing { typedef core::GenericMaskedDoseIterator::MaskAccessorPointer MaskAccessorPointer; typedef core::GenericMaskedDoseIterator::DoseAccessorPointer DoseAccessorPointer; /*! @brief GenericMaskedDoseIteratorTest. 1) test constructor (values as expected?) 2) test reset/next/get current values/isPositionValid */ - int GenericMaskedDoseIteratorTest(int argc, char* argv[]) + int GenericMaskedDoseIteratorTest(int /*argc*/, char* /*argv*/[]) { PREPARE_DEFAULT_TEST_REPORTING; boost::shared_ptr spTestDoseAccessor = boost::make_shared(); DoseAccessorPointer spDoseAccessor(spTestDoseAccessor); boost::shared_ptr spTestDoseAccessorInhomo = boost::make_shared(); DoseAccessorPointer spDoseAccessorInhomo(spTestDoseAccessorInhomo); const std::vector* doseVals = spTestDoseAccessor->getDoseVector(); core::GeometricInfo geoInfo; boost::shared_ptr spTestMaskAccessor = boost::make_shared (geoInfo); MaskAccessorPointer spMaskAccessor(spTestMaskAccessor); //1) test constructor (values as expected?) //not nullptr MaskAccessorPointer spNullMaskAccessor; DoseAccessorPointer spNullDoseAccessor; CHECK_THROW_EXPLICIT(core::GenericMaskedDoseIterator genMaskedDoseIterator(spNullMaskAccessor, spDoseAccessor), core::NullPointerException); CHECK_THROW_EXPLICIT(core::GenericMaskedDoseIterator genMaskedDoseIterator(spMaskAccessor, spNullDoseAccessor), core::NullPointerException); //not same core::GeometricInfo CHECK_THROW_EXPLICIT(core::GenericMaskedDoseIterator genMaskedDoseIterator(spMaskAccessor, spDoseAccessor), core::Exception); //set correct GeometricInfo geoInfo = spDoseAccessor->getGeometricInfo(); boost::shared_ptr spTestMaskAccessor1 = boost::make_shared (geoInfo); MaskAccessorPointer spMaskAccessorTemp(spTestMaskAccessor1); spMaskAccessor.swap(spMaskAccessorTemp); CHECK_NO_THROW(core::GenericMaskedDoseIterator genMaskedDoseIterator(spMaskAccessor, spDoseAccessor)); CHECK_EQUAL(spMaskAccessor->isGridHomogeneous(), true); core::GenericMaskedDoseIterator genMaskedDoseIterator(spMaskAccessor, spDoseAccessor); core::GenericMaskedDoseIterator genMaskedDoseIteratorInhomo(spMaskAccessor, spDoseAccessorInhomo); //2) test reset/next const DummyMaskAccessor::MaskVoxelListPointer maskedVoxelListPtr = spTestMaskAccessor1->getRelevantVoxelVector(); genMaskedDoseIterator.reset(); const DoseVoxelVolumeType homogeneousVoxelVolume = genMaskedDoseIterator.getCurrentVoxelVolume(); CHECK_EQUAL((maskedVoxelListPtr->begin())->getVoxelGridID(), genMaskedDoseIterator.getCurrentVoxelGridID()); geoInfo = spDoseAccessor->getGeometricInfo(); SpacingVectorType3D spacing = geoInfo.getSpacing(); CHECK_EQUAL(spacing(0)*spacing(1)*spacing(2) / 1000, genMaskedDoseIterator.getCurrentVoxelVolume()); CHECK_THROW_EXPLICIT(genMaskedDoseIteratorInhomo.getCurrentVoxelVolume(), core::InvalidParameterException); genMaskedDoseIterator.reset(); for (unsigned int i = 0; i < maskedVoxelListPtr->size(); i++) { CHECK_NO_THROW(genMaskedDoseIterator.next()); } CHECK_EQUAL(genMaskedDoseIterator.getCurrentRelevantVolumeFraction(), 0); //check if the correct voxels are accessed genMaskedDoseIterator.reset(); VoxelGridID defaultDoseVoxelGridID = genMaskedDoseIterator.getCurrentVoxelGridID(); DoseTypeGy controlValue = 0; VoxelGridID position = 0; while (genMaskedDoseIterator.isPositionValid()) { controlValue = doseVals->at((maskedVoxelListPtr->at(position)).getVoxelGridID()); CHECK_EQUAL(controlValue, genMaskedDoseIterator.getCurrentDoseValue()); controlValue = controlValue * (maskedVoxelListPtr->at(position)).getRelevantVolumeFraction(); CHECK_EQUAL(controlValue, genMaskedDoseIterator.getCurrentMaskedDoseValue()); CHECK_EQUAL(homogeneousVoxelVolume, genMaskedDoseIterator.getCurrentVoxelVolume()); CHECK_EQUAL((maskedVoxelListPtr->at(position)).getRelevantVolumeFraction(), genMaskedDoseIterator.getCurrentRelevantVolumeFraction()); CHECK_EQUAL((maskedVoxelListPtr->at(position)).getVoxelGridID(), genMaskedDoseIterator.getCurrentVoxelGridID()); CHECK(genMaskedDoseIterator.isPositionValid()); genMaskedDoseIterator.next(); position++; } //check isPositionValid() in invalid positions CHECK(!(genMaskedDoseIterator.isPositionValid())); //after end of dose genMaskedDoseIterator.reset(); CHECK_EQUAL(defaultDoseVoxelGridID, genMaskedDoseIterator.getCurrentVoxelGridID()); CHECK(genMaskedDoseIterator.isPositionValid());//at start of dose RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/core/GeometricInfoTest.cpp b/testing/core/GeometricInfoTest.cpp index 70b2f75..5e35dfc 100644 --- a/testing/core/GeometricInfoTest.cpp +++ b/testing/core/GeometricInfoTest.cpp @@ -1,555 +1,555 @@ // ----------------------------------------------------------------------- // 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. // //------------------------------------------------------------------------ #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbGeometricInfo.h" namespace rttb { namespace testing { /*!@brief GeometricInfoTest - test the API of GeometricInfo @note ITK pixel indexing: Index[0] = col, Index[1] = row, Index[2] = slice. 1) test default constructor (values as expected?) 2) test set/getImagePositionPatient 4) test set/getSpacing 5) test set/getNumColumns/Rows/Slices 6) test get/setOrientationMatrix 8) test operators "==" 9) test equalsAlmost 10) test world to index coordinate conversion 11) test isInside and index to world coordinate conversion 12) test with simple Geometry: isInside, continuousIndexToWorldCoordinate(), worldCoordinateToContinuousIndex(), indexToWorldCoordinate() 13) test getNumberOfVoxels 14) Test convert, validID and validIndex */ - int GeometricInfoTest(int argc, char* argv[]) + int GeometricInfoTest(int /*argc*/, char* /*argv*/[]) { PREPARE_DEFAULT_TEST_REPORTING; //1) test default constructor (values as expected?) CHECK_NO_THROW(core::GeometricInfo()); core::GeometricInfo geoInfo; SpacingVectorType3D testNullSV(0); WorldCoordinate3D testNullWC(0); OrientationMatrix testNullOM(0); CHECK_EQUAL(testNullSV, geoInfo.getSpacing()); CHECK_EQUAL(testNullWC, geoInfo.getImagePositionPatient()); CHECK_EQUAL(testNullOM, geoInfo.getOrientationMatrix()); //2) test set/getImagePositionPatient WorldCoordinate3D testIPP(1.2, 3.4, 5.6); CHECK_NO_THROW(geoInfo.setImagePositionPatient(testIPP)); geoInfo.setImagePositionPatient(testIPP); CHECK_EQUAL(testIPP, geoInfo.getImagePositionPatient()); //4) test set/getSpacing //negative spacing does not make sense! /*!@is related to #2028 Should SpacingTypeVector/GridVolumeType/OrientationMatrix be forced to be non-negative?*/ SpacingVectorType3D expectedSpacing(4.15, 2.35, 100); expectedSpacing(0) = 4.15; expectedSpacing(1) = 2.35; expectedSpacing(2) = 100; CHECK_NO_THROW(geoInfo.setSpacing(expectedSpacing)); geoInfo.setSpacing(expectedSpacing); CHECK_EQUAL(expectedSpacing, geoInfo.getSpacing()); //5) test set/getNumColumns/Rows/Slices const VoxelGridIndex3D expectedVoxelDims(10, 5, 3); //CHECK_THROW(geoInfo.setNumColumns(1.2)); -> implicit conversion will prevent exception CHECK_NO_THROW(geoInfo.setNumColumns(expectedVoxelDims(0))); geoInfo.setNumColumns(expectedVoxelDims(0)); CHECK_NO_THROW(geoInfo.setNumRows(expectedVoxelDims(1))); geoInfo.setNumRows(expectedVoxelDims(1)); //CHECK_THROW(geoInfo.setNumSlices(4.2)); -> implicit conversion will prevent exception CHECK_NO_THROW(geoInfo.setNumSlices(expectedVoxelDims(2))); geoInfo.setNumSlices(expectedVoxelDims(2)); ImageSize rttbSize = geoInfo.getImageSize(); CHECK_EQUAL(rttbSize(0), geoInfo.getNumColumns()); CHECK_EQUAL(rttbSize(1), geoInfo.getNumRows()); CHECK_EQUAL(rttbSize(2), geoInfo.getNumSlices()); rttbSize = ImageSize(11, 99, 6); core::GeometricInfo geoInfo3; geoInfo3.setImageSize(rttbSize); CHECK_EQUAL(rttbSize(0), geoInfo3.getNumColumns()); CHECK_EQUAL(rttbSize(1), geoInfo3.getNumRows()); CHECK_EQUAL(rttbSize(2), geoInfo3.getNumSlices()); //6) test get/setOrientationMatrix CHECK_EQUAL(testNullOM, geoInfo.getOrientationMatrix()); OrientationMatrix testOM(0); const WorldCoordinate3D testIORow(5.5, 4.7, 3.2); const WorldCoordinate3D testIOColumn(2.5, 1.8, 9.1); WorldCoordinate3D ortho = testIORow.cross(testIOColumn); testOM(0, 0) = testIORow(0); testOM(1, 0) = testIORow(1); testOM(2, 0) = testIORow(2); CHECK_NO_THROW(geoInfo.setOrientationMatrix(testOM)); geoInfo.setOrientationMatrix(testOM); CHECK_EQUAL(testOM, geoInfo.getOrientationMatrix()); testOM(0, 1) = testIOColumn(0); testOM(1, 1) = testIOColumn(1); testOM(2, 1) = testIOColumn(2); CHECK_NO_THROW(geoInfo.setOrientationMatrix(testOM)); geoInfo.setOrientationMatrix(testOM); CHECK_EQUAL(testOM, geoInfo.getOrientationMatrix()); testOM(0, 2) = ortho(0); testOM(1, 2) = ortho(1); testOM(2, 2) = ortho(2); CHECK_NO_THROW(geoInfo.setOrientationMatrix(testOM)); geoInfo.setOrientationMatrix(testOM); CHECK_EQUAL(testOM, geoInfo.getOrientationMatrix()); //8) test operators "==" core::GeometricInfo geoInfo2; CHECK_EQUAL(geoInfo, geoInfo); CHECK(!(geoInfo == geoInfo2)); CHECK_EQUAL(geoInfo.getOrientationMatrix(), testOM); CHECK(!(geoInfo.getOrientationMatrix() == testNullOM)); //9) test equalsALmost OrientationMatrix testOM2 = testOM; SpacingVectorType3D testSPV2 = expectedSpacing; WorldCoordinate3D testIPP2 = testIPP; core::GeometricInfo testGI2, testGIEmpty; testGI2.setImagePositionPatient(testIPP2); testGI2.setOrientationMatrix(testOM2); testGI2.setSpacing(testSPV2); double smallValue = 0.000000001; testOM(0, 0) += smallValue; testSPV2(2) += smallValue; testIPP2(1) += smallValue; core::GeometricInfo testGI2similar; testGI2similar.setImagePositionPatient(testIPP2); testGI2similar.setOrientationMatrix(testOM2); testGI2similar.setSpacing(testSPV2); CHECK_EQUAL(testGI2.equalsAlmost(testGI2similar), true); CHECK_EQUAL(testGI2similar.equalsAlmost(testGI2), true); CHECK_EQUAL(testGI2.equalsAlmost(testGI2similar, smallValue * 0.001), false); CHECK_EQUAL(testGIEmpty.equalsAlmost(testGI2), false); CHECK_EQUAL(testGI2.equalsAlmost(testGIEmpty), false); //10) test world to index coordinate conversion //use unit matrix as orientation matrix CHECK_NO_THROW(geoInfo.setOrientationMatrix(OrientationMatrix())); //origin (inside) WorldCoordinate3D insideTestWC1 = geoInfo.getImagePositionPatient(); //inside const VoxelGridIndex3D expectedIndex(8, 3, 2); WorldCoordinate3D insideTestWC2(expectedIndex(0)*expectedSpacing(0) + testIPP(0), expectedIndex(1)*expectedSpacing(1) + testIPP(1), expectedIndex(2)*expectedSpacing(2) + testIPP(2)); //outside WorldCoordinate3D insideTestWC3(-33.12, 0, 14); // outside (dimension of grid) WorldCoordinate3D insideTestWC4(expectedVoxelDims(0)*expectedSpacing(0) + testIPP(0), expectedVoxelDims(1)*expectedSpacing(1) + testIPP(1), expectedVoxelDims(2)*expectedSpacing(2) + testIPP(2)); CHECK(geoInfo.isInside(insideTestWC1)); CHECK(geoInfo.isInside(insideTestWC2)); CHECK(!(geoInfo.isInside(insideTestWC3))); CHECK(!(geoInfo.isInside(insideTestWC4))); VoxelGridIndex3D testConvert(0); CHECK(geoInfo.worldCoordinateToIndex(insideTestWC1, testConvert)); CHECK(geoInfo.isInside(testConvert)); CHECK_EQUAL(VoxelGridIndex3D(0), testConvert); CHECK(geoInfo.worldCoordinateToIndex(insideTestWC2, testConvert)); CHECK(geoInfo.isInside(testConvert)); CHECK_EQUAL(expectedIndex, testConvert); CHECK(!(geoInfo.worldCoordinateToIndex(insideTestWC3, testConvert))); //CHECK_EQUAL(VoxelGridIndex3D(0),testConvert); //if value is in a negative grid position it will be converted //to a very large unrelated number. CHECK(!(geoInfo.isInside(testConvert))); CHECK(!(geoInfo.worldCoordinateToIndex(insideTestWC4, testConvert))); CHECK_EQUAL(expectedVoxelDims, testConvert); CHECK(!(geoInfo.isInside(testConvert))); //use a more complicated orientation matrix OrientationMatrix newOrientation(0); newOrientation(0, 0) = 0.5; newOrientation(1, 2) = -3; newOrientation(2, 1) = 1; CHECK_NO_THROW(geoInfo.setOrientationMatrix(newOrientation)); testIPP = WorldCoordinate3D(20, 100, -1000); CHECK_NO_THROW(geoInfo.setImagePositionPatient(testIPP)); CHECK_NO_THROW(geoInfo.setSpacing(SpacingVectorType3D(1))); //values for testing were generated with a dedicated MeVisLab routine insideTestWC1 = geoInfo.getImagePositionPatient(); //origin (inside) const VoxelGridIndex3D expectedIndexWC1(0, 0, 0); insideTestWC2 = WorldCoordinate3D(22.5, 97, -998); //inside const VoxelGridIndex3D expectedIndexWC2(5, 2, 1); insideTestWC3 = WorldCoordinate3D(26, 88, -996); //outside const VoxelGridIndex3D expectedIndexWC3(12, 4, 4); insideTestWC4 = WorldCoordinate3D(25, 91, -995); // outside: Grid dimension = [10,5,3] const VoxelGridIndex3D expectedIndexWC4(10, 5, 3); CHECK(geoInfo.isInside(insideTestWC1)); CHECK_EQUAL(geoInfo.isInside(insideTestWC1), geoInfo.isInside(expectedIndexWC1)); CHECK(geoInfo.isInside(insideTestWC2)); CHECK_EQUAL(geoInfo.isInside(insideTestWC2), geoInfo.isInside(expectedIndexWC2)); CHECK(!(geoInfo.isInside(insideTestWC3))); CHECK_EQUAL(geoInfo.isInside(insideTestWC3), geoInfo.isInside(expectedIndexWC3)); CHECK(!(geoInfo.isInside(insideTestWC4))); CHECK_EQUAL(geoInfo.isInside(insideTestWC4), geoInfo.isInside(expectedIndexWC4)); CHECK(geoInfo.worldCoordinateToIndex(insideTestWC1, testConvert)); CHECK(geoInfo.isInside(testConvert)); CHECK_EQUAL(expectedIndexWC1, testConvert); CHECK(geoInfo.worldCoordinateToIndex(insideTestWC2, testConvert)); CHECK(geoInfo.isInside(testConvert)); CHECK_EQUAL(expectedIndexWC2, testConvert); CHECK(!(geoInfo.worldCoordinateToIndex(insideTestWC3, testConvert))); CHECK(!(geoInfo.isInside(testConvert))); CHECK_EQUAL(expectedIndexWC3, testConvert); CHECK(!(geoInfo.worldCoordinateToIndex(insideTestWC4, testConvert))); CHECK(!(geoInfo.isInside(testConvert))); CHECK_EQUAL(expectedIndexWC4, testConvert); //11) test isInside and index to world coordinate conversion //use unit matrix as orientation matrix CHECK_NO_THROW(geoInfo.setOrientationMatrix(OrientationMatrix())); VoxelGridIndex3D insideTest1(0, 0, 0); //origin (inside) VoxelGridIndex3D insideTest2(2, 3, 1); //inside VoxelGridIndex3D insideTest3(0, 6, 14); //outside VoxelGridIndex3D insideTest4 = expectedVoxelDims; // outside CHECK(geoInfo.isInside(insideTest1)); CHECK(geoInfo.isInside(insideTest2)); CHECK(!(geoInfo.isInside(insideTest3))); CHECK(!(geoInfo.isInside(insideTest4))); WorldCoordinate3D testInside(0); CHECK(geoInfo.indexToWorldCoordinate(insideTest1, testInside)); CHECK(geoInfo.isInside(testInside)); //CHECK_EQUAL(geoInfo.getImagePositionPatient(),testInside); //half voxel shift prevents equality! CHECK(geoInfo.indexToWorldCoordinate(insideTest2, testInside)); CHECK(geoInfo.isInside(testInside)); CHECK(!(geoInfo.indexToWorldCoordinate(insideTest3, testInside))); CHECK(!(geoInfo.isInside(testInside))); CHECK(!(geoInfo.indexToWorldCoordinate(insideTest4, testInside))); CHECK(!(geoInfo.isInside(testInside))); WorldCoordinate3D testWorldCoordinate; ContinuousVoxelGridIndex3D testDoubleIndex; ContinuousVoxelGridIndex3D doubleIndex1 = ContinuousVoxelGridIndex3D(0.1, 0, -0.3); const WorldCoordinate3D expectedDoubleIndex1(20.1, 100, -1000.3); ContinuousVoxelGridIndex3D doubleIndex2 = ContinuousVoxelGridIndex3D(11, 6, 15); //outside const WorldCoordinate3D expectedDoubleIndex2(31, 106, -985); ContinuousVoxelGridIndex3D doubleIndex3 = ContinuousVoxelGridIndex3D(10.1, 5.0, 3.0); // outside: Grid dimension = [10,5,3] const WorldCoordinate3D expectedDoubleIndex3(30.1, 105, -997); ContinuousVoxelGridIndex3D doubleIndex4 = ContinuousVoxelGridIndex3D(0.0, 0.0, 0.0); const WorldCoordinate3D expectedDoubleIndex4 = geoInfo.getImagePositionPatient(); //test double index to world coordinate geoInfo.continuousIndexToWorldCoordinate(doubleIndex1, testWorldCoordinate); CHECK_EQUAL(testWorldCoordinate, expectedDoubleIndex1); geoInfo.continuousIndexToWorldCoordinate(doubleIndex2, testWorldCoordinate); CHECK_EQUAL(testWorldCoordinate, expectedDoubleIndex2); geoInfo.continuousIndexToWorldCoordinate(doubleIndex3, testWorldCoordinate); CHECK_EQUAL(testWorldCoordinate, expectedDoubleIndex3); geoInfo.continuousIndexToWorldCoordinate(doubleIndex4, testWorldCoordinate); CHECK_EQUAL(testWorldCoordinate, expectedDoubleIndex4); geoInfo.worldCoordinateToContinuousIndex(expectedDoubleIndex4, testDoubleIndex); CHECK_EQUAL(testDoubleIndex, doubleIndex4); geoInfo.worldCoordinateToContinuousIndex(expectedDoubleIndex3, testDoubleIndex); CHECK_CLOSE(testDoubleIndex(0), doubleIndex3(0), errorConstant); CHECK_CLOSE(testDoubleIndex(1), doubleIndex3(1), errorConstant); CHECK_CLOSE(testDoubleIndex(2), doubleIndex3(2), errorConstant); geoInfo.worldCoordinateToContinuousIndex(expectedDoubleIndex2, testDoubleIndex); CHECK_EQUAL(testDoubleIndex, doubleIndex2); geoInfo.worldCoordinateToContinuousIndex(expectedDoubleIndex1, testDoubleIndex); CHECK_CLOSE(testDoubleIndex(0), doubleIndex1(0), errorConstant); CHECK_CLOSE(testDoubleIndex(1), doubleIndex1(1), errorConstant); CHECK_CLOSE(testDoubleIndex(2), doubleIndex1(2), errorConstant); VoxelGridIndex3D testIntIndex; geoInfo.worldCoordinateToIndex(expectedDoubleIndex4, testIntIndex); CHECK_EQUAL(testIntIndex, insideTest1); geoInfo.worldCoordinateToIndex(expectedDoubleIndex1, testIntIndex); CHECK_EQUAL(testIntIndex, insideTest1); geoInfo.worldCoordinateToIndex(expectedDoubleIndex3, testIntIndex); CHECK_EQUAL(testIntIndex, expectedVoxelDims); //use a more complicated orientation matrix newOrientation = OrientationMatrix(0); newOrientation(0, 0) = 0.5; newOrientation(1, 2) = -3; newOrientation(2, 1) = 1; CHECK_NO_THROW(geoInfo.setOrientationMatrix(newOrientation)); testIPP = WorldCoordinate3D(20, 100, -1000); CHECK_NO_THROW(geoInfo.setImagePositionPatient(testIPP)); CHECK_NO_THROW(geoInfo.setSpacing(SpacingVectorType3D(1))); //values for testing were generated with a dedicated MeVisLab routine //no half voxel shift anymore because we changed indexToWorldCoordinate/worldCoordinateToIndex insideTest1 = VoxelGridIndex3D(0, 0, 0); //origin (inside) const WorldCoordinate3D expectedIndex1(20, 100, -1000); insideTest2 = VoxelGridIndex3D(6, 0, 2); //inside const WorldCoordinate3D expectedIndex2(23, 94, -1000); insideTest3 = VoxelGridIndex3D(11, 6, 15); //outside const WorldCoordinate3D expectedIndex3(25.5, 55, -994); insideTest4 = VoxelGridIndex3D(10, 5, 3); // outside: Grid dimension = [10,5,3] const WorldCoordinate3D expectedIndex4(25, 91, -995); CHECK(geoInfo.isInside(insideTest1)); CHECK_EQUAL(geoInfo.isInside(insideTest1), geoInfo.isInside(expectedIndex1)); CHECK(geoInfo.isInside(insideTest2)); CHECK_EQUAL(geoInfo.isInside(insideTest2), geoInfo.isInside(expectedIndex2)); CHECK(!(geoInfo.isInside(insideTest3))); CHECK_EQUAL(geoInfo.isInside(insideTest3), geoInfo.isInside(expectedIndex3)); CHECK(!(geoInfo.isInside(insideTest4))); CHECK_EQUAL(geoInfo.isInside(insideTest4), geoInfo.isInside(expectedIndex4)); CHECK(geoInfo.indexToWorldCoordinate(insideTest1, testInside)); CHECK(geoInfo.isInside(testInside)); CHECK_EQUAL(expectedIndex1, testInside); CHECK(geoInfo.indexToWorldCoordinate(insideTest2, testInside)); CHECK(geoInfo.isInside(testInside)); CHECK_EQUAL(expectedIndex2, testInside); CHECK(!(geoInfo.indexToWorldCoordinate(insideTest3, testInside))); CHECK(!(geoInfo.isInside(testInside))); CHECK_EQUAL(expectedIndex3, testInside); CHECK(!(geoInfo.indexToWorldCoordinate(insideTest4, testInside))); CHECK(!(geoInfo.isInside(testInside))); CHECK_EQUAL(expectedIndex4, testInside); //12) test with simple Geometry: isInside, continuousIndexToWorldCoordinate(), worldCoordinateToContinuousIndex(), indexToWorldCoordinate() core::GeometricInfo geoInfoSimple; ImageSize rttbSimpleSize = ImageSize(10, 10, 10); geoInfoSimple.setImageSize(rttbSimpleSize); SpacingVectorType3D spacingSimple(1, 1, 1); geoInfoSimple.setSpacing(spacingSimple); OrientationMatrix OMOnes; geoInfoSimple.setOrientationMatrix(OMOnes); const ContinuousVoxelGridIndex3D doubleIndexPixelOutside1 = ContinuousVoxelGridIndex3D(-0.501, 0.0, 0.0); const ContinuousVoxelGridIndex3D doubleIndexPixelOutside2 = ContinuousVoxelGridIndex3D(0.0, 9.501, 0.0); const ContinuousVoxelGridIndex3D doubleIndexPixelZero1 = ContinuousVoxelGridIndex3D(0.0, 0.0, 0.0); const ContinuousVoxelGridIndex3D doubleIndexPixelZero2 = ContinuousVoxelGridIndex3D(-0.5, -0.5, -0.5); const ContinuousVoxelGridIndex3D doubleIndexPixelZero3 = ContinuousVoxelGridIndex3D(0.499999, 0.499999, 0.499999); const ContinuousVoxelGridIndex3D doubleIndexPixelOne1 = ContinuousVoxelGridIndex3D(1.0, 0.0, 0.0); const ContinuousVoxelGridIndex3D doubleIndexPixelOne2 = ContinuousVoxelGridIndex3D(0.5, 0.499999, 0.499999); const ContinuousVoxelGridIndex3D doubleIndexPixelOne3 = ContinuousVoxelGridIndex3D(1.49, -0.5, -0.5); const ContinuousVoxelGridIndex3D doubleIndexPixelLast1 = ContinuousVoxelGridIndex3D(9.0, 9.0, 9.0); const ContinuousVoxelGridIndex3D doubleIndexPixelLast2 = ContinuousVoxelGridIndex3D(9.4999, 9.4999, 9.4999); const ContinuousVoxelGridIndex3D doubleIndexPixelLast3 = ContinuousVoxelGridIndex3D(8.501, 8.501, 8.501); const VoxelGridIndex3D indexPixelOutside = VoxelGridIndex3D(11, 0, 0); const VoxelGridIndex3D indexPixelZero = VoxelGridIndex3D(0, 0, 0); const VoxelGridIndex3D indexPixelOne = VoxelGridIndex3D(1, 0, 0); const VoxelGridIndex3D indexPixelLast = VoxelGridIndex3D(9, 9, 9); const WorldCoordinate3D worldCoordinateOutside1(doubleIndexPixelOutside1(0), doubleIndexPixelOutside1(1), doubleIndexPixelOutside1(2)); const WorldCoordinate3D worldCoordinateOutside2(doubleIndexPixelOutside2(0), doubleIndexPixelOutside2(1), doubleIndexPixelOutside2(2)); const WorldCoordinate3D worldCoordinatePixelZero1(doubleIndexPixelZero1(0), doubleIndexPixelZero1(1), doubleIndexPixelZero1(2)); const WorldCoordinate3D worldCoordinatePixelZero2(doubleIndexPixelZero2(0), doubleIndexPixelZero2(1), doubleIndexPixelZero2(2)); const WorldCoordinate3D worldCoordinatePixelZero3(doubleIndexPixelZero3(0), doubleIndexPixelZero3(1), doubleIndexPixelZero3(2)); const WorldCoordinate3D worldCoordinatePixelOne1(doubleIndexPixelOne1(0), doubleIndexPixelOne1(1), doubleIndexPixelOne1(2)); const WorldCoordinate3D worldCoordinatePixelOne2(doubleIndexPixelOne2(0), doubleIndexPixelOne2(1), doubleIndexPixelOne2(2)); const WorldCoordinate3D worldCoordinatePixelOne3(doubleIndexPixelOne3(0), doubleIndexPixelOne3(1), doubleIndexPixelOne3(2)); const WorldCoordinate3D worldCoordinatePixelLast1(doubleIndexPixelLast1(0), doubleIndexPixelLast1(1), doubleIndexPixelLast1(2)); const WorldCoordinate3D worldCoordinatePixelLast2(doubleIndexPixelLast2(0), doubleIndexPixelLast2(1), doubleIndexPixelLast2(2)); const WorldCoordinate3D worldCoordinatePixelLast3(doubleIndexPixelLast3(0), doubleIndexPixelLast3(1), doubleIndexPixelLast3(2)); bool isInside; isInside = geoInfoSimple.continuousIndexToWorldCoordinate(doubleIndexPixelOutside1, testWorldCoordinate); CHECK(!isInside); isInside = geoInfoSimple.continuousIndexToWorldCoordinate(doubleIndexPixelOutside2, testWorldCoordinate); CHECK(!isInside); isInside = geoInfoSimple.continuousIndexToWorldCoordinate(doubleIndexPixelZero1, testWorldCoordinate); CHECK_EQUAL(testWorldCoordinate, worldCoordinatePixelZero1); CHECK(isInside); isInside = geoInfoSimple.continuousIndexToWorldCoordinate(doubleIndexPixelZero2, testWorldCoordinate); CHECK_EQUAL(testWorldCoordinate, worldCoordinatePixelZero2); CHECK(isInside); isInside = geoInfoSimple.continuousIndexToWorldCoordinate(doubleIndexPixelZero3, testWorldCoordinate); CHECK_EQUAL(testWorldCoordinate, worldCoordinatePixelZero3); CHECK(isInside); isInside = geoInfoSimple.continuousIndexToWorldCoordinate(doubleIndexPixelOne1, testWorldCoordinate); CHECK_EQUAL(testWorldCoordinate, worldCoordinatePixelOne1); CHECK(isInside); isInside = geoInfoSimple.continuousIndexToWorldCoordinate(doubleIndexPixelOne2, testWorldCoordinate); CHECK_EQUAL(testWorldCoordinate, worldCoordinatePixelOne2); CHECK(isInside); isInside = geoInfoSimple.continuousIndexToWorldCoordinate(doubleIndexPixelOne3, testWorldCoordinate); CHECK_EQUAL(testWorldCoordinate, worldCoordinatePixelOne3); CHECK(isInside); isInside = geoInfoSimple.continuousIndexToWorldCoordinate(doubleIndexPixelLast1, testWorldCoordinate); CHECK_EQUAL(testWorldCoordinate, worldCoordinatePixelLast1); CHECK(isInside); isInside = geoInfoSimple.continuousIndexToWorldCoordinate(doubleIndexPixelLast2, testWorldCoordinate); CHECK_EQUAL(testWorldCoordinate, worldCoordinatePixelLast2); CHECK(isInside); isInside = geoInfoSimple.continuousIndexToWorldCoordinate(doubleIndexPixelLast3, testWorldCoordinate); CHECK_EQUAL(testWorldCoordinate, worldCoordinatePixelLast3); CHECK(isInside); isInside = geoInfoSimple.worldCoordinateToContinuousIndex(worldCoordinateOutside1, testDoubleIndex); CHECK(!isInside); isInside = geoInfoSimple.worldCoordinateToContinuousIndex(worldCoordinateOutside2, testDoubleIndex); CHECK(!isInside); isInside = geoInfoSimple.worldCoordinateToContinuousIndex(worldCoordinatePixelZero1, testDoubleIndex); CHECK_EQUAL(testDoubleIndex, doubleIndexPixelZero1); CHECK(isInside); isInside = geoInfoSimple.worldCoordinateToContinuousIndex(worldCoordinatePixelZero2, testDoubleIndex); CHECK_EQUAL(testDoubleIndex, doubleIndexPixelZero2); CHECK(isInside); isInside = geoInfoSimple.worldCoordinateToContinuousIndex(worldCoordinatePixelZero3, testDoubleIndex); CHECK_EQUAL(testDoubleIndex, doubleIndexPixelZero3); CHECK(isInside); isInside = geoInfoSimple.worldCoordinateToContinuousIndex(worldCoordinatePixelOne1, testDoubleIndex); CHECK_EQUAL(testDoubleIndex, doubleIndexPixelOne1); CHECK(isInside); isInside = geoInfoSimple.worldCoordinateToContinuousIndex(worldCoordinatePixelOne2, testDoubleIndex); CHECK_EQUAL(testDoubleIndex, doubleIndexPixelOne2); CHECK(isInside); isInside = geoInfoSimple.worldCoordinateToContinuousIndex(worldCoordinatePixelOne3, testDoubleIndex); CHECK_EQUAL(testDoubleIndex, doubleIndexPixelOne3); CHECK(isInside); isInside = geoInfoSimple.worldCoordinateToContinuousIndex(worldCoordinatePixelLast1, testDoubleIndex); CHECK_EQUAL(testDoubleIndex, doubleIndexPixelLast1); CHECK(isInside); isInside = geoInfoSimple.worldCoordinateToContinuousIndex(worldCoordinatePixelLast2, testDoubleIndex); CHECK_EQUAL(testDoubleIndex, doubleIndexPixelLast2); CHECK(isInside); isInside = geoInfoSimple.worldCoordinateToContinuousIndex(worldCoordinatePixelLast3, testDoubleIndex); CHECK_EQUAL(testDoubleIndex, doubleIndexPixelLast3); CHECK(isInside); isInside = geoInfoSimple.indexToWorldCoordinate(indexPixelOutside, testWorldCoordinate); CHECK(!isInside); isInside = geoInfoSimple.indexToWorldCoordinate(indexPixelZero, testWorldCoordinate); CHECK(isInside); CHECK_EQUAL(testWorldCoordinate, worldCoordinatePixelZero1); isInside = geoInfoSimple.indexToWorldCoordinate(indexPixelOne, testWorldCoordinate); CHECK(isInside); CHECK_EQUAL(testWorldCoordinate, worldCoordinatePixelOne1); isInside = geoInfoSimple.indexToWorldCoordinate(indexPixelLast, testWorldCoordinate); CHECK(isInside); CHECK_EQUAL(testWorldCoordinate, worldCoordinatePixelLast1); isInside = geoInfoSimple.worldCoordinateToIndex(worldCoordinateOutside1, testIntIndex); CHECK(!isInside); isInside = geoInfoSimple.worldCoordinateToIndex(worldCoordinateOutside2, testIntIndex); CHECK(!isInside); isInside = geoInfoSimple.worldCoordinateToIndex(worldCoordinatePixelZero1, testIntIndex); CHECK(isInside); CHECK_EQUAL(testIntIndex, indexPixelZero); isInside = geoInfoSimple.worldCoordinateToIndex(worldCoordinatePixelZero2, testIntIndex); CHECK(isInside); CHECK_EQUAL(testIntIndex, indexPixelZero); isInside = geoInfoSimple.worldCoordinateToIndex(worldCoordinatePixelZero3, testIntIndex); CHECK(isInside); CHECK_EQUAL(testIntIndex, indexPixelZero); isInside = geoInfoSimple.worldCoordinateToIndex(worldCoordinatePixelOne1, testIntIndex); CHECK(isInside); CHECK_EQUAL(testIntIndex, indexPixelOne); isInside = geoInfoSimple.worldCoordinateToIndex(worldCoordinatePixelOne2, testIntIndex); CHECK(isInside); CHECK_EQUAL(testIntIndex, indexPixelOne); isInside = geoInfoSimple.worldCoordinateToIndex(worldCoordinatePixelOne3, testIntIndex); CHECK(isInside); CHECK_EQUAL(testIntIndex, indexPixelOne); isInside = geoInfoSimple.worldCoordinateToIndex(worldCoordinatePixelLast1, testIntIndex); CHECK(isInside); CHECK_EQUAL(testIntIndex, indexPixelLast); isInside = geoInfoSimple.worldCoordinateToIndex(worldCoordinatePixelLast2, testIntIndex); CHECK(isInside); CHECK_EQUAL(testIntIndex, indexPixelLast); isInside = geoInfoSimple.worldCoordinateToIndex(worldCoordinatePixelLast3, testIntIndex); CHECK(isInside); CHECK_EQUAL(testIntIndex, indexPixelLast); //13) test getNumberOfVoxels CHECK_EQUAL(expectedVoxelDims(0)*expectedVoxelDims(1)*expectedVoxelDims(2), geoInfo.getNumberOfVoxels()); //14) Test convert, validID and validIndex geoInfo.setNumColumns(50); geoInfo.setNumRows(30); geoInfo.setNumSlices(40); VoxelGridIndex3D startIndex(0, 0, 0); VoxelGridID startId(0); VoxelGridIndex3D endIndex(geoInfo.getNumColumns() - 1, geoInfo.getNumRows() - 1, geoInfo.getNumSlices() - 1); VoxelGridID endId((geoInfo.getNumColumns()*geoInfo.getNumRows()*geoInfo.getNumSlices()) - 1); VoxelGridIndex3D indexInvalid(geoInfo.getNumColumns(), geoInfo.getNumRows(), geoInfo.getNumSlices()); VoxelGridID idInvalid(geoInfo.getNumColumns()*geoInfo.getNumRows()*geoInfo.getNumSlices()); CHECK(geoInfo.validID(startId)); CHECK(geoInfo.validIndex(startIndex)); - VoxelGridIndex3D aIndex; - VoxelGridID aId; + VoxelGridIndex3D aIndex(9999999,999999,999999); + VoxelGridID aId = 99999999; CHECK(geoInfo.convert(startIndex, aId)); CHECK(geoInfo.convert(startId, aIndex)); CHECK_EQUAL(aId, startId); CHECK_EQUAL(aIndex, startIndex); CHECK(geoInfo.validID(endId)); CHECK(geoInfo.validIndex(endIndex)); CHECK(geoInfo.convert(endIndex, aId)); CHECK(geoInfo.convert(endId, aIndex)); CHECK_EQUAL(aId, endId); CHECK_EQUAL(aIndex, endIndex); CHECK(!geoInfo.validID(idInvalid)); CHECK(!geoInfo.validIndex(indexInvalid)); CHECK(!geoInfo.convert(idInvalid, aIndex)); CHECK(!geoInfo.convert(indexInvalid, aId)); RETURN_AND_REPORT_TEST_SUCCESS; } }//end namespace testing }//end namespace rttb diff --git a/testing/core/MaskVoxelTest.cpp b/testing/core/MaskVoxelTest.cpp index db593bd..f75a613 100644 --- a/testing/core/MaskVoxelTest.cpp +++ b/testing/core/MaskVoxelTest.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. // //------------------------------------------------------------------------ #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbMaskVoxel.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace testing { /*! @brief MaskVoxelTest - test the API of MaskVoxel 1) test constructors (values as expected?) 2) test set/getRelevantVolumeFraction 3) test operators "==" 4) test operator "<" */ - int MaskVoxelTest(int argc, char* argv[]) + int MaskVoxelTest(int /*argc*/, char* /*argv*/[]) { PREPARE_DEFAULT_TEST_REPORTING; //1) test constructors (values as expected?) //MaskVoxel(const VoxelGridID& aVoxelGridID); VoxelGridID anID = 5; const FractionType defaultFraction = 1; CHECK_NO_THROW(core::MaskVoxel MaskVoxel(anID)); CHECK_THROW_EXPLICIT(core::MaskVoxel MaskVoxel(-anID), core::InvalidParameterException); core::MaskVoxel aMaskVoxel2(anID); CHECK_EQUAL(anID, aMaskVoxel2.getVoxelGridID()); CHECK_EQUAL(defaultFraction, aMaskVoxel2.getRelevantVolumeFraction()); //MaskVoxel(const VoxelGridID& aVoxelGridID, FractionType aVolumeFraction) anID = 15; FractionType aFraction = 0.73; CHECK_NO_THROW(core::MaskVoxel MaskVoxel(anID, aFraction)); CHECK_THROW_EXPLICIT(core::MaskVoxel MaskVoxel(-anID, aFraction), core::InvalidParameterException); CHECK_THROW_EXPLICIT(core::MaskVoxel MaskVoxel(anID, -aFraction), core::InvalidParameterException); CHECK_THROW_EXPLICIT(core::MaskVoxel MaskVoxel(-anID, -aFraction), core::InvalidParameterException); CHECK_THROW_EXPLICIT(core::MaskVoxel MaskVoxel(anID, aFraction + 2), core::InvalidParameterException); CHECK_THROW_EXPLICIT(core::MaskVoxel MaskVoxel(-anID, aFraction + 2), core::InvalidParameterException); core::MaskVoxel aMaskVoxel3(anID, aFraction); CHECK_EQUAL(anID, aMaskVoxel3.getVoxelGridID()); CHECK_EQUAL(aFraction, aMaskVoxel3.getRelevantVolumeFraction()); //2) test set/getRelevantVolumeFraction aFraction = 0.42; anID = aMaskVoxel3.getVoxelGridID(); CHECK_NO_THROW(aMaskVoxel3.setRelevantVolumeFraction(aFraction)); CHECK_THROW_EXPLICIT(aMaskVoxel3.setRelevantVolumeFraction(-aFraction), core::InvalidParameterException); CHECK_THROW_EXPLICIT(aMaskVoxel3.setRelevantVolumeFraction(aFraction + 2), core::InvalidParameterException); aMaskVoxel3.setRelevantVolumeFraction(aFraction); CHECK_EQUAL(anID, aMaskVoxel3.getVoxelGridID()); CHECK_EQUAL(aFraction, aMaskVoxel3.getRelevantVolumeFraction()); //3) test operators "==" CHECK(!(aMaskVoxel2 == aMaskVoxel3)); //not equal core::MaskVoxel aMaskVoxel4(aMaskVoxel3.getVoxelGridID()); CHECK(!(aMaskVoxel4 == aMaskVoxel3)); //equal ID, but unequal volume fraction -> not equal aMaskVoxel4.setRelevantVolumeFraction(aMaskVoxel3.getRelevantVolumeFraction()); CHECK_EQUAL(aMaskVoxel4, aMaskVoxel3); //equal aMaskVoxel2.setRelevantVolumeFraction(aMaskVoxel3.getRelevantVolumeFraction()); CHECK(!(aMaskVoxel2 == aMaskVoxel3)); //no equal ID -> not equal //4) test operator "<" core::MaskVoxel aMaskVoxel5(2); CHECK(aMaskVoxel2 < aMaskVoxel3); CHECK(!(aMaskVoxel3 < aMaskVoxel4)); CHECK(!(aMaskVoxel4 < aMaskVoxel5)); RETURN_AND_REPORT_TEST_SUCCESS; } }//end namespace testing }//end namespace rttb diff --git a/testing/core/StructureTest.cpp b/testing/core/StructureTest.cpp index 59827e1..c5bce3a 100644 --- a/testing/core/StructureTest.cpp +++ b/testing/core/StructureTest.cpp @@ -1,132 +1,132 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbStructure.h" #include "rttbInvalidParameterException.h" #include "DummyStructure.h" #include "DummyDoseAccessor.h" namespace rttb { namespace testing { /*! @brief StructureTest - tests the API for Structure 1) constructors 2) get/setXX */ - int StructureTest(int argc, char* argv[]) + int StructureTest(int /*argc*/, char* /*argv*/[]) { PREPARE_DEFAULT_TEST_REPORTING; boost::shared_ptr spTestDoseAccessor = boost::make_shared(); DummyStructure myStructGenerator(spTestDoseAccessor->getGeometricInfo()); //1) constructors CHECK_NO_THROW(core::Structure()); core::Structure emptyTestStruct; CHECK_EQUAL("", emptyTestStruct.getLabel()); CHECK_NO_THROW(emptyTestStruct.getUID()); GridIndexType zPlane = 4; core::Structure rect = myStructGenerator.CreateRectangularStructureCentered(zPlane); CHECK_NO_THROW(core::Structure(rect.getStructureVector())); core::Structure rect2 = core::Structure(rect.getStructureVector()); CHECK_EQUAL(rect.getLabel(), rect2.getLabel()); CHECK(rect.getUID() != rect2.getUID()); PolygonSequenceType rectVec = rect.getStructureVector(); PolygonSequenceType rect2Vec = rect2.getStructureVector(); CHECK_EQUAL(rectVec.size(), rect2Vec.size()); PolygonSequenceType::iterator it = rectVec.begin(); PolygonSequenceType::iterator it2 = rect2Vec.begin(); for (; it != rectVec.end(); ++it) { CHECK_EQUAL(it->size(), it2->size()); PolygonType::iterator pit = it->begin(); PolygonType::iterator pit2 = it2->begin(); for (; pit != it->end(); ++pit) { CHECK_EQUAL(*(pit), *(pit2)); ++pit2; } ++it2; } CHECK_NO_THROW(core::Structure rect3 = rect); core::Structure rect3 = rect; CHECK_EQUAL(rect.getLabel(), rect3.getLabel()); CHECK_EQUAL(rect.getUID(), rect3.getUID()); PolygonSequenceType rect3Vec = rect3.getStructureVector(); CHECK_EQUAL(rectVec.size(), rect3Vec.size()); it = rectVec.begin(); PolygonSequenceType::iterator it3 = rect3Vec.begin(); for (; it != rectVec.end(); ++it) { CHECK_EQUAL(it->size(), it3->size()); PolygonType::iterator pit = it->begin(); PolygonType::iterator pit3 = it3->begin(); for (; pit != it->end(); ++pit) { CHECK_EQUAL(*(pit), *(pit3)); ++pit3; } ++it3; } //2) get/setXX CHECK_EQUAL("", emptyTestStruct.getLabel()); CHECK_NO_THROW(emptyTestStruct.setLabel("NEW Label")); CHECK_EQUAL("NEW Label", emptyTestStruct.getLabel()); CHECK_NO_THROW(emptyTestStruct.getUID()); CHECK_NO_THROW(emptyTestStruct.setUID("1.2.345.67.8.9")); CHECK_EQUAL("1.2.345.67.8.9", emptyTestStruct.getUID()); CHECK((emptyTestStruct.getStructureVector()).empty()); CHECK_EQUAL(0, emptyTestStruct.getNumberOfEndpoints()); CHECK_EQUAL(4, rect.getNumberOfEndpoints()); CHECK_EQUAL(rect.getNumberOfEndpoints(), rect2.getNumberOfEndpoints()); core::Structure circ = myStructGenerator.CreateTestStructureCircle(zPlane); CHECK_EQUAL(4004, circ.getNumberOfEndpoints()); core::Structure multiPoly = myStructGenerator.CreateTestStructureIntersectingTwoPolygonsInDifferentSlices(zPlane, zPlane + 1); CHECK_EQUAL(8, multiPoly.getNumberOfEndpoints()); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/examples/CMakeLists.txt b/testing/examples/CMakeLists.txt index 9a19d08..b66d7d1 100644 --- a/testing/examples/CMakeLists.txt +++ b/testing/examples/CMakeLists.txt @@ -1,26 +1,23 @@ #----------------------------------------------------------------------------- # Setup the system information test. Write out some basic failsafe # information in case the test doesn't run. #----------------------------------------------------------------------------- SET(CORE_TEST_EXAMPLES ${EXECUTABLE_OUTPUT_PATH}/${RTToolbox_PREFIX}ExamplesTests) SET(TEMP ${RTTBTesting_BINARY_DIR}/Temporary) #----------------------------------------------------------------------------- ADD_TEST(RTBioModelExampleTest ${CORE_TEST_EXAMPLES} RTBioModelExampleTest "${TEST_DATA_ROOT}/DVH/XML/dvh_PTV_HIT.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT1.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT2.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT3.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_TV.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_virtuos_diff_trunk6.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_virtuos_diff_trunk8.xml") -ADD_TEST(RTDoseIndexTest ${CORE_TEST_EXAMPLES} RTDoseIndexTest -"${TEST_DATA_ROOT}/DVH/XML/dvh_test_TV.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT1.xml" -"${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT2.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT3.xml") ADD_TEST(RTDoseStatisticsDicomTest ${CORE_TEST_EXAMPLES} RTDoseStatisticsDicomTest "${TEST_DATA_ROOT}/Dose/DICOM/ConstantTwo_withDoseGridScaling.dcm") ADD_TEST(RTDVHTest ${CORE_TEST_EXAMPLES} RTDVHTest "${TEST_DATA_ROOT}/DVH/XML/dvh_test.xml") ADD_TEST(RTBioModelScatterPlotExampleTest ${CORE_TEST_EXAMPLES} RTBioModelScatterPlotExampleTest "${TEST_DATA_ROOT}/DVH/XML/dvh_PTV_HIT.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT1.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_TV.xml") RTTB_CREATE_TEST_MODULE(Examples DEPENDS RTTBCore RTTBAlgorithms RTTBMask RTTBIndices RTTBDicomIO RTTBITKIO RTTBOtherIO RTTBModels PACKAGE_DEPENDS Litmus RTTBData) diff --git a/testing/examples/files.cmake b/testing/examples/files.cmake index f071ff8..f68aff8 100644 --- a/testing/examples/files.cmake +++ b/testing/examples/files.cmake @@ -1,13 +1,12 @@ SET(CPP_FILES RTBioModelExampleTest.cpp RTBioModelScatterPlotExampleTest.cpp - RTDoseIndexTest.cpp RTDoseStatisticsDicomTest.cpp RTDVHTest.cpp ../models/rttbScatterTester.cpp rttbTestExamples.cpp ) SET(H_FILES ../models/rttbScatterTester.h ) diff --git a/testing/indices/CMakeLists.txt b/testing/indices/CMakeLists.txt new file mode 100644 index 0000000..bfe301b --- /dev/null +++ b/testing/indices/CMakeLists.txt @@ -0,0 +1,32 @@ +#----------------------------------------------------------------------------- +# Setup the system information test. Write out some basic failsafe +# information in case the test doesn't run. +#----------------------------------------------------------------------------- + + +SET(INDICES_TESTS ${EXECUTABLE_OUTPUT_PATH}/${RTToolbox_PREFIX}IndicesTests) +SET(INDICES_HEADER_TEST ${EXECUTABLE_OUTPUT_PATH}/${RTToolbox_PREFIX}CoreIndicesTest) + +SET(TEMP ${RTTBTesting_BINARY_DIR}/temporary) + +#----------------------------------------------------------------------------- +ADD_TEST(ConformationNumberTest ${INDICES_TESTS} ConformationNumberTest +"${TEST_DATA_ROOT}/DVH/XML/dvh_test_TV.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT1.xml" +"${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT2.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT3.xml") +ADD_TEST(ConformalIndexTest ${INDICES_TESTS} ConformalIndexTest +"${TEST_DATA_ROOT}/DVH/XML/dvh_test_TV.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT1.xml" +"${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT2.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT3.xml") +ADD_TEST(ConformityIndexTest ${INDICES_TESTS} ConformityIndexTest +"${TEST_DATA_ROOT}/DVH/XML/dvh_test_TV.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT1.xml" +"${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT2.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT3.xml") +ADD_TEST(CoverageIndexTest ${INDICES_TESTS} CoverageIndexTest +"${TEST_DATA_ROOT}/DVH/XML/dvh_test_TV.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT1.xml" +"${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT2.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT3.xml") +ADD_TEST(HomogeneityIndexTest ${INDICES_TESTS} HomogeneityIndexTest +"${TEST_DATA_ROOT}/DVH/XML/dvh_test_TV.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT1.xml" +"${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT2.xml" "${TEST_DATA_ROOT}/DVH/XML/dvh_test_HT3.xml") + +RTTB_CREATE_TEST_MODULE(Indices DEPENDS RTTBCore RTTBIndices RTTBOtherIO PACKAGE_DEPENDS Boost Litmus) + + + diff --git a/testing/examples/RTDoseIndexTest.cpp b/testing/indices/ConformalIndexTest.cpp similarity index 58% copy from testing/examples/RTDoseIndexTest.cpp copy to testing/indices/ConformalIndexTest.cpp index 35899fc..17f2082 100644 --- a/testing/examples/RTDoseIndexTest.cpp +++ b/testing/indices/ConformalIndexTest.cpp @@ -1,202 +1,139 @@ -// ----------------------------------------------------------------------- -// 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. -// -//------------------------------------------------------------------------ - -// this file defines the rttbCoreTests for the test driver -// and all it expects is that you have a function called RegisterTests - -#include "litCheckMacros.h" -#include "rttbDoseIndex.h" -#include "rttbDVHSet.h" -#include "rttbBaseType.h" -#include "rttbNullPointerException.h" -#include "rttbConformalIndex.h" -#include "rttbConformationNumber.h" -#include "rttbConformityIndex.h" -#include "rttbCoverageIndex.h" -#include "rttbHomogeneityIndex.h" -#include "rttbException.h" -#include "rttbInvalidParameterException.h" -#include "rttbDVHXMLFileReader.h" - -#include - -#include -#include - -namespace rttb -{ - namespace testing - { - /*! @brief DoseIndexTest. ConformationNumber ConformalIndex ConformityIndex CoverageIndex HomogeneityIndex are tested. - test dvh: deltaV 0.125, deltaD 0.5 - 1. dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133 - 2. dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40 - 3. dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50 - 4. dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70 - - 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 RTDoseIndexTest(int argc, char* argv[]) - { - PREPARE_DEFAULT_TEST_REPORTING; - - //ARGUMENTS: 1: ptv dvh file name - // 2: normal tissue 1 dvh file name - // 3: normal tissue 2 dvh file name - // 4: normal tissue 3 dvh file name - - std::string DVH_FILENAME_PTV; - std::string DVH_FILENAME_NT1; - std::string DVH_FILENAME_NT2; - std::string DVH_FILENAME_NT3; - - - if (argc > 1) - { - DVH_FILENAME_PTV = argv[1]; - } - - if (argc > 2) - { - DVH_FILENAME_NT1 = argv[2]; - } - - if (argc > 3) - { - DVH_FILENAME_NT2 = argv[3]; - } - - if (argc > 4) - { - DVH_FILENAME_NT3 = argv[4]; - } - - - /*test dvh: deltaV 0.125, deltaD 0.5*/ - /*dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133*/ - rttb::io::other::DVHXMLFileReader dvhReader = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_PTV); - rttb::core::DVH dvhPTV = *(dvhReader.generateDVH()); - /*dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40*/ - rttb::io::other::DVHXMLFileReader dvhReader1 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT1); - core::DVH dvhNT1 = *(dvhReader1.generateDVH()); - /*dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50*/ - rttb::io::other::DVHXMLFileReader dvhReader2 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT2); - core::DVH dvhNT2 = *(dvhReader2.generateDVH()); - /*dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70*/ - rttb::io::other::DVHXMLFileReader dvhReader3 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT3); - core::DVH dvhNT3 = *(dvhReader3.generateDVH()); - - std::vector dvhTVSet; - std::vector dvhHTSet; - dvhTVSet.push_back(dvhPTV); - dvhHTSet.push_back(dvhNT1); - dvhHTSet.push_back(dvhNT2); - dvhHTSet.push_back(dvhNT3); - - ::boost::shared_ptr dvhSetPtr = ::boost::make_shared(dvhTVSet, dvhHTSet, - "testStrSet", dvhPTV.getDoseID()); - - /*test exception*/ - ::boost::shared_ptr dvhSetNullPtr; - CHECK_THROW_EXPLICIT(indices::ConformalIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformationNumber(dvhSetNullPtr, 0), - core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformityIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::CoverageIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::HomogeneityIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - - /*test exception for invalid reference dose*/ - CHECK_THROW_EXPLICIT(indices::ConformalIndex(dvhSetPtr, 100), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformationNumber(dvhSetPtr, 100), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformityIndex(dvhSetPtr, 100), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::HomogeneityIndex(dvhSetPtr, 0), core::InvalidParameterException); - - /*test index calculation*/ - - /*RTConformationNumber */ - //PTV covered by reference dose 30 = the whole PTV =362.5; Volume of the referece 30=362.5+1.25 - indices::ConformationNumber cn = indices::ConformationNumber(dvhSetPtr, 30); - //check if values are close. Equality is only achieved with double precission. - CHECK_CLOSE(362.5 / 363.75, cn.getValue(), errorConstant); - - //cn==1*TV0/V0=362.5/2466.25 - cn.setDoseReference(0); - CHECK_CLOSE(362.5 / 2466.25, cn.getValue(), errorConstant); - - cn.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, cn.getValue(), - errorConstant); //ref dose: 65 -> TVref=Vref -> cn=TVref/TV=2300/2900 - - CHECK_EQUAL(cn.getValue(), cn.getValueAt(0)); - CHECK_THROW_EXPLICIT(cn.getValueAt(1), core::InvalidParameterException); - - /*ConformalIndex */ - //HT 1 covered by ref=HT2 covered by ref=0, HT3 covered by ref=1.25 - indices::ConformalIndex coin = indices::ConformalIndex(dvhSetPtr, 30); - CHECK_CLOSE((362.5 / 363.75) * (1 - 1.25 / 151.25), coin.getValue(), errorConstant); - - coin.setDoseReference(0); - CHECK_EQUAL(0, coin.getValue()); - - coin.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, coin.getValue(), - errorConstant); //ref dose: 65 -> Vref=0 for all HT -> cn=cn*(1-0)=cn - - CHECK_EQUAL(coin.getValue(), coin.getValueAt(0)); - CHECK_THROW_EXPLICIT(coin.getValueAt(1), core::InvalidParameterException); - - /*ConformityIndex */ - indices::ConformityIndex ci = indices::ConformityIndex(dvhSetPtr, 30); - CHECK_CLOSE(362.5 / 363.75, ci.getValue(), errorConstant); - - ci.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, ci.getValue(), errorConstant); //ref dose: 65->ci=2300/2900*1*1*1 - - CHECK_EQUAL(ci.getValue(), ci.getValueAt(0)); - CHECK_THROW_EXPLICIT(ci.getValueAt(1), core::InvalidParameterException); - - /*CoverageIndex*/ - indices::CoverageIndex coverageI = indices::CoverageIndex(dvhSetPtr, 30); - CHECK_CLOSE(362.5 / 362.5, coverageI.getValue(), errorConstant); //ref dose: 30 -> coverage index=1 - - coverageI.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, coverageI.getValue(), - errorConstant); //ref dose: 65->coverage index=2300/2900 - - CHECK_EQUAL(coverageI.getValue(), coverageI.getValueAt(0)); - CHECK_THROW_EXPLICIT(coverageI.getValueAt(1), core::InvalidParameterException); - - - /*HomogeneityIndex TV max: 133*0.5=66.5, TV min: 127*0.5=63.5 -> hi=(66.5-63.5)/30*/ - indices::HomogeneityIndex hi = indices::HomogeneityIndex(dvhSetPtr, 30); - CHECK_CLOSE(3 / 30.0, hi.getValue(), errorConstant); - - hi.setDoseReference(65); - CHECK_CLOSE(3 / 65.0, hi.getValue(), errorConstant); - - CHECK_EQUAL(hi.getValue(), hi.getValueAt(0)); - CHECK_THROW_EXPLICIT(hi.getValueAt(1), core::InvalidParameterException); - - - RETURN_AND_REPORT_TEST_SUCCESS; - - - } - - }//testing +// ----------------------------------------------------------------------- +// 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. +// +//------------------------------------------------------------------------ + +// this file defines the rttbCoreTests for the test driver +// and all it expects is that you have a function called RegisterTests + +#include "litCheckMacros.h" +#include "rttbDoseIndex.h" +#include "rttbDVHSet.h" +#include "rttbBaseType.h" +#include "rttbNullPointerException.h" +#include "rttbConformalIndex.h" +#include "rttbException.h" +#include "rttbInvalidParameterException.h" +#include "rttbDVHXMLFileReader.h" + +#include + +#include +#include + +namespace rttb +{ + namespace testing + { + /*! @brief Test of ConformalIndex + test dvh: deltaV 0.125, deltaD 0.5 + 1. dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133 + 2. dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40 + 3. dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50 + 4. dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70 + + 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 ConformalIndexTest(int argc, char* argv[]) + { + PREPARE_DEFAULT_TEST_REPORTING; + + //ARGUMENTS: 1: ptv dvh file name + // 2: normal tissue 1 dvh file name + // 3: normal tissue 2 dvh file name + // 4: normal tissue 3 dvh file name + + std::string DVH_FILENAME_PTV; + std::string DVH_FILENAME_NT1; + std::string DVH_FILENAME_NT2; + std::string DVH_FILENAME_NT3; + + + if (argc > 1) + { + DVH_FILENAME_PTV = argv[1]; + } + + if (argc > 2) + { + DVH_FILENAME_NT1 = argv[2]; + } + + if (argc > 3) + { + DVH_FILENAME_NT2 = argv[3]; + } + + if (argc > 4) + { + DVH_FILENAME_NT3 = argv[4]; + } + + + /*test dvh: deltaV 0.125, deltaD 0.5*/ + /*dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133*/ + rttb::io::other::DVHXMLFileReader dvhReader = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_PTV); + rttb::core::DVH dvhPTV = *(dvhReader.generateDVH()); + /*dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40*/ + rttb::io::other::DVHXMLFileReader dvhReader1 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT1); + core::DVH dvhNT1 = *(dvhReader1.generateDVH()); + /*dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50*/ + rttb::io::other::DVHXMLFileReader dvhReader2 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT2); + core::DVH dvhNT2 = *(dvhReader2.generateDVH()); + /*dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70*/ + rttb::io::other::DVHXMLFileReader dvhReader3 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT3); + core::DVH dvhNT3 = *(dvhReader3.generateDVH()); + + std::vector dvhTVSet; + std::vector dvhHTSet; + dvhTVSet.push_back(dvhPTV); + dvhHTSet.push_back(dvhNT1); + dvhHTSet.push_back(dvhNT2); + dvhHTSet.push_back(dvhNT3); + + ::boost::shared_ptr dvhSetPtr = ::boost::make_shared(dvhTVSet, dvhHTSet, + "testStrSet", dvhPTV.getDoseID()); + + /*test exception*/ + ::boost::shared_ptr dvhSetNullPtr; + CHECK_THROW_EXPLICIT(indices::ConformalIndex(dvhSetNullPtr, 0), core::InvalidParameterException); + + /*test exception for invalid reference dose*/ + CHECK_THROW_EXPLICIT(indices::ConformalIndex(dvhSetPtr, 100), core::InvalidParameterException); + + /*test index calculation*/ + + /*ConformalIndex */ + //HT 1 covered by ref=HT2 covered by ref=0, HT3 covered by ref=1.25 + indices::ConformalIndex coin = indices::ConformalIndex(dvhSetPtr, 30); + CHECK_CLOSE((362.5 / 363.75) * (1 - 1.25 / 151.25), coin.getValue(), errorConstant); + + coin.setDoseReference(0); + CHECK_EQUAL(0, coin.getValue()); + + coin.setDoseReference(65); + CHECK_CLOSE(2300 / 2900.0, coin.getValue(), + errorConstant); //ref dose: 65 -> Vref=0 for all HT -> cn=cn*(1-0)=cn + + CHECK_EQUAL(coin.getValue(), coin.getValueAt(0)); + CHECK_THROW_EXPLICIT(coin.getValueAt(1), core::InvalidParameterException); + + RETURN_AND_REPORT_TEST_SUCCESS; + + } + + }//testing }//rttb \ No newline at end of file diff --git a/testing/examples/RTDoseIndexTest.cpp b/testing/indices/ConformationNumberTest.cpp similarity index 60% copy from testing/examples/RTDoseIndexTest.cpp copy to testing/indices/ConformationNumberTest.cpp index 35899fc..d5c4468 100644 --- a/testing/examples/RTDoseIndexTest.cpp +++ b/testing/indices/ConformationNumberTest.cpp @@ -1,202 +1,142 @@ -// ----------------------------------------------------------------------- -// 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. -// -//------------------------------------------------------------------------ - -// this file defines the rttbCoreTests for the test driver -// and all it expects is that you have a function called RegisterTests - -#include "litCheckMacros.h" -#include "rttbDoseIndex.h" -#include "rttbDVHSet.h" -#include "rttbBaseType.h" -#include "rttbNullPointerException.h" -#include "rttbConformalIndex.h" -#include "rttbConformationNumber.h" -#include "rttbConformityIndex.h" -#include "rttbCoverageIndex.h" -#include "rttbHomogeneityIndex.h" -#include "rttbException.h" -#include "rttbInvalidParameterException.h" -#include "rttbDVHXMLFileReader.h" - -#include - -#include -#include - -namespace rttb -{ - namespace testing - { - /*! @brief DoseIndexTest. ConformationNumber ConformalIndex ConformityIndex CoverageIndex HomogeneityIndex are tested. - test dvh: deltaV 0.125, deltaD 0.5 - 1. dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133 - 2. dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40 - 3. dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50 - 4. dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70 - - 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 RTDoseIndexTest(int argc, char* argv[]) - { - PREPARE_DEFAULT_TEST_REPORTING; - - //ARGUMENTS: 1: ptv dvh file name - // 2: normal tissue 1 dvh file name - // 3: normal tissue 2 dvh file name - // 4: normal tissue 3 dvh file name - - std::string DVH_FILENAME_PTV; - std::string DVH_FILENAME_NT1; - std::string DVH_FILENAME_NT2; - std::string DVH_FILENAME_NT3; - - - if (argc > 1) - { - DVH_FILENAME_PTV = argv[1]; - } - - if (argc > 2) - { - DVH_FILENAME_NT1 = argv[2]; - } - - if (argc > 3) - { - DVH_FILENAME_NT2 = argv[3]; - } - - if (argc > 4) - { - DVH_FILENAME_NT3 = argv[4]; - } - - - /*test dvh: deltaV 0.125, deltaD 0.5*/ - /*dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133*/ - rttb::io::other::DVHXMLFileReader dvhReader = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_PTV); - rttb::core::DVH dvhPTV = *(dvhReader.generateDVH()); - /*dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40*/ - rttb::io::other::DVHXMLFileReader dvhReader1 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT1); - core::DVH dvhNT1 = *(dvhReader1.generateDVH()); - /*dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50*/ - rttb::io::other::DVHXMLFileReader dvhReader2 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT2); - core::DVH dvhNT2 = *(dvhReader2.generateDVH()); - /*dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70*/ - rttb::io::other::DVHXMLFileReader dvhReader3 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT3); - core::DVH dvhNT3 = *(dvhReader3.generateDVH()); - - std::vector dvhTVSet; - std::vector dvhHTSet; - dvhTVSet.push_back(dvhPTV); - dvhHTSet.push_back(dvhNT1); - dvhHTSet.push_back(dvhNT2); - dvhHTSet.push_back(dvhNT3); - - ::boost::shared_ptr dvhSetPtr = ::boost::make_shared(dvhTVSet, dvhHTSet, - "testStrSet", dvhPTV.getDoseID()); - - /*test exception*/ - ::boost::shared_ptr dvhSetNullPtr; - CHECK_THROW_EXPLICIT(indices::ConformalIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformationNumber(dvhSetNullPtr, 0), - core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformityIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::CoverageIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::HomogeneityIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - - /*test exception for invalid reference dose*/ - CHECK_THROW_EXPLICIT(indices::ConformalIndex(dvhSetPtr, 100), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformationNumber(dvhSetPtr, 100), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformityIndex(dvhSetPtr, 100), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::HomogeneityIndex(dvhSetPtr, 0), core::InvalidParameterException); - - /*test index calculation*/ - - /*RTConformationNumber */ - //PTV covered by reference dose 30 = the whole PTV =362.5; Volume of the referece 30=362.5+1.25 - indices::ConformationNumber cn = indices::ConformationNumber(dvhSetPtr, 30); - //check if values are close. Equality is only achieved with double precission. - CHECK_CLOSE(362.5 / 363.75, cn.getValue(), errorConstant); - - //cn==1*TV0/V0=362.5/2466.25 - cn.setDoseReference(0); - CHECK_CLOSE(362.5 / 2466.25, cn.getValue(), errorConstant); - - cn.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, cn.getValue(), - errorConstant); //ref dose: 65 -> TVref=Vref -> cn=TVref/TV=2300/2900 - - CHECK_EQUAL(cn.getValue(), cn.getValueAt(0)); - CHECK_THROW_EXPLICIT(cn.getValueAt(1), core::InvalidParameterException); - - /*ConformalIndex */ - //HT 1 covered by ref=HT2 covered by ref=0, HT3 covered by ref=1.25 - indices::ConformalIndex coin = indices::ConformalIndex(dvhSetPtr, 30); - CHECK_CLOSE((362.5 / 363.75) * (1 - 1.25 / 151.25), coin.getValue(), errorConstant); - - coin.setDoseReference(0); - CHECK_EQUAL(0, coin.getValue()); - - coin.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, coin.getValue(), - errorConstant); //ref dose: 65 -> Vref=0 for all HT -> cn=cn*(1-0)=cn - - CHECK_EQUAL(coin.getValue(), coin.getValueAt(0)); - CHECK_THROW_EXPLICIT(coin.getValueAt(1), core::InvalidParameterException); - - /*ConformityIndex */ - indices::ConformityIndex ci = indices::ConformityIndex(dvhSetPtr, 30); - CHECK_CLOSE(362.5 / 363.75, ci.getValue(), errorConstant); - - ci.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, ci.getValue(), errorConstant); //ref dose: 65->ci=2300/2900*1*1*1 - - CHECK_EQUAL(ci.getValue(), ci.getValueAt(0)); - CHECK_THROW_EXPLICIT(ci.getValueAt(1), core::InvalidParameterException); - - /*CoverageIndex*/ - indices::CoverageIndex coverageI = indices::CoverageIndex(dvhSetPtr, 30); - CHECK_CLOSE(362.5 / 362.5, coverageI.getValue(), errorConstant); //ref dose: 30 -> coverage index=1 - - coverageI.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, coverageI.getValue(), - errorConstant); //ref dose: 65->coverage index=2300/2900 - - CHECK_EQUAL(coverageI.getValue(), coverageI.getValueAt(0)); - CHECK_THROW_EXPLICIT(coverageI.getValueAt(1), core::InvalidParameterException); - - - /*HomogeneityIndex TV max: 133*0.5=66.5, TV min: 127*0.5=63.5 -> hi=(66.5-63.5)/30*/ - indices::HomogeneityIndex hi = indices::HomogeneityIndex(dvhSetPtr, 30); - CHECK_CLOSE(3 / 30.0, hi.getValue(), errorConstant); - - hi.setDoseReference(65); - CHECK_CLOSE(3 / 65.0, hi.getValue(), errorConstant); - - CHECK_EQUAL(hi.getValue(), hi.getValueAt(0)); - CHECK_THROW_EXPLICIT(hi.getValueAt(1), core::InvalidParameterException); - - - RETURN_AND_REPORT_TEST_SUCCESS; - - - } - - }//testing +// ----------------------------------------------------------------------- +// 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. +// +//------------------------------------------------------------------------ + +// this file defines the rttbCoreTests for the test driver +// and all it expects is that you have a function called RegisterTests + +#include "litCheckMacros.h" +#include "rttbDoseIndex.h" +#include "rttbDVHSet.h" +#include "rttbBaseType.h" +#include "rttbNullPointerException.h" +#include "rttbConformationNumber.h" +#include "rttbException.h" +#include "rttbInvalidParameterException.h" +#include "rttbDVHXMLFileReader.h" + +#include + +#include +#include + +namespace rttb +{ + namespace testing + { + /*! @brief Test of ConformationNumber. + test dvh: deltaV 0.125, deltaD 0.5 + 1. dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133 + 2. dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40 + 3. dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50 + 4. dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70 + + 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 ConformationNumberTest(int argc, char* argv[]) + { + PREPARE_DEFAULT_TEST_REPORTING; + + //ARGUMENTS: 1: ptv dvh file name + // 2: normal tissue 1 dvh file name + // 3: normal tissue 2 dvh file name + // 4: normal tissue 3 dvh file name + + std::string DVH_FILENAME_PTV; + std::string DVH_FILENAME_NT1; + std::string DVH_FILENAME_NT2; + std::string DVH_FILENAME_NT3; + + + if (argc > 1) + { + DVH_FILENAME_PTV = argv[1]; + } + + if (argc > 2) + { + DVH_FILENAME_NT1 = argv[2]; + } + + if (argc > 3) + { + DVH_FILENAME_NT2 = argv[3]; + } + + if (argc > 4) + { + DVH_FILENAME_NT3 = argv[4]; + } + + + /*test dvh: deltaV 0.125, deltaD 0.5*/ + /*dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133*/ + rttb::io::other::DVHXMLFileReader dvhReader = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_PTV); + rttb::core::DVH dvhPTV = *(dvhReader.generateDVH()); + /*dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40*/ + rttb::io::other::DVHXMLFileReader dvhReader1 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT1); + core::DVH dvhNT1 = *(dvhReader1.generateDVH()); + /*dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50*/ + rttb::io::other::DVHXMLFileReader dvhReader2 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT2); + core::DVH dvhNT2 = *(dvhReader2.generateDVH()); + /*dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70*/ + rttb::io::other::DVHXMLFileReader dvhReader3 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT3); + core::DVH dvhNT3 = *(dvhReader3.generateDVH()); + + std::vector dvhTVSet; + std::vector dvhHTSet; + dvhTVSet.push_back(dvhPTV); + dvhHTSet.push_back(dvhNT1); + dvhHTSet.push_back(dvhNT2); + dvhHTSet.push_back(dvhNT3); + + ::boost::shared_ptr dvhSetPtr = ::boost::make_shared(dvhTVSet, dvhHTSet, + "testStrSet", dvhPTV.getDoseID()); + + /*test exception*/ + ::boost::shared_ptr dvhSetNullPtr; + CHECK_THROW_EXPLICIT(indices::ConformationNumber(dvhSetNullPtr, 0), + core::InvalidParameterException); + + /*test exception for invalid reference dose*/ + CHECK_THROW_EXPLICIT(indices::ConformationNumber(dvhSetPtr, 100), core::InvalidParameterException); + + /*test index calculation*/ + + /*RTConformationNumber */ + //PTV covered by reference dose 30 = the whole PTV =362.5; Volume of the referece 30=362.5+1.25 + indices::ConformationNumber cn = indices::ConformationNumber(dvhSetPtr, 30); + //check if values are close. Equality is only achieved with double precission. + CHECK_CLOSE(362.5 / 363.75, cn.getValue(), errorConstant); + + //cn==1*TV0/V0=362.5/2466.25 + cn.setDoseReference(0); + CHECK_CLOSE(362.5 / 2466.25, cn.getValue(), errorConstant); + + cn.setDoseReference(65); + CHECK_CLOSE(2300 / 2900.0, cn.getValue(), + errorConstant); //ref dose: 65 -> TVref=Vref -> cn=TVref/TV=2300/2900 + + CHECK_EQUAL(cn.getValue(), cn.getValueAt(0)); + CHECK_THROW_EXPLICIT(cn.getValueAt(1), core::InvalidParameterException); + + RETURN_AND_REPORT_TEST_SUCCESS; + + } + + }//testing }//rttb \ No newline at end of file diff --git a/testing/examples/RTDoseIndexTest.cpp b/testing/indices/ConformityIndexTest.cpp similarity index 55% copy from testing/examples/RTDoseIndexTest.cpp copy to testing/indices/ConformityIndexTest.cpp index 35899fc..670efe8 100644 --- a/testing/examples/RTDoseIndexTest.cpp +++ b/testing/indices/ConformityIndexTest.cpp @@ -1,202 +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. -// -//------------------------------------------------------------------------ - -// this file defines the rttbCoreTests for the test driver -// and all it expects is that you have a function called RegisterTests - -#include "litCheckMacros.h" -#include "rttbDoseIndex.h" -#include "rttbDVHSet.h" -#include "rttbBaseType.h" -#include "rttbNullPointerException.h" -#include "rttbConformalIndex.h" -#include "rttbConformationNumber.h" -#include "rttbConformityIndex.h" -#include "rttbCoverageIndex.h" -#include "rttbHomogeneityIndex.h" -#include "rttbException.h" -#include "rttbInvalidParameterException.h" -#include "rttbDVHXMLFileReader.h" - -#include - -#include -#include - -namespace rttb -{ - namespace testing - { - /*! @brief DoseIndexTest. ConformationNumber ConformalIndex ConformityIndex CoverageIndex HomogeneityIndex are tested. - test dvh: deltaV 0.125, deltaD 0.5 - 1. dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133 - 2. dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40 - 3. dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50 - 4. dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70 - - 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 RTDoseIndexTest(int argc, char* argv[]) - { - PREPARE_DEFAULT_TEST_REPORTING; - - //ARGUMENTS: 1: ptv dvh file name - // 2: normal tissue 1 dvh file name - // 3: normal tissue 2 dvh file name - // 4: normal tissue 3 dvh file name - - std::string DVH_FILENAME_PTV; - std::string DVH_FILENAME_NT1; - std::string DVH_FILENAME_NT2; - std::string DVH_FILENAME_NT3; - - - if (argc > 1) - { - DVH_FILENAME_PTV = argv[1]; - } - - if (argc > 2) - { - DVH_FILENAME_NT1 = argv[2]; - } - - if (argc > 3) - { - DVH_FILENAME_NT2 = argv[3]; - } - - if (argc > 4) - { - DVH_FILENAME_NT3 = argv[4]; - } - - - /*test dvh: deltaV 0.125, deltaD 0.5*/ - /*dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133*/ - rttb::io::other::DVHXMLFileReader dvhReader = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_PTV); - rttb::core::DVH dvhPTV = *(dvhReader.generateDVH()); - /*dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40*/ - rttb::io::other::DVHXMLFileReader dvhReader1 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT1); - core::DVH dvhNT1 = *(dvhReader1.generateDVH()); - /*dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50*/ - rttb::io::other::DVHXMLFileReader dvhReader2 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT2); - core::DVH dvhNT2 = *(dvhReader2.generateDVH()); - /*dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70*/ - rttb::io::other::DVHXMLFileReader dvhReader3 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT3); - core::DVH dvhNT3 = *(dvhReader3.generateDVH()); - - std::vector dvhTVSet; - std::vector dvhHTSet; - dvhTVSet.push_back(dvhPTV); - dvhHTSet.push_back(dvhNT1); - dvhHTSet.push_back(dvhNT2); - dvhHTSet.push_back(dvhNT3); - - ::boost::shared_ptr dvhSetPtr = ::boost::make_shared(dvhTVSet, dvhHTSet, - "testStrSet", dvhPTV.getDoseID()); - - /*test exception*/ - ::boost::shared_ptr dvhSetNullPtr; - CHECK_THROW_EXPLICIT(indices::ConformalIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformationNumber(dvhSetNullPtr, 0), - core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformityIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::CoverageIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::HomogeneityIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - - /*test exception for invalid reference dose*/ - CHECK_THROW_EXPLICIT(indices::ConformalIndex(dvhSetPtr, 100), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformationNumber(dvhSetPtr, 100), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformityIndex(dvhSetPtr, 100), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::HomogeneityIndex(dvhSetPtr, 0), core::InvalidParameterException); - - /*test index calculation*/ - - /*RTConformationNumber */ - //PTV covered by reference dose 30 = the whole PTV =362.5; Volume of the referece 30=362.5+1.25 - indices::ConformationNumber cn = indices::ConformationNumber(dvhSetPtr, 30); - //check if values are close. Equality is only achieved with double precission. - CHECK_CLOSE(362.5 / 363.75, cn.getValue(), errorConstant); - - //cn==1*TV0/V0=362.5/2466.25 - cn.setDoseReference(0); - CHECK_CLOSE(362.5 / 2466.25, cn.getValue(), errorConstant); - - cn.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, cn.getValue(), - errorConstant); //ref dose: 65 -> TVref=Vref -> cn=TVref/TV=2300/2900 - - CHECK_EQUAL(cn.getValue(), cn.getValueAt(0)); - CHECK_THROW_EXPLICIT(cn.getValueAt(1), core::InvalidParameterException); - - /*ConformalIndex */ - //HT 1 covered by ref=HT2 covered by ref=0, HT3 covered by ref=1.25 - indices::ConformalIndex coin = indices::ConformalIndex(dvhSetPtr, 30); - CHECK_CLOSE((362.5 / 363.75) * (1 - 1.25 / 151.25), coin.getValue(), errorConstant); - - coin.setDoseReference(0); - CHECK_EQUAL(0, coin.getValue()); - - coin.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, coin.getValue(), - errorConstant); //ref dose: 65 -> Vref=0 for all HT -> cn=cn*(1-0)=cn - - CHECK_EQUAL(coin.getValue(), coin.getValueAt(0)); - CHECK_THROW_EXPLICIT(coin.getValueAt(1), core::InvalidParameterException); - - /*ConformityIndex */ - indices::ConformityIndex ci = indices::ConformityIndex(dvhSetPtr, 30); - CHECK_CLOSE(362.5 / 363.75, ci.getValue(), errorConstant); - - ci.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, ci.getValue(), errorConstant); //ref dose: 65->ci=2300/2900*1*1*1 - - CHECK_EQUAL(ci.getValue(), ci.getValueAt(0)); - CHECK_THROW_EXPLICIT(ci.getValueAt(1), core::InvalidParameterException); - - /*CoverageIndex*/ - indices::CoverageIndex coverageI = indices::CoverageIndex(dvhSetPtr, 30); - CHECK_CLOSE(362.5 / 362.5, coverageI.getValue(), errorConstant); //ref dose: 30 -> coverage index=1 - - coverageI.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, coverageI.getValue(), - errorConstant); //ref dose: 65->coverage index=2300/2900 - - CHECK_EQUAL(coverageI.getValue(), coverageI.getValueAt(0)); - CHECK_THROW_EXPLICIT(coverageI.getValueAt(1), core::InvalidParameterException); - - - /*HomogeneityIndex TV max: 133*0.5=66.5, TV min: 127*0.5=63.5 -> hi=(66.5-63.5)/30*/ - indices::HomogeneityIndex hi = indices::HomogeneityIndex(dvhSetPtr, 30); - CHECK_CLOSE(3 / 30.0, hi.getValue(), errorConstant); - - hi.setDoseReference(65); - CHECK_CLOSE(3 / 65.0, hi.getValue(), errorConstant); - - CHECK_EQUAL(hi.getValue(), hi.getValueAt(0)); - CHECK_THROW_EXPLICIT(hi.getValueAt(1), core::InvalidParameterException); - - - RETURN_AND_REPORT_TEST_SUCCESS; - - - } - - }//testing +// ----------------------------------------------------------------------- +// 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. +// +//------------------------------------------------------------------------ + +// this file defines the rttbCoreTests for the test driver +// and all it expects is that you have a function called RegisterTests + +#include "litCheckMacros.h" +#include "rttbDoseIndex.h" +#include "rttbDVHSet.h" +#include "rttbBaseType.h" +#include "rttbNullPointerException.h" +#include "rttbConformityIndex.h" +#include "rttbException.h" +#include "rttbInvalidParameterException.h" +#include "rttbDVHXMLFileReader.h" + +#include + +#include +#include + +namespace rttb +{ + namespace testing + { + /*! @brief Test of ConformityIndex. + test dvh: deltaV 0.125, deltaD 0.5 + 1. dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133 + 2. dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40 + 3. dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50 + 4. dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70 + + 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 ConformityIndexTest(int argc, char* argv[]) + { + PREPARE_DEFAULT_TEST_REPORTING; + + //ARGUMENTS: 1: ptv dvh file name + // 2: normal tissue 1 dvh file name + // 3: normal tissue 2 dvh file name + // 4: normal tissue 3 dvh file name + + std::string DVH_FILENAME_PTV; + std::string DVH_FILENAME_NT1; + std::string DVH_FILENAME_NT2; + std::string DVH_FILENAME_NT3; + + + if (argc > 1) + { + DVH_FILENAME_PTV = argv[1]; + } + + if (argc > 2) + { + DVH_FILENAME_NT1 = argv[2]; + } + + if (argc > 3) + { + DVH_FILENAME_NT2 = argv[3]; + } + + if (argc > 4) + { + DVH_FILENAME_NT3 = argv[4]; + } + + + /*test dvh: deltaV 0.125, deltaD 0.5*/ + /*dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133*/ + rttb::io::other::DVHXMLFileReader dvhReader = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_PTV); + rttb::core::DVH dvhPTV = *(dvhReader.generateDVH()); + /*dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40*/ + rttb::io::other::DVHXMLFileReader dvhReader1 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT1); + core::DVH dvhNT1 = *(dvhReader1.generateDVH()); + /*dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50*/ + rttb::io::other::DVHXMLFileReader dvhReader2 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT2); + core::DVH dvhNT2 = *(dvhReader2.generateDVH()); + /*dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70*/ + rttb::io::other::DVHXMLFileReader dvhReader3 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT3); + core::DVH dvhNT3 = *(dvhReader3.generateDVH()); + + std::vector dvhTVSet; + std::vector dvhHTSet; + dvhTVSet.push_back(dvhPTV); + dvhHTSet.push_back(dvhNT1); + dvhHTSet.push_back(dvhNT2); + dvhHTSet.push_back(dvhNT3); + + ::boost::shared_ptr dvhSetPtr = ::boost::make_shared(dvhTVSet, dvhHTSet, + "testStrSet", dvhPTV.getDoseID()); + + /*test exception*/ + ::boost::shared_ptr dvhSetNullPtr; + CHECK_THROW_EXPLICIT(indices::ConformityIndex(dvhSetNullPtr, 0), core::InvalidParameterException); + + /*test exception for invalid reference dose*/ + CHECK_THROW_EXPLICIT(indices::ConformityIndex(dvhSetPtr, 100), core::InvalidParameterException); + + /*test index calculation*/ + + /*ConformityIndex */ + indices::ConformityIndex ci = indices::ConformityIndex(dvhSetPtr, 30); + CHECK_CLOSE(362.5 / 363.75, ci.getValue(), errorConstant); + + ci.setDoseReference(65); + CHECK_CLOSE(2300 / 2900.0, ci.getValue(), errorConstant); //ref dose: 65->ci=2300/2900*1*1*1 + + CHECK_EQUAL(ci.getValue(), ci.getValueAt(0)); + CHECK_THROW_EXPLICIT(ci.getValueAt(1), core::InvalidParameterException); + + RETURN_AND_REPORT_TEST_SUCCESS; + + } + + }//testing }//rttb \ No newline at end of file diff --git a/testing/examples/RTDoseIndexTest.cpp b/testing/indices/CoverageIndexTest.cpp similarity index 54% copy from testing/examples/RTDoseIndexTest.cpp copy to testing/indices/CoverageIndexTest.cpp index 35899fc..a0a1e17 100644 --- a/testing/examples/RTDoseIndexTest.cpp +++ b/testing/indices/CoverageIndexTest.cpp @@ -1,202 +1,132 @@ -// ----------------------------------------------------------------------- -// RTToolbox - DKFZ radiotherapy quantitative evaluation library -// -// Copyright (c) German Cancer Research Center (DKFZ), -// Software development for Integrated Diagnostics and Therapy (SIDT). -// ALL RIGHTS RESERVED. -// See rttbCopyright.txt or -// http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] -// -// This software is distributed WITHOUT ANY WARRANTY; without even -// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -// PURPOSE. See the above copyright notices for more information. -// -//------------------------------------------------------------------------ - -// this file defines the rttbCoreTests for the test driver -// and all it expects is that you have a function called RegisterTests - -#include "litCheckMacros.h" -#include "rttbDoseIndex.h" -#include "rttbDVHSet.h" -#include "rttbBaseType.h" -#include "rttbNullPointerException.h" -#include "rttbConformalIndex.h" -#include "rttbConformationNumber.h" -#include "rttbConformityIndex.h" -#include "rttbCoverageIndex.h" -#include "rttbHomogeneityIndex.h" -#include "rttbException.h" -#include "rttbInvalidParameterException.h" -#include "rttbDVHXMLFileReader.h" - -#include - -#include -#include - -namespace rttb -{ - namespace testing - { - /*! @brief DoseIndexTest. ConformationNumber ConformalIndex ConformityIndex CoverageIndex HomogeneityIndex are tested. - test dvh: deltaV 0.125, deltaD 0.5 - 1. dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133 - 2. dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40 - 3. dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50 - 4. dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70 - - 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 RTDoseIndexTest(int argc, char* argv[]) - { - PREPARE_DEFAULT_TEST_REPORTING; - - //ARGUMENTS: 1: ptv dvh file name - // 2: normal tissue 1 dvh file name - // 3: normal tissue 2 dvh file name - // 4: normal tissue 3 dvh file name - - std::string DVH_FILENAME_PTV; - std::string DVH_FILENAME_NT1; - std::string DVH_FILENAME_NT2; - std::string DVH_FILENAME_NT3; - - - if (argc > 1) - { - DVH_FILENAME_PTV = argv[1]; - } - - if (argc > 2) - { - DVH_FILENAME_NT1 = argv[2]; - } - - if (argc > 3) - { - DVH_FILENAME_NT2 = argv[3]; - } - - if (argc > 4) - { - DVH_FILENAME_NT3 = argv[4]; - } - - - /*test dvh: deltaV 0.125, deltaD 0.5*/ - /*dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133*/ - rttb::io::other::DVHXMLFileReader dvhReader = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_PTV); - rttb::core::DVH dvhPTV = *(dvhReader.generateDVH()); - /*dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40*/ - rttb::io::other::DVHXMLFileReader dvhReader1 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT1); - core::DVH dvhNT1 = *(dvhReader1.generateDVH()); - /*dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50*/ - rttb::io::other::DVHXMLFileReader dvhReader2 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT2); - core::DVH dvhNT2 = *(dvhReader2.generateDVH()); - /*dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70*/ - rttb::io::other::DVHXMLFileReader dvhReader3 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT3); - core::DVH dvhNT3 = *(dvhReader3.generateDVH()); - - std::vector dvhTVSet; - std::vector dvhHTSet; - dvhTVSet.push_back(dvhPTV); - dvhHTSet.push_back(dvhNT1); - dvhHTSet.push_back(dvhNT2); - dvhHTSet.push_back(dvhNT3); - - ::boost::shared_ptr dvhSetPtr = ::boost::make_shared(dvhTVSet, dvhHTSet, - "testStrSet", dvhPTV.getDoseID()); - - /*test exception*/ - ::boost::shared_ptr dvhSetNullPtr; - CHECK_THROW_EXPLICIT(indices::ConformalIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformationNumber(dvhSetNullPtr, 0), - core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformityIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::CoverageIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::HomogeneityIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - - /*test exception for invalid reference dose*/ - CHECK_THROW_EXPLICIT(indices::ConformalIndex(dvhSetPtr, 100), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformationNumber(dvhSetPtr, 100), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformityIndex(dvhSetPtr, 100), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::HomogeneityIndex(dvhSetPtr, 0), core::InvalidParameterException); - - /*test index calculation*/ - - /*RTConformationNumber */ - //PTV covered by reference dose 30 = the whole PTV =362.5; Volume of the referece 30=362.5+1.25 - indices::ConformationNumber cn = indices::ConformationNumber(dvhSetPtr, 30); - //check if values are close. Equality is only achieved with double precission. - CHECK_CLOSE(362.5 / 363.75, cn.getValue(), errorConstant); - - //cn==1*TV0/V0=362.5/2466.25 - cn.setDoseReference(0); - CHECK_CLOSE(362.5 / 2466.25, cn.getValue(), errorConstant); - - cn.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, cn.getValue(), - errorConstant); //ref dose: 65 -> TVref=Vref -> cn=TVref/TV=2300/2900 - - CHECK_EQUAL(cn.getValue(), cn.getValueAt(0)); - CHECK_THROW_EXPLICIT(cn.getValueAt(1), core::InvalidParameterException); - - /*ConformalIndex */ - //HT 1 covered by ref=HT2 covered by ref=0, HT3 covered by ref=1.25 - indices::ConformalIndex coin = indices::ConformalIndex(dvhSetPtr, 30); - CHECK_CLOSE((362.5 / 363.75) * (1 - 1.25 / 151.25), coin.getValue(), errorConstant); - - coin.setDoseReference(0); - CHECK_EQUAL(0, coin.getValue()); - - coin.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, coin.getValue(), - errorConstant); //ref dose: 65 -> Vref=0 for all HT -> cn=cn*(1-0)=cn - - CHECK_EQUAL(coin.getValue(), coin.getValueAt(0)); - CHECK_THROW_EXPLICIT(coin.getValueAt(1), core::InvalidParameterException); - - /*ConformityIndex */ - indices::ConformityIndex ci = indices::ConformityIndex(dvhSetPtr, 30); - CHECK_CLOSE(362.5 / 363.75, ci.getValue(), errorConstant); - - ci.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, ci.getValue(), errorConstant); //ref dose: 65->ci=2300/2900*1*1*1 - - CHECK_EQUAL(ci.getValue(), ci.getValueAt(0)); - CHECK_THROW_EXPLICIT(ci.getValueAt(1), core::InvalidParameterException); - - /*CoverageIndex*/ - indices::CoverageIndex coverageI = indices::CoverageIndex(dvhSetPtr, 30); - CHECK_CLOSE(362.5 / 362.5, coverageI.getValue(), errorConstant); //ref dose: 30 -> coverage index=1 - - coverageI.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, coverageI.getValue(), - errorConstant); //ref dose: 65->coverage index=2300/2900 - - CHECK_EQUAL(coverageI.getValue(), coverageI.getValueAt(0)); - CHECK_THROW_EXPLICIT(coverageI.getValueAt(1), core::InvalidParameterException); - - - /*HomogeneityIndex TV max: 133*0.5=66.5, TV min: 127*0.5=63.5 -> hi=(66.5-63.5)/30*/ - indices::HomogeneityIndex hi = indices::HomogeneityIndex(dvhSetPtr, 30); - CHECK_CLOSE(3 / 30.0, hi.getValue(), errorConstant); - - hi.setDoseReference(65); - CHECK_CLOSE(3 / 65.0, hi.getValue(), errorConstant); - - CHECK_EQUAL(hi.getValue(), hi.getValueAt(0)); - CHECK_THROW_EXPLICIT(hi.getValueAt(1), core::InvalidParameterException); - - - RETURN_AND_REPORT_TEST_SUCCESS; - - - } - - }//testing +// ----------------------------------------------------------------------- +// 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. +// +//------------------------------------------------------------------------ + +// this file defines the rttbCoreTests for the test driver +// and all it expects is that you have a function called RegisterTests + +#include "litCheckMacros.h" +#include "rttbDoseIndex.h" +#include "rttbDVHSet.h" +#include "rttbBaseType.h" +#include "rttbNullPointerException.h" +#include "rttbCoverageIndex.h" +#include "rttbException.h" +#include "rttbInvalidParameterException.h" +#include "rttbDVHXMLFileReader.h" + +#include + +#include +#include + +namespace rttb +{ + namespace testing + { + /*! @brief Test of CoverageIndex. + test dvh: deltaV 0.125, deltaD 0.5 + 1. dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133 + 2. dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40 + 3. dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50 + 4. dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70 + + 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 CoverageIndexTest(int argc, char* argv[]) + { + PREPARE_DEFAULT_TEST_REPORTING; + + //ARGUMENTS: 1: ptv dvh file name + // 2: normal tissue 1 dvh file name + // 3: normal tissue 2 dvh file name + // 4: normal tissue 3 dvh file name + + std::string DVH_FILENAME_PTV; + std::string DVH_FILENAME_NT1; + std::string DVH_FILENAME_NT2; + std::string DVH_FILENAME_NT3; + + + if (argc > 1) + { + DVH_FILENAME_PTV = argv[1]; + } + + if (argc > 2) + { + DVH_FILENAME_NT1 = argv[2]; + } + + if (argc > 3) + { + DVH_FILENAME_NT2 = argv[3]; + } + + if (argc > 4) + { + DVH_FILENAME_NT3 = argv[4]; + } + + + /*test dvh: deltaV 0.125, deltaD 0.5*/ + /*dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133*/ + rttb::io::other::DVHXMLFileReader dvhReader = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_PTV); + rttb::core::DVH dvhPTV = *(dvhReader.generateDVH()); + /*dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40*/ + rttb::io::other::DVHXMLFileReader dvhReader1 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT1); + core::DVH dvhNT1 = *(dvhReader1.generateDVH()); + /*dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50*/ + rttb::io::other::DVHXMLFileReader dvhReader2 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT2); + core::DVH dvhNT2 = *(dvhReader2.generateDVH()); + /*dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70*/ + rttb::io::other::DVHXMLFileReader dvhReader3 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT3); + core::DVH dvhNT3 = *(dvhReader3.generateDVH()); + + std::vector dvhTVSet; + std::vector dvhHTSet; + dvhTVSet.push_back(dvhPTV); + dvhHTSet.push_back(dvhNT1); + dvhHTSet.push_back(dvhNT2); + dvhHTSet.push_back(dvhNT3); + + ::boost::shared_ptr dvhSetPtr = ::boost::make_shared(dvhTVSet, dvhHTSet, + "testStrSet", dvhPTV.getDoseID()); + + /*test exception*/ + ::boost::shared_ptr dvhSetNullPtr; + CHECK_THROW_EXPLICIT(indices::CoverageIndex(dvhSetNullPtr, 0), core::InvalidParameterException); + + /*test index calculation*/ + + /*CoverageIndex*/ + indices::CoverageIndex coverageI = indices::CoverageIndex(dvhSetPtr, 30); + CHECK_CLOSE(362.5 / 362.5, coverageI.getValue(), errorConstant); //ref dose: 30 -> coverage index=1 + + coverageI.setDoseReference(65); + CHECK_CLOSE(2300 / 2900.0, coverageI.getValue(), + errorConstant); //ref dose: 65->coverage index=2300/2900 + + CHECK_EQUAL(coverageI.getValue(), coverageI.getValueAt(0)); + CHECK_THROW_EXPLICIT(coverageI.getValueAt(1), core::InvalidParameterException); + + RETURN_AND_REPORT_TEST_SUCCESS; + + } + + }//testing }//rttb \ No newline at end of file diff --git a/testing/examples/RTDoseIndexTest.cpp b/testing/indices/HomogeneityIndexTest.cpp similarity index 55% rename from testing/examples/RTDoseIndexTest.cpp rename to testing/indices/HomogeneityIndexTest.cpp index 35899fc..09da4ea 100644 --- a/testing/examples/RTDoseIndexTest.cpp +++ b/testing/indices/HomogeneityIndexTest.cpp @@ -1,202 +1,133 @@ -// ----------------------------------------------------------------------- -// 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. -// -//------------------------------------------------------------------------ - -// this file defines the rttbCoreTests for the test driver -// and all it expects is that you have a function called RegisterTests - -#include "litCheckMacros.h" -#include "rttbDoseIndex.h" -#include "rttbDVHSet.h" -#include "rttbBaseType.h" -#include "rttbNullPointerException.h" -#include "rttbConformalIndex.h" -#include "rttbConformationNumber.h" -#include "rttbConformityIndex.h" -#include "rttbCoverageIndex.h" -#include "rttbHomogeneityIndex.h" -#include "rttbException.h" -#include "rttbInvalidParameterException.h" -#include "rttbDVHXMLFileReader.h" - -#include - -#include -#include - -namespace rttb -{ - namespace testing - { - /*! @brief DoseIndexTest. ConformationNumber ConformalIndex ConformityIndex CoverageIndex HomogeneityIndex are tested. - test dvh: deltaV 0.125, deltaD 0.5 - 1. dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133 - 2. dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40 - 3. dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50 - 4. dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70 - - 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 RTDoseIndexTest(int argc, char* argv[]) - { - PREPARE_DEFAULT_TEST_REPORTING; - - //ARGUMENTS: 1: ptv dvh file name - // 2: normal tissue 1 dvh file name - // 3: normal tissue 2 dvh file name - // 4: normal tissue 3 dvh file name - - std::string DVH_FILENAME_PTV; - std::string DVH_FILENAME_NT1; - std::string DVH_FILENAME_NT2; - std::string DVH_FILENAME_NT3; - - - if (argc > 1) - { - DVH_FILENAME_PTV = argv[1]; - } - - if (argc > 2) - { - DVH_FILENAME_NT1 = argv[2]; - } - - if (argc > 3) - { - DVH_FILENAME_NT2 = argv[3]; - } - - if (argc > 4) - { - DVH_FILENAME_NT3 = argv[4]; - } - - - /*test dvh: deltaV 0.125, deltaD 0.5*/ - /*dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133*/ - rttb::io::other::DVHXMLFileReader dvhReader = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_PTV); - rttb::core::DVH dvhPTV = *(dvhReader.generateDVH()); - /*dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40*/ - rttb::io::other::DVHXMLFileReader dvhReader1 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT1); - core::DVH dvhNT1 = *(dvhReader1.generateDVH()); - /*dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50*/ - rttb::io::other::DVHXMLFileReader dvhReader2 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT2); - core::DVH dvhNT2 = *(dvhReader2.generateDVH()); - /*dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70*/ - rttb::io::other::DVHXMLFileReader dvhReader3 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT3); - core::DVH dvhNT3 = *(dvhReader3.generateDVH()); - - std::vector dvhTVSet; - std::vector dvhHTSet; - dvhTVSet.push_back(dvhPTV); - dvhHTSet.push_back(dvhNT1); - dvhHTSet.push_back(dvhNT2); - dvhHTSet.push_back(dvhNT3); - - ::boost::shared_ptr dvhSetPtr = ::boost::make_shared(dvhTVSet, dvhHTSet, - "testStrSet", dvhPTV.getDoseID()); - - /*test exception*/ - ::boost::shared_ptr dvhSetNullPtr; - CHECK_THROW_EXPLICIT(indices::ConformalIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformationNumber(dvhSetNullPtr, 0), - core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformityIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::CoverageIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::HomogeneityIndex(dvhSetNullPtr, 0), core::InvalidParameterException); - - /*test exception for invalid reference dose*/ - CHECK_THROW_EXPLICIT(indices::ConformalIndex(dvhSetPtr, 100), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformationNumber(dvhSetPtr, 100), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::ConformityIndex(dvhSetPtr, 100), core::InvalidParameterException); - CHECK_THROW_EXPLICIT(indices::HomogeneityIndex(dvhSetPtr, 0), core::InvalidParameterException); - - /*test index calculation*/ - - /*RTConformationNumber */ - //PTV covered by reference dose 30 = the whole PTV =362.5; Volume of the referece 30=362.5+1.25 - indices::ConformationNumber cn = indices::ConformationNumber(dvhSetPtr, 30); - //check if values are close. Equality is only achieved with double precission. - CHECK_CLOSE(362.5 / 363.75, cn.getValue(), errorConstant); - - //cn==1*TV0/V0=362.5/2466.25 - cn.setDoseReference(0); - CHECK_CLOSE(362.5 / 2466.25, cn.getValue(), errorConstant); - - cn.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, cn.getValue(), - errorConstant); //ref dose: 65 -> TVref=Vref -> cn=TVref/TV=2300/2900 - - CHECK_EQUAL(cn.getValue(), cn.getValueAt(0)); - CHECK_THROW_EXPLICIT(cn.getValueAt(1), core::InvalidParameterException); - - /*ConformalIndex */ - //HT 1 covered by ref=HT2 covered by ref=0, HT3 covered by ref=1.25 - indices::ConformalIndex coin = indices::ConformalIndex(dvhSetPtr, 30); - CHECK_CLOSE((362.5 / 363.75) * (1 - 1.25 / 151.25), coin.getValue(), errorConstant); - - coin.setDoseReference(0); - CHECK_EQUAL(0, coin.getValue()); - - coin.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, coin.getValue(), - errorConstant); //ref dose: 65 -> Vref=0 for all HT -> cn=cn*(1-0)=cn - - CHECK_EQUAL(coin.getValue(), coin.getValueAt(0)); - CHECK_THROW_EXPLICIT(coin.getValueAt(1), core::InvalidParameterException); - - /*ConformityIndex */ - indices::ConformityIndex ci = indices::ConformityIndex(dvhSetPtr, 30); - CHECK_CLOSE(362.5 / 363.75, ci.getValue(), errorConstant); - - ci.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, ci.getValue(), errorConstant); //ref dose: 65->ci=2300/2900*1*1*1 - - CHECK_EQUAL(ci.getValue(), ci.getValueAt(0)); - CHECK_THROW_EXPLICIT(ci.getValueAt(1), core::InvalidParameterException); - - /*CoverageIndex*/ - indices::CoverageIndex coverageI = indices::CoverageIndex(dvhSetPtr, 30); - CHECK_CLOSE(362.5 / 362.5, coverageI.getValue(), errorConstant); //ref dose: 30 -> coverage index=1 - - coverageI.setDoseReference(65); - CHECK_CLOSE(2300 / 2900.0, coverageI.getValue(), - errorConstant); //ref dose: 65->coverage index=2300/2900 - - CHECK_EQUAL(coverageI.getValue(), coverageI.getValueAt(0)); - CHECK_THROW_EXPLICIT(coverageI.getValueAt(1), core::InvalidParameterException); - - - /*HomogeneityIndex TV max: 133*0.5=66.5, TV min: 127*0.5=63.5 -> hi=(66.5-63.5)/30*/ - indices::HomogeneityIndex hi = indices::HomogeneityIndex(dvhSetPtr, 30); - CHECK_CLOSE(3 / 30.0, hi.getValue(), errorConstant); - - hi.setDoseReference(65); - CHECK_CLOSE(3 / 65.0, hi.getValue(), errorConstant); - - CHECK_EQUAL(hi.getValue(), hi.getValueAt(0)); - CHECK_THROW_EXPLICIT(hi.getValueAt(1), core::InvalidParameterException); - - - RETURN_AND_REPORT_TEST_SUCCESS; - - - } - - }//testing +// ----------------------------------------------------------------------- +// 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. +// +//------------------------------------------------------------------------ + +// this file defines the rttbCoreTests for the test driver +// and all it expects is that you have a function called RegisterTests + +#include "litCheckMacros.h" +#include "rttbDoseIndex.h" +#include "rttbDVHSet.h" +#include "rttbBaseType.h" +#include "rttbNullPointerException.h" +#include "rttbHomogeneityIndex.h" +#include "rttbException.h" +#include "rttbInvalidParameterException.h" +#include "rttbDVHXMLFileReader.h" + +#include + +#include +#include + +namespace rttb +{ + namespace testing + { + /*! @brief HomogeneityIndex is tested. + test dvh: deltaV 0.125, deltaD 0.5 + 1. dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133 + 2. dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40 + 3. dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50 + 4. dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70 + + 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 HomogeneityIndexTest(int argc, char* argv[]) + { + PREPARE_DEFAULT_TEST_REPORTING; + + //ARGUMENTS: 1: ptv dvh file name + // 2: normal tissue 1 dvh file name + // 3: normal tissue 2 dvh file name + // 4: normal tissue 3 dvh file name + + std::string DVH_FILENAME_PTV; + std::string DVH_FILENAME_NT1; + std::string DVH_FILENAME_NT2; + std::string DVH_FILENAME_NT3; + + + if (argc > 1) + { + DVH_FILENAME_PTV = argv[1]; + } + + if (argc > 2) + { + DVH_FILENAME_NT1 = argv[2]; + } + + if (argc > 3) + { + DVH_FILENAME_NT2 = argv[3]; + } + + if (argc > 4) + { + DVH_FILENAME_NT3 = argv[4]; + } + + + /*test dvh: deltaV 0.125, deltaD 0.5*/ + /*dvh TV: number of voxels 2900, maximum dose bin 133, dose bin 127~133*/ + rttb::io::other::DVHXMLFileReader dvhReader = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_PTV); + rttb::core::DVH dvhPTV = *(dvhReader.generateDVH()); + /*dvh HT1: number of voxels 5410, maximum dose bin 40, dose bin 0~2,40*/ + rttb::io::other::DVHXMLFileReader dvhReader1 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT1); + core::DVH dvhNT1 = *(dvhReader1.generateDVH()); + /*dvh HT2: number of voxels 10210, maximum dose bin 50, dose bin 0~2,50*/ + rttb::io::other::DVHXMLFileReader dvhReader2 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT2); + core::DVH dvhNT2 = *(dvhReader2.generateDVH()); + /*dvh HT3: number of voxels 1210, maximum dose bin 70, dose bin 0~2,70*/ + rttb::io::other::DVHXMLFileReader dvhReader3 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT3); + core::DVH dvhNT3 = *(dvhReader3.generateDVH()); + + std::vector dvhTVSet; + std::vector dvhHTSet; + dvhTVSet.push_back(dvhPTV); + dvhHTSet.push_back(dvhNT1); + dvhHTSet.push_back(dvhNT2); + dvhHTSet.push_back(dvhNT3); + + ::boost::shared_ptr dvhSetPtr = ::boost::make_shared(dvhTVSet, dvhHTSet, + "testStrSet", dvhPTV.getDoseID()); + + /*test exception*/ + ::boost::shared_ptr dvhSetNullPtr; + CHECK_THROW_EXPLICIT(indices::HomogeneityIndex(dvhSetNullPtr, 0), core::InvalidParameterException); + + /*test exception for invalid reference dose*/ + CHECK_THROW_EXPLICIT(indices::HomogeneityIndex(dvhSetPtr, 0), core::InvalidParameterException); + + /*test index calculation*/ + /*HomogeneityIndex TV max: 133*0.5=66.5, TV min: 127*0.5=63.5 -> hi=(66.5-63.5)/30*/ + indices::HomogeneityIndex hi = indices::HomogeneityIndex(dvhSetPtr, 30); + CHECK_CLOSE(3 / 30.0, hi.getValue(), errorConstant); + + hi.setDoseReference(65); + CHECK_CLOSE(3 / 65.0, hi.getValue(), errorConstant); + + CHECK_EQUAL(hi.getValue(), hi.getValueAt(0)); + CHECK_THROW_EXPLICIT(hi.getValueAt(1), core::InvalidParameterException); + + RETURN_AND_REPORT_TEST_SUCCESS; + + } + + }//testing }//rttb \ No newline at end of file diff --git a/testing/indices/files.cmake b/testing/indices/files.cmake new file mode 100644 index 0000000..27624aa --- /dev/null +++ b/testing/indices/files.cmake @@ -0,0 +1,11 @@ +SET(CPP_FILES + rttbIndicesTests.cpp + ConformationNumberTest.cpp + ConformalIndexTest.cpp + ConformityIndexTest.cpp + CoverageIndexTest.cpp + HomogeneityIndexTest.cpp + ) + +SET(H_FILES +) diff --git a/testing/indices/rttbIndicesTests.cpp b/testing/indices/rttbIndicesTests.cpp new file mode 100644 index 0000000..e79fc79 --- /dev/null +++ b/testing/indices/rttbIndicesTests.cpp @@ -0,0 +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. +// +//------------------------------------------------------------------------ + +// 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(ConformationNumberTest); + LIT_REGISTER_TEST(ConformalIndexTest); + LIT_REGISTER_TEST(ConformityIndexTest); + LIT_REGISTER_TEST(CoverageIndexTest); + LIT_REGISTER_TEST(HomogeneityIndexTest); + } + } +} + +int main(int argc, char* argv[]) +{ + int result = 0; + + rttb::testing::registerTests(); + + try + { + result = lit::multiTestsMain(argc, argv); + } + + catch (...) + { + result = -1; + } + + return result; +}