diff --git a/apps/BioModelCalc/BioModelCalcApplicationData.h b/apps/BioModelCalc/BioModelCalcApplicationData.h index 9a27136..525f5b8 100644 --- a/apps/BioModelCalc/BioModelCalcApplicationData.h +++ b/apps/BioModelCalc/BioModelCalcApplicationData.h @@ -1,62 +1,62 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ #ifndef __BIO_MODEL_CALC_APPLICATION_DATA_H #define __BIO_MODEL_CALC_APPLICATION_DATA_H #include #include #include "rttbDoseAccessorInterface.h" namespace rttb { namespace apps { namespace bioModelCalc { class BioModelCmdLineParser; /*! @class ApplicationData @brief Class for storing all relevant variables needed in BioModelCalc */ class ApplicationData { public: - core::DoseAccessorInterface::DoseAccessorPointer _dose; - std::deque _modelParameterMaps; + core::DoseAccessorInterface::Pointer _dose; + std::deque _modelParameterMaps; std::string _doseFileName; std::string _doseLoadStyle; std::string _parameterMapsLoadStyle; double _doseScaling; unsigned int _nFractions; std::string _outputFileName; std::string _model; std::vector _modelParameters; std::vector _modelParameterMapsFilename; void reset(); ApplicationData(); }; /*! @brief Reads the necessary arguments from the BioModelCmdLineParser and writes them in the respective variables of ApplicationData */ void populateAppData(boost::shared_ptr argParser, ApplicationData& appData); } } } #endif diff --git a/apps/BioModelCalc/BioModelCalcHelper.cpp b/apps/BioModelCalc/BioModelCalcHelper.cpp index 53de684..d87a645 100644 --- a/apps/BioModelCalc/BioModelCalcHelper.cpp +++ b/apps/BioModelCalc/BioModelCalcHelper.cpp @@ -1,96 +1,96 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1374 $ (last changed revision) // @date $Date: 2016-05-30 14:15:42 +0200 (Mo, 30 Mai 2016) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "BioModelCalcHelper.h" #include "boost/make_shared.hpp" #include "boost/shared_ptr.hpp" #include "rttbExceptionMacros.h" #include "BioModelCalcApplicationData.h" #include "rttbITKImageAccessorConverter.h" #include "rttbImageWriter.h" #include "rttbLQModelAccessor.h" void rttb::apps::bioModelCalc::processData(rttb::apps::bioModelCalc::ApplicationData& appData) { - rttb::core::DoseAccessorInterface::DoseAccessorPointer outputAccessor; + rttb::core::DoseAccessorInterface::Pointer outputAccessor; std::cout << std::endl << "generate biomodel... "; - rttb::core::AccessorInterface::AccessorPointer bioModelAccessor; + rttb::core::AccessorInterface::Pointer bioModelAccessor; if (!appData._modelParameters.empty()){ bioModelAccessor = generateBioModel(appData._dose, appData._model, appData._modelParameters, appData._nFractions, appData._doseScaling); } else { bioModelAccessor = generateBioModelWithMaps(appData._dose, appData._model, appData._modelParameterMaps, appData._nFractions, appData._doseScaling); } std::cout << "done." << std::endl; std::cout << std::endl << "generate output image... "; io::itk::ITKImageAccessorConverter converter(bioModelAccessor); converter.setFailOnInvalidIDs(true); converter.process(); io::itk::ITKImageAccessorConverter::ITKImageType::Pointer itkImage = converter.getITKImage(); std::cout << "done." << std::endl; std::cout << std::endl << "write output image... "; io::itk::ImageWriter writer(appData._outputFileName, itkImage.GetPointer()); writer.writeFile(); std::cout << "done." << std::endl; } -rttb::core::AccessorInterface::AccessorPointer rttb::apps::bioModelCalc::generateBioModel( - rttb::core::DoseAccessorInterface::DoseAccessorPointer dose, const std::string& model, +rttb::core::AccessorInterface::Pointer rttb::apps::bioModelCalc::generateBioModel( + rttb::core::DoseAccessorInterface::Pointer dose, const std::string& model, const std::vector& modelParameters, unsigned int nFractions, double doseScaling) { if (model == "LQ") { return boost::make_shared(dose, modelParameters.at(0), modelParameters.at(1), nFractions, doseScaling); } else { rttbDefaultExceptionStaticMacro( << "Unknown model selected. Cannot load data. Selected model: " << model); } } -rttb::core::AccessorInterface::AccessorPointer rttb::apps::bioModelCalc::generateBioModelWithMaps( - rttb::core::DoseAccessorInterface::DoseAccessorPointer dose, const std::string& model, - const std::deque& modelParameterMaps, unsigned int nFractions, double doseScaling) +rttb::core::AccessorInterface::Pointer rttb::apps::bioModelCalc::generateBioModelWithMaps( + rttb::core::DoseAccessorInterface::Pointer dose, const std::string& model, + const std::deque& modelParameterMaps, unsigned int nFractions, double doseScaling) { if (model == "LQ") { return boost::make_shared(dose, modelParameterMaps.at(0), modelParameterMaps.at(1), nFractions, doseScaling); } else { rttbDefaultExceptionStaticMacro(<< "Unknown model selected. Cannot load data. Selected model: " << model); } } diff --git a/apps/BioModelCalc/BioModelCalcHelper.h b/apps/BioModelCalc/BioModelCalcHelper.h index c1c84f2..a4078e2 100644 --- a/apps/BioModelCalc/BioModelCalcHelper.h +++ b/apps/BioModelCalc/BioModelCalcHelper.h @@ -1,53 +1,53 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1210 $ (last changed revision) // @date $Date: 2015-11-24 15:52:45 +0100 (Di, 24 Nov 2015) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __BIO_MODEL_CALC_HELPER_H #define __BIO_MODEL_CALC_HELPER_H #include #include "rttbAccessorInterface.h" #include "rttbDoseAccessorInterface.h" namespace rttb { namespace apps { namespace bioModelCalc { class ApplicationData; void processData(ApplicationData& appData); - core::AccessorInterface::AccessorPointer generateBioModel( - core::DoseAccessorInterface::DoseAccessorPointer dose, const std::string& model, + core::AccessorInterface::Pointer generateBioModel( + core::DoseAccessorInterface::Pointer dose, const std::string& model, const std::vector& modelParameters, unsigned int nFractions=1, double doseScaling = 1.0); - rttb::core::AccessorInterface::AccessorPointer generateBioModelWithMaps( - rttb::core::DoseAccessorInterface::DoseAccessorPointer dose, const std::string& model, - const std::deque& modelParameterMaps, unsigned int nFractions = 1, double doseScaling = 1.0); + rttb::core::AccessorInterface::Pointer generateBioModelWithMaps( + rttb::core::DoseAccessorInterface::Pointer dose, const std::string& model, + const std::deque& modelParameterMaps, unsigned int nFractions = 1, double doseScaling = 1.0); } } } #endif diff --git a/apps/DoseAcc/DoseAccApplicationData.h b/apps/DoseAcc/DoseAccApplicationData.h index 85de2f8..c0a3139 100644 --- a/apps/DoseAcc/DoseAccApplicationData.h +++ b/apps/DoseAcc/DoseAccApplicationData.h @@ -1,68 +1,68 @@ // ----------------------------------------------------------------------- // 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 __DOSE_ACC_APPLICATION_DATA_H #define __DOSE_ACC_APPLICATION_DATA_H #include "mapRegistration.h" #include "rttbDoseAccessorInterface.h" namespace rttb { namespace apps { namespace doseAcc { class DoseAccCmdLineParser; /*! @class ApplicationData @brief Class for storing all relevant variables needed in DoseAcc */ class ApplicationData { public: typedef map::core::Registration<3, 3> RegistrationType; /** Loaded Dose.*/ - core::DoseAccessorInterface::DoseAccessorPointer _dose1; + core::DoseAccessorInterface::Pointer _dose1; std::string _dose1FileName; std::string _dose1LoadStyle; - core::DoseAccessorInterface::DoseAccessorPointer _dose2; + core::DoseAccessorInterface::Pointer _dose2; std::string _dose2FileName; std::string _dose2LoadStyle; RegistrationType::Pointer _spReg; std::string _regFileName; std::string _operator; std::string _outputFileName; double _weightDose1; double _weightDose2; std::string _interpolatorName; void Reset(); ApplicationData(); }; /*! @brief Reads the necessary arguments from the DoseToolCmdLineParser and writes them in the respective variables of ApplicationData. */ void populateAppData(boost::shared_ptr argParser, ApplicationData& appData); } } } #endif diff --git a/apps/DoseAcc/DoseAccHelper.cpp b/apps/DoseAcc/DoseAccHelper.cpp index 2ee9211..0a5eac7 100644 --- a/apps/DoseAcc/DoseAccHelper.cpp +++ b/apps/DoseAcc/DoseAccHelper.cpp @@ -1,172 +1,172 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1132 $ (last changed revision) // @date $Date: 2015-10-06 14:48:56 +0200 (Di, 06 Okt 2015) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "DoseAccHelper.h" #include "boost/make_shared.hpp" #include "mapRegistrationFileReader.h" #include "rttbExceptionMacros.h" #include "rttbITKImageAccessorConverter.h" #include "rttbSimpleMappableDoseAccessor.h" #include "rttbMatchPointTransformation.h" #include "rttbLinearInterpolation.h" #include "rttbNearestNeighborInterpolation.h" #include "rttbRosuMappableDoseAccessor.h" #include "rttbArithmetic.h" #include "rttbBinaryFunctorAccessor.h" #include "rttbImageWriter.h" rttb::apps::doseAcc::ApplicationData::RegistrationType::Pointer rttb::apps::doseAcc::loadRegistration(const std::string& fileName) { map::io::RegistrationFileReader::Pointer spRegReader = map::io::RegistrationFileReader::New(); map::io::RegistrationFileReader::LoadedRegistrationPointer spReg; std::cout << std::endl << "read registration file... "; spReg = spRegReader->read(fileName); std::cout << "done." << std::endl; ApplicationData::RegistrationType::Pointer resultPtr = dynamic_cast(spReg.GetPointer()); if (resultPtr.IsNull()) { rttbDefaultExceptionStaticMacro( << "Loaded registration cannot be used. Only 3D 3D registrations are allowed."); } return resultPtr; }; -rttb::core::DoseAccessorInterface::DoseAccessorPointer generateNNMappableAccessor( +rttb::core::DoseAccessorInterface::Pointer generateNNMappableAccessor( const rttb::core::GeometricInfo& geoInfoTargetImage, - const rttb::core::DoseAccessorInterface::DoseAccessorPointer doseMovingImage, + const rttb::core::DoseAccessorInterface::Pointer doseMovingImage, const rttb::interpolation::TransformationInterface::Pointer aTransformation) { auto interpolate = boost::make_shared(); return boost::make_shared(geoInfoTargetImage, doseMovingImage, aTransformation, interpolate); } -rttb::core::DoseAccessorInterface::DoseAccessorPointer generateLinearMappableAccessor( +rttb::core::DoseAccessorInterface::Pointer generateLinearMappableAccessor( const rttb::core::GeometricInfo& geoInfoTargetImage, - const rttb::core::DoseAccessorInterface::DoseAccessorPointer doseMovingImage, + const rttb::core::DoseAccessorInterface::Pointer doseMovingImage, const rttb::interpolation::TransformationInterface::Pointer aTransformation) { auto interpolate = boost::make_shared(); return boost::make_shared(geoInfoTargetImage, doseMovingImage, aTransformation, interpolate); } -rttb::core::DoseAccessorInterface::DoseAccessorPointer generateRosuMappableAccessor( +rttb::core::DoseAccessorInterface::Pointer generateRosuMappableAccessor( const rttb::core::GeometricInfo& geoInfoTargetImage, - const rttb::core::DoseAccessorInterface::DoseAccessorPointer doseMovingImage, + const rttb::core::DoseAccessorInterface::Pointer doseMovingImage, const rttb::interpolation::TransformationInterface::Pointer aTransformation) { return boost::make_shared(geoInfoTargetImage, doseMovingImage, aTransformation); } /**Private helper function for processData(). Generates a suitable output accessor * (depending on the configuration in appData a suitable accessor pipeline is established) * which performs the accumulation of the doses and returns the output.to */ -rttb::core::DoseAccessorInterface::DoseAccessorPointer +rttb::core::DoseAccessorInterface::Pointer assembleOutputAccessor(rttb::apps::doseAcc::ApplicationData& appData) { - rttb::core::DoseAccessorInterface::DoseAccessorPointer dose2Accessor = appData._dose2; + rttb::core::DoseAccessorInterface::Pointer dose2Accessor = appData._dose2; if (appData._spReg.IsNotNull()) { auto transform = boost::make_shared(appData._spReg); if (appData._interpolatorName == "rosu") { dose2Accessor = generateRosuMappableAccessor(appData._dose1->getGeometricInfo(), appData._dose2, transform); } else if (appData._interpolatorName == "nn") { dose2Accessor = generateNNMappableAccessor(appData._dose1->getGeometricInfo(), appData._dose2, transform); } else if (appData._interpolatorName == "linear") { dose2Accessor = generateLinearMappableAccessor(appData._dose1->getGeometricInfo(), appData._dose2, transform); } else { rttbDefaultExceptionStaticMacro( << "Unkown interpolation type selected. Cannot map dose. Interpolation type: " << appData._interpolatorName); } } - rttb::core::DoseAccessorInterface::DoseAccessorPointer outputAccessor; + rttb::core::DoseAccessorInterface::Pointer outputAccessor; if (appData._operator == "+") { rttb::algorithms::arithmetic::doseOp::AddWeighted addOp(appData._weightDose1, appData._weightDose2); outputAccessor = boost::make_shared >(appData._dose1, dose2Accessor, addOp); } else if (appData._operator == "*") { outputAccessor = boost::make_shared > (appData._dose1, dose2Accessor, rttb::algorithms::arithmetic::doseOp::Multiply()); } else { rttbDefaultExceptionStaticMacro( << "Unkown operator selected. Cannot map dose. Operator: " << appData._interpolatorName); } return outputAccessor; } void rttb::apps::doseAcc::processData(rttb::apps::doseAcc::ApplicationData& appData) { - rttb::core::DoseAccessorInterface::DoseAccessorPointer outputAccessor = assembleOutputAccessor( + rttb::core::DoseAccessorInterface::Pointer outputAccessor = assembleOutputAccessor( appData); std::cout << std::endl << "generate output image... "; io::itk::ITKImageAccessorConverter converter(outputAccessor); converter.setFailOnInvalidIDs(true); converter.process(); io::itk::ITKImageAccessorConverter::ITKImageType::Pointer itkImage = converter.getITKImage(); std::cout << "done." << std::endl; std::cout << std::endl << "write output image... "; io::itk::ImageWriter writer(appData._outputFileName, itkImage.GetPointer()); writer.writeFile(); std::cout << "done." << std::endl; }; diff --git a/apps/DoseMap/DoseMapApplicationData.h b/apps/DoseMap/DoseMapApplicationData.h index 517d754..550b9bf 100644 --- a/apps/DoseMap/DoseMapApplicationData.h +++ b/apps/DoseMap/DoseMapApplicationData.h @@ -1,66 +1,66 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ #ifndef __DOSEMAP_APPLICATION_DATA_H #define __DOSEMAP_APPLICATION_DATA_H #include "mapRegistration.h" #include "rttbDoseAccessorInterface.h" namespace rttb { namespace apps { namespace doseMap { class DoseMapCmdLineParser; /*! @class ApplicationData @brief Class for storing all relevant variables needed in DoseMap */ class ApplicationData { public: typedef map::core::Registration<3, 3> RegistrationType; /** Loaded Dose.*/ - core::DoseAccessorInterface::DoseAccessorPointer _inputDose; + core::DoseAccessorInterface::Pointer _inputDose; std::string _inputDoseFileName; std::string _inputDoseLoadStyle; - core::DoseAccessorInterface::DoseAccessorPointer _refDose; + core::DoseAccessorInterface::Pointer _refDose; std::string _refDoseFileName; std::string _refDoseLoadStyle; RegistrationType::Pointer _spReg; std::string _regFileName; std::string _outputFileName; std::string _interpolatorName; void reset(); ApplicationData(); }; /*! @brief Reads the necessary arguments from the DoseToolCmdLineParser and writes them in the respective variables of ApplicationData. */ void populateAppData(boost::shared_ptr argParser, ApplicationData& appData); } } } #endif diff --git a/apps/DoseMap/DoseMapHelper.cpp b/apps/DoseMap/DoseMapHelper.cpp index 4670e43..6d833d9 100644 --- a/apps/DoseMap/DoseMapHelper.cpp +++ b/apps/DoseMap/DoseMapHelper.cpp @@ -1,120 +1,120 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1127 $ (last changed revision) // @date $Date: 2015-10-01 13:33:33 +0200 (Do, 01 Okt 2015) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "DoseMapHelper.h" #include #include "mapRegistrationFileReader.h" #include "rttbITKImageAccessorConverter.h" #include "rttbSimpleMappableDoseAccessor.h" #include "rttbMatchPointTransformation.h" #include "rttbLinearInterpolation.h" #include "rttbNearestNeighborInterpolation.h" #include "rttbRosuMappableDoseAccessor.h" #include "rttbArithmetic.h" #include "rttbBinaryFunctorAccessor.h" #include "rttbExceptionMacros.h" #include "rttbImageWriter.h" rttb::apps::doseMap::ApplicationData::RegistrationType::Pointer rttb::apps::doseMap::loadRegistration(const std::string& fileName) { map::io::RegistrationFileReader::Pointer spRegReader = map::io::RegistrationFileReader::New(); map::io::RegistrationFileReader::LoadedRegistrationPointer spReg; std::cout << std::endl << "read registration file... "; spReg = spRegReader->read(fileName); std::cout << "done." << std::endl; ApplicationData::RegistrationType::Pointer resultPtr = dynamic_cast(spReg.GetPointer()); if (resultPtr.IsNull()) { mapDefaultExceptionStaticMacro( << "Loaded registration cannot be used. Only 3D 3D registrations are allowed."); } return resultPtr; }; /**Private helper function for processData(). Generates a suitable output accessor * (depending on the configuration in appData a suitable accessor pipeline is established) * which performs the accumulation of the doses and returns the output.to */ -rttb::core::DoseAccessorInterface::DoseAccessorPointer +rttb::core::DoseAccessorInterface::Pointer assembleOutputAccessor(rttb::apps::doseMap::ApplicationData& appData) { - rttb::core::DoseAccessorInterface::DoseAccessorPointer outputAccessor = appData._inputDose; + rttb::core::DoseAccessorInterface::Pointer outputAccessor = appData._inputDose; auto transform = boost::make_shared(appData._spReg); if (appData._interpolatorName == "rosu") { outputAccessor = boost::make_shared(appData._refDose->getGeometricInfo(), appData._inputDose, transform); } else { rttb::interpolation::InterpolationBase::Pointer interpolate = boost::make_shared(); if (appData._interpolatorName == "nn") { interpolate = boost::make_shared(); } else if (appData._interpolatorName != "linear") { mapDefaultExceptionStaticMacro( << "Unkown interpolation type selected. Cannot map dose. Interpolation type: " << appData._interpolatorName); } outputAccessor = boost::make_shared(appData._refDose->getGeometricInfo(), appData._inputDose, transform, interpolate); } return outputAccessor; } void rttb::apps::doseMap::processData(rttb::apps::doseMap::ApplicationData& appData) { - rttb::core::DoseAccessorInterface::DoseAccessorPointer outputAccessor = assembleOutputAccessor( + rttb::core::DoseAccessorInterface::Pointer outputAccessor = assembleOutputAccessor( appData); std::cout << std::endl << "generate output image... "; io::itk::ITKImageAccessorConverter converter(outputAccessor); converter.setFailOnInvalidIDs(true); converter.process(); io::itk::ITKImageAccessorConverter::ITKImageType::Pointer itkImage = converter.getITKImage(); std::cout << "done." << std::endl; std::cout << std::endl << "write output image... "; io::itk::ImageWriter writer(appData._outputFileName, itkImage.GetPointer()); writer.writeFile(); std::cout << "done." << std::endl; }; diff --git a/apps/DoseTool/DoseToolApplicationData.h b/apps/DoseTool/DoseToolApplicationData.h index 73c0d6a..384bf27 100644 --- a/apps/DoseTool/DoseToolApplicationData.h +++ b/apps/DoseTool/DoseToolApplicationData.h @@ -1,66 +1,66 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ #ifndef __DOSETOOL_APPLICATION_DATA_H #define __DOSETOOL_APPLICATION_DATA_H #include #include "rttbDoseAccessorInterface.h" #include "rttbStructureSetGeneratorInterface.h" namespace rttb { namespace apps { namespace doseTool { class DoseToolCmdLineParser; /*! @class ApplicationData @brief Class for storing all relevant variables needed in DoseTool */ class ApplicationData { public: - core::DoseAccessorInterface::DoseAccessorPointer _dose; - core::StructureSetGeneratorInterface::StructureSetPointer _struct; + core::DoseAccessorInterface::Pointer _dose; + core::StructureSet::Pointer _struct; std::string _structNameRegex; std::vector _structNames; std::string _doseFileName; std::string _structFileName; std::string _doseLoadStyle; std::string _structLoadStyle; bool _computeComplexDoseStatistics; DoseTypeGy _prescribedDose; std::string _doseStatisticOutputFileName; bool _allowSelfIntersection; bool _multipleStructsMode; bool _computeDVH; bool _computeDoseStatistics; std::string _dvhOutputFilename; /*! @brief Resets the variables. _prescribedDose is set to 1.0 because it produces no exception then (as it is not needed). Consistency checks are done in DoseToolCmdLineParser::validateInput() */ void reset(); ApplicationData(); }; /*! @brief Reads the necessary arguments from the DoseToolCmdLineParser and writes them in the respective variables of ApplicationData. */ void populateAppData(boost::shared_ptr argParser, ApplicationData& appData); } } } #endif diff --git a/apps/DoseTool/DoseToolHelper.cpp b/apps/DoseTool/DoseToolHelper.cpp index 80260c5..8b4687e 100644 --- a/apps/DoseTool/DoseToolHelper.cpp +++ b/apps/DoseTool/DoseToolHelper.cpp @@ -1,201 +1,211 @@ // ----------------------------------------------------------------------- // 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 "DoseToolHelper.h" #include "boost/make_shared.hpp" #include "boost/shared_ptr.hpp" #include "boost/property_tree/ptree.hpp" #include "boost/property_tree/xml_parser.hpp" #include "boost/filesystem.hpp" #include "DoseToolApplicationData.h" #include "rttbDicomFileStructureSetGenerator.h" #include "rttbITKImageFileMaskAccessorGenerator.h" #include "rttbDoseStatistics.h" #include "rttbDVH.h" #include "rttbDVHCalculator.h" #include "rttbDVHXMLFileWriter.h" #include "rttbDoseStatisticsCalculator.h" #include "rttbBoostMaskAccessor.h" #include "rttbGenericMaskedDoseIterator.h" #include "rttbDoseStatisticsXMLWriter.h" -std::vector rttb::apps::doseTool::generateMasks(rttb::apps::doseTool::ApplicationData& appData) { - - std::vector maskAccessorPtrVector; +std::vector +rttb::apps::doseTool::generateMasks( + rttb::apps::doseTool::ApplicationData& appData) +{ + std::vector maskAccessorPtrVector; if (appData._structLoadStyle == "itk" || appData._structLoadStyle == "itkDicom") { maskAccessorPtrVector.push_back(rttb::io::itk::ITKImageFileMaskAccessorGenerator(appData._structFileName).generateMaskAccessor()); appData._structNames.push_back(appData._structNameRegex); } else { if (appData._struct->getNumberOfStructures() > 0) { //default behavior: read only first struct that matches the regex unsigned int maxIterationCount = 1; //only if specified: read all structs that matches the regex if (appData._multipleStructsMode) { maxIterationCount = appData._struct->getNumberOfStructures(); } bool strict = !appData._allowSelfIntersection; for (size_t i = 0; i < maxIterationCount; i++) { maskAccessorPtrVector.emplace_back(boost::make_shared(appData._struct->getStructure(i), appData._dose->getGeometricInfo(), strict)); maskAccessorPtrVector.at(i)->updateMask(); appData._structNames.push_back(appData._struct->getStructure(i)->getLabel()); } } else { std::cout << "no structures in structure set!" << std::endl; } } return maskAccessorPtrVector; } -rttb::core::DoseIteratorInterface::DoseIteratorPointer rttb::apps::doseTool::generateMaskedDoseIterator( - rttb::core::MaskAccessorInterface::MaskAccessorPointer maskAccessorPtr, - rttb::core::DoseAccessorInterface::DoseAccessorPointer doseAccessorPtr) { - - boost::shared_ptr maskedDoseIterator = boost::make_shared(maskAccessorPtr, doseAccessorPtr); - rttb::core::DoseIteratorInterface::DoseIteratorPointer doseIterator(maskedDoseIterator); +rttb::core::DoseIteratorInterface::Pointer +rttb::apps::doseTool::generateMaskedDoseIterator( + rttb::core::MaskAccessorInterface::Pointer maskAccessorPtr, + rttb::core::DoseAccessorInterface::Pointer doseAccessorPtr) +{ + boost::shared_ptr maskedDoseIterator = + boost::make_shared(maskAccessorPtr, doseAccessorPtr); + rttb::core::DoseIteratorInterface::Pointer doseIterator(maskedDoseIterator); return doseIterator; } -rttb::algorithms::DoseStatistics::DoseStatisticsPointer calculateDoseStatistics( - rttb::core::DoseIteratorInterface::DoseIteratorPointer doseIterator, - bool calculateComplexDoseStatistics, - rttb::DoseTypeGy prescribedDose) { - +rttb::algorithms::DoseStatistics::Pointer +calculateDoseStatistics( + rttb::core::DoseIteratorInterface::Pointer doseIterator, bool calculateComplexDoseStatistics, + rttb::DoseTypeGy prescribedDose) +{ rttb::algorithms::DoseStatisticsCalculator doseStatsCalculator(doseIterator); if (calculateComplexDoseStatistics) { return doseStatsCalculator.calculateDoseStatistics(prescribedDose); } else { return doseStatsCalculator.calculateDoseStatistics(); } } -rttb::core::DVH::DVHPointer calculateDVH(rttb::core::DoseIteratorInterface::DoseIteratorPointer doseIterator, rttb::IDType structUID, rttb::IDType doseUID) { +rttb::core::DVH::Pointer calculateDVH( + rttb::core::DoseIteratorInterface::Pointer + doseIterator, rttb::IDType structUID, rttb::IDType doseUID) +{ rttb::core::DVHCalculator calc(doseIterator, structUID, doseUID); - rttb::core::DVH::DVHPointer dvh = calc.generateDVH(); + rttb::core::DVH::Pointer dvh = calc.generateDVH(); return dvh; } std::string rttb::apps::doseTool::assembleFilenameWithStruct(const std::string& originalFilename, const std::string& structName) { boost::filesystem::path originalFile(originalFilename); std::string newFilename = originalFile.stem().string() + "_" + structName + originalFile.extension().string(); boost::filesystem::path newFile(originalFile.parent_path() / newFilename); return newFile.string(); } /*! @brief Writes the dose statistics as XML to a file @details adds a .... part to the RTTB generated xml where the used files and struct names are stored. */ -void writeDoseStatisticsFile(rttb::algorithms::DoseStatistics::DoseStatisticsPointer statistics, - const std::string& filename, - const std::string& structName, - rttb::apps::doseTool::ApplicationData& appData) { +void writeDoseStatisticsFile( + rttb::algorithms::DoseStatistics::Pointer statistics, + const std::string& filename, const std::string& structName, + rttb::apps::doseTool::ApplicationData& appData) +{ auto doseStatisticsXMLWriter = rttb::io::other::DoseStatisticsXMLWriter(); boost::property_tree::ptree originalTree = doseStatisticsXMLWriter.writeDoseStatistics(statistics); //add config part to xml originalTree.add("statistics.config.requestedStructRegex", appData._structNameRegex); originalTree.add("statistics.config.structName", structName); originalTree.add("statistics.config.doseUID", appData._dose->getUID()); originalTree.add("statistics.config.doseFile", appData._doseFileName); originalTree.add("statistics.config.structFile", appData._structFileName); boost::property_tree::ptree reorderedTree, configTree, resultsTree; configTree = originalTree.get_child("statistics.config"); resultsTree = originalTree.get_child("statistics.results"); reorderedTree.add_child("statistics.config", configTree); reorderedTree.add_child("statistics.results", resultsTree); boost::property_tree::write_xml(filename, reorderedTree, std::locale(), boost::property_tree::xml_writer_make_settings('\t', 1)); } -void writeDVHFile(rttb::core::DVH::DVHPointer dvh, const std::string& filename) { +void writeDVHFile(rttb::core::DVH::Pointer dvh, const std::string& filename) { rttb::DVHType typeCum = { rttb::DVHType::Cumulative }; rttb::io::other::DVHXMLFileWriter dvhWriter(filename, typeCum); dvhWriter.writeDVH(dvh); } void rttb::apps::doseTool::processData(rttb::apps::doseTool::ApplicationData& appData) { std::cout << std::endl << "generating masks... "; - std::vector maskAccessorPtrVector = generateMasks(appData); + std::vector maskAccessorPtrVector = generateMasks( + appData); std::cout << "done." << std::endl; for (size_t i = 0; i < maskAccessorPtrVector.size(); i++) { - core::DoseIteratorInterface::DoseIteratorPointer spDoseIterator(generateMaskedDoseIterator( + core::DoseIteratorInterface::Pointer spDoseIterator(generateMaskedDoseIterator( maskAccessorPtrVector.at(i), appData._dose)); if (appData._computeDoseStatistics) { std::cout << std::endl << "computing dose statistics... "; - algorithms::DoseStatistics::DoseStatisticsPointer statistics = calculateDoseStatistics( + auto statistics = calculateDoseStatistics( spDoseIterator, appData._computeComplexDoseStatistics, appData._prescribedDose); std::cout << "done." << std::endl; std::cout << std::endl << "writing dose statistics to file... "; std::string outputFilename; if (appData._multipleStructsMode) { outputFilename = assembleFilenameWithStruct(appData._doseStatisticOutputFileName, appData._structNames.at(i)); } else { outputFilename = appData._doseStatisticOutputFileName; } writeDoseStatisticsFile(statistics, outputFilename, appData._structNames.at(i), appData); std::cout << "done." << std::endl; } if (appData._computeDVH) { std::cout << std::endl << "computing DVH... "; rttb::IDType structUID; rttb::IDType doseUID; //Generate random UID if (appData._structLoadStyle == "itk") { structUID = "struct.fromVoxelizedITK"; doseUID = "dose.fromVoxelizedITK"; } else { structUID = appData._struct->getUID(); doseUID = appData._dose->getUID(); } - core::DVH::DVHPointer dvh = calculateDVH(spDoseIterator, structUID, doseUID); + core::DVH::Pointer dvh = calculateDVH(spDoseIterator, structUID, + doseUID); std::cout << "done." << std::endl; std::cout << std::endl << "writing DVH to file... "; std::string outputFilename; if (appData._multipleStructsMode) { outputFilename = assembleFilenameWithStruct(appData._dvhOutputFilename, appData._structNames.at(i)); } else { outputFilename = appData._dvhOutputFilename; } writeDVHFile(dvh, outputFilename); std::cout << "done." << std::endl; } } } diff --git a/apps/DoseTool/DoseToolHelper.h b/apps/DoseTool/DoseToolHelper.h index 09fd25e..54f2da1 100644 --- a/apps/DoseTool/DoseToolHelper.h +++ b/apps/DoseTool/DoseToolHelper.h @@ -1,68 +1,60 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1374 $ (last changed revision) // @date $Date: 2016-05-30 14:15:42 +0200 (Mo, 30 Mai 2016) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __DOSETOOL_HELPER_H #define __DOSETOOL_HELPER_H #include "rttbDoseAccessorInterface.h" #include "rttbStructureSetGeneratorInterface.h" #include "rttbDoseIteratorInterface.h" #include "rttbMaskAccessorInterface.h" namespace rttb { namespace apps { namespace doseTool { class ApplicationData; /*! @brief Contains the business logic of processing all information to calculate the dose statistics and writing them to an xml file. @details Uses appData for the input data and the correct configuration. */ void processData(ApplicationData& appData); /*! @brief Generates a mask from the struct file by using the boostAccessor. In case of itk image, it directly loads the voxelized image. */ - std::vector generateMasks( + std::vector generateMasks( ApplicationData& appData); - /*algorithms::DoseStatistics::DoseStatisticsPointer calculateDoseStatistics( - core::DoseIteratorInterface::DoseIteratorPointer - doseIterator, bool calculateComplexDoseStatistics, DoseTypeGy prescribedDose); - - core::DVH::DVHPointer calculateDVH(core::DoseIteratorInterface::DoseIteratorPointer doseIterator, - IDType structUID, - IDType doseUID);*/ - - core::DoseIteratorInterface::DoseIteratorPointer generateMaskedDoseIterator( - core::MaskAccessorInterface::MaskAccessorPointer - maskAccessorPtr, core::DoseAccessorInterface::DoseAccessorPointer doseAccessorPtr); + core::DoseIteratorInterface::Pointer generateMaskedDoseIterator( + core::MaskAccessorInterface::Pointer + maskAccessorPtr, core::DoseAccessorInterface::Pointer doseAccessorPtr); std::string assembleFilenameWithStruct(const std::string& originalFilename, const std::string& structName); } } } #endif diff --git a/apps/VoxelizerTool/VoxelizerToolApplicationData.h b/apps/VoxelizerTool/VoxelizerToolApplicationData.h index f68ee09..db8e74f 100644 --- a/apps/VoxelizerTool/VoxelizerToolApplicationData.h +++ b/apps/VoxelizerTool/VoxelizerToolApplicationData.h @@ -1,66 +1,66 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ #ifndef __VoxelizerApplicationData_h #define __VoxelizerApplicationData_h #include "boost/shared_ptr.hpp" #include "rttbDoseAccessorInterface.h" #include "rttbStructureSetGeneratorInterface.h" #include #include namespace rttb { namespace apps { namespace voxelizerTool { class VoxelizerCmdLineParser; /*! @class ApplicationData @brief Class for storing all relevant variables needed in VoxelizerTool */ class ApplicationData { public: - core::DoseAccessorInterface::DoseAccessorPointer _dose; - core::StructureSetGeneratorInterface::StructureSetPointer _struct; + core::DoseAccessorInterface::Pointer _dose; + core::StructureSet::Pointer _struct; std::string _structFile; std::string _referenceFile; std::string _outputFilename; std::string _regEx; std::string _referenceFileLoadStyle; std::string _structFileLoadStyle; bool _multipleStructs; bool _binaryVoxelization; bool _addStructures; bool _noStrictVoxelization; /*! @brief Resets the variables. */ void reset(); ApplicationData(); }; /*! @brief Reads the necessary arguments from the VoxelizerCmdLineParser and writes them in the respective variables of ApplicationData. */ void populateAppData(boost::shared_ptr argParser, ApplicationData& appData); } } } #endif diff --git a/apps/VoxelizerTool/VoxelizerToolHelper.cpp b/apps/VoxelizerTool/VoxelizerToolHelper.cpp index cbeb35c..d53f3a5 100644 --- a/apps/VoxelizerTool/VoxelizerToolHelper.cpp +++ b/apps/VoxelizerTool/VoxelizerToolHelper.cpp @@ -1,216 +1,216 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1127 $ (last changed revision) // @date $Date: 2015-10-01 13:33:33 +0200 (Do, 01 Okt 2015) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include #include "rttbBoostMaskAccessor.h" #include "itkMacro.h" #include "VoxelizerToolHelper.h" #include "VoxelizerToolApplicationData.h" #include "rttbITKImageMaskAccessorConverter.h" #include "rttbImageWriter.h" #include "itkBinaryThresholdImageFilter.h" #include "itkAddImageFilter.h" #include #include #include "rttbUtils.h" #include "rttbDicomFileStructureSetGenerator.h" void rttb::apps::voxelizerTool::removeSpecialCharacters(std::string& label) { //Replace / to avoid problems with directories (struct "Magen/DD" --> Magen/DD.mhd), delete trailing . to avoid filenames with two trailing points (Niere re. --> Niere re..mhd) while (label.find("/") != std::string::npos) { label.replace(label.find("/"), 1, "_"); } if (*label.rbegin() == '.') { label.replace(label.size() - 1, 1, ""); } } -rttb::core::MaskAccessorInterface::MaskAccessorPointer rttb::apps::voxelizerTool::createMask( - rttb::core::DoseAccessorInterface::DoseAccessorPointer doseAccessorPtr, - rttb::core::Structure::StructTypePointer structurePtr, +rttb::core::MaskAccessorInterface::Pointer rttb::apps::voxelizerTool::createMask( + rttb::core::DoseAccessorInterface::Pointer doseAccessorPtr, + rttb::core::Structure::Pointer structurePtr, bool strict) { - rttb::core::MaskAccessorInterface::MaskAccessorPointer maskAccessorPtr; + rttb::core::MaskAccessorInterface::Pointer maskAccessorPtr; if (doseAccessorPtr != nullptr && structurePtr != nullptr) { maskAccessorPtr = boost::make_shared (structurePtr, doseAccessorPtr->getGeometricInfo(), strict); maskAccessorPtr->updateMask(); } return maskAccessorPtr; } -void rttb::apps::voxelizerTool::writeMaskToFile(std::vector maskVector, +void rttb::apps::voxelizerTool::writeMaskToFile(std::vector maskVector, const std::string& outputFileName, bool voxelization) { if (!maskVector.empty()) { io::itk::ITKImageMaskAccessor::ITKMaskImageType::ConstPointer itkImage; if (maskVector.size() > 1) { itkImage = addMultipleStructsToImage(maskVector); } else { io::itk::ITKImageMaskAccessorConverter maskAccessorConverter(maskVector.at(0)); maskAccessorConverter.process(); itkImage = maskAccessorConverter.getITKImage(); } if (voxelization) { itkImage = applyThresholdFilter(itkImage); } io::itk::ImageWriter writer(outputFileName, itkImage); writer.writeFile(); } } rttb::io::itk::ITKImageMaskAccessor::ITKMaskImageType::ConstPointer rttb::apps::voxelizerTool::addMultipleStructsToImage( - std::vector maskVector) + std::vector maskVector) { std::vector listOfITKImages; for (const auto & i : maskVector) { io::itk::ITKImageMaskAccessorConverter maskAccessorConverter(i); maskAccessorConverter.process(); listOfITKImages.push_back(maskAccessorConverter.getITKImage()); } itk::AddImageFilter , itk::Image>::Pointer addFilter = itk::AddImageFilter , itk::Image>::New(); io::itk::ITKImageMaskAccessor::ITKMaskImageType::Pointer filterResult; for (int k = 1; k < listOfITKImages.size(); k++) { if (k == 1) { addFilter->SetInput1(listOfITKImages.at(0)); } else { addFilter->SetInput1(filterResult); } addFilter->SetInput2(listOfITKImages.at(k)); addFilter->Update(); filterResult = addFilter->GetOutput(); } return filterResult.GetPointer(); } rttb::io::itk::ITKImageMaskAccessor::ITKMaskImageType::ConstPointer rttb::apps::voxelizerTool::applyThresholdFilter( io::itk::ITKImageMaskAccessor::ITKMaskImageType::ConstPointer itkImage) { itk::BinaryThresholdImageFilter< itk::Image, itk::Image >::Pointer filter = itk::BinaryThresholdImageFilter< itk::Image, itk::Image >::New(); filter->SetInput(itkImage); filter->SetLowerThreshold(0.5); filter->SetUpperThreshold(1.0); filter->SetInsideValue(1.0); filter->Update(); return filter->GetOutput(); } void rttb::apps::voxelizerTool::processData(rttb::apps::voxelizerTool::ApplicationData& appData) { if (appData._struct->getNumberOfStructures()>0) { - std::vector maskVector; + std::vector maskVector; if (appData._addStructures) { for (size_t i=0; igetNumberOfStructures(); i++ ) { std::cout << "creating mask #" << i << "..."; maskVector.push_back(createMask(appData._dose, appData._struct->getStructure(i), !appData._noStrictVoxelization)); std::cout << "done" << std::endl; } std::cout << "writing mask to file..."; writeMaskToFile(maskVector, appData._outputFilename, appData._binaryVoxelization); std::cout << "done" << std::endl; } else { //default behavior: read only first struct that matches the regex unsigned int maxIterationCount = 1; //only if specified: read all structs that matches the regex if (appData._multipleStructs) { maxIterationCount = appData._struct->getNumberOfStructures(); } for (size_t i = 0; igetStructure(i), !appData._noStrictVoxelization); std::cout << "done" << std::endl; std::string labelOfInterest = appData._struct->getStructure(i)->getLabel(); removeSpecialCharacters(labelOfInterest); std::string outputName = appData._outputFilename; if (appData._multipleStructs) { std::string fileName = rttb::core::getFilenameWithoutEnding( appData._outputFilename); std::string fileEnding = rttb::core::getFileEnding(appData._outputFilename); outputName = fileName + "_" + labelOfInterest + fileEnding; } - std::vector currenMaskVector{ currentMask }; + std::vector currenMaskVector{ currentMask }; std::cout << "writing mask #" << i << " to file..."; writeMaskToFile(currenMaskVector, outputName, appData._binaryVoxelization); std::cout << "done" << std::endl; } } } else { std::cout << "No struct found" << std::endl; } } \ No newline at end of file diff --git a/apps/VoxelizerTool/VoxelizerToolHelper.h b/apps/VoxelizerTool/VoxelizerToolHelper.h index 312777a..14482aa 100644 --- a/apps/VoxelizerTool/VoxelizerToolHelper.h +++ b/apps/VoxelizerTool/VoxelizerToolHelper.h @@ -1,67 +1,67 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1127 $ (last changed revision) // @date $Date: 2015-10-01 13:33:33 +0200 (Do, 01 Okt 2015) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include #include #include "rttbStructure.h" #include "rttbMaskAccessorInterface.h" #include "rttbITKImageMaskAccessor.h" #include "rttbDoseAccessorInterface.h" namespace rttb { namespace apps { namespace voxelizerTool { class ApplicationData; void processData(ApplicationData& appData); /**@brief Search the label with the position from index @return a label from the list as string */ void removeSpecialCharacters(std::string& label); /**@brief create a mask with _rtStructureSet and _doseAccessor object. @return a mask object */ - core::MaskAccessorInterface::MaskAccessorPointer createMask( - core::DoseAccessorInterface::DoseAccessorPointer doseAccessorPtr, - rttb::core::Structure::StructTypePointer structurePtr, + core::MaskAccessorInterface::Pointer createMask( + core::DoseAccessorInterface::Pointer doseAccessorPtr, + rttb::core::Structure::Pointer structurePtr, bool strict); /**@brief write the mask into the outputfile @param Outputfilename */ - void writeMaskToFile(std::vector maskVector, + void writeMaskToFile(std::vector maskVector, const std::string& outputFileName, bool voxelization); io::itk::ITKImageMaskAccessor::ITKMaskImageType::ConstPointer addMultipleStructsToImage( - std::vector maskVector); + std::vector maskVector); io::itk::ITKImageMaskAccessor::ITKMaskImageType::ConstPointer applyThresholdFilter( io::itk::ITKImageMaskAccessor::ITKMaskImageType::ConstPointer itkImage); } } } \ No newline at end of file diff --git a/code/algorithms/rttbArithmetic.h b/code/algorithms/rttbArithmetic.h index 88ba643..d62e403 100644 --- a/code/algorithms/rttbArithmetic.h +++ b/code/algorithms/rttbArithmetic.h @@ -1,159 +1,159 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __ARITHMETIC_H #define __ARITHMETIC_H #include "rttbDoseAccessorInterface.h" #include "rttbMutableMaskAccessorInterface.h" #include "rttbMutableDoseAccessorInterface.h" #include "rttbMaskAccessorInterface.h" namespace rttb { namespace algorithms { namespace arithmetic { - using DoseAccessorPointer = core::DoseAccessorInterface::DoseAccessorPointer; - using MutableDoseAccessorPointer = core::MutableDoseAccessorInterface::MutableDoseAccessorPointer; - using MutableMaskAccessorPointer = core::MutableMaskAccessorInterface::MutableMaskAccessorPointer; - using MaskAccessorPointer = core::MaskAccessorInterface::MaskAccessorPointer; + using DoseAccessorPointer = core::DoseAccessorInterface::Pointer; + using MutableDoseAccessorPointer = core::MutableDoseAccessorInterface::Pointer; + using MutableMaskAccessorPointer = core::MutableMaskAccessorInterface::Pointer; + using MaskAccessorPointer = core::MaskAccessorInterface::Pointer; using MaskVoxelList = core::MaskAccessorInterface::MaskVoxelList; using MaskVoxelListPointer = core::MaskAccessorInterface::MaskVoxelListPointer; /*! Applies the given dose operation to the given doses and stores the result in result @pre pointers to accessors are !nullptr. The geometric Info of the individual accessors must be equal. @exception NullPointerException thrown if one of the input accessors is nullptr. @exception InvalidParameterException thrown if the geometricInfo of the given accessors does not match. */ template void arithmetic(const DoseAccessorPointer dose1, const DoseAccessorPointer dose2, MutableDoseAccessorPointer result, TDoseOperation op); ///*! Applies the given dose operation to the mapped given doses (transformation given by MatchPoint) and stores the result in result // @pre pointers to accessors are ! nullptr. // @exception NullPointerException thrown if one of the input accessors is nullptr. // @exception TransformationOutsideImageException thrown if the transformation maps to a position outside the original image. // */ // template // void arithmetic (const DoseAccessorPointer dose1, const MappableDoseAccessorPointer dose2, // MutableDoseAccessorPointer result, TDoseOperation op); /*! Applies the given dose-mask operation to the given dose and mask and stores the result in result @pre pointers to accessors are ! nullptr. The geometric Info of the individual accessors must be equal. @exception NullPointerException thrown if one of the input accessors is nullptr. @exception InvalidParameterException thrown if the geometricInfo of the given accessors does not match. */ template void arithmetic(const DoseAccessorPointer dose, const MaskAccessorPointer mask, MutableDoseAccessorPointer result, TDoseMaskOperation op); /*! Applies the given mask operation to the given masks and stores the result in result @pre pointers to accessors are !nullptr. The geometric Info of the individual accessors must be equal. @exception NullPointerException thrown if one of the input accessors is nullptr. @exception InvalidParameterException thrown if the geometricInfo of the given accessors does not match. */ template void arithmetic(const MaskAccessorPointer mask1, const MaskAccessorPointer mask2, MutableMaskAccessorPointer result, TMaskOperation op); //convenience functions void add(const DoseAccessorPointer dose1, const DoseAccessorPointer dose2, MutableDoseAccessorPointer result); //void add(const DoseAccessorPointer dose1, const MappableDoseAccessorPointer dose2, // MutableDoseAccessorPointer result); void add(const MaskAccessorPointer mask1, const MaskAccessorPointer mask2, MutableMaskAccessorPointer result); void subtract(const MaskAccessorPointer mask1, const MaskAccessorPointer mask2, MutableMaskAccessorPointer result); void multiply(const DoseAccessorPointer dose, const MaskAccessorPointer mask, MutableDoseAccessorPointer result); /*all operation classes need to implement the function calc() that performs the entry wise operation The operations are sorted into name spaces according to useful application. If the input values are compatible the operations can also be applied to accessors they were not meant for. */ //Operations for binary-dose-operation template namespace doseOp { class Add { public: DoseTypeGy calc(const DoseTypeGy dose1Val, const DoseTypeGy dose2Val) const; }; class AddWeighted { private: DoseCalcType weight1, weight2; public: /* ! Constructor initializes weights applied to individual doses values on adding. */ AddWeighted(const DoseCalcType w1 = 1, const DoseCalcType w2 = 1); DoseTypeGy calc(const DoseTypeGy dose1Val, const DoseTypeGy dose2Val) const; }; class Multiply { public: DoseTypeGy calc(const DoseTypeGy dose1Val, const DoseTypeGy dose2Val) const; }; } //Operations for binary-dose-mask-operation template namespace doseMaskOp { class Multiply { public: DoseTypeGy calc(const DoseTypeGy doseVal, const FractionType maskVal) const; }; } //Operations for binary-mask-operation template //the result of these operations needs to be between 0 and 1 namespace maskOp { class Add { public: FractionType calc(const FractionType mask1Val, const FractionType mask2Val) const; }; class Subtract { public: FractionType calc(const FractionType mask1Val, const FractionType mask2Val) const; }; } }//end namespace arithmetic }//end namespace algorithms }//end namespace core #include "rttbArithmetic.tpp" #endif diff --git a/code/algorithms/rttbBinaryFunctorAccessor.h b/code/algorithms/rttbBinaryFunctorAccessor.h index cb3d0ef..ffa3e45 100644 --- a/code/algorithms/rttbBinaryFunctorAccessor.h +++ b/code/algorithms/rttbBinaryFunctorAccessor.h @@ -1,99 +1,99 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __BINARY_FUNCTOR_ACCESSOR_H #define __BINARY_FUNCTOR_ACCESSOR_H #include "rttbAccessorInterface.h" #include "rttbBaseType.h" namespace rttb { namespace algorithms { /*! @class BinaryFunctorAccessor @brief Class that allows to access the results of a binary operation. @details this Accessor takes two accessors as operants (the operants must have the same geometry) and computes a resulting value by using a given operation functor. The resulting value will be returned from the accessor as its value upon request. @remark this can be seen as a lazy filter pattern, thus the accessor is filtering/operating on dose values upon request. */ template class BinaryFunctorAccessor: public core::AccessorInterface { protected: - AccessorPointer _spData1; - AccessorPointer _spData2; + core::AccessorInterface::ConstPointer _spData1; + core::AccessorInterface::ConstPointer _spData2; TDoseOperation _functor; public: /*! @brief Constructor. @param data1 pointer to the 1st data operand @param data2 pointer to the 2nd data operand @param functor Instance of the operation that should be used @pre all input parameters have to be valid @exception core::NullPointerException if one input parameter is nullptr or if geometricInfos don't match */ - BinaryFunctorAccessor(const AccessorPointer data1, const DoseAccessorPointer data2, + BinaryFunctorAccessor(core::AccessorInterface::ConstPointer data1, core::AccessorInterface::ConstPointer data2, const TDoseOperation& functor); /*! @brief Virtual destructor */ ~BinaryFunctorAccessor() override = default; /*! @pre: the geometricInfo of both doseAccessors are equal */ inline const core::GeometricInfo& getGeometricInfo() const override { return _spData1->getGeometricInfo(); }; /*! @pre: the geometricInfo of both doseAccessors are equal */ inline GridSizeType getGridSize() const override { return _spData1->getGeometricInfo().getNumberOfVoxels(); }; /*! @brief Returns the result dose computed by the functor. It uses the dose values of both operand doses specified via the passed ID. @return the dose value if inside, -1 else @pre .calc(dose1,dose2) has to be implemented */ GenericValueType getValueAt(const VoxelGridID aID) const override; /*! @brief Returns the result dose computed by the functor. It uses the dose values of both operand doses specified via the passed index. @return the dose value if inside, -1 else @pre .calc(dose1,dose2) has to be implemented */ GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const override; const IDType getUID() const override { return IDType(); } }; } } #include "rttbBinaryFunctorAccessor.tpp" #endif diff --git a/code/algorithms/rttbBinaryFunctorAccessor.tpp b/code/algorithms/rttbBinaryFunctorAccessor.tpp index b95950f..7b2887d 100644 --- a/code/algorithms/rttbBinaryFunctorAccessor.tpp +++ b/code/algorithms/rttbBinaryFunctorAccessor.tpp @@ -1,82 +1,82 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbBinaryFunctorAccessor.h" #ifndef __BINARY_FUNCTOR_ACCESSOR_TPP #define __BINARY_FUNCTOR_ACCESSOR_TPP namespace rttb { namespace algorithms { template - BinaryFunctorAccessor::BinaryFunctorAccessor(const AccessorPointer - data1, const AccessorPointer data2, + BinaryFunctorAccessor::BinaryFunctorAccessor(core::AccessorInterface::ConstPointer + data1, core::AccessorInterface::ConstPointer data2, const TDoseOperation& functor) { if (data1 == nullptr || data2 == nullptr) { throw core::NullPointerException("Pointers to input accessors cannot be nullptr."); } if (!(data1->getGeometricInfo() == data2->getGeometricInfo())) { throw core::InvalidParameterException("The geometricInfo of all given accessors needs to be equal."); } _spData1 = data1; _spData2 = data2; _functor = functor; } template GenericValueType BinaryFunctorAccessor::getValueAt( const VoxelGridID aID) const { if (getGeometricInfo().validID(aID)) { GenericValueType value = _functor.calc(_spData1->getValueAt(aID), _spData2->getValueAt(aID)); return value; } else { return -1; } } template DoseTypeGy BinaryFunctorAccessor::getValueAt( const VoxelGridIndex3D& aIndex) const { VoxelGridID aVoxelGridID; if (_spData1->getGeometricInfo().convert(aIndex, aVoxelGridID)) { return getValueAt(aVoxelGridID); } else { return -1; } } } } #endif \ No newline at end of file diff --git a/code/algorithms/rttbDoseStatistics.cpp b/code/algorithms/rttbDoseStatistics.cpp index fc60984..464a80f 100644 --- a/code/algorithms/rttbDoseStatistics.cpp +++ b/code/algorithms/rttbDoseStatistics.cpp @@ -1,293 +1,293 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbDoseStatistics.h" #include "boost/make_shared.hpp" #include "rttbDataNotAvailableException.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace algorithms { DoseStatistics::DoseStatistics(DoseStatisticType minimum, DoseStatisticType maximum, DoseStatisticType mean, DoseStatisticType stdDeviation, VoxelNumberType numVoxels, VolumeType volume, ResultListPointer maximumVoxelPositions /*= ResultListPointer()*/, ResultListPointer minimumVoxelPositions /*= ResultListPointer()*/, VolumeToDoseMeasureCollection Dx, DoseToVolumeMeasureCollection Vx, VolumeToDoseMeasureCollection MOHx, VolumeToDoseMeasureCollection MOCx, VolumeToDoseMeasureCollection MaxOHx, VolumeToDoseMeasureCollection MinOCx, DoseTypeGy referenceDose /*=-1*/): _minimum(minimum), _maximum(maximum), _mean(mean), _stdDeviation(stdDeviation), _numVoxels(numVoxels), _volume(volume), _Dx(::boost::make_shared(Dx)), _Vx(::boost::make_shared(Vx)), _MOHx(::boost::make_shared(MOHx)), _MOCx(::boost::make_shared(MOCx)), _MaxOHx(::boost::make_shared(MaxOHx)), _MinOCx(::boost::make_shared(MinOCx)) { if (maximumVoxelPositions == nullptr) { _maximumVoxelPositions = boost::make_shared > > (std::vector >()); } else { _maximumVoxelPositions = maximumVoxelPositions; } if (minimumVoxelPositions == nullptr) { _minimumVoxelPositions = boost::make_shared > > (std::vector >()); } else { _minimumVoxelPositions = minimumVoxelPositions; } if (referenceDose <= 0) { _referenceDose = _maximum; } else { _referenceDose = referenceDose; } } DoseStatistics::~DoseStatistics() = default; void DoseStatistics::setMinimumVoxelPositions(ResultListPointer minimumVoxelPositions) { _minimumVoxelPositions = minimumVoxelPositions; } void DoseStatistics::setMaximumVoxelPositions(ResultListPointer maximumVoxelPositions) { _maximumVoxelPositions = maximumVoxelPositions; } - void DoseStatistics::setDx(VolumeToDoseMeasureCollectionPointer DxValues) + void DoseStatistics::setDx(VolumeToDoseMeasureCollection::Pointer DxValues) { _Dx = DxValues; } - void DoseStatistics::setVx(DoseToVolumeMeasureCollectionPointer VxValues) + void DoseStatistics::setVx(DoseToVolumeMeasureCollection::Pointer VxValues) { _Vx = VxValues; } - void DoseStatistics::setMOHx(VolumeToDoseMeasureCollectionPointer MOHxValues) + void DoseStatistics::setMOHx(VolumeToDoseMeasureCollection::Pointer MOHxValues) { _MOHx = MOHxValues; } - void DoseStatistics::setMOCx(VolumeToDoseMeasureCollectionPointer MOCxValues) + void DoseStatistics::setMOCx(VolumeToDoseMeasureCollection::Pointer MOCxValues) { _MOCx = MOCxValues; } - void DoseStatistics::setMaxOHx(VolumeToDoseMeasureCollectionPointer MaxOHValues) + void DoseStatistics::setMaxOHx(VolumeToDoseMeasureCollection::Pointer MaxOHValues) { _MaxOHx = MaxOHValues; } - void DoseStatistics::setMinOCx(VolumeToDoseMeasureCollectionPointer MinOCValues) + void DoseStatistics::setMinOCx(VolumeToDoseMeasureCollection::Pointer MinOCValues) { _MinOCx = MinOCValues; } void DoseStatistics::setReferenceDose(DoseTypeGy referenceDose) { if (referenceDose <= 0) { _referenceDose = _maximum; } else { _referenceDose = referenceDose; } } VoxelNumberType DoseStatistics::getNumberOfVoxels() const { return _numVoxels; } VolumeType DoseStatistics::getVolume() const { return _volume; } DoseTypeGy DoseStatistics::getReferenceDose() const { return _referenceDose; } DoseStatisticType DoseStatistics::getMaximum() const { return _maximum; } DoseStatisticType DoseStatistics::getMinimum() const { return _minimum; } DoseStatisticType DoseStatistics::getMean() const { return _mean; } DoseStatisticType DoseStatistics::getStdDeviation() const { return _stdDeviation; } DoseStatisticType DoseStatistics::getVariance() const { return _stdDeviation * _stdDeviation; } double DoseStatistics::getValue(const std::map& aMap, double key, bool findNearestValueInstead, double& storedKey) const { if (aMap.find(key) != std::end(aMap)) { return aMap.find(key)->second; } else { //value not in map. We have to find the nearest value if (aMap.empty()) { throw core::DataNotAvailableException("No Vx values are defined"); } else { if (findNearestValueInstead) { auto iterator = findNearestKeyInMap(aMap, key); storedKey = iterator->first; return iterator->second; } else { throw core::DataNotAvailableException("No Vx value with required dose is defined"); } } } } std::map::const_iterator DoseStatistics::findNearestKeyInMap( const std::map& aMap, double key) const { double minDistance = 1e19; double minDistanceLast = 1e20; auto iterator = std::begin(aMap); while (iterator != std::end(aMap)) { minDistanceLast = minDistance; minDistance = fabs(iterator->first - key); if (minDistanceLast > minDistance) { ++iterator; } else { if (iterator != std::begin(aMap)) { --iterator; return iterator; } else { return std::begin(aMap); } } } --iterator; return iterator; } DoseStatistics::ResultListPointer DoseStatistics::getMaximumVoxelPositions() const { return _maximumVoxelPositions; } DoseStatistics::ResultListPointer DoseStatistics::getMinimumVoxelPositions() const { return _minimumVoxelPositions; } DoseToVolumeMeasureCollection DoseStatistics::getVx() const { return *_Vx; } VolumeToDoseMeasureCollection DoseStatistics::getDx() const { return *_Dx; } VolumeToDoseMeasureCollection DoseStatistics::getMOHx() const { return *_MOHx; } VolumeToDoseMeasureCollection DoseStatistics::getMOCx() const { return *_MOCx; } VolumeToDoseMeasureCollection DoseStatistics::getMaxOHx() const { return *_MaxOHx; } VolumeToDoseMeasureCollection DoseStatistics::getMinOCx() const { return *_MinOCx; } }//end namespace algorithms }//end namespace rttb diff --git a/code/algorithms/rttbDoseStatistics.h b/code/algorithms/rttbDoseStatistics.h index c7f11a9..d6a8e6b 100644 --- a/code/algorithms/rttbDoseStatistics.h +++ b/code/algorithms/rttbDoseStatistics.h @@ -1,171 +1,170 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DOSE_STATISTICS_H #define __DOSE_STATISTICS_H #include #include -#include "boost/shared_ptr.hpp" +#include + #include #include "rttbBaseType.h" #include "RTTBAlgorithmsExports.h" #include "rttbVolumeToDoseMeasureCollection.h" #include "rttbDoseToVolumeMeasureCollection.h" namespace rttb { namespace algorithms { /*! @class DoseStatistics @brief This is a data class storing different statistical values from a rt dose distribution @sa DoseStatisticsCalculator */ class RTTBAlgorithms_EXPORT DoseStatistics { public: + rttbClassMacroNoParent(DoseStatistics); typedef boost::shared_ptr > > ResultListPointer; - using VolumeToDoseMeasureCollectionPointer = boost::shared_ptr; - using DoseToVolumeMeasureCollectionPointer = boost::shared_ptr; - using DoseStatisticsPointer = boost::shared_ptr; private: double getValue(const std::map& aMap, double key, bool findNearestValueInstead, double& storedKey) const; std::map::const_iterator findNearestKeyInMap(const std::map& aMap, double key) const; DoseStatisticType _minimum; DoseStatisticType _maximum; DoseStatisticType _mean; DoseStatisticType _stdDeviation; VoxelNumberType _numVoxels; VolumeType _volume; ResultListPointer _minimumVoxelPositions; ResultListPointer _maximumVoxelPositions; - VolumeToDoseMeasureCollectionPointer _Dx; - DoseToVolumeMeasureCollectionPointer _Vx; - VolumeToDoseMeasureCollectionPointer _MOHx; - VolumeToDoseMeasureCollectionPointer _MOCx; - VolumeToDoseMeasureCollectionPointer _MaxOHx; - VolumeToDoseMeasureCollectionPointer _MinOCx; + VolumeToDoseMeasureCollection::Pointer _Dx; + DoseToVolumeMeasureCollection::Pointer _Vx; + VolumeToDoseMeasureCollection::Pointer _MOHx; + VolumeToDoseMeasureCollection::Pointer _MOCx; + VolumeToDoseMeasureCollection::Pointer _MaxOHx; + VolumeToDoseMeasureCollection::Pointer _MinOCx; DoseTypeGy _referenceDose; //for Vx computation public: /*! @brief Standard Constructor */ //DoseStatistics(); /*! @brief Constructor @details the dose statistic values are set. Complex values maximumVoxelLocation, maximumVoxelLocation, Dx, Vx, MOHx, MOCx, MaxOHx and MinOCx are optional */ DoseStatistics(DoseStatisticType minimum, DoseStatisticType maximum, DoseStatisticType mean, DoseStatisticType stdDeviation, VoxelNumberType numVoxels, VolumeType volume, ResultListPointer minimumVoxelPositions = nullptr, ResultListPointer maximumVoxelPositions = nullptr, VolumeToDoseMeasureCollection Dx = VolumeToDoseMeasureCollection(VolumeToDoseMeasureCollection::Dx), DoseToVolumeMeasureCollection Vx = DoseToVolumeMeasureCollection(DoseToVolumeMeasureCollection::Vx), VolumeToDoseMeasureCollection MOHx = VolumeToDoseMeasureCollection(VolumeToDoseMeasureCollection::MOHx), VolumeToDoseMeasureCollection MOCx = VolumeToDoseMeasureCollection(VolumeToDoseMeasureCollection::MOCx), VolumeToDoseMeasureCollection MaxOHx = VolumeToDoseMeasureCollection(VolumeToDoseMeasureCollection::MaxOHx), VolumeToDoseMeasureCollection MinOCx = VolumeToDoseMeasureCollection(VolumeToDoseMeasureCollection::MinOCx), DoseTypeGy referenceDose = -1); ~DoseStatistics(); void setMinimumVoxelPositions(ResultListPointer minimumVoxelPositions); void setMaximumVoxelPositions(ResultListPointer maximumVoxelPositions); - void setDx(VolumeToDoseMeasureCollectionPointer DxValues); - void setVx(DoseToVolumeMeasureCollectionPointer VxValues); - void setMOHx(VolumeToDoseMeasureCollectionPointer MOHxValues); - void setMOCx(VolumeToDoseMeasureCollectionPointer MOCxValues); - void setMaxOHx(VolumeToDoseMeasureCollectionPointer MaxOHxValues); - void setMinOCx(VolumeToDoseMeasureCollectionPointer MinOCxValues); + void setDx(VolumeToDoseMeasureCollection::Pointer DxValues); + void setVx(DoseToVolumeMeasureCollection::Pointer VxValues); + void setMOHx(VolumeToDoseMeasureCollection::Pointer MOHxValues); + void setMOCx(VolumeToDoseMeasureCollection::Pointer MOCxValues); + void setMaxOHx(VolumeToDoseMeasureCollection::Pointer MaxOHxValues); + void setMinOCx(VolumeToDoseMeasureCollection::Pointer MinOCxValues); void setReferenceDose(DoseTypeGy referenceDose); /*! @brief Get number of voxels in doseIterator, with sub-voxel accuracy. */ VoxelNumberType getNumberOfVoxels() const; /*! @brief Get the volume of the voxels in doseIterator (in cm3), with sub-voxel accuracy */ VolumeType getVolume() const; /*! @brief Get the reference dose for Vx computation */ DoseTypeGy getReferenceDose() const; /*! @brief Get the maximum of the current dose distribution. @return Return the maximum dose in Gy */ DoseStatisticType getMaximum() const; /*! @brief Get a vector of the the maximum dose VoxelGridIDs together with their dose value in Gy @exception InvalidDoseException if the vector has not been set (i.e. is empty) */ ResultListPointer getMaximumVoxelPositions() const; /*! @brief Get the minimum of the current dose distribution. @return Return the minimum dose in Gy */ DoseStatisticType getMinimum() const; /*! @brief Get a vector of the the minimum dose VoxelGridIDs together with their dose value in Gy @exception InvalidDoseException if the vector has not been set (i.e. is empty) */ ResultListPointer getMinimumVoxelPositions() const; /*! @brief Get the mean of the current dose distribution. @return Return the mean dose in Gy */ DoseStatisticType getMean() const; /*! @brief Get the standard deviation of the current dose distribution. @return Return the standard deviation in Gy */ DoseStatisticType getStdDeviation() const; /*! @brief Get the variance of of the current dose distribution. @return Return the variance in Gy */ DoseStatisticType getVariance() const; VolumeToDoseMeasureCollection getDx() const; DoseToVolumeMeasureCollection getVx() const; VolumeToDoseMeasureCollection getMOHx() const; VolumeToDoseMeasureCollection getMOCx() const; VolumeToDoseMeasureCollection getMaxOHx() const; VolumeToDoseMeasureCollection getMinOCx() const; }; } } #endif diff --git a/code/algorithms/rttbDoseStatisticsCalculator.h b/code/algorithms/rttbDoseStatisticsCalculator.h index 75ba9c6..a66091f 100644 --- a/code/algorithms/rttbDoseStatisticsCalculator.h +++ b/code/algorithms/rttbDoseStatisticsCalculator.h @@ -1,199 +1,199 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DOSE_STATISTICS_CALCULATOR_H #define __DOSE_STATISTICS_CALCULATOR_H #include #include #include #include "rttbDoseIteratorInterface.h" #include "rttbDoseStatistics.h" #include "RTTBAlgorithmsExports.h" #include "rttbDxVolumeToDoseMeasureCollectionCalculator.h" #include "rttbVxDoseToVolumeMeasureCollectionCalculator.h" #include "rttbMOHxVolumeToDoseMeasureCollectionCalculator.h" #include "rttbMOCxVolumeToDoseMeasureCollectionCalculator.h" #include "rttbMaxOHxVolumeToDoseMeasureCollectionCalculator.h" #include "rttbMinOCxVolumeToDoseMeasureCollectionCalculator.h" namespace rttb { namespace algorithms { /*! @class DoseStatisticsCalculator @brief Class for calculating different statistical values from a RT dose distribution @details These values range from standard statistical values such as minimum, maximum and mean to more complex dose specific measures such as Vx (volume irradiated with a dose >=x), Dx (minimal dose delivered to x% of the VOI) or MOHx (mean in the hottest volume). For a complete list, see calculateDoseStatistics(). @note the complex dose statistics are precomputed and cannot be computed "on the fly" lateron! The doses/volumes that should be used for precomputation have to be set in calculateDoseStatistics() */ class RTTBAlgorithms_EXPORT DoseStatisticsCalculator { public: - using DoseIteratorPointer = core::DoseIteratorInterface::DoseIteratorPointer; + using DoseIteratorPointer = core::DoseIteratorInterface::Pointer; using ResultListPointer = DoseStatistics::ResultListPointer; - using DoseStatisticsPointer = DoseStatistics::DoseStatisticsPointer; + using DoseStatisticsPointer = DoseStatistics::Pointer; private: DoseIteratorPointer _doseIterator; /*! @brief Contains relevant dose values sorted in descending order. */ std::vector _doseVector; /*! @brief Contains the corresponding voxel proportions to the values in doseVector. */ std::vector _voxelProportionVector; /*! @brief The doseStatistics are stored here. */ DoseStatisticsPointer _statistics; bool _simpleDoseStatisticsCalculated; bool _complexDoseStatisticsCalculated; bool _multiThreading; ::boost::shared_ptr _mutex; - ::boost::shared_ptr _Vx; - ::boost::shared_ptr _Dx; - ::boost::shared_ptr _MOHx; - ::boost::shared_ptr _MOCx; - ::boost::shared_ptr _MaxOHx; - ::boost::shared_ptr _MinOCx; + VxDoseToVolumeMeasureCollectionCalculator::Pointer _Vx; + DxVolumeToDoseMeasureCollectionCalculator::Pointer _Dx; + MOHxVolumeToDoseMeasureCollectionCalculator::Pointer _MOHx; + MOCxVolumeToDoseMeasureCollectionCalculator::Pointer _MOCx; + MaxOHxVolumeToDoseMeasureCollectionCalculator::Pointer _MaxOHx; + MinOCxVolumeToDoseMeasureCollectionCalculator::Pointer _MinOCx; /*! @brief Calculates the positions where the dose has its maximum @param maxNumberMaximaPositions the maximal amount of computed positions @pre maximumDose must be defined in _statistics with the correct value */ ResultListPointer computeMaximumPositions(unsigned int maxNumberMaximaPositions) const; /*! @brief Calculates the positions where the dose has its minimum @param maxNumberMinimaPositions the maximal amount of computed positions (they are read sequentially using the iterator until maxNumberMinimaPositions have been read, other positions are not considered) @pre minimumDose must be defined in _statistics with the correct value */ ResultListPointer computeMinimumPositions(unsigned int maxNumberMinimaPositions) const; /*! @brief Calculates simple dose statistics (min, mean, max, stdDev, minDosePositions, maxDosePositions) @param maxNumberMinimaPositions the maximal amount of computed positions where the dose has its minimum that is computed @param maxNumberMaximaPositions the maximal amount of computed positions where the dose has its maximum that is computed */ void calculateSimpleDoseStatistics(unsigned int maxNumberMinimaPositions, unsigned int maxNumberMaximaPositions); /*! @brief Calculates complex dose statistics (Dx, Vx, MOHx, MOCx, MaxOHx, MinOCx) @warning computations can take quite long (>1 min) for large structures as many statistics are precomputed */ void calculateComplexDoseStatistics(DoseTypeGy referenceDose, const std::vector& precomputeDoseValues, const std::vector& precomputeVolumeValues); public: ~DoseStatisticsCalculator(); /*! @brief Constructor @param aDoseIterator the dose to be analyzed */ DoseStatisticsCalculator(DoseIteratorPointer aDoseIterator); DoseIteratorPointer getDoseIterator() const; /*! @brief Compute simple or complex dose statistics with default relative x values and the maximum dose as default reference dose (for Vx computation) @details The following statistics are calculated always (i.e. also if computeComplexMeasures=false):
  • minimum dose
  • mean dose
  • maximum dose
  • standard deviation dose
  • voxel positions of minimum dose
  • voxel positions of maximum dose
Additionally, these statistics are computed if computeComplexMeasures=true:
  • Dx (the minimal dose delivered to a volume >= x)
  • Vx (the volume irradiated with a dose >= x)
  • MOHx (mean dose of the hottest x volume)
  • MOCx (mean dose of the coldest x volume)
  • MaxOHx (Maximum outside of the hottest x volume)
  • MinOCx (Minimum outside of the coldest x volume)
Default x values for Vx are 0.02, 0.05, 0.1, 0.9, 0.95 and 0.98, with respect to maxDose. Default x values for Dx, MOHx, MOCx, MaxOHx and MinOCx are 0.02, 0.05, 0.1, 0.9, 0.95 and 0.98, with respect to volume. @param computeComplexMeasures should complex statistics be calculated? If it is true, the complex dose statistics will be calculated with default relative x values and the maximum dose as reference dose @param maxNumberMinimaPositions the maximal amount of computed positions where the dose has its minimum that is computed @param maxNumberMaximaPositions the maximal amount of computed positions where the dose has its maximum that is computed @warning If computeComplexMeasures==true, computations can take quite long (>1 min) for large structures as many statistics are precomputed @note The complex dose statistics are precomputed and cannot be computed "on the fly" lateron! Only the default x values can be requested in DoseStatistics! */ DoseStatisticsPointer calculateDoseStatistics(bool computeComplexMeasures = false, unsigned int maxNumberMinimaPositions = 10, unsigned int maxNumberMaximaPositions = 10); /*! @brief Compute complex dose statistics with given reference dose and default relative x values @param referenceDose the reference dose to compute Vx, normally it should be the prescribed dose @param maxNumberMinimaPositions the maximal amount of computed positions where the dose has its minimum that is computed @param maxNumberMaximaPositions the maximal amount of computed positions where the dose has its maximum that is computed @exception InvalidParameterException thrown if referenceDose <= 0 @warning Computations can take quite long (>1 min) for large structures as many statistics are precomputed @note The complex dose statistics are precomputed and cannot be computed "on the fly" lateron! Only the default x values can be requested in DoseStatistics! */ DoseStatisticsPointer calculateDoseStatistics(DoseTypeGy referenceDose, unsigned int maxNumberMinimaPositions = 10, unsigned int maxNumberMaximaPositions = 10); /*! @brief Compute complex dose statistics with given relative x values and reference dose @param precomputeDoseValues the relative dose values for Vx precomputation, e.g. 0.02, 0.05, 0.95... @param precomputeVolumeValues the relative volume values for Dx, MOHx, MOCx, MaxOHx and MinOCx precomputation, e.g. 0.02, 0.05, 0.95... @param referenceDose the reference dose to compute Vx, normally it should be the prescribed dose. Default value is the maximum dose. @param maxNumberMinimaPositions the maximal amount of computed positions where the dose has its minimum that is computed @param maxNumberMaximaPositions the maximal amount of computed positions where the dose has its maximum that is computed @warning Computations can take quite long (>1 min) for large structures as many statistics are precomputed @note The complex dose statistics are precomputed and cannot be computed "on the fly" lateron! The doses/volumes that should be used for precomputation have to be set by in precomputeDoseValues and precomputeVolumeValues. Only these values can be requested in DoseStatistics! */ DoseStatisticsPointer calculateDoseStatistics(const std::vector& precomputeDoseValues, const std::vector& precomputeVolumeValues, DoseTypeGy referenceDose = -1, unsigned int maxNumberMinimaPositions = 10, unsigned int maxNumberMaximaPositions = 10); /*! @brief Adds additonal precompute values for all complex Dose Statistics @exception InvalidDoseException if complexDoseStatistics are not already calculated */ void addPrecomputeValues(const std::vector& values); /*! @brief Recalculates the DoseMeasures for all complex Dose Statistics @exception InvalidDoseException if complexDoseStatistics are not already calculated */ void recalculateDoseStatistics(); void setMultiThreading(bool choice); }; } } #endif diff --git a/code/algorithms/rttbDoseToVolumeMeasureCollection.h b/code/algorithms/rttbDoseToVolumeMeasureCollection.h index 1b70b99..b1687f8 100644 --- a/code/algorithms/rttbDoseToVolumeMeasureCollection.h +++ b/code/algorithms/rttbDoseToVolumeMeasureCollection.h @@ -1,72 +1,74 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __DOSE_TO_VOLUME_MEASURE_COLLECTION_H #define __DOSE_TO_VOLUME_MEASURE_COLLECTION_H #include "rttbMeasureCollection.h" +#include namespace rttb { namespace algorithms { /*! @class DoseToVolumeMeasureCollection @brief This class handels the access to the DoseToVolumeMeasureCollection elements for a specific complex statistic @note _referenceDose has to be set to use getValueRelative() otherwise an exception is thrown */ class RTTBAlgorithms_EXPORT DoseToVolumeMeasureCollection : public MeasureCollection { public: + rttbClassMacro(DoseToVolumeMeasureCollection, MeasureCollection) typedef std::map DoseToVolumeFunctionType; private: complexStatistics _name; DoseTypeGy _referenceDose; DoseToVolumeFunctionType _values; public: DoseToVolumeMeasureCollection(complexStatistics name, DoseTypeGy referenceDose = -1); /*! @brief This has to be set >=0 to use getValueRelative() */ void setReferenceDose(DoseTypeGy referenceDose); void insertValue(DoseTypeGy dose, VolumeType volume); /*! @brief Gets the volume irradiated with a dose >= x, depending on the complexStatistics name. @return Return absolute volume in absolute cm^3. @exception InvalidDoseException if the vector values is empty or _referenceDose is -1 @exception NoDataException if the requested Dose is not in the vector */ VolumeType getValue(DoseTypeGy xVolumeAbsolute) const; VolumeType getValue(DoseTypeGy xVolumeAbsolute, bool findNearestValue, DoseTypeGy& nearestXDose) const; VolumeType getValueRelative(DoseTypeGy xDoseRelative) const; VolumeType getValueRelative(DoseTypeGy xDoseRelative, bool findNearestValue, DoseTypeGy& nearestXDose) const; DoseToVolumeFunctionType getAllValues() const; friend bool operator==(const DoseToVolumeMeasureCollection& volumeToDoseMesureCollection, const DoseToVolumeMeasureCollection& otherVolumeToDoseMesureCollection); }; } } #endif diff --git a/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.cpp b/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.cpp index 37ddf16..9709cbf 100644 --- a/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.cpp +++ b/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.cpp @@ -1,92 +1,92 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "rttbDoseToVolumeMeasureCollectionCalculator.h" #include #include "rttbInvalidParameterException.h" #include "rttbUtils.h" #include //#include namespace rttb { namespace algorithms { DoseToVolumeMeasureCollectionCalculator::DoseToVolumeMeasureCollectionCalculator(const std::vector& precomputeDoseValues, - const DoseTypeGy referenceDose, const core::DoseIteratorInterface::DoseIteratorPointer doseIterator, + const DoseTypeGy referenceDose, const core::DoseIteratorInterface::Pointer doseIterator, DoseToVolumeMeasureCollection::complexStatistics name, bool multiThreading) : _doseIterator(doseIterator), _referenceDose(referenceDose), _measureCollection(::boost::make_shared(name)), _multiThreading(multiThreading) { addPrecomputeDoseValues(precomputeDoseValues); } void DoseToVolumeMeasureCollectionCalculator::compute() { std::vector threads; for (double _precomputeDoseValue : _precomputeDoseValues) { double xAbsolute = _precomputeDoseValue * _referenceDose; if (!rttb::core::isKey(_measureCollection->getAllValues(), xAbsolute)) { if (_multiThreading) { throw rttb::core::InvalidParameterException("MultiThreading is not implemented yet."); //threads.push_back(boost::thread(&DoseToVolumeMeasureCollectionCalculator::insertIntoMeasureCollection, this , xAbsolute, computeSpecificValue(xAbsolute))); } else { insertIntoMeasureCollection(xAbsolute, this->computeSpecificValue(xAbsolute)); } } } for (auto & thread : threads) { thread.join(); } } void DoseToVolumeMeasureCollectionCalculator::addPrecomputeDoseValues(const std::vector& values) { for (double value : values) { if (value > 1 || value < 0) { throw rttb::core::InvalidParameterException("Values must be between 1 and 0!"); } if (!rttb::core::isKey(_precomputeDoseValues, value)) { _precomputeDoseValues.push_back(value); } } } - DoseStatistics::DoseToVolumeMeasureCollectionPointer DoseToVolumeMeasureCollectionCalculator::getMeasureCollection() + DoseToVolumeMeasureCollection::Pointer DoseToVolumeMeasureCollectionCalculator::getMeasureCollection() { return _measureCollection; } void DoseToVolumeMeasureCollectionCalculator::insertIntoMeasureCollection(DoseTypeGy xAbsolute, VolumeType resultVolume) { _measureCollection->insertValue(xAbsolute, resultVolume); } } } diff --git a/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.h b/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.h index c10f320..56de578 100644 --- a/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.h +++ b/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.h @@ -1,90 +1,91 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __DOSE_TO_VOLUME_MEASURE_COLLECTION_CALCULATOR_H #define __DOSE_TO_VOLUME_MEASURE_COLLECTION_CALCULATOR_H #include #include #include "rttbBaseType.h" #include "RTTBAlgorithmsExports.h" #include "rttbDoseToVolumeMeasureCollection.h" #include "rttbDoseIteratorInterface.h" -#include +#include #include "rttbDoseStatistics.h" namespace rttb { namespace algorithms { /*! @class DoseToVolumeMeasureCollectionCalculator @brief Class for calculating DoseToVolume measures @details This class is used as a basis for DoseToVolumeMeasureCollectionCalculators. It implements the compute() method that is the same for every inheriting subclass, it accesses computeSpecificValue, which has to be implemented for each different complex statistic. */ class RTTBAlgorithms_EXPORT DoseToVolumeMeasureCollectionCalculator { public: + rttbClassMacroNoParent(DoseToVolumeMeasureCollectionCalculator) typedef std::map VolumeToDoseFunctionType; protected: - core::DoseIteratorInterface::DoseIteratorPointer _doseIterator; + core::DoseIteratorInterface::Pointer _doseIterator; private: std::vector _precomputeDoseValues; DoseTypeGy _referenceDose; - DoseStatistics::DoseToVolumeMeasureCollectionPointer _measureCollection; + DoseToVolumeMeasureCollection::Pointer _measureCollection; bool _multiThreading; public: /*! @brief Computes not already computed values for the measureCollection. Algorithm for the specific complex Statistic has to be implemented in the corresponding subclass. */ void compute(); /*! @brief Adds additional values to the _precomputeDoseValues vector. @exception InvalidParameterException If values vector contains values that are not between 0 and 1 */ void addPrecomputeDoseValues(const std::vector& values); - DoseStatistics::DoseToVolumeMeasureCollectionPointer getMeasureCollection(); + DoseToVolumeMeasureCollection::Pointer getMeasureCollection(); protected: DoseToVolumeMeasureCollectionCalculator(const std::vector& precomputeDoseValues, - const DoseTypeGy referenceDose, const core::DoseIteratorInterface::DoseIteratorPointer doseIterator, + const DoseTypeGy referenceDose, const core::DoseIteratorInterface::Pointer doseIterator, DoseToVolumeMeasureCollection::complexStatistics name, bool multiThreading); void insertIntoMeasureCollection(DoseTypeGy xAbsolute, VolumeType resultVolume); /*! @brief Computes the specific VolumeType depending on the complext statistic @note has to be overwritten */ virtual VolumeType computeSpecificValue(double xAbsolute) const = 0; }; } } #endif diff --git a/code/algorithms/rttbDxVolumeToDoseMeasureCollectionCalculator.h b/code/algorithms/rttbDxVolumeToDoseMeasureCollectionCalculator.h index a87fae5..aac332d 100644 --- a/code/algorithms/rttbDxVolumeToDoseMeasureCollectionCalculator.h +++ b/code/algorithms/rttbDxVolumeToDoseMeasureCollectionCalculator.h @@ -1,52 +1,56 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __DX_VOLUME_TO_DOSE_MEASURE_COLLECTION_CALCULATOR_H #define __DX_VOLUME_TO_DOSE_MEASURE_COLLECTION_CALCULATOR_H #include "rttbVolumeToDoseMeasureCollectionCalculator.h" +#include + namespace rttb { namespace algorithms { /*! @class DxVolumeToDoseMeasureCollectionCalculator @brief Class for calculating Dx VolumeToDose measures */ class RTTBAlgorithms_EXPORT DxVolumeToDoseMeasureCollectionCalculator: public VolumeToDoseMeasureCollectionCalculator { + public: + rttbClassMacro(DxVolumeToDoseMeasureCollectionCalculator, VolumeToDoseMeasureCollectionCalculator) private: DoseStatisticType _minimum; public: DxVolumeToDoseMeasureCollectionCalculator(const std::vector& precomputeVolumeValues, const VolumeType volume, const std::vector& doseVector, const std::vector& voxelProportionVector, const DoseVoxelVolumeType currentVoxelVolume, const DoseStatisticType minimum, bool multiThreading = false); protected: DoseTypeGy computeSpecificValue(double xAbsolute) const override; }; } } #endif diff --git a/code/algorithms/rttbMOCxVolumeToDoseMeasureCollectionCalculator.h b/code/algorithms/rttbMOCxVolumeToDoseMeasureCollectionCalculator.h index 91d6793..0e0251a 100644 --- a/code/algorithms/rttbMOCxVolumeToDoseMeasureCollectionCalculator.h +++ b/code/algorithms/rttbMOCxVolumeToDoseMeasureCollectionCalculator.h @@ -1,49 +1,52 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __MOCX_VOLUME_TO_DOSE_MEASURE_COLLECTION_CALCULATOR_H #define __MOCX_VOLUME_TO_DOSE_MEASURE_COLLECTION_CALCULATOR_H #include "rttbVolumeToDoseMeasureCollectionCalculator.h" +#include + namespace rttb { namespace algorithms { /*! @class MOCxVolumeToDoseMeasureCollectionCalculator @brief Class for calculating MOCx VolumeToDose measures */ class RTTBAlgorithms_EXPORT MOCxVolumeToDoseMeasureCollectionCalculator : public VolumeToDoseMeasureCollectionCalculator { public: + rttbClassMacro(MOCxVolumeToDoseMeasureCollectionCalculator, VolumeToDoseMeasureCollectionCalculator) MOCxVolumeToDoseMeasureCollectionCalculator(const std::vector& precomputeVolumeValues, const VolumeType volume, const std::vector& doseVector, const std::vector& voxelProportionVector, const DoseVoxelVolumeType currentVoxelVolume, bool multiThreading = false); protected: DoseTypeGy computeSpecificValue(double xAbsolute) const override; }; } } #endif diff --git a/code/algorithms/rttbMOHxVolumeToDoseMeasureCollectionCalculator.h b/code/algorithms/rttbMOHxVolumeToDoseMeasureCollectionCalculator.h index 8f8cc02..291af78 100644 --- a/code/algorithms/rttbMOHxVolumeToDoseMeasureCollectionCalculator.h +++ b/code/algorithms/rttbMOHxVolumeToDoseMeasureCollectionCalculator.h @@ -1,52 +1,55 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __MOHX_VOLUME_TO_DOSE_MEASURE_COLLECTION_CALCULATOR_H #define __MOHX_VOLUME_TO_DOSE_MEASURE_COLLECTION_CALCULATOR_H #include "rttbVolumeToDoseMeasureCollectionCalculator.h" +#include + namespace rttb { namespace algorithms { /*! @class MOHxVolumeToDoseMeasureCollectionCalculator @brief Class for calculating MOHx VolumeToDose measures */ class RTTBAlgorithms_EXPORT MOHxVolumeToDoseMeasureCollectionCalculator : public VolumeToDoseMeasureCollectionCalculator { - + public: + rttbClassMacro(MOHxVolumeToDoseMeasureCollectionCalculator, VolumeToDoseMeasureCollectionCalculator) private: DoseStatisticType _minimum; public: MOHxVolumeToDoseMeasureCollectionCalculator(const std::vector& precomputeVolumeValues, const VolumeType volume, const std::vector& doseVector, const std::vector& voxelProportionVector, const DoseVoxelVolumeType currentVoxelVolume, bool multiThreading = false); protected: DoseTypeGy computeSpecificValue(double xAbsolute) const override; }; } } #endif diff --git a/code/algorithms/rttbMaxOHxVolumeToDoseMeasureCollectionCalculator.h b/code/algorithms/rttbMaxOHxVolumeToDoseMeasureCollectionCalculator.h index f1981f6..e4fcd7b 100644 --- a/code/algorithms/rttbMaxOHxVolumeToDoseMeasureCollectionCalculator.h +++ b/code/algorithms/rttbMaxOHxVolumeToDoseMeasureCollectionCalculator.h @@ -1,49 +1,50 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __MAXOHX_VOLUME_TO_DOSE_MEASURE_CALCULATOR_COLLECTION_H #define __MAXOHX_VOLUME_TO_DOSE_MEASURE_CALCULATOR_COLLECTION_H #include "rttbVolumeToDoseMeasureCollectionCalculator.h" namespace rttb { namespace algorithms { /*! @class MaxOHxVolumeToDoseMeasureCollectionCalculator @brief Class for calculating MaxOH VolumeToDose measures */ class RTTBAlgorithms_EXPORT MaxOHxVolumeToDoseMeasureCollectionCalculator : public VolumeToDoseMeasureCollectionCalculator { public: + rttbClassMacro(MaxOHxVolumeToDoseMeasureCollectionCalculator, VolumeToDoseMeasureCollectionCalculator) MaxOHxVolumeToDoseMeasureCollectionCalculator(const std::vector& precomputeVolumeValues, const VolumeType volume, const std::vector& doseVector, const std::vector& voxelProportionVector, const DoseVoxelVolumeType currentVoxelVolume, bool multiThreading = false); protected: DoseTypeGy computeSpecificValue(double xAbsolute) const override; }; } } #endif diff --git a/code/algorithms/rttbMeasureCollection.h b/code/algorithms/rttbMeasureCollection.h index 5c372f1..fd8de9e 100644 --- a/code/algorithms/rttbMeasureCollection.h +++ b/code/algorithms/rttbMeasureCollection.h @@ -1,58 +1,60 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __MEASURE_COLLECTION_H #define __MEASURE_COLLECTION_H #include +#include #include "rttbBaseType.h" #include "RTTBAlgorithmsExports.h" namespace rttb { namespace algorithms { /*! @class MeasureCollection @brief This class handels the access to the MeasureCollection elements and defines which names can be used for them */ class RTTBAlgorithms_EXPORT MeasureCollection { public: + rttbClassMacroNoParent(MeasureCollection) enum complexStatistics { Dx, Vx, MOHx, MOCx, MaxOHx, MinOCx }; protected: complexStatistics _name; public: complexStatistics getName() const; protected: double getSpecificValue(const std::map& values, double key, bool findNearestValueInstead, double& storedKey) const; std::map::const_iterator findNearestKeyInMap(const std::map& values, double key) const; }; } } #endif diff --git a/code/algorithms/rttbMinOCxVolumeToDoseMeasureCollectionCalculator.h b/code/algorithms/rttbMinOCxVolumeToDoseMeasureCollectionCalculator.h index 6fd1718..a33b34e 100644 --- a/code/algorithms/rttbMinOCxVolumeToDoseMeasureCollectionCalculator.h +++ b/code/algorithms/rttbMinOCxVolumeToDoseMeasureCollectionCalculator.h @@ -1,53 +1,55 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __MINOCX_VOLUME_TO_DOSE_MEASURE_COLLECTION_CALCULATOR_H #define __MINOCX_VOLUME_TO_DOSE_MEASURE_COLLECTION_CALCULATOR_H #include "rttbVolumeToDoseMeasureCollectionCalculator.h" namespace rttb { namespace algorithms { /*! @class MinOCxVolumeToDoseMeasureCollectionCalculator @brief Class for calculating MinOC VolumeToDose measures */ class RTTBAlgorithms_EXPORT MinOCxVolumeToDoseMeasureCollectionCalculator : public VolumeToDoseMeasureCollectionCalculator { + public: + rttbClassMacro(MinOCxVolumeToDoseMeasureCollectionCalculator, VolumeToDoseMeasureCollectionCalculator) private: DoseStatisticType _minimum; DoseStatisticType _maximum; public: MinOCxVolumeToDoseMeasureCollectionCalculator(const std::vector& precomputeVolumeValues, const VolumeType volume, const std::vector& doseVector, const std::vector& voxelProportionVector, const DoseVoxelVolumeType currentVoxelVolume, const DoseStatisticType minimum, const DoseStatisticType maximum, bool multiThreading = false); protected: DoseTypeGy computeSpecificValue(double xAbsolute) const override; }; } } #endif diff --git a/code/algorithms/rttbVolumeToDoseMeasureCollection.h b/code/algorithms/rttbVolumeToDoseMeasureCollection.h index c09d572..ffddcf6 100644 --- a/code/algorithms/rttbVolumeToDoseMeasureCollection.h +++ b/code/algorithms/rttbVolumeToDoseMeasureCollection.h @@ -1,72 +1,74 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __VOLUME_TO_DOSE_MEASURE_COLLECTION_H #define __VOLUME_TO_DOSE_MEASURE_COLLECTION_H #include "rttbMeasureCollection.h" +#include namespace rttb { namespace algorithms { /*! @class VolumeToDoseMeasureCollection @brief This class handels the access to the VolumeToDoseMeasureCollection elements for a specific complex statistic @note _volume has to be set to use getValueRelative() otherwise an exception is thrown */ class RTTBAlgorithms_EXPORT VolumeToDoseMeasureCollection : public MeasureCollection { public: + rttbClassMacro(VolumeToDoseMeasureCollection, MeasureCollection) typedef std::map VolumeToDoseFunctionType; private: complexStatistics _name; VolumeType _volume; VolumeToDoseFunctionType _values; public: VolumeToDoseMeasureCollection(complexStatistics name, VolumeType volume = -1); /*! @brief This has to be set >=0 to use getValueRelative() */ void setVolume(VolumeType volume); void insertValue(VolumeType volume, DoseTypeGy dose); /*! @brief Gets the x of the current volume, depending on the complexStatistics name. @return Return dose value in Gy. @exception InvalidDoseException if the vector values is empty @exception DataNotAvailableException if _volume is not set */ DoseTypeGy getValue(VolumeType xVolumeAbsolute) const; DoseTypeGy getValue(VolumeType xVolumeAbsolute, bool findNearestValue, VolumeType& nearestXDose) const; DoseTypeGy getValueRelative(VolumeType xDoseRelative) const; DoseTypeGy getValueRelative(VolumeType xDoseRelative, bool findNearestValue, VolumeType& nearestXDose) const; VolumeToDoseFunctionType getAllValues() const; friend bool operator==(const VolumeToDoseMeasureCollection& volumeToDoseMesureCollection, const VolumeToDoseMeasureCollection& otherVolumeToDoseMesureCollection); }; } } #endif diff --git a/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.cpp b/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.cpp index f3e5ecf..3a84ac2 100644 --- a/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.cpp +++ b/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.cpp @@ -1,90 +1,90 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "rttbVolumeToDoseMeasureCollectionCalculator.h" #include #include "rttbInvalidParameterException.h" #include "rttbUtils.h" #include //#include namespace rttb { namespace algorithms { VolumeToDoseMeasureCollectionCalculator::VolumeToDoseMeasureCollectionCalculator(const std::vector& precomputeVolumeValues, const VolumeType volume, const std::vector& doseVector, const std::vector& voxelProportionVector, const DoseVoxelVolumeType currentVoxelVolume, VolumeToDoseMeasureCollection::complexStatistics name, bool multiThreading) : _doseVector(doseVector), _currentVoxelVolume(currentVoxelVolume), _voxelProportionVector(voxelProportionVector), _volume(volume), _measureCollection(::boost::make_shared(name)), _multiThreading(multiThreading) { addPrecomputeVolumeValues(precomputeVolumeValues); } void VolumeToDoseMeasureCollectionCalculator::compute() { std::vector threads; for (double _precomputeVolumeValue : _precomputeVolumeValues) { double xAbsolute = _precomputeVolumeValue * _volume; if (!rttb::core::isKey(_measureCollection->getAllValues(), xAbsolute)) { if (_multiThreading) { throw rttb::core::InvalidParameterException("MultiThreading is not implemented yet."); //threads.push_back(boost::thread(&VolumeToDoseMeasureCollectionCalculator::insertIntoMeasureCollection, this, xAbsolute, computeSpecificValue(xAbsolute))); } else { insertIntoMeasureCollection(xAbsolute, this->computeSpecificValue(xAbsolute)); } } } for (auto & thread : threads) { thread.join(); } } void VolumeToDoseMeasureCollectionCalculator::addPrecomputeVolumeValues(const std::vector& values) { for (double value : values) { if (value > 1 || value < 0) { throw rttb::core::InvalidParameterException("Values must be between 1 and 0!"); } if (!rttb::core::isKey(_precomputeVolumeValues, value)) { _precomputeVolumeValues.push_back(value); } } } - DoseStatistics::VolumeToDoseMeasureCollectionPointer VolumeToDoseMeasureCollectionCalculator::getMeasureCollection() + VolumeToDoseMeasureCollection::Pointer VolumeToDoseMeasureCollectionCalculator::getMeasureCollection() { return _measureCollection; } void VolumeToDoseMeasureCollectionCalculator::insertIntoMeasureCollection(VolumeType xAbsolute, DoseTypeGy resultDose) { _measureCollection->insertValue(xAbsolute, resultDose); } } } diff --git a/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.h b/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.h index ad6968a..ee6c5af 100644 --- a/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.h +++ b/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.h @@ -1,83 +1,84 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __VOLUME_TO_DOSE_MEASURE_COLLECTION_CALCULATOR_H #define __VOLUME_TO_DOSE_MEASURE_COLLECTION_CALCULATOR_H #include "rttbVolumeToDoseMeasureCollection.h" -#include +#include #include "rttbDoseStatistics.h" namespace rttb { namespace algorithms { /*! @class VolumeToDoseMeasureCollectionCalculator @brief Class for calculating VolumeToDose measures @details This class is used as a basis for VolumeToDoseMeasureCollectionCalculator. It implements the compute() method that is the same for every inheriting subclass, it accesses computeSpecificValue, which has to be implemented for each different complex statistic. */ class RTTBAlgorithms_EXPORT VolumeToDoseMeasureCollectionCalculator { public: + rttbClassMacroNoParent(VolumeToDoseMeasureCollectionCalculator) typedef std::map VolumeToDoseFunctionType; protected: std::vector _doseVector; DoseVoxelVolumeType _currentVoxelVolume; std::vector _voxelProportionVector; private: std::vector _precomputeVolumeValues; VolumeType _volume; - DoseStatistics::VolumeToDoseMeasureCollectionPointer _measureCollection; + VolumeToDoseMeasureCollection::Pointer _measureCollection; bool _multiThreading; public: /*! @brief Computes not already computed values for the measureCollection. Algorithm for the specific complex Statistic has to be implemented in the corresponding subclass. */ void compute(); /*! @brief Adds additional values to the _precomputeVolumeValues vector. @exception InvalidParameterException If values vector contains values that are not between 0 and 1 */ void addPrecomputeVolumeValues(const std::vector& values); - DoseStatistics::VolumeToDoseMeasureCollectionPointer getMeasureCollection(); + VolumeToDoseMeasureCollection::Pointer getMeasureCollection(); protected: VolumeToDoseMeasureCollectionCalculator(const std::vector& precomputeVolumeValues, const VolumeType volume, const std::vector& doseVector, const std::vector& voxelProportionVector, const DoseVoxelVolumeType currentVoxelVolume, VolumeToDoseMeasureCollection::complexStatistics name, bool multiThreading); void insertIntoMeasureCollection(VolumeType xAbsolute, DoseTypeGy resultDose); /*! @brief Computes the specific DoseTypeGy depending on the complext statistic @note has to be overwritten */ virtual DoseTypeGy computeSpecificValue(double xAbsolute) const = 0; }; } } #endif diff --git a/code/algorithms/rttbVxDoseToVolumeMeasureCollectionCalculator.cpp b/code/algorithms/rttbVxDoseToVolumeMeasureCollectionCalculator.cpp index 8dfc1d7..2325fe1 100644 --- a/code/algorithms/rttbVxDoseToVolumeMeasureCollectionCalculator.cpp +++ b/code/algorithms/rttbVxDoseToVolumeMeasureCollectionCalculator.cpp @@ -1,55 +1,55 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "rttbVxDoseToVolumeMeasureCollectionCalculator.h" namespace rttb { namespace algorithms { VxDoseToVolumeMeasureCollectionCalculator::VxDoseToVolumeMeasureCollectionCalculator(const std::vector& precomputeDoseValues, - const DoseTypeGy referenceDose, const core::DoseIteratorInterface::DoseIteratorPointer doseIterator, bool multiThreading) : + const DoseTypeGy referenceDose, const core::DoseIteratorInterface::Pointer doseIterator, bool multiThreading) : DoseToVolumeMeasureCollectionCalculator(precomputeDoseValues, referenceDose, doseIterator, DoseToVolumeMeasureCollection::Vx, multiThreading) {} VolumeType VxDoseToVolumeMeasureCollectionCalculator::computeSpecificValue(double xAbsolute) const { rttb::FractionType count = 0; _doseIterator->reset(); DoseTypeGy currentDose = 0; while (_doseIterator->isPositionValid()) { currentDose = _doseIterator->getCurrentDoseValue(); if (currentDose >= xAbsolute) { count += _doseIterator->getCurrentRelevantVolumeFraction(); } _doseIterator->next(); } return count * this->_doseIterator->getCurrentVoxelVolume(); } } } \ No newline at end of file diff --git a/code/algorithms/rttbVxDoseToVolumeMeasureCollectionCalculator.h b/code/algorithms/rttbVxDoseToVolumeMeasureCollectionCalculator.h index 2be65d3..5a7ea85 100644 --- a/code/algorithms/rttbVxDoseToVolumeMeasureCollectionCalculator.h +++ b/code/algorithms/rttbVxDoseToVolumeMeasureCollectionCalculator.h @@ -1,49 +1,52 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __DV_DOSE_TO_VOLUME_MEASURE_CALCULATOR_H #define __DV_DOSE_TO_VOLUME_MEASURE_CALCULATOR_H #include "rttbDoseToVolumeMeasureCollectionCalculator.h" +#include + namespace rttb { namespace algorithms { /*! @class VxDoseToVolumeMeasureCollectionCalculator @brief Class for calculating Vx DoseToVolume measures */ class RTTBAlgorithms_EXPORT VxDoseToVolumeMeasureCollectionCalculator : public DoseToVolumeMeasureCollectionCalculator { public: + rttbClassMacro(VxDoseToVolumeMeasureCollectionCalculator, DoseToVolumeMeasureCollectionCalculator) VxDoseToVolumeMeasureCollectionCalculator(const std::vector& precomputeDoseValues, - const DoseTypeGy referenceDose, const core::DoseIteratorInterface::DoseIteratorPointer doseIterator, + const DoseTypeGy referenceDose, const core::DoseIteratorInterface::Pointer doseIterator, bool multiThreading = false); protected: VolumeType computeSpecificValue(double xAbsolute) const override; }; } } #endif diff --git a/code/core/files.cmake b/code/core/files.cmake index a10deda..5f2cbff 100644 --- a/code/core/files.cmake +++ b/code/core/files.cmake @@ -1,57 +1,58 @@ SET(CPP_FILES rttbAccessorWithGeoInfoBase.cpp rttbDoseIteratorInterface.cpp rttbDVH.cpp rttbDVHCalculator.cpp rttbDVHSet.cpp rttbGenericDoseIterator.cpp rttbGenericMaskedDoseIterator.cpp rttbGeometricInfo.cpp rttbMaskedDoseIteratorInterface.cpp rttbMaskVoxel.cpp rttbStructure.cpp rttbStructureSet.cpp rttbStrVectorStructureSetGenerator.cpp rttbUtils.cpp ) SET(H_FILES rttbAccessorInterface.h rttbAccessorWithGeoInfoBase.h rttbBaseType.h rttbDataNotAvailableException.h rttbDoseAccessorInterface.h rttbDoseIteratorInterface.h rttbDoseAccessorGeneratorBase.h rttbDoseAccessorGeneratorInterface.h rttbDVH.h rttbDVHCalculator.h rttbDVHGeneratorInterface.h rttbDVHSet.h rttbException.h rttbExceptionMacros.h rttbGenericDoseIterator.h rttbGenericMaskedDoseIterator.h rttbGeometricInfo.h rttbIndexConversionInterface.h rttbIndexOutOfBoundsException.h rttbInvalidDoseException.h rttbInvalidParameterException.h rttbMappingOutsideOfImageException.h rttbMaskAccessorGeneratorBase.h rttbMaskAccessorGeneratorInterface.h rttbMaskAccessorInterface.h rttbMaskAccessorProcessorBase.h rttbMaskAccessorProcessorInterface.h rttbMaskedDoseIteratorInterface.h rttbMaskVoxel.h rttbMutableDoseAccessorInterface.h rttbMutableMaskAccessorInterface.h rttbNullPointerException.h rttbPaddingException.h rttbStructure.h rttbStructureSet.h rttbStructureSetGeneratorInterface.h rttbStrVectorStructureSetGenerator.h rttbUtils.h + rttbCommon.h ) diff --git a/code/core/rttbAccessorInterface.h b/code/core/rttbAccessorInterface.h index 8783061..02d0e27 100644 --- a/code/core/rttbAccessorInterface.h +++ b/code/core/rttbAccessorInterface.h @@ -1,100 +1,101 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __ACCESSOR_INTERFACE_H #define __ACCESSOR_INTERFACE_H -#include +#include #include "rttbBaseType.h" #include "rttbGeometricInfo.h" #include "rttbIndexConversionInterface.h" +#include "rttbCommon.h" #include #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class AccessorInterface @brief Interface for any sort of Accessor */ class RTTBCore_EXPORT AccessorInterface : public IndexConversionInterface { public: - using AccessorPointer = boost::shared_ptr; - using DoseAccessorPointer = boost::shared_ptr; + rttbClassMacro(AccessorInterface, IndexConversionInterface); + private: AccessorInterface(const AccessorInterface&) = delete; //not implemented on purpose -> non-copyable AccessorInterface& operator=(const AccessorInterface&) = delete;//not implemented on purpose -> non-copyable public: AccessorInterface() = default; ~AccessorInterface() override = default; /*! @brief test if given ID is inside current dose grid */ bool validID(const VoxelGridID aID) const { return this->getGeometricInfo().validID(aID); }; /*! @brief test if given index is inside current dose grid */ bool validIndex(const VoxelGridIndex3D& aIndex) const { return this->getGeometricInfo().validIndex(aIndex); }; virtual const core::GeometricInfo& getGeometricInfo() const = 0; virtual GridSizeType getGridSize() const { return this->getGeometricInfo().getNumberOfVoxels(); }; virtual GenericValueType getValueAt(const VoxelGridID aID) const = 0; virtual GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const = 0; /*! @brief is true if dose is on a homogeneous grid @remarks Inhomogeneous grids are not supported at the moment, but if they will be supported in the future the interface does not need to change. */ virtual bool isGridHomogeneous() const { return true; } virtual const IDType getUID() const = 0; }; } } #endif diff --git a/code/core/rttbCommon.h b/code/core/rttbCommon.h new file mode 100644 index 0000000..ba7c376 --- /dev/null +++ b/code/core/rttbCommon.h @@ -0,0 +1,42 @@ +// ----------------------------------------------------------------------- +// 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 __RTTB_COMMON_H +#define __RTTB_COMMON_H + +#include + +#define rttbClassMacro(className, superClassName) \ + typedef className Self; \ + typedef superClassName Superclass; \ + typedef boost::shared_ptr Pointer; \ + typedef boost::shared_ptr ConstPointer; \ + static const char *getStaticNameOfClass() { return #className; } \ + virtual const char *getNameOfClass() const override \ + { \ + return #className; \ + } + +#define rttbClassMacroNoParent(className) \ + typedef className Self; \ + typedef boost::shared_ptr Pointer; \ + typedef boost::shared_ptr ConstPointer; \ + static const char *getStaticNameOfClass() { return #className; } \ + virtual const char *getNameOfClass() const \ + { \ + return #className; \ + } + +#endif diff --git a/code/core/rttbDVH.h b/code/core/rttbDVH.h index aa19851..ac0dc19 100644 --- a/code/core/rttbDVH.h +++ b/code/core/rttbDVH.h @@ -1,213 +1,215 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DVH_H #define __DVH_H #include #include #include #include "boost/shared_ptr.hpp" #include "rttbBaseType.h" +#include "rttbCommon.h" #include "RTTBCoreExports.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class DVH @brief This is a class representing a dose volume histogram (DVH) */ class RTTBCore_EXPORT DVH { public: using DataDifferentialType = std::deque; - using DVHPointer = boost::shared_ptr; + rttbClassMacroNoParent(DVH); + private: /*! @brief Differential dvh data index is the dose bin, value is the voxel number (sub voxel accuracy) of the dose bin */ DataDifferentialType _dataDifferential; /*! @brief Absolute dose value of a dose-bin in Gy */ DoseTypeGy _deltaD; /*! @brief Volume of a voxel in cm3 */ DoseVoxelVolumeType _deltaV; IDType _structureID; IDType _doseID; IDType _voxelizationID; StructureLabel _label; DoseStatisticType _maximum; DoseStatisticType _minimum; DoseStatisticType _mean; DoseStatisticType _modal; DVHVoxelNumber _numberOfVoxels; DoseStatisticType _median; DoseStatisticType _stdDeviation; DoseStatisticType _variance; DataDifferentialType _dataCumulative; /*! @brief DVH initialization The DVH is initialized and all statistical values are calculated. @throw if _deltaV or _deltaD are zero @throw is _data differential is empty */ void init(); /*! @brief Calculate the cumulative data of dvh */ void calcCumulativeDVH(); public: ~DVH(); /*! @throw if _deltaV or _deltaD are zero @throw is _data differential is empty */ DVH(const DataDifferentialType& aDataDifferential, const DoseTypeGy& aDeltaD, const DoseVoxelVolumeType& aDeltaV, const IDType& aStructureID, const IDType& aDoseID); /*! @throw if _deltaV or _deltaD are zero @throw is _data differential is empty */ DVH(const DataDifferentialType& aDataDifferential, DoseTypeGy aDeltaD, DoseVoxelVolumeType aDeltaV, const IDType& aStructureID, const IDType& aDoseID, const IDType& aVoxelizationID); DVH(const DVH& copy); /*! @throw if _deltaV or _deltaD are zero @throw is _data differential is empty */ DVH& operator=(const DVH& copy); /*! equality operator DVHs are considered equal if the following are equal (let alone double inconsistencies): - structureID - doseID - voxelizationID - number of voxels - Histogram entries. */ bool friend operator==(const DVH& aDVH, const DVH& otherDVH); friend std::ostream& operator<<(std::ostream& s, const DVH& aDVH); void setLabel(StructureLabel aLabel); StructureLabel getLabel() const; /*! @param relativeVolume default false-> Value is the voxel number of the dose bin; if true-> value is the relative volume % between 0 and 1, (the voxel number of this dose bin)/(number of voxels) @return Return differential data of the dvh (relative or absolute depending on the input parameter). */ DataDifferentialType getDataDifferential() const; /*! @param relativeVolume default false-> Value is the voxel number of the dose bin; if true-> value is the relative volume % between 0 and 1, (the voxel number of this dose bin)/(number of voxels) @return Return cumulative data of the dvh */ DataDifferentialType getDataCumulative() const; DoseVoxelVolumeType getDeltaV() const; DoseTypeGy getDeltaD() const; IDType getStructureID() const; IDType getDoseID() const; IDType getVoxelizationID() const; void setDoseID(IDType aDoseID); void setStructureID(IDType aStrID); /*! @brief Calculate number of the voxels (with sub voxel accuracy) @return Return -1 if not initialized */ DVHVoxelNumber getNumberOfVoxels() const; /*! @brief Get the maximum dose in Gy from dvh @return Return the maximum dose in Gy (i+0.5)*deltaD, i-the maximal dose-bin with volume>0 Return -1 if not initialized */ DoseStatisticType getMaximum() const; /*! @brief Get the minimum dose in Gy from dvh @return Return the minimum dose (i+0.5)*deltaD, i-the minimal dose-bin with volume>0 Return -1 if not initialized */ DoseStatisticType getMinimum() const; DoseStatisticType getMean() const; DoseStatisticType getMedian() const; DoseStatisticType getModal() const; DoseStatisticType getStdDeviation() const; DoseStatisticType getVariance() const; /*! @brief Get Vx the volume irradiated to >= x @return Return absolute Volume in absolute cm3 Return -1 if not initialized */ VolumeType getVx(DoseTypeGy xDoseAbsolute) const; /*! @brief Get Dx the minimal dose delivered to x @return Return absolute dose value in Gy Return -1 if not initialized */ DoseTypeGy getDx(VolumeType xVolumeAbsolute) const; /*! @brief Calculate the absolute volume in cm3 @param relativePercent 0~100, the percent of the whole volume */ VolumeType getAbsoluteVolume(int relativePercent) const; /*! @brief Convert absolute values relative to the total number of voxels */ DataDifferentialType convertAbsoluteToRelative(bool isCumulative = true) const; /* @brief Multiplies each values with its Delta value. Values depend on DVHType. @param The DVHType that is being used DVHType::Cumulative or DVHType::Differential */ std::map getNormalizedDVH(DVHType dvhType = { DVHType::Cumulative }) const; }; } } #endif diff --git a/code/core/rttbDVHCalculator.cpp b/code/core/rttbDVHCalculator.cpp index 4bc44c9..cbf9049 100644 --- a/code/core/rttbDVHCalculator.cpp +++ b/code/core/rttbDVHCalculator.cpp @@ -1,131 +1,131 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include "rttbDVHCalculator.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace core { DVHCalculator::DVHCalculator(DoseIteratorPointer aDoseIterator, const IDType& aStructureID, const IDType& aDoseID, DoseTypeGy aDeltaD, const int aNumberOfBins) { if (aDoseIterator == nullptr) { throw NullPointerException("aDoseIterator must not be nullptr! "); } _doseIteratorPtr = aDoseIterator; _structureID = aStructureID; _doseID = aDoseID; if (aNumberOfBins <= 0 || aDeltaD < 0) { throw InvalidParameterException("aNumberOfBins/aDeltaD must be >0! "); } _numberOfBins = aNumberOfBins; _deltaD = aDeltaD; if (_deltaD == 0) { aDoseIterator->reset(); DoseTypeGy max = 0; while (aDoseIterator->isPositionValid()) { DoseTypeGy currentVal = 0; currentVal = aDoseIterator->getCurrentDoseValue(); if (currentVal > max) { max = currentVal; } aDoseIterator->next(); } _deltaD = (max * 1.5 / _numberOfBins); if (_deltaD == 0) { _deltaD = 0.1; } } } DVHCalculator::~DVHCalculator() = default; - DVHCalculator::DVHPointer DVHCalculator::generateDVH() + DVH::Pointer DVHCalculator::generateDVH() { std::deque dataDifferential(_numberOfBins, 0); // calculate DVH _doseIteratorPtr->reset(); while (_doseIteratorPtr->isPositionValid()) { DoseTypeGy currentVal = 0; FractionType voxelProportion = _doseIteratorPtr->getCurrentRelevantVolumeFraction(); currentVal = _doseIteratorPtr->getCurrentDoseValue(); auto dose_bin = static_cast(currentVal / _deltaD); if (dose_bin < _numberOfBins) { dataDifferential[dose_bin] += voxelProportion; } else { throw InvalidParameterException("_numberOfBins is too small: dose bin out of bounds! "); } _doseIteratorPtr->next(); } if (boost::dynamic_pointer_cast(_doseIteratorPtr)) { _dvh = boost::make_shared(dataDifferential, _deltaD, _doseIteratorPtr->getCurrentVoxelVolume(), _structureID, _doseID, _doseIteratorPtr->getVoxelizationID()); } else { _dvh = boost::make_shared(dataDifferential, _deltaD, _doseIteratorPtr->getCurrentVoxelVolume(), _structureID, _doseID); } return _dvh; } }//end namespace core }//end namespace rttb diff --git a/code/core/rttbDVHCalculator.h b/code/core/rttbDVHCalculator.h index 9be7e98..c6a34c1 100644 --- a/code/core/rttbDVHCalculator.h +++ b/code/core/rttbDVHCalculator.h @@ -1,78 +1,78 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DVH_CALCULATOR_H #define __DVH_CALCULATOR_H #include "rttbBaseType.h" #include "rttbDoseIteratorInterface.h" #include "rttbMaskedDoseIteratorInterface.h" #include "rttbDVHGeneratorInterface.h" #include "RTTBCoreExports.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class DVHCalculator @brief Calculates a DVH for a given DoseIterator. */ class RTTBCore_EXPORT DVHCalculator : public DVHGeneratorInterface { public: - using DoseIteratorPointer = core::DoseIteratorInterface::DoseIteratorPointer; - using MaskedDoseIteratorPointer = core::MaskedDoseIteratorInterface::MaskedDoseIteratorPointer; + using DoseIteratorPointer = core::DoseIteratorInterface::Pointer; + using MaskedDoseIteratorPointer = core::MaskedDoseIteratorInterface::Pointer; DoseIteratorPointer _doseIteratorPtr; IDType _structureID; IDType _doseID; DoseTypeGy _deltaD; int _numberOfBins; /*! @brief Constructor. @param aDeltaD the absolute dose value in Gy for dose_bin [i,i+1). Optional, if aDeltaD==0, it will be calculated using aDeltaD=max(aDoseIterator)*1.5/aNumberOfBins @exception InvalidParameterException throw if _numberOfBins<=0 or _deltaD<0 */ DVHCalculator(DoseIteratorPointer aDoseIterator, const IDType& aStructureID, const IDType& aDoseID, const DoseTypeGy aDeltaD = 0, const int aNumberOfBins = 201); ~DVHCalculator(); /*! @brief Generate DVH @return Return new shared pointer of DVH. @exception InvalidParameterException throw if _numberOfBins invalid: _numberOfBins must be > max(aDoseIterator)/aDeltaD! */ - DVHPointer generateDVH() override; + DVH::Pointer generateDVH() override; }; } } #endif diff --git a/code/core/rttbDVHGeneratorInterface.h b/code/core/rttbDVHGeneratorInterface.h index f6745fb..d87587a 100644 --- a/code/core/rttbDVHGeneratorInterface.h +++ b/code/core/rttbDVHGeneratorInterface.h @@ -1,55 +1,53 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DVH_GENERATOR_INTERFACE_H #define __DVH_GENERATOR_INTERFACE_H #include #include "rttbDVH.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class DVHGeneratorInterface @brief Interface for all DVH generating classes */ class DVHGeneratorInterface { - public: - using DVHPointer = core::DVH::DVHPointer; protected: - DVHPointer _dvh; + core::DVH::Pointer _dvh; public: /*! @brief Generate DVH @return Return new shared pointer of DVH. */ - virtual DVHPointer generateDVH() = 0; + virtual core::DVH::Pointer generateDVH() = 0; }; } } #endif diff --git a/code/core/rttbDVHSet.h b/code/core/rttbDVHSet.h index c13f586..b99046e 100644 --- a/code/core/rttbDVHSet.h +++ b/code/core/rttbDVHSet.h @@ -1,146 +1,148 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DVH_SET_H #define __DVH_SET_H #include #include #include +#include "rttbCommon.h" #include "rttbBaseType.h" #include "rttbDVH.h" #include "RTTBCoreExports.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class DVHSet @brief This is a class representing a RT DVHSet including Target Volume and Organ at Risk. @details A DVHSet consists of three subsets: one for the target volume (_dvhTVSet), one for healthy tissue (_dvhHTSet), and one for the whole volume (_dvhWVSet). */ class RTTBCore_EXPORT DVHSet { public: + rttbClassMacroNoParent(DVHSet) using DVHSetType = std::vector; using IndexType = DVHSetType::size_type; private: IDType _structureSetID; IDType _doseID; DVHSetType _dvhTVSet; DVHSetType _dvhHTSet; DVHSetType _dvhWVSet; public: DVHSet(IDType aStructureSetID = "", IDType aDoseID = ""); DVHSet(DVHSetType aDVHTVSet, DVHSetType aDVHHTSet, IDType aStructureSetID = "", IDType aDoseID = ""); DVHSet(DVHSetType aDVHTVSet, DVHSetType aDVHHTSet, DVHSetType aDVHWVSet, IDType aStructureSetID = "", IDType aDoseID = ""); /*! @brief Get the size of the DVHSet, that is the sum of the numbers of DVHs in all sub-sets. */ std::size_t size() const; void setStrSetID(IDType aStrSetID); void setDoseID(IDType aDoseID); IDType getStrSetID() const; IDType getDoseID() const; /*! @brief Get the DVH according to the structure ID @return Return nullptr if not found */ DVH* getDVH(IDType aStructureID); /*! @brief Insert a DVH object. @brief param aDVHType "TV" for target volume or "HT" for healthy tissue or "WV" for whole volume @exception InvalidParameterException Thrown if no valid DVHRole was given. */ void insert(DVH& aDvh, DVHRole aDVHRole); /*! @brief Get DVH subset for target volume */ const DVHSetType& getTargetVolumeSet() const { return _dvhTVSet; }; /*! @brief Get DVH subset for healthy tissue */ const DVHSetType& getHealthyTissueSet() const { return _dvhHTSet; }; /*! @brief Get DVH subset for whole volume */ const DVHSetType& getWholeVolumeSet() const { return _dvhWVSet; }; /*! @brief Get the whole volume irradiated to >= aDoseAbsolute */ VolumeType getWholeVolume(DoseTypeGy aDoseAbsolute) const; /*! @brief Get the healthy tissue volume irradiated to >= aDoseAbsolute @return Return -1 if DVH of _dvhHTSet init() failed */ VolumeType getHealthyTissueVolume(DoseTypeGy aDoseAbsolute) const; /*! @brief Get the target volume irradiated to >= aDoseAbsolute @return Return -1 if DVH of _dvhTVSet init() failed */ VolumeType getTargetVolume(DoseTypeGy aDoseAbsolute) const; /*! DVHSets are considered equal if they have the same structureSet, dose and voxelization ID and the number of DVHs are equal. */ bool friend operator==(const DVHSet& aDVHSet, const DVHSet& otherDVHSet); friend std::ostream& operator<<(std::ostream& s, const DVHSet& aDVHSet); friend std::ostream& operator<<(std::ostream& s, const DVHSetType& aDVHSet); }; bool operator==(const DVHSet& aDVHSet, const DVHSet& otherDVHSet); std::ostream& operator<<(std::ostream& s, const DVHSet& aDVHSet); std::ostream& operator<<(std::ostream& s, const DVHSet::DVHSetType& aDVHSet); } } #endif diff --git a/code/core/rttbDoseAccessorGeneratorInterface.h b/code/core/rttbDoseAccessorGeneratorInterface.h index b2fd5a3..8165327 100644 --- a/code/core/rttbDoseAccessorGeneratorInterface.h +++ b/code/core/rttbDoseAccessorGeneratorInterface.h @@ -1,66 +1,66 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DOSE_ACCESSOR_GENERATOR_INTERFACE_H #define __DOSE_ACCESSOR_GENERATOR_INTERFACE_H #include "rttbDoseAccessorInterface.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class DoseAccessorGeneratorInterface @brief Interface for all Dose Accessor generating classes */ class DoseAccessorGeneratorInterface { public: - using DoseAccessorPointer = core::AccessorInterface::AccessorPointer; + using DoseAccessorPointer = core::AccessorInterface::Pointer; private: DoseAccessorGeneratorInterface(const DoseAccessorGeneratorInterface&) = delete; //not implemented on purpose -> non-copyable DoseAccessorGeneratorInterface& operator=(const DoseAccessorGeneratorInterface&) = delete;//not implemented on purpose -> non-copyable protected: DoseAccessorGeneratorInterface() = default; virtual ~DoseAccessorGeneratorInterface() = default; public: /*! @brief Generate DoseAccessor @return Return shared pointer of DoseAccessor. */ virtual DoseAccessorPointer generateDoseAccessor() = 0; }; } } #endif diff --git a/code/core/rttbDoseIteratorInterface.h b/code/core/rttbDoseIteratorInterface.h index 6bd1324..2096c1c 100644 --- a/code/core/rttbDoseIteratorInterface.h +++ b/code/core/rttbDoseIteratorInterface.h @@ -1,102 +1,101 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DOSE_ITERATOR_INTERFACE_NEW_H #define __DOSE_ITERATOR_INTERFACE_NEW_H -#include - #include "rttbBaseType.h" +#include "rttbCommon.h" #include "rttbDoseAccessorInterface.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { class GeometricInfo; /*! @class DoseIteratorInterface @brief This class represents the dose iterator interface. */ class DoseIteratorInterface { public: - using DoseAccessorPointer = boost::shared_ptr; - using DoseIteratorPointer = boost::shared_ptr; + rttbClassMacroNoParent(DoseIteratorInterface); + using DoseAccessorPointer = DoseAccessorInterface::Pointer; private: DoseIteratorInterface(const DoseIteratorInterface&) = delete; //not implemented on purpose -> non-copyable DoseIteratorInterface& operator=(const DoseIteratorInterface&) = delete;//not implemented on purpose -> non-copyable DoseIteratorInterface() = default; protected: /*! @brief DoseAccessor to get access to actual dose data */ DoseAccessorPointer _spDoseAccessor; public: /*! @brief Constructor with a DoseIterator this should be the default for all implementations. */ DoseIteratorInterface(DoseAccessorPointer aDoseAccessor); virtual ~DoseIteratorInterface() = default; /*! @brief Set the iterator to the start of the dose. */ virtual bool reset() = 0; /*! @brief Move to next position. If this position is valid is not necessarily tested. */ virtual void next() = 0; virtual bool isPositionValid() const = 0; /*! @brief Return volume of one voxel (in cm3)*/ //previously getDeltaV() virtual DoseVoxelVolumeType getCurrentVoxelVolume() const = 0; virtual DoseTypeGy getCurrentDoseValue() const = 0; /*! @return If this is a masked dose iterator, return the voxel proportion inside a given structure, value 0~1; Otherwise, 1 */ virtual FractionType getCurrentRelevantVolumeFraction() const = 0; virtual VoxelGridID getCurrentVoxelGridID() const = 0; virtual IDType getVoxelizationID() const { return ""; }; IDType getDoseUID() const { return _spDoseAccessor->getUID(); }; }; //end class }//end: namespace core }//end: namespace rttb #endif diff --git a/code/core/rttbGenericDoseIterator.h b/code/core/rttbGenericDoseIterator.h index de74257..86f315a 100644 --- a/code/core/rttbGenericDoseIterator.h +++ b/code/core/rttbGenericDoseIterator.h @@ -1,107 +1,107 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __GENERIC_DOSE_ITERATOR_INTERFACE_NEW_H #define __GENERIC_DOSE_ITERATOR_INTERFACE_NEW_H #include #include #include #include "rttbBaseType.h" #include "rttbDoseIteratorInterface.h" #include "RTTBCoreExports.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class GenericDoseIterator @brief Standard implementation of the dose iterator interface. */ class RTTBCore_EXPORT GenericDoseIterator : public DoseIteratorInterface { public: - using DoseAccessorPointer = DoseIteratorInterface::DoseAccessorPointer; - using DoseIteratorPointer = DoseIteratorInterface::DoseIteratorPointer; + using DoseAccessorPointer = DoseAccessorInterface::Pointer; + using DoseIteratorPointer = DoseIteratorInterface::Pointer; private: VoxelGridID _currentDoseVoxelGridID; DoseVoxelVolumeType _currentVoxelVolume; GenericDoseIterator(const GenericDoseIterator&) = delete; //not implemented on purpose -> non-copyable GenericDoseIterator& operator=(const GenericDoseIterator&) = delete;//not implemented on purpose -> non-copyable public: /*! @brief Constructor @param aDoseAccessor contains the corresponding dose data */ GenericDoseIterator(DoseAccessorPointer aDoseAccessor); /*! @brief Set the itterator to the start of the Dose. @exception InvalidParameterException if a inhomogeneous grid is defined in the dose accessors, because these grids are currently not supported. */ bool reset() override; /*! @brief Test if next voxel position is still on the data grid, if so move to next position. */ void next() override; /*! @brief Determine if the current voxel position is valid. */ bool isPositionValid() const override; /*! @brief Return 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; DoseTypeGy getCurrentDoseValue() const override; /*! @brief For DoseIterators this function returns 1, always, because no mask is applied. */ inline FractionType getCurrentRelevantVolumeFraction() const override { return 1; }; inline VoxelGridID getCurrentVoxelGridID() const override { return _currentDoseVoxelGridID; }; }; } } #endif diff --git a/code/core/rttbGeometricInfo.h b/code/core/rttbGeometricInfo.h index c782c75..416c03d 100644 --- a/code/core/rttbGeometricInfo.h +++ b/code/core/rttbGeometricInfo.h @@ -1,186 +1,189 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __GEOMETRIC_INFO_NEW_H #define __GEOMETRIC_INFO_NEW_H #include #include #include "rttbBaseType.h" #include +#include "rttbCommon.h" + #include "RTTBCoreExports.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @brief GeometricInfo objects contain all the information required for transformations between voxel grid coordinates and world coordinates. Corresponding converter functions are also available. @note ITK Pixel Indexing used (http://www.itk.org/Doxygen45/html/classitk_1_1Image.html): The Index type reverses the order so that with Index[0] = col, Index[1] = row, Index[2] = slice. */ class RTTBCore_EXPORT GeometricInfo { - + public: + rttbClassMacroNoParent(GeometricInfo) private: WorldCoordinate3D _imagePositionPatient{ 0 }; OrientationMatrix _orientationMatrix{ 0 }; OrientationMatrix _invertedOrientationMatrix{ 0 }; SpacingVectorType3D _spacing{ 0 }; VoxelGridDimensionType _numberOfColumns{0}; VoxelGridDimensionType _numberOfRows{0}; VoxelGridDimensionType _numberOfFrames{0}; /* @brief Matrix inversion routine. Uses lu_factorize and lu_substitute in uBLAS to invert a matrix http://savingyoutime.wordpress.com/2009/09/21/c-matrix-inversion-boostublas/ */ bool computeInvertOrientation(); public: /*! @brief Constructor, initializes orientation matrix, spacing vector and patient position with zeros. */ GeometricInfo() = default; void setSpacing(const SpacingVectorType3D& aSpacingVector); const SpacingVectorType3D& getSpacing() const; void setImagePositionPatient(const WorldCoordinate3D& aImagePositionPatient); const WorldCoordinate3D& getImagePositionPatient() const; void setOrientationMatrix(const OrientationMatrix& anOrientationMatrix); const OrientationMatrix getOrientationMatrix() const { return _orientationMatrix; }; void setImageSize(const ImageSize& aSize); const ImageSize getImageSize() const; void setNumColumns(const VoxelGridDimensionType aValue); const VoxelGridDimensionType getNumColumns() const; void setNumRows(const VoxelGridDimensionType aValue); const VoxelGridDimensionType getNumRows() const; void setNumSlices(const VoxelGridDimensionType aValue); const VoxelGridDimensionType getNumSlices() const; /*! @brief determines equality of two GeometricInfo objects. */ friend bool RTTBCore_EXPORT operator == (const GeometricInfo& gInfo, const GeometricInfo& gInfo1); bool equalsAlmost(const GeometricInfo& another, double errorConstantGI = 1e-5) const; /*! @brief converts world coordinates to voxel grid index. @details the voxels world coordinates are defined by spacing, orientation and imagePositionPatient. (-0.5/-0.5/-0.5) --> (0/0/0) and (0.4999/0.4999/0.4999) --> (0/0/0) define the outer coordinates of a voxel with spacing=1, orientation= x y z (identity matrix) and imagePositionPatient=(0/0/0). @sa WorldCoordinate3D VoxelGridIndex3D @note The conversion of values is done even if the target index is not inside the given voxel grid. @returns false if aWorldCoordinate is outside the voxel grid, true otherwise. */ bool worldCoordinateToIndex(const WorldCoordinate3D& aWorldCoordinate, VoxelGridIndex3D& aIndex) const; /*! @brief converts world coordinates to double geometry coordinate. @details This is needed because of a double precision voxel coordinate system for voxelization. The world coordinate of the image position patient is the center of the first voxel (0.0/0.0/0.0). (-0.5/-0.5/-0.5) --> (-0.5/-0.5/-0.5) and (0.4999/0.4999/0.4999) --> (0.4999/0.4999/0.4999) with spacing=1, orientation= x y z (identity matrix) and imagePositionPatient=(0/0/0). @sa WorldCoordinate3D, DoubleVoxelGridIndex3D @note The conversion of values is done even if the target index is not inside the given voxel grid. @returns false if aWorldCoordinate is outside the voxel grid, true otherwise. */ bool worldCoordinateToGeometryCoordinate(const WorldCoordinate3D& aWorldCoordinate, DoubleVoxelGridIndex3D& aIndex) const; /*! @brief converts double geometry coordinate to world coordinates. @details This is needed because of a double precision voxel coordinate system for voxelization. The world coordinate of the image position patient is the center of the first voxel (0.0/0.0/0.0). (-0.5/-0.5/-0.5) --> (-0.5/-0.5/-0.5) and (5.5/3.2/1.0) --> (5.5/3.2/1.0) with spacing=1, orientation= x y z (identity matrix) and imagePositionPatient=(0/0/0). @sa DoubleVoxelGridIndex3D, WorldCoordinate3D @note The conversion of values is done even if the target index is not inside the given voxel grid. @returns false if aWorldCoordinate is outside the voxel grid, true otherwise. */ bool geometryCoordinateToWorldCoordinate(const DoubleVoxelGridIndex3D& aIndex, WorldCoordinate3D& aWorldCoordinate) const; /*! @brief convert voxel grid index to world coordinates @details The world coordinate of the image position patient (center of the first voxel) is the center of the first voxel (0.0/0.0/0.0) (0/0/0) --> (0.0/0.0/0.0) and (1/1/2) --> (1.0/1.0/2.0) with spacing=1, orientation= x y z (identity matrix) and imagePositionPatient=(0/0/0). Thus, the center of the voxel is taken and converted. @sa VoxelGridIndex3D, WorldCoordinate3D @note The conversion of values is done even if the target index is not inside the given voxel grid. @returns false if aWorldCoordinate is outside the voxel grid, true otherwise. */ bool indexToWorldCoordinate(const VoxelGridIndex3D& aIndex, WorldCoordinate3D& aWorldCoordinate) const; /*! @brief check if a given voxel grid index is inside the given voxel grid.*/ bool isInside(const VoxelGridIndex3D& aIndex) const; /*! @brief check if a given world coordinate is inside the given voxel grid.*/ bool isInside(const WorldCoordinate3D& aWorldCoordinate) const; const GridSizeType getNumberOfVoxels() const; bool convert(const VoxelGridID& gridID, VoxelGridIndex3D& gridIndex) const; bool convert(const VoxelGridIndex3D& gridIndex, VoxelGridID& gridID) const; /*! @brief test if given ID is inside current dose grid */ bool validID(const VoxelGridID aID) const; /*! @brief test if given index is inside current dose grid */ bool validIndex(const VoxelGridIndex3D& aIndex) const; /*!@ brief generates string stream representation of the GeometricInfo object. */ friend std::ostream& operator << (std::ostream& s, const GeometricInfo& anGeometricInfo); }; } } #endif diff --git a/code/core/rttbIndexConversionInterface.h b/code/core/rttbIndexConversionInterface.h index 474ba03..0914ab7 100644 --- a/code/core/rttbIndexConversionInterface.h +++ b/code/core/rttbIndexConversionInterface.h @@ -1,53 +1,56 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __INDEX_CONVERSION_INTERFACE_NEW_H #define __INDEX_CONVERSION_INTERFACE_NEW_H #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif +#include namespace rttb { namespace core { /*! @class IndexConversionInterface @brief This class represents the conversion of 3D grid indices to 1D grid IDs. */ class IndexConversionInterface { + public: + rttbClassMacroNoParent(IndexConversionInterface); private: IndexConversionInterface(const IndexConversionInterface&) = delete; //not implemented on purpose -> non-copyable IndexConversionInterface& operator=(const IndexConversionInterface&) = delete;//not implemented on purpose -> non-copyable public: IndexConversionInterface() = default; virtual ~IndexConversionInterface() = default; }; } } #endif diff --git a/code/core/rttbMaskAccessorGeneratorBase.h b/code/core/rttbMaskAccessorGeneratorBase.h index ad3da9a..2a29984 100644 --- a/code/core/rttbMaskAccessorGeneratorBase.h +++ b/code/core/rttbMaskAccessorGeneratorBase.h @@ -1,58 +1,58 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __MASK_ACCESSOR_GENERATOR_BASE_H #define __MASK_ACCESSOR_GENERATOR_BASE_H #include "rttbMaskAccessorGeneratorInterface.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class MaskAccessorGeneratorBase @brief Abstract class for all DoseAccessor generating classes */ class MaskAccessorGeneratorBase: public MaskAccessorGeneratorInterface { public: - using MaskAccessorPointer = core::MaskAccessorInterface::MaskAccessorPointer; + using MaskAccessorPointer = core::MaskAccessorInterface::Pointer; private: protected: /*! @brief Mask accessor which should be generated */ MaskAccessorPointer _maskAccessor; public: }; } } #endif diff --git a/code/core/rttbMaskAccessorGeneratorInterface.h b/code/core/rttbMaskAccessorGeneratorInterface.h index 8da98e9..8220cc8 100644 --- a/code/core/rttbMaskAccessorGeneratorInterface.h +++ b/code/core/rttbMaskAccessorGeneratorInterface.h @@ -1,66 +1,66 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __MASK_ACCESSOR_GENERATOR_INTERFACE_H #define __MASK_ACCESSOR_GENERATOR_INTERFACE_H #include "rttbMaskAccessorInterface.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class MaskAccessorGeneratorInterface @brief Interface for all MaskAccessor generating classes */ class MaskAccessorGeneratorInterface { public: - using MaskAccessorPointer = core::MaskAccessorInterface::MaskAccessorPointer; + using MaskAccessorPointer = core::MaskAccessorInterface::Pointer; private: MaskAccessorGeneratorInterface(const MaskAccessorGeneratorInterface&) = delete; //not implemented on purpose -> non-copyable MaskAccessorGeneratorInterface& operator=(const MaskAccessorGeneratorInterface&) = delete;//not implemented on purpose -> non-copyable protected: MaskAccessorGeneratorInterface() = default; virtual ~MaskAccessorGeneratorInterface() = default; public: /*! @brief Generate MaskAccessor @return Return shared pointer of MaskAccessor. */ virtual MaskAccessorPointer generateMaskAccessor() = 0; }; } } #endif diff --git a/code/core/rttbMaskAccessorInterface.h b/code/core/rttbMaskAccessorInterface.h index 59b821b..59e1d17 100644 --- a/code/core/rttbMaskAccessorInterface.h +++ b/code/core/rttbMaskAccessorInterface.h @@ -1,108 +1,107 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __MASK_ACCESSOR_INTERFACE_NEW_H #define __MASK_ACCESSOR_INTERFACE_NEW_H -#include - +#include "rttbCommon.h" #include "rttbBaseType.h" #include "rttbMaskVoxel.h" #include "rttbIndexConversionInterface.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { class GeometricInfo; /*! @class MaskAccessorInterface @brief This class triggers the voxelization and gives acess to the masked voxels. */ class MaskAccessorInterface: public IndexConversionInterface { public: + rttbClassMacro(MaskAccessorInterface, IndexConversionInterface); using MaskVoxelList = std::vector; using MaskVoxelListPointer = boost::shared_ptr; - using MaskAccessorPointer = boost::shared_ptr; private: MaskAccessorInterface(const MaskAccessorInterface&) = delete; //not implemented on purpose -> non-copyable MaskAccessorInterface& operator=(const MaskAccessorInterface&) = delete;//not implemented on purpose -> non-copyable public: MaskAccessorInterface() = default; ~MaskAccessorInterface() override = default; /*! @brief Start generation of mask @post mask is valid and acessible */ virtual void updateMask() = 0; virtual const GeometricInfo& getGeometricInfo() const = 0; /*! @brief Get vector containing all relevant voxels that are inside the given structure. */ virtual MaskVoxelListPointer getRelevantVoxelVector() = 0; /*! @brief get vector containing all relevant voxels that have a relevant volume above the given threshold and are inside the given structure @pre updateMask should have been called (at least once, to ensure a valid mask). */ virtual MaskVoxelListPointer getRelevantVoxelVector(float lowerThreshold) = 0; /*! @brief Get masked voxel value corresponding to a given VoxelGridID. @post after a valid call voxel contains the mask information corresponding to aID. If aID is not valid, voxel values are undefined. @return Indicates if a MaskVoxel for the given ID exists and therefore if parameter voxel containes valid values. @pre updateMask should have been called (at least once, to ensure a valid mask). */ virtual bool getMaskAt(const VoxelGridID aID, MaskVoxel& voxel) const = 0; /*! @brief Get masked voxel value corresponding to a given VoxelGridIndex. @post after a valid call voxel contains the mask information corresponding to gridIndex. If gridIndex is not valid, voxel values are undefined. @return Indicates if a MaskVoxel for the given index exists and therefore if parameter voxel containes valid values. @pre updateMask should have been called (at least once, to ensure a valid mask). */ virtual bool getMaskAt(const VoxelGridIndex3D& gridIndex, MaskVoxel& voxel) const = 0; /* @brief Is true if dose is on a homogeneous grid. @note Inhomogeneous grids are not supported at the moment, but if they will be supported in the future the interface does not need to change. */ virtual bool isGridHomogeneous() const { return true; } virtual IDType getMaskUID() const = 0; }; } } #endif diff --git a/code/core/rttbMaskAccessorProcessorBase.h b/code/core/rttbMaskAccessorProcessorBase.h index 13679fc..b741323 100644 --- a/code/core/rttbMaskAccessorProcessorBase.h +++ b/code/core/rttbMaskAccessorProcessorBase.h @@ -1,64 +1,64 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __MASK_ACCESSOR_PROCESSOR_BASE_H #define __MASK_ACCESSOR_PROCESSOR_BASE_H #include "rttbMaskAccessorProcessorInterface.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class MaskAccessorProcessorBase @brief Abstract class for all MaskAccessor converter classes */ class MaskAccessorProcessorBase: public MaskAccessorProcessorInterface { public: - using MaskAccessorPointer = core::MaskAccessorInterface::MaskAccessorPointer; + using MaskAccessorPointer = core::MaskAccessorInterface::Pointer; void setMaskAccessor(MaskAccessorPointer accessor) override { _maskAccessor = accessor; }; private: MaskAccessorProcessorBase(const MaskAccessorProcessorBase&) = delete; //not implemented on purpose -> non-copyable MaskAccessorProcessorBase& operator=(const MaskAccessorProcessorBase&) = delete;//not implemented on purpose -> non-copyable protected: MaskAccessorProcessorBase() = default; ~MaskAccessorProcessorBase() override = default; /*! @brief Mask accessor which should be generated */ MaskAccessorPointer _maskAccessor; }; } } #endif diff --git a/code/core/rttbMaskAccessorProcessorInterface.h b/code/core/rttbMaskAccessorProcessorInterface.h index 85de32a..0c9ce8f 100644 --- a/code/core/rttbMaskAccessorProcessorInterface.h +++ b/code/core/rttbMaskAccessorProcessorInterface.h @@ -1,70 +1,70 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __MASK_ACCESSOR_PROCESSOR_INTERFACE_H #define __MASK_ACCESSOR_PROCESSOR_INTERFACE_H #include "rttbMaskAccessorInterface.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class MaskAccessorProcessorInterface @brief Interface for all MaskAccessor converter classes */ class MaskAccessorProcessorInterface { public: - using MaskAccessorPointer = core::MaskAccessorInterface::MaskAccessorPointer; + using MaskAccessorPointer = core::MaskAccessorInterface::Pointer; private: MaskAccessorProcessorInterface(const MaskAccessorProcessorInterface&) = delete; //not implemented on purpose -> non-copyable MaskAccessorProcessorInterface& operator=(const MaskAccessorProcessorInterface&) = delete;//not implemented on purpose -> non-copyable protected: MaskAccessorProcessorInterface() = default; virtual ~MaskAccessorProcessorInterface() = default; public: /*! @brief Sets the MaskAccessor that should be processed @pre passed accessor must point to a valid instance. */ virtual void setMaskAccessor(MaskAccessorPointer accessor) = 0; /*! @brief Process the passed MaskAccessor @return if the processing was successful. */ virtual bool process() = 0; }; } } #endif diff --git a/code/core/rttbMaskedDoseIteratorInterface.h b/code/core/rttbMaskedDoseIteratorInterface.h index b2c7f11..5a0e8b2 100644 --- a/code/core/rttbMaskedDoseIteratorInterface.h +++ b/code/core/rttbMaskedDoseIteratorInterface.h @@ -1,80 +1,81 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __MASKED_DOSE_ITERATOR_INTERFACE_NEW_H #define __MASKED_DOSE_ITERATOR_INTERFACE_NEW_H -#include +#include #include "rttbDoseIteratorInterface.h" +#include "rttbMaskAccessorInterface.h" #include "RTTBCoreExports.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { class MaskAccessorInterface; /*! @class MaskedDoseIteratorInterface @brief Give access to masked dose data. */ class RTTBCore_EXPORT MaskedDoseIteratorInterface : public DoseIteratorInterface { public: - using MaskAccessorPointer = boost::shared_ptr; - using DoseAccessorPointer = DoseIteratorInterface::DoseAccessorPointer; - using DoseIteratorPointer = DoseIteratorInterface::DoseIteratorPointer; - using MaskedDoseIteratorPointer = boost::shared_ptr; + rttbClassMacro(MaskedDoseIteratorInterface, DoseIteratorInterface); + using MaskAccessorPointer = MaskAccessorInterface::Pointer; + using DoseAccessorPointer = DoseAccessorInterface::Pointer; + using DoseIteratorPointer = DoseIteratorInterface::Pointer; private: MaskedDoseIteratorInterface(const MaskedDoseIteratorInterface&) = delete; MaskedDoseIteratorInterface& operator=(const MaskedDoseIteratorInterface&) = delete; protected: /*! @brief Mask that is to be applied to currently loaded dose*/ MaskAccessorPointer _spMask; public: /* Constructor @pre core::GeometricInfo represents the same geometric space for both mask and dose, i.e. both live on the same data grid. Both accessors need to be valid. */ MaskedDoseIteratorInterface(MaskAccessorPointer aMaskAccessor, DoseAccessorPointer aDoseAccessor); ~MaskedDoseIteratorInterface() override = default; inline MaskAccessorPointer getMaskAccessor() const { return _spMask; }; /* Return doseValue*voxelFraction for the current position */ virtual DoseTypeGy getCurrentMaskedDoseValue() const = 0; }; } } #endif \ No newline at end of file diff --git a/code/core/rttbMutableDoseAccessorInterface.h b/code/core/rttbMutableDoseAccessorInterface.h index 9d32763..d1bb534 100644 --- a/code/core/rttbMutableDoseAccessorInterface.h +++ b/code/core/rttbMutableDoseAccessorInterface.h @@ -1,54 +1,55 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __MUTABLE_DOSE_ACCESSOR_INTERFACE_NEW_H #define __MUTABLE_DOSE_ACCESSOR_INTERFACE_NEW_H #include "rttbDoseAccessorInterface.h" #include "rttbBaseType.h" +#include "rttbCommon.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class MutableDoseAccessorInterface @brief Extends the DoseAccessorInterface to provide writing access to the data. */ class MutableDoseAccessorInterface: public DoseAccessorInterface { public: - using MutableDoseAccessorPointer = boost::shared_ptr; + rttbClassMacro(MutableDoseAccessorInterface, DoseAccessorInterface) virtual void setDoseAt(const VoxelGridID aID, DoseTypeGy value) = 0; virtual void setDoseAt(const VoxelGridIndex3D& aIndex, DoseTypeGy value) = 0; }; } } #endif diff --git a/code/core/rttbMutableMaskAccessorInterface.h b/code/core/rttbMutableMaskAccessorInterface.h index 08b1d9d..8023af4 100644 --- a/code/core/rttbMutableMaskAccessorInterface.h +++ b/code/core/rttbMutableMaskAccessorInterface.h @@ -1,61 +1,61 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __MUTABLE_MASK_ACCESSOR_INTERFACE_H #define __MUTABLE_MASK_ACCESSOR_INTERFACE_H -#include +#include "rttbCommon.h" #include "rttbMaskAccessorInterface.h" #include "rttbBaseType.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { class MaskVoxel; /*! @class MutableMaskAccessorInterface @brief Extends the MaskAccessorInterface to provide writing access to the data. @details This interface is created for external manipulation of generated masks. For example to store the results of arithmetic operations on other masks. */ class MutableMaskAccessorInterface: public MaskAccessorInterface { public: - using MutableMaskAccessorPointer = boost::shared_ptr; + rttbClassMacro(MutableMaskAccessorInterface, MaskAccessorInterface) using MaskVoxelList = core::MaskAccessorInterface::MaskVoxelList; using MaskVoxelListPointer = core::MaskAccessorInterface::MaskVoxelListPointer; virtual void setRelevantVoxelVector(MaskVoxelListPointer aVoxelListPointer) = 0; virtual void setMaskAt(VoxelGridID aID, const MaskVoxel& voxel) = 0; virtual void setMaskAt(const VoxelGridIndex3D& gridIndex, const MaskVoxel& voxel) = 0; }; } } #endif diff --git a/code/core/rttbStrVectorStructureSetGenerator.h b/code/core/rttbStrVectorStructureSetGenerator.h index b030d9a..d428c89 100644 --- a/code/core/rttbStrVectorStructureSetGenerator.h +++ b/code/core/rttbStrVectorStructureSetGenerator.h @@ -1,79 +1,79 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __STR_VECTOR_STRUCTURE_SET_GENERATOR_H #define __STR_VECTOR_STRUCTURE_SET_GENERATOR_H #include #include #include "rttbStructureSetGeneratorInterface.h" #include "rttbStructureSet.h" #include "RTTBCoreExports.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class StrVectorStructureSetGenerator @brief Generate a structure set with a vector of Structures. */ class RTTBCore_EXPORT StrVectorStructureSetGenerator : public core::StructureSetGeneratorInterface { public: - using StructTypePointer = core::StructureSet::StructTypePointer; + using StructTypePointer = core::Structure::Pointer; - using StructureSetPointer = StructureSetGeneratorInterface::StructureSetPointer; + using StructureSetPointer = StructureSet::Pointer; protected: IDType _patientUID; std::vector _strVector; StrVectorStructureSetGenerator() = default; public: /*! @brief Constructor @param aStructureVector the vector of structure shared pointer @param aPatientUID the patient UID. */ StrVectorStructureSetGenerator(std::vector& aStructureVector, IDType aPatientUID = ""); /*! @brief Generate StructureSet @return Return shared pointer of StructureSet. */ StructureSetPointer generateStructureSet() override; }; } } #endif diff --git a/code/core/rttbStructure.h b/code/core/rttbStructure.h index 924fcd3..21622a2 100644 --- a/code/core/rttbStructure.h +++ b/code/core/rttbStructure.h @@ -1,113 +1,110 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ -/* Changes in Architecture: -This class should be universally used independent of the origin of the Structures. All UID references are omitted. -*/ + #ifndef __STRUCTURE_H #define __STRUCTURE_H #include #include -#include - #include "rttbBaseType.h" +#include "rttbCommon.h" #include "RTTBCoreExports.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class Structure @brief This is a class representing a RT Structure */ class RTTBCore_EXPORT Structure { public: - using StructTypePointer = boost::shared_ptr; + rttbClassMacroNoParent(Structure); private: /*! @brief WorldCoordinate3D in mm */ PolygonSequenceType _structureVector; /*! @brief Contour Geometric Type using DICOM-RT definition (3006,0042). * POINT: indicates that the contour is a single point, defining a specific location of significance. * OPEN_PLANAR: indicates that the last vertex shall not be connected to the first point, and that all points * in Contour Data (3006,0050) shall be coplanar. * OPEN_NONPLANAR: indicates that the last vertex shall not be connected to the first point, and that the points * in Contour Data(3006,0050) may be non-coplanar. * CLOSED_PLANAR: indicates that the last point shall be connected to the first point, where the first point is * not repeated in the Contour Data. All points in Contour Data (3006,0050) shall be coplanar. */ std::vector _contourGeometricTypeVector; /*! @brief Structure UID*/ IDType _strUID; /*! @brief Structure Label*/ StructureLabel _label; public: /*! @brief Structure Standard Constructor uid will be randomly generated using boost::uuid library at first. To change the uid using setUID(). */ Structure(); /*! @brief Structure Constructor uid will be randomly generated using boost::uuid library at first. To change the uid using setUID(). */ Structure(PolygonSequenceType strVector); Structure(const Structure& copy); ~Structure(); const PolygonSequenceType& getStructureVector() const; /*! @brief Get the number of end points (points that define the polygon) of all contours of the structure. */ int getNumberOfEndpoints() const; IDType getUID() const; void setUID(const IDType& aUID); void setLabel(const StructureLabel& aLabel); StructureLabel getLabel() const; }; }//end namespace core }//end namespace rttb #endif diff --git a/code/core/rttbStructureSet.cpp b/code/core/rttbStructureSet.cpp index 35cc7ce..81624be 100644 --- a/code/core/rttbStructureSet.cpp +++ b/code/core/rttbStructureSet.cpp @@ -1,84 +1,84 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include #include #include #include "rttbStructureSet.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace core { - StructureSet::StructureSet(const std::vector& aStructureVector, + StructureSet::StructureSet(const std::vector& aStructureVector, IDType aPatientUID, IDType aUID) { _structureSetVector = aStructureVector; _patientUID = aPatientUID; _UID = aUID; if (_UID == "") { boost::uuids::uuid id; boost::uuids::random_generator generator; id = generator(); std::stringstream ss; ss << id; _UID = ss.str(); } } - StructureSet::StructTypePointer StructureSet::getStructure(size_t aStructureNo) const + Structure::Pointer StructureSet::getStructure(size_t aStructureNo) const { auto size = this->getNumberOfStructures(); if (aStructureNo >= size) { std::stringstream sstr; sstr << "aStructureNo must be between 0 and " << size; throw InvalidParameterException(sstr.str()); } return _structureSetVector.at(aStructureNo); } StructureSet::NumberOfStructuresType StructureSet::getNumberOfStructures() const { return _structureSetVector.size(); } IDType StructureSet::getUID() const { return _UID; } IDType StructureSet::getPatientUID() const { return _patientUID; } }//end namespace core }//end namespace rttb diff --git a/code/core/rttbStructureSet.h b/code/core/rttbStructureSet.h index dad4663..f827276 100644 --- a/code/core/rttbStructureSet.h +++ b/code/core/rttbStructureSet.h @@ -1,90 +1,89 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __STRUCTURE_SET_H #define __STRUCTURE_SET_H #include -#include - #include "rttbBaseType.h" +#include "rttbCommon.h" #include "rttbStructure.h" #include "RTTBCoreExports.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { /*! @class StructureSet @brief This is an class representing a structure set, which can be used to generate masks. */ class RTTBCore_EXPORT StructureSet { public: - using StructTypePointer = Structure::StructTypePointer; + rttbClassMacroNoParent(StructureSet); using NumberOfStructuresType = size_t; protected: - std::vector _structureSetVector; + std::vector _structureSetVector; IDType _UID; IDType _patientUID; public: virtual ~StructureSet() = default; /*! @brief Constructor @param aPatientUID the patient UID. @param aUID the structure set UID. If it is empty, it will be calculated in the constructor */ - StructureSet(const std::vector& aStructureVector, IDType aPatientUID = "", + StructureSet(const std::vector& aStructureVector, IDType aPatientUID = "", IDType aUID = ""); /*! @brief Get the Structure with the index aStructureNo @return Return Structure pointer. @exception InvalidParameterException Thrown if structureNo not between 0 and number of structures of structureSet. */ - StructTypePointer getStructure(size_t aStructureNo) const; + Structure::Pointer getStructure(size_t aStructureNo) const; /*! @brief Get the number of structures @return Return the number of structures. */ NumberOfStructuresType getNumberOfStructures() const; virtual IDType getUID() const; virtual IDType getPatientUID() const; }; } } #endif diff --git a/code/core/rttbStructureSetGeneratorInterface.h b/code/core/rttbStructureSetGeneratorInterface.h index 1020b59..b6a21d4 100644 --- a/code/core/rttbStructureSetGeneratorInterface.h +++ b/code/core/rttbStructureSetGeneratorInterface.h @@ -1,91 +1,90 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __STRUCTURE_SET_GENERATOR_INTERFACE_H #define __STRUCTURE_SET_GENERATOR_INTERFACE_H -#include +#include + +#include "rttbStructureSet.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace core { - class StructureSet; /*! @class StructureSetGeneratorInterface @brief Interface for all structure set generating classes */ class StructureSetGeneratorInterface { public: - using StructureSetPointer = boost::shared_ptr; - - + rttbClassMacroNoParent(StructureSetGeneratorInterface); private: StructureSetGeneratorInterface(const StructureSetGeneratorInterface&) = delete; //not implemented on purpose -> non-copyable StructureSetGeneratorInterface& operator=(const StructureSetGeneratorInterface&) = delete;//not implemented on purpose -> non-copyable protected: StructureSetGeneratorInterface() = default; virtual ~StructureSetGeneratorInterface() = default; private: bool _activeFilter{false}; std::string _filterRegEx; public: void setStructureLabelFilterActive(bool active) { _activeFilter = active; }; bool getStructureLabelFilterActive() const { return _activeFilter; }; void setFilterRegEx(const std::string& filter) { _filterRegEx = filter; }; std::string getFilterRegEx() const { return _filterRegEx; }; /*! @brief Generate StructureSet @return Return shared pointer of StructureSet. */ - virtual StructureSetPointer generateStructureSet() = 0; + virtual StructureSet::Pointer generateStructureSet() = 0; }; } } #endif diff --git a/code/indices/rttbConformalIndex.cpp b/code/indices/rttbConformalIndex.cpp index a251e20..d373653 100644 --- a/code/indices/rttbConformalIndex.cpp +++ b/code/indices/rttbConformalIndex.cpp @@ -1,126 +1,126 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbConformalIndex.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "rttbExceptionMacros.h" namespace rttb { namespace indices { - ConformalIndex::ConformalIndex(ConformalIndex::DVHSetPtr dvhSet, DoseTypeGy aDoseReference) + ConformalIndex::ConformalIndex(core::DVHSet::Pointer dvhSet, DoseTypeGy aDoseReference) : DvhBasedDoseIndex(dvhSet, aDoseReference) { init(); } bool ConformalIndex::calcIndex() { VolumeType TV = _dvhSet->getTargetVolume(0); VolumeType Vref = _dvhSet->getWholeVolume(_doseReference); if (TV != 0 && Vref != 0) { _value = (_dvhSet->getTargetVolume(_doseReference) / TV) * (_dvhSet->getTargetVolume(_doseReference) / Vref); std::vector dvhHTSet = this->_dvhSet->getHealthyTissueSet(); std::vector::iterator it; for (it = dvhHTSet.begin(); it != dvhHTSet.end(); ++it) { core::DVH dvh = *(it); VolumeType HT = dvh.getVx(0); if (HT != 0) { _value *= (1 - dvh.getVx(this->_doseReference) / HT); } } } else if (TV == 0) { throw core::InvalidParameterException("DVH Set invalid: Target volume should not be 0!"); } else { rttbExceptionMacro(core::InvalidParameterException, << "Reference dose " << this->getDoseReference() << " invalid: Volume of reference dose should not be 0!"); } return true; } IndexValueType ConformalIndex::getValueAt(core::DVHSet::IndexType tvIndex) { std::vector dvhTVSet = this->_dvhSet->getTargetVolumeSet(); VolumeType Vref = _dvhSet->getWholeVolume(_doseReference); if (tvIndex >= dvhTVSet.size()) { rttbExceptionMacro(core::InvalidParameterException, << "tvIndex invalid: it should be <" << dvhTVSet.size() << "!"); } else { core::DVH dvh = dvhTVSet.at(tvIndex); VolumeType TV = dvh.getVx(0); if (TV == 0) { throw core::InvalidParameterException("DVH invalid: Volume of tvIndex should not be 0!"); } else if (Vref == 0) { rttbExceptionMacro(core::InvalidParameterException, << "Reference dose " << this->getDoseReference() << " invalid: Volume of reference dose should not be 0!"); } double value = dvh.getVx(_doseReference) / TV; //the irradiation factor of i-th target volume value = value * dvh.getVx(_doseReference) / Vref; //conformation number std::vector dvhHTSet = this->_dvhSet->getHealthyTissueSet(); std::vector::iterator it; for (it = dvhHTSet.begin(); it != dvhHTSet.end(); ++it) { dvh = *(it); VolumeType HT = dvh.getVx(0); if (HT != 0) { value *= (1 - dvh.getVx(this->_doseReference) / HT); } } return value; } } }//end namespace indices }//end namespace rttb diff --git a/code/indices/rttbConformalIndex.h b/code/indices/rttbConformalIndex.h index 617e02e..0a2ec27 100644 --- a/code/indices/rttbConformalIndex.h +++ b/code/indices/rttbConformalIndex.h @@ -1,70 +1,70 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __CONFORMAL_INDEX_H #define __CONFORMAL_INDEX_H #include "rttbDvhBasedDoseIndex.h" #include "rttbBaseType.h" #include "RTTBIndicesExports.h" namespace rttb { namespace indices { /*! @class ConformalIndex @brief This class representing a ConformalIndex Object. @details Conformal Index \f$(COIN)= Conformation Number(CN)* (1-Vref,0/Vnt,0)*(1-Vref,1/Vnt,1)... i\f$, i: i-th critiacal organ Conformation Number \f$(CN)= \frac{TVref}{TV} * \frac{TVref}{Vref}\f$ @ingroup indices */ class RTTBIndices_EXPORT ConformalIndex : public DvhBasedDoseIndex { protected: /*! @brief Calculate conformal index @exception InvalidParameterException Thrown if dvhSet or aDoseReference invalid */ bool calcIndex() override; public: /*! @brief Constructor */ - ConformalIndex(DVHSetPtr dvhSet, DoseTypeGy aDoseReference); + ConformalIndex(core::DVHSet::Pointer dvhSet, DoseTypeGy aDoseReference); /*! @brief Dose index calculation for tvIndex-th treated volume @param tvIndex index in the DVH in the current set of tv-DVHs @return Return index value @exception InvalidParameterException Thrown if tvIndex or aDoseReference invalid */ IndexValueType getValueAt(const core::DVHSet::IndexType tvIndex) override; }; } } #endif diff --git a/code/indices/rttbConformationNumber.cpp b/code/indices/rttbConformationNumber.cpp index 129a14f..5cc6e40 100644 --- a/code/indices/rttbConformationNumber.cpp +++ b/code/indices/rttbConformationNumber.cpp @@ -1,97 +1,97 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbConformationNumber.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "rttbExceptionMacros.h" namespace rttb { namespace indices { - ConformationNumber::ConformationNumber(DVHSetPtr dvhSet, DoseTypeGy aDoseReference) + ConformationNumber::ConformationNumber(core::DVHSet::Pointer dvhSet, DoseTypeGy aDoseReference) : DvhBasedDoseIndex(dvhSet, aDoseReference) { init(); } bool ConformationNumber::calcIndex() { VolumeType TV = _dvhSet->getTargetVolume(0); VolumeType Vref = _dvhSet->getWholeVolume(_doseReference); if (TV != 0 && Vref != 0) { _value = (_dvhSet->getTargetVolume(_doseReference) / TV) * (_dvhSet->getTargetVolume(_doseReference) / Vref); } else if (TV == 0) { throw core::InvalidParameterException("DVH Set invalid: Target volume should not be 0!"); } else { rttbExceptionMacro(core::InvalidParameterException, << "Reference dose " << this->getDoseReference() << " invalid: Volume of reference dose should not be 0!"); } return true; } IndexValueType ConformationNumber::getValueAt(core::DVHSet::IndexType tvIndex) { std::vector dvhTVSet = this->_dvhSet->getTargetVolumeSet(); VolumeType Vref = _dvhSet->getWholeVolume(_doseReference); if (tvIndex >= dvhTVSet.size()) { rttbExceptionMacro(core::InvalidParameterException, << "tvIndex invalid: it should be <" << dvhTVSet.size() << "!"); } else { core::DVH dvh = dvhTVSet.at(tvIndex); VolumeType TV = dvh.getVx(0); if (TV == 0) { throw core::InvalidParameterException("DVH invalid: Volume of tvIndex should not be 0!"); } else if (Vref == 0) { rttbExceptionMacro(core::InvalidParameterException, << "Reference dose " << this->getDoseReference() << " invalid: Volume of reference dose should not be 0!"); } IndexValueType value = dvh.getVx(_doseReference) / TV; //the irradiation factor of i-th target volume value = value * dvh.getVx(_doseReference) / Vref; return value; } } }//end namespace indices }//end namespace rttb \ No newline at end of file diff --git a/code/indices/rttbConformationNumber.h b/code/indices/rttbConformationNumber.h index e50bc1c..ad6b10e 100644 --- a/code/indices/rttbConformationNumber.h +++ b/code/indices/rttbConformationNumber.h @@ -1,70 +1,70 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __CONFORMATION_NUMBER_H #define __CONFORMATION_NUMBER_H #include "rttbDvhBasedDoseIndex.h" #include "rttbBaseType.h" #include "RTTBIndicesExports.h" namespace rttb { namespace indices { /*! @class ConformationNumber @brief This class representing a ConformationNumber Object. @details Conformation Number \f$(CN)= (TVref/TV) * (TVref/Vref)\f$ @ingroup indices */ class RTTBIndices_EXPORT ConformationNumber : public DvhBasedDoseIndex { protected: /*! @brief Calculate conformation number @exception InvalidParameterException Thrown if dvhSet or aDoseReference invalid */ bool calcIndex() override; public: /*! @brief Constructor */ - ConformationNumber(DVHSetPtr dvhSet, DoseTypeGy aDoseReference); + ConformationNumber(core::DVHSet::Pointer dvhSet, DoseTypeGy aDoseReference); /*! @brief Dose index calculation for tvIndex-th treated volume @param tvIndex index in the DVH in the current set of tv-DVHs @return Return index value @exception InvalidParameterException Thrown if tvIndex or aDoseReference invalid */ IndexValueType getValueAt(const core::DVHSet::IndexType tvIndex) override; }; } } #endif diff --git a/code/indices/rttbConformityIndex.cpp b/code/indices/rttbConformityIndex.cpp index 35fcab9..4fd6bf3 100644 --- a/code/indices/rttbConformityIndex.cpp +++ b/code/indices/rttbConformityIndex.cpp @@ -1,96 +1,96 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbConformityIndex.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "rttbExceptionMacros.h" namespace rttb { namespace indices { - ConformityIndex::ConformityIndex(DVHSetPtr dvhSet, DoseTypeGy aDoseReference) + ConformityIndex::ConformityIndex(core::DVHSet::Pointer dvhSet, DoseTypeGy aDoseReference) : DvhBasedDoseIndex(dvhSet, aDoseReference) { init(); } bool ConformityIndex::calcIndex() { VolumeType TV = _dvhSet->getTargetVolume(0); VolumeType Vref = _dvhSet->getWholeVolume(_doseReference); if (TV != 0 && Vref != 0) { _value = (_dvhSet->getTargetVolume(this->_doseReference) / TV) * (1 - _dvhSet->getHealthyTissueVolume(_doseReference) / Vref); } else if (TV == 0) { throw core::InvalidParameterException("DVH Set invalid: Target volume should not be 0!"); } else { rttbExceptionMacro(core::InvalidParameterException, << "Reference dose " << this->getDoseReference() << " invalid: Volume of reference dose should not be 0!"); } return true; } IndexValueType ConformityIndex::getValueAt(core::DVHSet::IndexType tvIndex) { std::vector dvhTVSet = this->_dvhSet->getTargetVolumeSet(); VolumeType Vref = _dvhSet->getWholeVolume(_doseReference); if (tvIndex >= dvhTVSet.size()) { rttbExceptionMacro(core::InvalidParameterException, << "tvIndex invalid: it should be <" << dvhTVSet.size() << "!"); } else { core::DVH dvh = dvhTVSet.at(tvIndex); VolumeType TV = dvh.getVx(0); if (TV == 0) { throw core::InvalidParameterException("DVH invalid: Volume of tvIndex should not be 0!"); } else if (Vref == 0) { rttbExceptionMacro(core::InvalidParameterException, << "Reference dose " << this->getDoseReference() << " invalid: Volume of reference dose should not be 0!"); } double value = dvh.getVx(_doseReference) / TV; //the irradiation factor of i-th treated volume value = value * (1 - _dvhSet->getHealthyTissueVolume(_doseReference) / Vref); return value; } } }//end namespace indices }//end namespace rttb diff --git a/code/indices/rttbConformityIndex.h b/code/indices/rttbConformityIndex.h index 36bdbe7..3de3557 100644 --- a/code/indices/rttbConformityIndex.h +++ b/code/indices/rttbConformityIndex.h @@ -1,69 +1,69 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __CONFORMITY_INDEX_H #define __CONFORMITY_INDEX_H #include "rttbDvhBasedDoseIndex.h" #include "rttbBaseType.h" #include "RTTBIndicesExports.h" namespace rttb { namespace indices { /*! @class ConformityIndex @brief This class representing a ConformityIndex Object. @details: Conformity Index (CI): \f$CI(D)=IFtv(D)*(1-IFht(D))\f$, D:reference dose, IFtv(D): the irradiation factor of the PTV, defined as the fraction of the PTV receiving a dose higher than D IFht(D): the irradiation factor of healthy tissue, defined as the radio of the volume of tissue outside the PTV receiving a dose greater than D to the volume of isodose D @ingroup indices */ class RTTBIndices_EXPORT ConformityIndex : public DvhBasedDoseIndex { protected: /*! @brief Calculate Conformity index @exception InvalidParameterException Thrown if dvhSet or aDoseReference invalid */ bool calcIndex() override; public: /*! @brief Constructor */ - ConformityIndex(DVHSetPtr dvhSet, DoseTypeGy aDoseReference); + ConformityIndex(core::DVHSet::Pointer dvhSet, DoseTypeGy aDoseReference); /*! @brief Dose index calculation for tvIndex-th treated volume @param tvIndex index in the DVH in the current set of tv-DVHs @return Return index value @exception InvalidParameterException Thrown if tvIndex or aDoseReference invalid */ IndexValueType getValueAt(const core::DVHSet::IndexType tvIndex) override; }; } } #endif diff --git a/code/indices/rttbCoverageIndex.cpp b/code/indices/rttbCoverageIndex.cpp index f79ec24..6b5606d 100644 --- a/code/indices/rttbCoverageIndex.cpp +++ b/code/indices/rttbCoverageIndex.cpp @@ -1,79 +1,79 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbCoverageIndex.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "rttbExceptionMacros.h" namespace rttb { namespace indices { - CoverageIndex::CoverageIndex(DVHSetPtr dvhSet, DoseTypeGy aDoseReference) + CoverageIndex::CoverageIndex(core::DVHSet::Pointer dvhSet, DoseTypeGy aDoseReference) : DvhBasedDoseIndex(dvhSet, aDoseReference) { init(); } bool CoverageIndex::calcIndex() { VolumeType TV = _dvhSet->getTargetVolume(0); if (TV != 0) { _value = _dvhSet->getTargetVolume(this->_doseReference) / TV; } else { throw core::InvalidParameterException("DVH Set invalid: Target volume should not be 0!"); } return true; } IndexValueType CoverageIndex::getValueAt(core::DVHSet::IndexType tvIndex) { std::vector dvhTVSet = this->_dvhSet->getTargetVolumeSet(); if (tvIndex >= dvhTVSet.size()) { rttbExceptionMacro(core::InvalidParameterException, << "tvIndex invalid: it should be <" << dvhTVSet.size() << "!"); } core::DVH dvh = dvhTVSet.at(tvIndex); VolumeType TV = dvh.getVx(0); if (TV == 0) { throw core::InvalidParameterException("DVH invalid: Volume of tvIndex should not be 0!"); } IndexValueType value = dvh.getVx(_doseReference) / TV; //the irradiation factor of i-th treated volume return value; } }//end namespace indices }//end namespace rttb diff --git a/code/indices/rttbCoverageIndex.h b/code/indices/rttbCoverageIndex.h index 7449fb2..7040b39 100644 --- a/code/indices/rttbCoverageIndex.h +++ b/code/indices/rttbCoverageIndex.h @@ -1,67 +1,67 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __COVERAGE_INDEX_H #define __COVERAGE_INDEX_H #include "rttbDvhBasedDoseIndex.h" #include "rttbBaseType.h" #include "rttbDVHSet.h" #include "RTTBIndicesExports.h" namespace rttb { namespace indices { /*! @class CoverageIndex @brief This class representing a CoverageIndex Object. @details Coverage Index fraction of the target volume receiving a dose >= the reference dose @ingroup indices */ class RTTBIndices_EXPORT CoverageIndex : public DvhBasedDoseIndex { protected: /*! @brief Calculate conformation number @exception InvalidParameterException Thrown if dvhSet invalid */ bool calcIndex() override; public: /*! @brief Constructor */ - CoverageIndex(DVHSetPtr dvhSet, DoseTypeGy aDoseReference); + CoverageIndex(core::DVHSet::Pointer dvhSet, DoseTypeGy aDoseReference); /*! @brief Dose index calculation for tvIndex-th treated volume * @param tvIndex: index in the vector of DVH TV * @return Return index value @exception InvalidParameterException Thrown if tvIndex invalid */ IndexValueType getValueAt(const core::DVHSet::IndexType tvIndex) override; }; } } #endif diff --git a/code/indices/rttbDvhBasedDoseIndex.cpp b/code/indices/rttbDvhBasedDoseIndex.cpp index 94649b6..b89537b 100644 --- a/code/indices/rttbDvhBasedDoseIndex.cpp +++ b/code/indices/rttbDvhBasedDoseIndex.cpp @@ -1,50 +1,50 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbDvhBasedDoseIndex.h" namespace rttb { namespace indices { - DvhBasedDoseIndex::DvhBasedDoseIndex(DvhBasedDoseIndex::DVHSetPtr aDVHSet, + DvhBasedDoseIndex::DvhBasedDoseIndex(core::DVHSet::Pointer aDVHSet, DoseTypeGy aDoseReference) : DoseIndex(aDoseReference), _dvhSet(aDVHSet) { } bool DvhBasedDoseIndex::checkInputs() { if (!_dvhSet) { return false; } else { return true; } } } } diff --git a/code/indices/rttbDvhBasedDoseIndex.h b/code/indices/rttbDvhBasedDoseIndex.h index 49a9079..b1f9458 100644 --- a/code/indices/rttbDvhBasedDoseIndex.h +++ b/code/indices/rttbDvhBasedDoseIndex.h @@ -1,58 +1,55 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DVH_BASED_DOSE_INDEX_H #define __DVH_BASED_DOSE_INDEX_H #include "rttbBaseType.h" #include "rttbDVHSet.h" #include "rttbDoseIndex.h" #include "RTTBIndicesExports.h" namespace rttb { namespace indices { /*! @class DvhBasedDoseIndex @brief This is the interface for dose/plan comparison indices calculated by DVh set of the dose. */ class RTTBIndices_EXPORT DvhBasedDoseIndex : public DoseIndex { - public: - using DVHSetPtr = boost::shared_ptr; - protected: - DVHSetPtr _dvhSet; + core::DVHSet::Pointer _dvhSet; /*! @brief Check inputs*/ bool checkInputs() override; public: /*! @brief Constructor*/ - DvhBasedDoseIndex(DVHSetPtr aDVHSet, DoseTypeGy aDoseReference); + DvhBasedDoseIndex(core::DVHSet::Pointer aDVHSet, DoseTypeGy aDoseReference); }; } } #endif diff --git a/code/indices/rttbHomogeneityIndex.cpp b/code/indices/rttbHomogeneityIndex.cpp index fd6ec79..7897871 100644 --- a/code/indices/rttbHomogeneityIndex.cpp +++ b/code/indices/rttbHomogeneityIndex.cpp @@ -1,103 +1,103 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include "rttbHomogeneityIndex.h" #include "rttbInvalidParameterException.h" #include "rttbExceptionMacros.h" namespace rttb { namespace indices { - HomogeneityIndex::HomogeneityIndex(DVHSetPtr dvhSet, DoseTypeGy aDoseReference) + HomogeneityIndex::HomogeneityIndex(core::DVHSet::Pointer dvhSet, DoseTypeGy aDoseReference) : DvhBasedDoseIndex(dvhSet, aDoseReference) { init(); } bool HomogeneityIndex::calcIndex() { double max = 0; double min = std::numeric_limits::max(); std::vector dvhTVSet = this->_dvhSet->getTargetVolumeSet(); std::vector::iterator it; for (it = dvhTVSet.begin(); it != dvhTVSet.end(); ++it) { core::DVH dvh = *(it); if (it == dvhTVSet.begin()) { min = dvh.getMinimum(); } if (dvh.getMaximum() > max) { max = dvh.getMaximum(); } if (dvh.getMinimum() < min) { min = dvh.getMinimum(); } } if (this->getDoseReference() != 0) { _value = (max - min) / this->getDoseReference(); } else { rttbExceptionMacro(core::InvalidParameterException, << "Reference dose " << this->getDoseReference() << " invalid: Volume of reference dose should not be 0!"); } return true; } IndexValueType HomogeneityIndex::getValueAt(core::DVHSet::IndexType tvIndex) { std::vector dvhTVSet = this->_dvhSet->getTargetVolumeSet(); if (tvIndex >= dvhTVSet.size()) { rttbExceptionMacro(core::InvalidParameterException, << "tvIndex invalid: it should be <" << dvhTVSet.size() << "!"); } core::DVH dvh = dvhTVSet.at(tvIndex); if (this->getDoseReference() <= 0) { rttbExceptionMacro(core::InvalidParameterException, << "Reference dose " << this->getDoseReference() << " invalid: Volume of reference dose should not be 0!"); } return (dvh.getMaximum() - dvh.getMinimum()) / this->getDoseReference(); } }//end namespace indices }//end namespace rttb diff --git a/code/indices/rttbHomogeneityIndex.h b/code/indices/rttbHomogeneityIndex.h index d14a72d..568326a 100644 --- a/code/indices/rttbHomogeneityIndex.h +++ b/code/indices/rttbHomogeneityIndex.h @@ -1,65 +1,65 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __HOMOGENEITY_INDEX_H #define __HOMOGENEITY_INDEX_H #include "rttbDvhBasedDoseIndex.h" #include "rttbBaseType.h" #include "RTTBIndicesExports.h" namespace rttb { namespace indices { /*! @class HomogeneityIndex @brief This class representing a HomogeneityIndex Object. @details Homogeneity Index \f$(HI) = \frac{D_{max}(PTV)-D_{min}(PTV)}{D_{ref}}\f$ @ingroup indices */ class RTTBIndices_EXPORT HomogeneityIndex : public DvhBasedDoseIndex { protected: /*! @brief Calculate Conformity index @exception InvalidParameterException Thrown if aDoseReference invalid */ bool calcIndex() override; public: /*! @brief Constructor */ - HomogeneityIndex(DVHSetPtr dvhSet, DoseTypeGy aDoseReference); + HomogeneityIndex(core::DVHSet::Pointer dvhSet, DoseTypeGy aDoseReference); /*! @brief Dose index calculation for tvIndex-th treated volume @param tvIndex index in the DVH in the current set of tv-DVHs @return Return index value @exception InvalidParameterException Thrown if tvIndex or aDoseReference invalid */ IndexValueType getValueAt(const core::DVHSet::IndexType tvIndex) override; }; } } #endif diff --git a/code/interpolation/ITKTransformation/rttbITKTransformation.h b/code/interpolation/ITKTransformation/rttbITKTransformation.h index c2a9f9b..830fda5 100644 --- a/code/interpolation/ITKTransformation/rttbITKTransformation.h +++ b/code/interpolation/ITKTransformation/rttbITKTransformation.h @@ -1,82 +1,81 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __ITK_MAPPABLE_DOSE_ACCESSOR_H #define __ITK_MAPPABLE_DOSE_ACCESSOR_H #include #include "itkTransform.h" #include "rttbTransformationInterface.h" #include "RTTBInterpolationITKTransformationExports.h" namespace rttb { namespace interpolation { /*! @class ITKTransformation @brief This class can deal with dose information that has to be transformed into another geometry than the original dose image (transformation specified by ITK transformation object). */ class RTTBInterpolationITKTransformation_EXPORT ITKTransformation : public TransformationInterface { public: static const unsigned int InputDimension3D = 3; static const unsigned int OutputDimension3D = 3; using TransformScalarType = double; typedef itk::Transform Transform3D3DType; using InputPointType = Transform3D3DType::InputPointType; using OutputPointType = Transform3D3DType::OutputPointType; - using Pointer = boost::shared_ptr; private: //! Has to be a Pointer type because of inheritance issues with itkSmartPointer (that doesn't recognize the inheritance) const Transform3D3DType* _pTransformation; protected: void convert(const WorldCoordinate3D& aWorldCoordinate, InputPointType& aInputPoint) const; void convert(const OutputPointType& aOutputPoint, WorldCoordinate3D& aWorldCoordinate) const; public: /*! @brief Constructor. @param aTransformation transformation in ITK format. @sa MappableDoseAccessorBase @pre all input parameters have to be valid @exception core::NullPointerException if one input parameter is nullptr @exception core::PaddingException if the transformation is undefined and if _acceptPadding==false */ ITKTransformation(const Transform3D3DType* aTransformation); ~ITKTransformation() override = default; /*! @brief performs a transformation targetImage --> movingImage */ bool transformInverse(const WorldCoordinate3D& worldCoordinateTarget, WorldCoordinate3D& worldCoordinateMoving) const override; /*! @brief performs a transformation movingImage --> targetImage */ bool transform(const WorldCoordinate3D& worldCoordinateMoving, WorldCoordinate3D& worldCoordinateTarget) const override; }; } } #endif diff --git a/code/interpolation/rttbInterpolationBase.cpp b/code/interpolation/rttbInterpolationBase.cpp index add8bf7..0fd1863 100644 --- a/code/interpolation/rttbInterpolationBase.cpp +++ b/code/interpolation/rttbInterpolationBase.cpp @@ -1,197 +1,197 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include "rttbInterpolationBase.h" #include "rttbInvalidParameterException.h" #include "rttbNullPointerException.h" #include "rttbMappingOutsideOfImageException.h" namespace rttb { namespace interpolation { - void InterpolationBase::setAccessorPointer(const AccessorPointer originalData) + void InterpolationBase::setAccessorPointer(core::AccessorInterface::ConstPointer originalData) { if (originalData != nullptr) { _spOriginalData = originalData; } else { throw core::NullPointerException("originalDose is nullptr!"); } }; void InterpolationBase::getNeighborhoodVoxelValues( const WorldCoordinate3D& aWorldCoordinate, unsigned int neighborhood, std::array& target, boost::shared_ptr values) const { if (_spOriginalData == nullptr) { throw core::NullPointerException("originalDose is nullptr!"); } //Determine target (abs(desired worldCoordinate- corner pixel world coordinate/pixel spacing) and values of corner pixels (from originalDose) VoxelGridIndex3D aIndex; if (_spOriginalData->getGeometricInfo().worldCoordinateToIndex(aWorldCoordinate, aIndex)) { //determine just the nearest voxel to the world coordinate if (neighborhood == 0) { values[0] = _spOriginalData->getValueAt(aIndex); } //determine the 8 voxels around the world coordinate else if (neighborhood == 8) { std::list cornerPoints; WorldCoordinate3D theNextVoxel; _spOriginalData->getGeometricInfo().indexToWorldCoordinate(aIndex, theNextVoxel); SpacingVectorType3D pixelSpacing = (_spOriginalData->getGeometricInfo()).getSpacing(); VoxelGridIndex3D leftTopFrontCoordinate; //find the voxel with the smallest coordinate values in each dimension. This defines the standard cube for (unsigned int i = 0; i < 3; i++) { if (aWorldCoordinate[i] < theNextVoxel[i]) { if (aIndex[i] > 0) { leftTopFrontCoordinate[i] = aIndex[i] - 1; target[i] = (aWorldCoordinate[i] - (theNextVoxel[i] - pixelSpacing[i])) / pixelSpacing[i]; } //@todo: see T22315 else { leftTopFrontCoordinate[i] = aIndex[i]; target[i] = (aWorldCoordinate[i] - (theNextVoxel[i] - pixelSpacing[i])) / pixelSpacing[i]; } } else { leftTopFrontCoordinate[i] = aIndex[i]; target[i] = (aWorldCoordinate[i] - theNextVoxel[i]) / pixelSpacing[i]; } } for (unsigned int zIncr = 0; zIncr < 2; zIncr++) { for (unsigned int yIncr = 0; yIncr < 2; yIncr++) { for (unsigned int xIncr = 0; xIncr < 2; xIncr++) { cornerPoints.emplace_back(leftTopFrontCoordinate[0] + xIncr, leftTopFrontCoordinate[1] + yIncr, leftTopFrontCoordinate[2] + zIncr); } } } //target range has to be always [0,1] for (unsigned int i = 0; i < 3; i++) { assert(target[i] >= 0.0 && target[i] <= 1.0); } unsigned int count = 0; //now just get the values of all (dose) voxels and store them in values for (auto cornerPointsIterator = cornerPoints.begin(); cornerPointsIterator != cornerPoints.end(); ++cornerPointsIterator, ++count) { if (_spOriginalData->getGeometricInfo().isInside(*cornerPointsIterator)) { values[count] = _spOriginalData->getValueAt(*cornerPointsIterator); } else { //outside value! boundary treatment values[count] = getNearestInsideVoxelValue(*cornerPointsIterator); } assert(values[count] != -1); } } else { throw core::InvalidParameterException("neighborhoods other than 0 and 8 not yet supported in Interpolation"); } } else { throw core::MappingOutsideOfImageException("Error in conversion from world coordinates to index"); } } DoseTypeGy InterpolationBase::getNearestInsideVoxelValue(const VoxelGridIndex3D& currentVoxelIndex) const { VoxelGridIndex3D voxelChangedXYZ[] = {currentVoxelIndex, currentVoxelIndex, currentVoxelIndex, currentVoxelIndex, currentVoxelIndex, currentVoxelIndex, currentVoxelIndex}; unsigned int runningIndex; //x,y,z for (runningIndex = 0; runningIndex < 3; ++runningIndex) { voxelChangedXYZ[runningIndex][runningIndex] -= 1; } //xy voxelChangedXYZ[runningIndex][0] -= 1; voxelChangedXYZ[runningIndex][1] -= 1; ++runningIndex; //xz voxelChangedXYZ[runningIndex][0] -= 1; voxelChangedXYZ[runningIndex][2] -= 1; ++runningIndex; //yz voxelChangedXYZ[runningIndex][1] -= 1; voxelChangedXYZ[runningIndex][2] -= 1; ++runningIndex; //xyz voxelChangedXYZ[runningIndex][0] -= 1; voxelChangedXYZ[runningIndex][1] -= 1; voxelChangedXYZ[runningIndex][2] -= 1; ++runningIndex; unsigned int replacementVoxelIndex = 0; while (replacementVoxelIndex < runningIndex) { if (_spOriginalData->getGeometricInfo().validIndex(voxelChangedXYZ[replacementVoxelIndex])) { return _spOriginalData->getValueAt(voxelChangedXYZ[replacementVoxelIndex]); } ++replacementVoxelIndex; } return -1; } }//end namespace core }//end namespace rttb diff --git a/code/interpolation/rttbInterpolationBase.h b/code/interpolation/rttbInterpolationBase.h index 4db726c..72aec88 100644 --- a/code/interpolation/rttbInterpolationBase.h +++ b/code/interpolation/rttbInterpolationBase.h @@ -1,91 +1,91 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __INTERPOLATION_BASE_H #define __INTERPOLATION_BASE_H #include #include +#include #include "rttbAccessorInterface.h" #include "RTTBInterpolationExports.h" namespace rttb { namespace interpolation { /*! @class InterpolationBase @brief Base class for interpolation. @ingroup interpolation */ class RTTBInterpolation_EXPORT InterpolationBase { public: - using Pointer = boost::shared_ptr; - using AccessorPointer = rttb::core::AccessorInterface::AccessorPointer; + rttbClassMacroNoParent(InterpolationBase) /*! @brief Constructor */ InterpolationBase() = default; /*! @brief Virtual destructor of base class */ virtual ~InterpolationBase() = default; /*! @brief Sets the AccessorPointer @pre originalData initialized @exception core::NullPointerException if originalData==nullptr */ - void setAccessorPointer(const AccessorPointer originalData); + void setAccessorPointer(core::AccessorInterface::ConstPointer originalData); /*! @brief Returns the interpolated value for the given world coordinate */ virtual DoseTypeGy getValue(const WorldCoordinate3D& aWorldCoordinate) const = 0; protected: - AccessorPointer _spOriginalData; + rttb::core::AccessorInterface::ConstPointer _spOriginalData; /*! @brief determines voxels in a certain neighborhood of a physical based coordinate and converts in a standard cube with corner points [0 0 0], [1 0 0], [0 1 0], [1 1 0], [0 0 1], [1 0 1], [0 1 1], [1 1 1]. @param aWorldCoordinate the coordinate where to start @param neighborhood voxel around coordinate (currently only 0 and 8 implemented) @param target coordinates inside the standard cube with values [0 1] in each dimension. @param values dose values at all corner points of the standard cube. Is of type boost:shared_ptr[neighborhood] @pre target and values have to be correctly initialized (e.g. std::array target = {0.0, 0.0, 0.0}; boost::shared_ptr values(new DoseTypeGy[8]()); where 8 is neighborhood) @exception core::InvalidParameterException if neighborhood =! 0 && !=8 @exception core::MappingOutsideOfImageException if initial mapping of aWorldCoordinate is outside image @exception core::NullPointerException if dose is nullptr */ void getNeighborhoodVoxelValues(const WorldCoordinate3D& aWorldCoordinate, unsigned int neighborhood, std::array& target, boost::shared_ptr values) const; /*! @brief returns the nearest inside voxel value @pre the voxelGridIndex is outside the image and voxelGridIndex>image.size() for all dimensions. Also voxelGridIndex[]>=0 for all dimensions @note used for virtually expanding the image by one voxel as edge handling */ DoseTypeGy getNearestInsideVoxelValue(const VoxelGridIndex3D& currentVoxelIndex) const; }; } } #endif diff --git a/code/interpolation/rttbMappableDoseAccessorInterface.h b/code/interpolation/rttbMappableDoseAccessorInterface.h index ec6fc74..b691c8e 100644 --- a/code/interpolation/rttbMappableDoseAccessorInterface.h +++ b/code/interpolation/rttbMappableDoseAccessorInterface.h @@ -1,100 +1,100 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __MAPPABLE_DOSE_ACCESSOR_BASE_H #define __MAPPABLE_DOSE_ACCESSOR_BASE_H -#include +#include #include "rttbDoseAccessorInterface.h" #include "rttbGeometricInfo.h" #include "rttbBaseType.h" #include "rttbTransformationInterface.h" #include "rttbNullPointerException.h" namespace rttb { namespace interpolation { /*! @class MappableDoseAccessorInterface @brief Interface for dealing with dose information that has to be transformed into another geometry than the original dose image @details implementation of strategy is done by derived class (e.g. SimpleMappableDoseAccessor or RosuMappableDoseAccessor. Transformation is defined in TransformationInterface @ingroup interpolation */ class MappableDoseAccessorInterface: public core::DoseAccessorInterface { public: - using Pointer = boost::shared_ptr; + rttbClassMacro(MappableDoseAccessorInterface,core::DoseAccessorInterface) protected: - DoseAccessorPointer _spOriginalDoseDataMovingImage; + core::DoseAccessorInterface::ConstPointer _spOriginalDoseDataMovingImage; TransformationInterface::Pointer _spTransformation; core::GeometricInfo _geoInfoTargetImage; bool _acceptPadding; DoseTypeGy _defaultOutsideValue; public: /*! @brief Constructor. @param geoInfoTargetImage target image geometry @param doseMovingImage dose of moving image @param aTransformation the transformation @param acceptPadding is mapping outside the image allowed @param defaultOutsideValue the default outside voxel value if accepptPadding=true @pre all input parameters have to be valid @exception core::NullPointerException if one input parameter is nullptr */ MappableDoseAccessorInterface(const core::GeometricInfo& geoInfoTargetImage, - const DoseAccessorPointer doseMovingImage, const TransformationInterface::Pointer aTransformation, + core::DoseAccessorInterface::ConstPointer doseMovingImage, const TransformationInterface::Pointer aTransformation, bool acceptPadding = true, DoseTypeGy defaultOutsideValue = 0.0): _spOriginalDoseDataMovingImage(doseMovingImage), _spTransformation(aTransformation), _geoInfoTargetImage(geoInfoTargetImage), _acceptPadding(acceptPadding), _defaultOutsideValue(defaultOutsideValue) { //handle null pointers if (doseMovingImage == nullptr || aTransformation == nullptr) { throw core::NullPointerException("Pointers to input accessors/transformation cannot be nullptr."); } } /*! @brief Virtual destructor of base class */ ~MappableDoseAccessorInterface() override = default; inline const core::GeometricInfo& getGeometricInfo() const override { return _geoInfoTargetImage; }; inline GridSizeType getGridSize() const override { return _geoInfoTargetImage.getNumberOfVoxels(); }; const IDType getUID() const override { return _spOriginalDoseDataMovingImage->getUID(); }; }; } } #endif diff --git a/code/interpolation/rttbRosuMappableDoseAccessor.cpp b/code/interpolation/rttbRosuMappableDoseAccessor.cpp index bcb9a2c..5e75151 100644 --- a/code/interpolation/rttbRosuMappableDoseAccessor.cpp +++ b/code/interpolation/rttbRosuMappableDoseAccessor.cpp @@ -1,167 +1,167 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ #include "rttbRosuMappableDoseAccessor.h" #include #include "rttbNullPointerException.h" #include "rttbMappingOutsideOfImageException.h" #include "rttbLinearInterpolation.h" namespace rttb { namespace interpolation { RosuMappableDoseAccessor::RosuMappableDoseAccessor(const core::GeometricInfo& geoInfoTargetImage, - const DoseAccessorPointer doseMovingImage, - const TransformationPointer aTransformation, + core::DoseAccessorInterface::ConstPointer doseMovingImage, + const TransformationInterface::Pointer aTransformation, bool acceptPadding, DoseTypeGy defaultOutsideValue): MappableDoseAccessorInterface(geoInfoTargetImage, doseMovingImage, aTransformation, acceptPadding, defaultOutsideValue) { //define linear interpolation auto interpolationLinear = ::boost::make_shared(); _spInterpolation = interpolationLinear; _spInterpolation->setAccessorPointer(_spOriginalDoseDataMovingImage); } GenericValueType RosuMappableDoseAccessor::getValueAt(const VoxelGridID aID) const { VoxelGridIndex3D aVoxelGridIndex3D; if (_geoInfoTargetImage.convert(aID, aVoxelGridIndex3D)) { return getValueAt(aVoxelGridIndex3D); } else { if (_acceptPadding) { return _defaultOutsideValue; } else { throw core::MappingOutsideOfImageException("Error in conversion from index to world coordinates"); } } } GenericValueType RosuMappableDoseAccessor::getValueAt(const VoxelGridIndex3D& aIndex) const { //Transform requested voxel coordinates of original image into world coordinates with RTTB WorldCoordinate3D worldCoordinateTarget; if (_geoInfoTargetImage.indexToWorldCoordinate(aIndex, worldCoordinateTarget)) { std::vector octants = getOctants(worldCoordinateTarget); if (octants.size() > 2) { DoseTypeGy interpolatedDoseValue = 0.0; //get trilinear interpolation value of every octant point for (std::vector::const_iterator octantIterator = octants.begin(); octantIterator != octants.end(); ++octantIterator) { //transform coordinates WorldCoordinate3D worldCoordinateMoving; WorldCoordinate3D worldCoordinateTargetOctant = *octantIterator; _spTransformation->transformInverse(worldCoordinateTargetOctant, worldCoordinateMoving); try { interpolatedDoseValue += _spInterpolation->getValue(worldCoordinateMoving); } //Mapped outside of image? Check if padding is allowed catch (core::MappingOutsideOfImageException& /*e*/) { if (_acceptPadding) { interpolatedDoseValue += _defaultOutsideValue; } else { throw core::MappingOutsideOfImageException("Mapping outside of image"); } } catch (core::Exception& e) { std::cout << e.what() << std::endl; return -1; } } return interpolatedDoseValue / (DoseTypeGy)octants.size(); } else { if (_acceptPadding) { return _defaultOutsideValue; } else { throw core::MappingOutsideOfImageException("Too many samples are mapped outside the image!"); } } } else { if (_acceptPadding) { return _defaultOutsideValue; } else { throw core::MappingOutsideOfImageException("Error in conversion from index to world coordinates"); } } } std::vector RosuMappableDoseAccessor::getOctants( const WorldCoordinate3D& aCoordinate) const { std::vector octants; SpacingVectorType3D spacingTargetImage = _geoInfoTargetImage.getSpacing(); core::GeometricInfo geometricInfoDoseData = _spOriginalDoseDataMovingImage->getGeometricInfo(); //as the corner point is the coordinate of the voxel (grid), 0.25 and 0.75 are the center of the subvoxels for (double xOct = -0.25; xOct <= 0.25; xOct += 0.5) { for (double yOct = -0.25; yOct <= 0.25; yOct += 0.5) { for (double zOct = -0.25; zOct <= 0.25; zOct += 0.5) { WorldCoordinate3D aWorldCoordinate(aCoordinate.x() + (xOct * spacingTargetImage.x()), aCoordinate.y() + (yOct * spacingTargetImage.y()), aCoordinate.z() + (zOct * spacingTargetImage.z())); if (geometricInfoDoseData.isInside(aWorldCoordinate)) { octants.push_back(aWorldCoordinate); } } } } return octants; } }//end namespace interpolation }//end namespace rttb diff --git a/code/interpolation/rttbRosuMappableDoseAccessor.h b/code/interpolation/rttbRosuMappableDoseAccessor.h index ea52d49..aaecd0d 100644 --- a/code/interpolation/rttbRosuMappableDoseAccessor.h +++ b/code/interpolation/rttbRosuMappableDoseAccessor.h @@ -1,82 +1,80 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __ROSU_MAPPABLE_DOSE_ACCESSOR_H #define __ROSU_MAPPABLE_DOSE_ACCESSOR_H #include #include "rttbBaseType.h" #include "rttbInterpolationBase.h" #include "rttbMappableDoseAccessorInterface.h" namespace rttb { namespace interpolation { class TransformationInterface; /*! @class RosuMappableDoseAccessor @brief Class for dose mapping based on interpolation described in the Rosu2005 paper @details implementation of the following paper: Rosu, M., Chetty, I. J., Balter, J. M., Kessler, M. L., McShan, D. L., & Ten Haken, R. K. (2005). Dose reconstruction in deforming lung anatomy: Dose grid size effects and clinical implications. Medical Physics, 32(8), 2487. @ingroup interpolation */ class RosuMappableDoseAccessor: public MappableDoseAccessorInterface { private: InterpolationBase::Pointer _spInterpolation; public: - using Pointer = boost::shared_ptr; - using TransformationPointer = boost::shared_ptr; /*! @brief Constructor. Just hands values over to base class constructor. @note no interpolation as parameter since linear interpolation is fixed. @sa MappableDoseAccessorBase */ RosuMappableDoseAccessor(const core::GeometricInfo& geoInfoTargetImage, - const DoseAccessorPointer doseMovingImage, - const TransformationPointer aTransformation, + core::DoseAccessorInterface::ConstPointer doseMovingImage, + const TransformationInterface::Pointer aTransformation, bool acceptPadding = true, DoseTypeGy defaultOutsideValue = 0.0); /*! @brief Virtual destructor. */ ~RosuMappableDoseAccessor() override = default; GenericValueType getValueAt(const VoxelGridID aID) const override; /*! @brief Returns the dose for a given voxel grid index. The computation of the octant around the voxel is done and the interpolation is performed. @details Boundary treatment: if more than 6 subvoxels are outside: return _defaultOutsideValue. Otherwise: ignore the outside values. @return the dose or if (isOutside==true && _acceptPadding==true) then _defaultValue @exception core::MappingOutsideOfImageException if the point is mapped outside and if _acceptPadding==false, possibly returning _defaultValue) */ GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const override; private: /*! @brief returns the octant coordinates around a coordinate. @details i.e. coordinate is the center of a virtual voxel. Then, each side is divided into equal parts. The centers of the new subvoxels are then returned. @return a vector of the octant coordinates. */ std::vector getOctants(const WorldCoordinate3D& aCoordinate) const; }; } } #endif diff --git a/code/interpolation/rttbSimpleMappableDoseAccessor.cpp b/code/interpolation/rttbSimpleMappableDoseAccessor.cpp index a2d47c5..c0c3a76 100644 --- a/code/interpolation/rttbSimpleMappableDoseAccessor.cpp +++ b/code/interpolation/rttbSimpleMappableDoseAccessor.cpp @@ -1,113 +1,113 @@ // ----------------------------------------------------------------------- // 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 "rttbSimpleMappableDoseAccessor.h" #include "rttbNullPointerException.h" #include "rttbMappingOutsideOfImageException.h" namespace rttb { namespace interpolation { SimpleMappableDoseAccessor::SimpleMappableDoseAccessor(const core::GeometricInfo& geoInfoTargetImage, - const DoseAccessorPointer doseMovingImage, TransformationInterface::Pointer aTransformation, + core::DoseAccessorInterface::ConstPointer doseMovingImage, const TransformationInterface::Pointer aTransformation, const InterpolationBase::Pointer aInterpolation, bool acceptPadding, double defaultOutsideValue): MappableDoseAccessorInterface(geoInfoTargetImage, doseMovingImage, aTransformation, acceptPadding, defaultOutsideValue), _spInterpolation(aInterpolation) { //handle null pointers if (aInterpolation == nullptr) { throw core::NullPointerException("Pointer to interpolation cannot be nullptr."); } else { _spInterpolation->setAccessorPointer(_spOriginalDoseDataMovingImage); } } GenericValueType SimpleMappableDoseAccessor::getValueAt(const VoxelGridID aID) const { VoxelGridIndex3D aVoxelGridIndex3D; if (_geoInfoTargetImage.convert(aID, aVoxelGridIndex3D)) { return getValueAt(aVoxelGridIndex3D); } else { if (_acceptPadding) { return _defaultOutsideValue; } else { throw core::MappingOutsideOfImageException("Error in conversion from index to world coordinates"); } } } GenericValueType SimpleMappableDoseAccessor::getValueAt(const VoxelGridIndex3D& aIndex) const { //Transform requested voxel coordinates of original image into world coordinates with RTTB WorldCoordinate3D worldCoordinateTarget; if (_geoInfoTargetImage.indexToWorldCoordinate(aIndex, worldCoordinateTarget)) { //transform coordinates WorldCoordinate3D worldCoordinateMoving; _spTransformation->transformInverse(worldCoordinateTarget, worldCoordinateMoving); //Use Interpolation to compute dose at mappedImage try { return _spInterpolation->getValue(worldCoordinateMoving); } //Mapped outside of image? Check if padding is allowed catch (core::MappingOutsideOfImageException& /*e*/) { if (_acceptPadding) { return _defaultOutsideValue; } else { throw core::MappingOutsideOfImageException("Error in conversion from index to world coordinates"); } } catch (core::Exception& e) { std::cout << e.what() << std::endl; return -1; } } //ok, if that fails, throw exception. Makes no sense to go further else { if (_acceptPadding) { return _defaultOutsideValue; } else { throw core::MappingOutsideOfImageException("Error in conversion from index to world coordinates"); } } } }//end namespace interpolation }//end namespace rttb diff --git a/code/interpolation/rttbSimpleMappableDoseAccessor.h b/code/interpolation/rttbSimpleMappableDoseAccessor.h index d4f8bc8..35f3b89 100644 --- a/code/interpolation/rttbSimpleMappableDoseAccessor.h +++ b/code/interpolation/rttbSimpleMappableDoseAccessor.h @@ -1,78 +1,76 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __SIMPLE_MAPPABLE_DOSE_ACCESSOR_H #define __SIMPLE_MAPPABLE_DOSE_ACCESSOR_H #include #include #include "rttbInterpolationBase.h" #include "rttbLinearInterpolation.h" #include "rttbTransformationInterface.h" #include "rttbMappableDoseAccessorInterface.h" #include "RTTBInterpolationExports.h" namespace rttb { namespace interpolation { /*! @class SimpleMappableDoseAccessor @brief Class for dose mapping based on simple trilinear interpolation @ingroup interpolation */ class RTTBInterpolation_EXPORT SimpleMappableDoseAccessor : public MappableDoseAccessorInterface { private: InterpolationBase::Pointer _spInterpolation; public: - using Pointer = boost::shared_ptr; - /*! @brief Constructor. Just hands values over to base class constructor. @param aInterpolation the used interpolation. @sa MappableDoseAccessorBase */ SimpleMappableDoseAccessor(const core::GeometricInfo& geoInfoTargetImage, - const DoseAccessorPointer doseMovingImage, + core::DoseAccessorInterface::ConstPointer doseMovingImage, const TransformationInterface::Pointer aTransformation, const InterpolationBase::Pointer aInterpolation = ::boost::make_shared(), bool acceptPadding = true, DoseTypeGy defaultOutsideValue = 0.0); /*! @brief Virtual destructor of class */ ~SimpleMappableDoseAccessor() override = default; /*! @brief Returns the dose for a given voxel grid id. Plain trilinear interpolation is performed. @sa getDoseAt(const VoxelGridIndex3D& aIndex) */ GenericValueType getValueAt(const VoxelGridID aID) const override; /*! @brief Returns the dose for a given voxel grid index. Plain trilinear interpolation is performed. @return the dose or if (isOutside==true && _acceptPadding==true) then _defaultValue @exception core::MappingOutsideOfImageException if the point is mapped outside and if _acceptPadding==false, possibly returning _defaultValue) */ GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const override; }; } } #endif diff --git a/code/interpolation/rttbTransformationInterface.h b/code/interpolation/rttbTransformationInterface.h index 4d230fe..235c037 100644 --- a/code/interpolation/rttbTransformationInterface.h +++ b/code/interpolation/rttbTransformationInterface.h @@ -1,71 +1,71 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __TRANSFORMATION_INTERFACE_H #define __TRANSFORMATION_INTERFACE_H -#include +#include #include "rttbBaseType.h" #include "RTTBInterpolationExports.h" namespace rttb { namespace interpolation { /*! @class TransformationInterface @brief Base class for transformation (in World coordinates). @ingroup interpolation */ class RTTBInterpolation_EXPORT TransformationInterface { public: - using Pointer = boost::shared_ptr; + rttbClassMacroNoParent(TransformationInterface) protected: /*! @brief Constructor */ TransformationInterface() = default; /*! @brief Virtual destructor of interface class */ virtual ~TransformationInterface() = default; public: /*! @brief performs a transformation targetImage --> movingImage */ virtual bool transformInverse(const WorldCoordinate3D& worldCoordinateTarget, WorldCoordinate3D& worldCoordinateMoving) const = 0; /*! @brief performs a transformation movingImage --> targetImage */ virtual bool transform(const WorldCoordinate3D& worldCoordinateMoving, WorldCoordinate3D& worldCoordinateTarget) const = 0; private: TransformationInterface(const TransformationInterface&) = delete;//not implemented on purpose -> non-copyable TransformationInterface& operator=(const TransformationInterface&) = delete;//not implemented on purpose -> non-copyable }; } } #endif diff --git a/code/io/dicom/rttbDicomFileDoseAccessorWriter.cpp b/code/io/dicom/rttbDicomFileDoseAccessorWriter.cpp index 6f66e6a..55e3b0a 100644 --- a/code/io/dicom/rttbDicomFileDoseAccessorWriter.cpp +++ b/code/io/dicom/rttbDicomFileDoseAccessorWriter.cpp @@ -1,257 +1,257 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include #include #include "rttbDicomFileDoseAccessorWriter.h" #include "rttbInvalidDoseException.h" #include "rttbGeometricInfo.h" #include "rttbGenericDoseIterator.h" #include "rttbDoseStatisticsCalculator.h" namespace rttb { namespace io { namespace dicom { DicomFileDoseAccessorWriter::DicomFileDoseAccessorWriter() { _doseIOD = boost::make_shared(); _dataset = _fileformat.getDataset(); } void DicomFileDoseAccessorWriter::setFileName(DICOMRTFileNameString aFileName) { _fileName = aFileName; } bool DicomFileDoseAccessorWriter::process() { OFCondition status; /* Prepare dcmtk */ DcmItem* dcm_item = nullptr; //get geometric info rttb::core::GeometricInfo geometricInfo = _doseAccessor->getGeometricInfo(); /* ----------------------------------------------------------------- */ /* Part 1 -- General header */ /* ----------------------------------------------------------------- */ OFString CreationUID(_doseAccessor->getUID().c_str()); _dataset->putAndInsertString(DCM_ImageType, R"(DERIVED\SECONDARY\REFORMATTED)"); _dataset->putAndInsertOFStringArray(DCM_InstanceCreationDate, "");//Creation Date _dataset->putAndInsertOFStringArray(DCM_InstanceCreationTime, "");//Creation Time _dataset->putAndInsertOFStringArray(DCM_InstanceCreatorUID, CreationUID); _dataset->putAndInsertString(DCM_SOPClassUID, UID_RTDoseStorage); _dataset->putAndInsertString(DCM_SOPInstanceUID, _doseAccessor->getUID().c_str()); _dataset->putAndInsertOFStringArray(DCM_StudyDate, ""); _dataset->putAndInsertOFStringArray(DCM_StudyTime, ""); _dataset->putAndInsertOFStringArray(DCM_AccessionNumber, ""); _dataset->putAndInsertOFStringArray(DCM_Modality, "RTDOSE"); _dataset->putAndInsertString(DCM_Manufacturer, "RTToolbox"); _dataset->putAndInsertString(DCM_InstitutionName, ""); _dataset->putAndInsertString(DCM_ReferringPhysicianName, ""); _dataset->putAndInsertString(DCM_StationName, ""); _dataset->putAndInsertString(DCM_ManufacturerModelName, "RTToolbox"); /* (0008,1140) DCM_ReferencedImageSequence -- MIM likes this */ dcm_item = nullptr; _dataset->findOrCreateSequenceItem( DCM_ReferencedImageSequence, dcm_item, -2); dcm_item->putAndInsertString(DCM_ReferencedSOPClassUID, UID_CTImageStorage); dcm_item->putAndInsertString(DCM_ReferencedSOPInstanceUID, ""); _dataset->putAndInsertString(DCM_PatientName, ""); _dataset->putAndInsertString(DCM_PatientID, ""); _dataset->putAndInsertString(DCM_PatientBirthDate, ""); _dataset->putAndInsertString(DCM_PatientSex, "O"); _dataset->putAndInsertString(DCM_SliceThickness, boost::lexical_cast(geometricInfo.getSpacing()(2)).c_str()); _dataset->putAndInsertString(DCM_SoftwareVersions, ""); _dataset->putAndInsertString(DCM_StudyInstanceUID, ""); _dataset->putAndInsertString(DCM_SeriesInstanceUID, ""); _dataset->putAndInsertString(DCM_StudyID, "10001"); _dataset->putAndInsertString(DCM_SeriesNumber, ""); _dataset->putAndInsertString(DCM_InstanceNumber, "1"); /* GCS FIX: PatientOrientation */ std::ostringstream sstr; sstr << geometricInfo.getImagePositionPatient().x() << R"(\)" << geometricInfo.getImagePositionPatient().y() << R"(\)" << geometricInfo.getImagePositionPatient().z(); _dataset->putAndInsertString(DCM_PatientOrientation, "L/P"); _dataset->putAndInsertString(DCM_ImagePositionPatient, sstr.str().c_str()); auto orientationMatrix = geometricInfo.getOrientationMatrix(); sstr.str(""); sstr << orientationMatrix(0,0) << R"(\)" << orientationMatrix(1,0) << R"(\)" << orientationMatrix(2,0) << R"(\)" << orientationMatrix(0,1) << R"(\)" << orientationMatrix(1,1) << R"(\)" << orientationMatrix(2,1); _dataset->putAndInsertString(DCM_ImageOrientationPatient, sstr.str().c_str()); _dataset->putAndInsertString(DCM_FrameOfReferenceUID, ""); _dataset->putAndInsertString(DCM_SamplesPerPixel, "1"); _dataset->putAndInsertString(DCM_PhotometricInterpretation, "MONOCHROME2"); sstr.str(""); sstr << geometricInfo.getNumSlices(); _dataset->putAndInsertString(DCM_NumberOfFrames, sstr.str().c_str()); /* GCS FIX: Add FrameIncrementPointer */ _dataset->putAndInsertString(DCM_FrameIncrementPointer, "(3004,000c)"); _dataset->putAndInsertUint16(DCM_Rows, static_cast(geometricInfo.getNumRows())); _dataset->putAndInsertUint16(DCM_Columns, static_cast(geometricInfo.getNumColumns())); sstr.str(""); sstr << geometricInfo.getSpacing()(1) << R"(\)" << geometricInfo.getSpacing()(0); _dataset->putAndInsertString(DCM_PixelSpacing, sstr.str().c_str()); _dataset->putAndInsertString(DCM_BitsAllocated, "32"); _dataset->putAndInsertString(DCM_BitsStored, "32"); _dataset->putAndInsertString(DCM_HighBit, "31"); _dataset->putAndInsertString(DCM_DoseUnits, "GY"); _dataset->putAndInsertString(DCM_DoseSummationType, "PLAN"); sstr.str("0"); for (unsigned int i = 1; i < geometricInfo.getNumSlices(); i++) { sstr << R"(\)" << i* geometricInfo.getSpacing()(2); } _dataset->putAndInsertString(DCM_GridFrameOffsetVector, sstr.str().c_str()); /* We need to convert image to uint16_t, but first we need to scale it so that the maximum dose fits in a 16-bit unsigned integer. Compute an appropriate scaling factor based on the maximum dose. */ /* Find the maximum value in the image */ boost::shared_ptr spTestDoseIterator = boost::make_shared(_doseAccessor); rttb::core::GenericDoseIterator::DoseIteratorPointer spDoseIterator(spTestDoseIterator); rttb::algorithms::DoseStatisticsCalculator myDoseStatsCalculator(spDoseIterator); - rttb::algorithms::DoseStatistics::DoseStatisticsPointer doseStatistics = + auto doseStatistics = myDoseStatsCalculator.calculateDoseStatistics(); double maxDose = doseStatistics->getMaximum(); /* Find scale factor */ double dose_scale; dose_scale = maxDose / PixelDataMaxValue; /* Scale the image and add scale factor to _dataset */ sstr.str(""); sstr << dose_scale; _dataset->putAndInsertString(DCM_DoseGridScaling, sstr.str().c_str()); /* (300c,0002) ReferencedRTPlanSequence -- for future expansion */ dcm_item = nullptr; _dataset->findOrCreateSequenceItem( DCM_ReferencedRTPlanSequence, dcm_item, -2); dcm_item->putAndInsertString(DCM_ReferencedSOPClassUID, UID_RTPlanStorage); dcm_item->putAndInsertString(DCM_ReferencedSOPInstanceUID, ""); /* (300c,0060) DCM_ReferencedStructureSetSequence -- MIM likes this */ dcm_item = nullptr; _dataset->findOrCreateSequenceItem( DCM_ReferencedStructureSetSequence, dcm_item, -2); dcm_item->putAndInsertString(DCM_ReferencedSOPClassUID, UID_RTStructureSetStorage); dcm_item->putAndInsertString(DCM_ReferencedSOPInstanceUID, ""); /* Convert image bytes to integer, then add to _dataset */ Uint16* pixelData; auto pixelCount = static_cast(geometricInfo.getNumRows() * geometricInfo.getNumColumns() * geometricInfo.getNumSlices()); pixelData = new Uint16[pixelCount]; for (unsigned int i = 0; i < pixelCount; ++i) { double doseValue = _doseAccessor->getValueAt(i); double pixelValue = doseValue / dose_scale; if (pixelValue > PixelDataMaxValue) { pixelValue = PixelDataMaxValue; } pixelData[i] = boost::numeric_cast(pixelValue); } status = _dataset->putAndInsertUint16Array(DCM_PixelData, pixelData, pixelCount); if (!status.good()) { throw core::InvalidDoseException("Error: put and insert pixel data failed!"); } //Write dose to file status = _fileformat.saveFile(_fileName.c_str(), EXS_LittleEndianExplicit); if (status.bad()) { std::cerr << "Error: cannot write DICOM RTDOSE!" << std::endl; } return true; } }//end namespace itk }//end namespace io }//end namespace rttb diff --git a/code/io/dicom/rttbDicomFileDoseAccessorWriter.h b/code/io/dicom/rttbDicomFileDoseAccessorWriter.h index 43d6880..8f58ac4 100644 --- a/code/io/dicom/rttbDicomFileDoseAccessorWriter.h +++ b/code/io/dicom/rttbDicomFileDoseAccessorWriter.h @@ -1,82 +1,82 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DICOM_FILE_DOSE_ACCESSOR_WRITER_H #define __DICOM_FILE_DOSE_ACCESSOR_WRITER_H #include "../itk/rttbDoseAccessorProcessorBase.h" #include "../itk/rttbDoseAccessorConversionSettingInterface.h" #include "rttbDicomDoseAccessor.h" //pixel data max value UINT16_MAX #define PixelDataMaxValue 0xffff namespace rttb { namespace io { namespace dicom { /*! @class DicomFileDoseAccessorWriter @brief Class converts/dumps the processed accessor into an dicom file @remark DoseAccessorConversionInterface defines how the converter should react on non valid dose values. */ class DicomFileDoseAccessorWriter: public core::DoseAccessorProcessorBase, public core::DoseAccessorConversionSettingInterface { public: - using DoseAccessorPointer = core::DoseAccessorInterface::DoseAccessorPointer; + using DoseAccessorPointer = core::DoseAccessorInterface::Pointer; using DRTDoseIODPointer = DicomDoseAccessor::DRTDoseIODPtr; /*! @brief Standard Constructor. */ DicomFileDoseAccessorWriter(); ~DicomFileDoseAccessorWriter() override = default; /*! Set a file name to write the dose @param aFileName a file name to write the dose */ void setFileName(DICOMRTFileNameString aFileName); /*! @brief Convert the accessor into dicom dataset and write dicom dataset to a file @exception InvalidDoseException thrown if put and insert pixel data into dicom dataset failed */ bool process() override; private: DicomFileDoseAccessorWriter(const DicomFileDoseAccessorWriter&) = delete; //not implemented on purpose -> non-copyable DicomFileDoseAccessorWriter& operator=(const DicomFileDoseAccessorWriter&) = delete;//not implemented on purpose -> non-copyable DRTDoseIODPointer _doseIOD; DICOMRTFileNameString _fileName; DcmFileFormat _fileformat; DcmDataset* _dataset; }; } } } #endif diff --git a/code/io/dicom/rttbDicomFileStructureSetGenerator.h b/code/io/dicom/rttbDicomFileStructureSetGenerator.h index 4acb743..4fbb8a7 100644 --- a/code/io/dicom/rttbDicomFileStructureSetGenerator.h +++ b/code/io/dicom/rttbDicomFileStructureSetGenerator.h @@ -1,91 +1,91 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ /* Changes in Architecture: The DICOM specific classes will be removed and transfered to the corresponding IO classes. This class should only provide general structure functionality. */ #ifndef __DICOM_FILE_STRUCTURE_SET_GENERATOR_H #define __DICOM_FILE_STRUCTURE_SET_GENERATOR_H #include #include #include "drtstrct.h" #include "rttbBaseType.h" #include "rttbStrVectorStructureSetGenerator.h" #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4251) #endif namespace rttb { namespace io { namespace dicom { /*! @class DicomFileStructureSetGenerator @brief Generate a structure set from a corresponding dicomRT file. */ class DicomFileStructureSetGenerator: public core::StrVectorStructureSetGenerator { public: - using StructTypePointer = core::StructureSet::StructTypePointer; - using StructureSetPointer = StructureSetGeneratorInterface::StructureSetPointer; + using StructTypePointer = core::Structure::Pointer; + using StructureSetPointer = core::StructureSet::Pointer; using DRTStrSetIODPtr = boost::shared_ptr; private: IDType _UID; DICOMRTFileNameString _fileName; DicomFileStructureSetGenerator() = default; public: /*! @brief Constructor @param aDICOMRTStrSetFileName a DICOM-RT Structure set file name or a directory name @exception InvalidParameterException thrown if the file does not exist or the directory has no dicom structure file @exception DcmrtException thrown if load and read file failed */ DicomFileStructureSetGenerator(DICOMRTFileNameString aDICOMRTStrSetFileName); /*! @brief Destructor */ ~DicomFileStructureSetGenerator() override; /*! @brief generate structure set @return return shared pointer of StructureSet @exception DcmrtException Thrown if loadFile and read failed @exception InvalidParameterException throw if the imported header tags are not numerical. */ StructureSetPointer generateStructureSet() override; }; } } } #endif diff --git a/code/io/dicom/rttbDicomIODStructureSetGenerator.h b/code/io/dicom/rttbDicomIODStructureSetGenerator.h index 482ffcb..2be016c 100644 --- a/code/io/dicom/rttbDicomIODStructureSetGenerator.h +++ b/code/io/dicom/rttbDicomIODStructureSetGenerator.h @@ -1,91 +1,91 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ /* Changes in Architecture: The DICOM specific classes will be removed and transfered to the corresponding IO classes. This class should only provide general structure functionality. */ #ifndef __DICOM_IOD_STRUCTURE_SET_GENERATOR_H #define __DICOM_IOD_STRUCTURE_SET_GENERATOR_H #include #include "drtstrct.h" #include "rttbBaseType.h" #include "rttbStrVectorStructureSetGenerator.h" namespace rttb { namespace io { namespace dicom { /*! @class DicomIODStructureSetGenerator @brief Generate a structure set from a DRTStructureSetIOD pointer. */ class DicomIODStructureSetGenerator: public core::StrVectorStructureSetGenerator { public: - using StructTypePointer = core::StructureSet::StructTypePointer; - using StructureSetPointer = StructureSetGeneratorInterface::StructureSetPointer; + using StructTypePointer = core::Structure::Pointer; + using StructureSetPointer = core::StructureSet::Pointer; using DRTStrSetIODPtr = boost::shared_ptr; private: DRTStrSetIODPtr _drtStrSetIOD; IDType _UID; /*! Import Structure data from file. @exception InvalidParameterException Thrown if the imported header tags are not numerical. */ void readStrSet(); /*! Replaces the character 'á' ((int)-96) to ' ' ((int)32) in a string. */ void correctSpacesInROIName(std::string& roiName); public: /*! @brief Structure Constructor Get the vector of structures from DRTStructureSetIOD object @exception NullPointerException Thrown if structureSet is nullptr */ DicomIODStructureSetGenerator(DRTStrSetIODPtr aDRTStructureSetIOD); /*! @brief Destructor */ ~DicomIODStructureSetGenerator() override; /*! @brief generate structure set @return return shared pointer of StructureSet @exception InvalidParameterException throw if the imported header tags are not numerical. */ StructureSetPointer generateStructureSet() override; }; } } } #endif diff --git a/code/io/itk/itkDoseAccessorImageFilter.h b/code/io/itk/itkDoseAccessorImageFilter.h index 703ac99..f41e9a9 100644 --- a/code/io/itk/itkDoseAccessorImageFilter.h +++ b/code/io/itk/itkDoseAccessorImageFilter.h @@ -1,118 +1,118 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __itkDoseAccessorImageFilter_h #define __itkDoseAccessorImageFilter_h #include "itkImageToImageFilter.h" #include "rttbDoseAccessorInterface.h" #include "rttbITKImageAccessor.h" namespace itk { /** \class DoseAccessorImageFilter * \brief Perform a generic pixel-wise operation on the input image by setting its pixel values according to the dose accessor output. * * \ingroup IntensityImageFilters MultiThreaded * \ingroup ITKImageIntensity */ typedef rttb::io::itk::ITKImageAccessor::ITKImageType RTTBDoseImageType; class ITK_EXPORT DoseAccessorImageFilter: public ImageToImageFilter< RTTBDoseImageType, RTTBDoseImageType > { public: /** Standard class typedefs. */ typedef DoseAccessorImageFilter Self; typedef ImageToImageFilter< RTTBDoseImageType, RTTBDoseImageType > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(DoseAccessorImageFilter, ImageToImageFilter); /** Some typedefs. */ typedef RTTBDoseImageType InputImageType; typedef InputImageType::Pointer InputImagePointer; typedef InputImageType::RegionType InputImageRegionType; typedef InputImageType::PixelType InputImagePixelType; typedef RTTBDoseImageType OutputImageType; typedef OutputImageType::Pointer OutputImagePointer; typedef OutputImageType::RegionType OutputImageRegionType; typedef OutputImageType::PixelType OutputImagePixelType; typedef rttb::core::DoseAccessorInterface DoseAccessorType; - typedef rttb::core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; + typedef rttb::core::DoseAccessorInterface::Pointer DoseAccessorPointer; /** Get the accessor pointer. */ DoseAccessorPointer GetAccessor() { return m_Accessor; } /** Set the accessor pointer. */ void SetAccessor(DoseAccessorPointer accessor) { if (m_Accessor != accessor) { m_Accessor = accessor; this->Modified(); } } /** ImageDimension constants */ itkStaticConstMacro( InputImageDimension, unsigned int, InputImageType::ImageDimension); itkStaticConstMacro( OutputImageDimension, unsigned int, OutputImageType::ImageDimension); protected: DoseAccessorImageFilter(); ~DoseAccessorImageFilter() override {} /** DoseAccessorImageFilter can be implemented as a multi threaded filter. * Therefore, this implementation provides a ThreadedGenerateData() routine * which is called for each processing thread. The output image data is * allocated automatically by the superclass prior to calling * ThreadedGenerateData(). ThreadedGenerateData can only write to the * portion of the output image specified by the parameter * "outputRegionForThread" * * \sa ImageToImageFilter::ThreadedGenerateData(), * ImageToImageFilter::GenerateData() */ void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, ThreadIdType threadId) override; private: DoseAccessorImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented DoseAccessorPointer m_Accessor; }; } // end namespace itk #endif diff --git a/code/io/itk/itkMaskAccessorImageSource.h b/code/io/itk/itkMaskAccessorImageSource.h index 2448cde..543d992 100644 --- a/code/io/itk/itkMaskAccessorImageSource.h +++ b/code/io/itk/itkMaskAccessorImageSource.h @@ -1,111 +1,111 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1221 $ (last changed revision) // @date $Date: 2015-12-01 13:43:31 +0100 (Di, 01 Dez 2015) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __itkMaskAccessorImageSource_h #define __itkMaskAccessorImageSource_h #include "itkGenerateImageSource.h" #include "rttbMaskAccessorInterface.h" #include "rttbITKImageMaskAccessor.h" namespace itk { /** \class MaskAccessorImageSource * \brief Converts a given mask accessor into an itk image. * */ typedef rttb::io::itk::ITKImageMaskAccessor::ITKMaskImageType RTTBMaskImageType; class ITK_EXPORT MaskAccessorImageSource: public GenerateImageSource< RTTBMaskImageType> { public: /** Standard class typedefs. */ typedef MaskAccessorImageSource Self; typedef GenerateImageSource< RTTBMaskImageType > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(MaskAccessorImageSource, ImageToImageFilter); /** Some typedefs. */ typedef RTTBMaskImageType OutputImageType; typedef OutputImageType::Pointer OutputImagePointer; typedef OutputImageType::RegionType OutputImageRegionType; typedef OutputImageType::PixelType OutputImagePixelType; typedef rttb::core::MaskAccessorInterface AccessorType; - typedef rttb::core::MaskAccessorInterface::MaskAccessorPointer AccessorPointer; + typedef rttb::core::MaskAccessorInterface::Pointer AccessorPointer; /** Get the accessor pointer. */ itkGetConstMacro(Accessor, AccessorPointer); /** Set the accessor pointer. */ void SetAccessor(AccessorPointer accessor) { if (m_Accessor != accessor) { m_Accessor = accessor; this->Modified(); } } itkSetMacro(FailsOnInvalidIDs, bool); itkGetConstMacro(FailsOnInvalidIDs, bool); itkSetMacro(InvalidMaskValue, OutputImageType::ValueType); itkGetConstMacro(InvalidMaskValue, OutputImageType::ValueType); /** ImageDimension constants */ itkStaticConstMacro( OutputImageDimension, unsigned int, OutputImageType::ImageDimension); protected: MaskAccessorImageSource(); ~MaskAccessorImageSource() override {} void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, ThreadIdType threadId) override; void BeforeThreadedGenerateData() override; private: MaskAccessorImageSource(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented typedef std::map VoxelMapType; VoxelMapType m_idMap; rttb::core::MaskAccessorInterface::MaskVoxelListPointer m_MaskedVoxels; AccessorPointer m_Accessor; bool m_FailsOnInvalidIDs{true}; OutputImageType::ValueType m_InvalidMaskValue{0}; }; } // end namespace itk #endif diff --git a/code/io/itk/rttbDoseAccessorProcessorBase.h b/code/io/itk/rttbDoseAccessorProcessorBase.h index da156d2..7283f31 100644 --- a/code/io/itk/rttbDoseAccessorProcessorBase.h +++ b/code/io/itk/rttbDoseAccessorProcessorBase.h @@ -1,61 +1,61 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DOSE_ACCESSOR_PROCESSOR_BASE_H #define __DOSE_ACCESSOR_PROCESSOR_BASE_H #include #include "rttbDoseAccessorProcessorInterface.h" namespace rttb { namespace core { /*! @class DoseAccessorProcessorBase @brief Abstract class for all DoseAccessor generating classes */ class DoseAccessorProcessorBase: public DoseAccessorProcessorInterface { public: - using DoseAccessorPointer = core::DoseAccessorInterface::DoseAccessorPointer; + using DoseAccessorPointer = core::DoseAccessorInterface::Pointer; void setDoseAccessor(DoseAccessorPointer accessor) override { _doseAccessor = accessor; }; private: DoseAccessorProcessorBase(const DoseAccessorProcessorBase&) = delete; //not implemented on purpose -> non-copyable DoseAccessorProcessorBase& operator=(const DoseAccessorProcessorBase&) = delete;//not implemented on purpose -> non-copyable protected: DoseAccessorProcessorBase() = default; ~DoseAccessorProcessorBase() override = default; /*! @brief Dose accessor which should be generated */ DoseAccessorPointer _doseAccessor; }; } } #endif diff --git a/code/io/itk/rttbDoseAccessorProcessorInterface.h b/code/io/itk/rttbDoseAccessorProcessorInterface.h index fe29431..52abd1f 100644 --- a/code/io/itk/rttbDoseAccessorProcessorInterface.h +++ b/code/io/itk/rttbDoseAccessorProcessorInterface.h @@ -1,65 +1,65 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DOSE_ACCESSOR_PROCESSOR_INTERFACE_H #define __DOSE_ACCESSOR_PROCESSOR_INTERFACE_H #include "rttbDoseAccessorInterface.h" namespace rttb { namespace core { /*! @class DoseAccessorProcessorInterface @brief Interface for all DoseAccessor generating classes */ class DoseAccessorProcessorInterface { public: - using DoseAccessorPointer = core::DoseAccessorInterface::DoseAccessorPointer; + using DoseAccessorPointer = core::DoseAccessorInterface::Pointer; private: DoseAccessorProcessorInterface(const DoseAccessorProcessorInterface&) = delete; //not implemented on purpose -> non-copyable DoseAccessorProcessorInterface& operator=(const DoseAccessorProcessorInterface&) = delete;//not implemented on purpose -> non-copyable protected: DoseAccessorProcessorInterface() = default; virtual ~DoseAccessorProcessorInterface() = default; public: /*! @brief Sets the DoseAccessor that should be processed @pre passed accessor must point to a valid instance. */ virtual void setDoseAccessor(DoseAccessorPointer accessor) = 0; /*! @brief Process the passed DoseAccessor @return if the processing was successful. */ virtual bool process() = 0; }; } } #endif diff --git a/code/io/itk/rttbITKImageAccessorConverter.h b/code/io/itk/rttbITKImageAccessorConverter.h index 2911b7e..2ff380c 100644 --- a/code/io/itk/rttbITKImageAccessorConverter.h +++ b/code/io/itk/rttbITKImageAccessorConverter.h @@ -1,69 +1,69 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __ITK_IMAGE_ACCESSOR_CONVERTER_H #define __ITK_IMAGE_ACCESSOR_CONVERTER_H #include "rttbDoseAccessorProcessorBase.h" #include "rttbDoseAccessorConversionSettingInterface.h" #include "itkImage.h" #include "RTTBITKIOExports.h" namespace rttb { namespace io { namespace itk { /*! @class ITKImageAccessorConverter @brief Class converts/dumps the processed accessor into an itk image @remark DoseAccessorConversionInterface defines how the converter should react on non valid dose values. */ class RTTBITKIO_EXPORT ITKImageAccessorConverter : public core::DoseAccessorProcessorBase, public core::DoseAccessorConversionSettingInterface { public: typedef ::itk::Image ITKImageType; - using DoseAccessorPointer = core::DoseAccessorInterface::DoseAccessorPointer; + using DoseAccessorPointer = core::DoseAccessorInterface::Pointer; bool process() override; ITKImageType::Pointer getITKImage() { return _itkImage; } ITKImageAccessorConverter(DoseAccessorPointer accessor); ~ITKImageAccessorConverter() override = default; private: ITKImageAccessorConverter(const ITKImageAccessorConverter&) = delete; //not implemented on purpose -> non-copyable ITKImageAccessorConverter& operator=(const ITKImageAccessorConverter&) = delete;//not implemented on purpose -> non-copyable ITKImageType::Pointer _itkImage; }; } } } #endif diff --git a/code/io/itk/rttbITKImageMaskAccessor.h b/code/io/itk/rttbITKImageMaskAccessor.h index 60ed22a..9fad60c 100644 --- a/code/io/itk/rttbITKImageMaskAccessor.h +++ b/code/io/itk/rttbITKImageMaskAccessor.h @@ -1,112 +1,111 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __ITK_IMAGE_MASK_ACCESSOR_H #define __ITK_IMAGE_MASK_ACCESSOR_H #include "rttbMaskAccessorInterface.h" #include "rttbBaseType.h" +#include "rttbGeometricInfo.h" #include "itkImage.h" namespace rttb { namespace io { namespace itk { /*! @class ITKImageMaskAccessor @brief This class gives access to mask information stored in an itk image */ class ITKImageMaskAccessor: public core::MaskAccessorInterface { public: typedef ::itk::Image ITKMaskImageType; using ITKImageBaseType = ::itk::ImageBase<3>; using MaskVoxelList = core::MaskAccessorInterface::MaskVoxelList; using MaskVoxelListPointer = core::MaskAccessorInterface::MaskVoxelListPointer; - using GeometricInfoPointer = boost::shared_ptr; - private: /** @brief The mask as itkImage */ ITKMaskImageType::ConstPointer _mask; IDType _maskUID; - GeometricInfoPointer _geoInfo; + core::GeometricInfo::Pointer _geoInfo; /*! vector containing list of mask voxels*/ MaskVoxelListPointer _relevantVoxelVector; /*! @brief get all required data from the itk image contained in _Mask @exception InvalidDoseException if PixelSpacing is 0 or size in any dimension is 0. */ bool assembleGeometricInfo(); public: ~ITKImageMaskAccessor() override; ITKImageMaskAccessor(ITKMaskImageType::ConstPointer aMaskImage); /*! @brief voxelization of the given structures according to the original RTToolbox algorithm*/ void updateMask() override; /*! @brief get vector conatining al relevant voxels that are inside the given structure*/ MaskVoxelListPointer getRelevantVoxelVector() override; /*! @brief get vector conatining al relevant voxels that have a relevant volume above the given threshold and are inside the given structure*/ MaskVoxelListPointer getRelevantVoxelVector(float lowerThreshold) override; /*!@brief determine how a given voxel on the dose grid is masked * @param aID ID of the voxel in grid. * @param voxel Reference to the voxel. * @post after a valid call voxel contains the information of the specified grid voxel. If aID is not valid, voxel values are undefined. * The relevant volume fraction will be set to zero. * @return Indicates of the voxel exists and therefore if parameter voxel contains valid values.*/ bool getMaskAt(const VoxelGridID aID, core::MaskVoxel& voxel) const override; bool getMaskAt(const VoxelGridIndex3D& aIndex, core::MaskVoxel& voxel) const override; /*! @brief give access to GeometricInfo*/ const core::GeometricInfo& getGeometricInfo() const override; /* @ brief is true if Mask is on a homogeneous grid */ // Inhomogeneous grids are not supported at the moment, but if they will // be supported in the future the interface does not need to change. bool isGridHomogeneous() const override { return true; }; IDType getMaskUID() const override { return _maskUID; }; }; } } } #endif diff --git a/code/io/itk/rttbITKImageMaskAccessorConverter.h b/code/io/itk/rttbITKImageMaskAccessorConverter.h index 2ed117e..9bde713 100644 --- a/code/io/itk/rttbITKImageMaskAccessorConverter.h +++ b/code/io/itk/rttbITKImageMaskAccessorConverter.h @@ -1,70 +1,70 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __ITK_IMAGE_MASK_ACCESSOR_CONVERTER_H #define __ITK_IMAGE_MASK_ACCESSOR_CONVERTER_H #include "rttbITKImageMaskAccessor.h" #include "rttbMaskAccessorProcessorBase.h" #include "../itk/rttbDoseAccessorConversionSettingInterface.h" #include "RTTBITKIOExports.h" namespace rttb { namespace io { namespace itk { /*! @class ITKImageMaskAccessorConverter @brief Class converts/dumps the processed accessor into an itk image @remark MaskAccessorConversionInterface defines how the converter should react on non valid Mask values. */ class RTTBITKIO_EXPORT ITKImageMaskAccessorConverter : public core::MaskAccessorProcessorBase, public rttb::core::DoseAccessorConversionSettingInterface { public: - using MaskAccessorPointer = core::MaskAccessorInterface::MaskAccessorPointer; + using MaskAccessorPointer = core::MaskAccessorInterface::Pointer; bool process() override; const ITKImageMaskAccessor::ITKMaskImageType::Pointer getITKImage() { return _itkImage; } ITKImageMaskAccessorConverter(MaskAccessorPointer accessor); ~ITKImageMaskAccessorConverter() override = default; private: ITKImageMaskAccessorConverter(const ITKImageMaskAccessorConverter&) = delete; //not implemented on purpose -> non-copyable ITKImageMaskAccessorConverter& operator=(const ITKImageMaskAccessorConverter&) = delete;//not implemented on purpose -> non-copyable ITKImageMaskAccessor::ITKMaskImageType::Pointer _itkImage; }; } } } #endif diff --git a/code/io/models/rttbModelXMLWriter.cpp b/code/io/models/rttbModelXMLWriter.cpp index 311259e..81a2bb0 100644 --- a/code/io/models/rttbModelXMLWriter.cpp +++ b/code/io/models/rttbModelXMLWriter.cpp @@ -1,149 +1,148 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1328 $ (last changed revision) // @date $Date: 2016-04-22 09:50:01 +0200 (Fr, 22 Apr 2016) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "rttbModelXMLWriter.h" #include /*boost includes*/ #include #include #include -#include #include "rttbInvalidParameterException.h" #include "rttbDVHXMLFileWriter.h" #include "rttbDoseStatisticsXMLWriter.h" namespace rttb { namespace io { namespace models { ModelXMLWriter::ModelXMLWriter(const std::string& filename, - boost::shared_ptr model, bool printDVH) : _filename(filename), + rttb::models::BioModel::Pointer model, bool printDVH) : _filename(filename), _model(model), _printDVH(printDVH) { } void ModelXMLWriter::setFilename(FileNameString filename) { _filename = filename; } FileNameString ModelXMLWriter::getFilename() const { return _filename; } - void ModelXMLWriter::setModel(boost::shared_ptr model) + void ModelXMLWriter::setModel(rttb::models::BioModel::Pointer model) { _model = model; } - boost::shared_ptr ModelXMLWriter::getModel() const + rttb::models::BioModel::Pointer ModelXMLWriter::getModel() const { return _model; } void ModelXMLWriter::setPrintDVH(bool printDVH) { _printDVH = printDVH; } bool ModelXMLWriter::getPrintDVH() const { return _printDVH; } void ModelXMLWriter::writeModel() { std::setprecision(2); boost::property_tree::ptree pt; std::string xmlattrNameTag = ".name"; std::string modelTag = "BioModel"; std::string propertyTag = "property"; std::string configTag = "config"; std::string resultsTag = "results"; std::string valueTag = "value"; auto dvh = _model->getDVH(); boost::property_tree::ptree propertynode; boost::property_tree::ptree confignode; confignode.put("BioModelType", _model->getModelType()); confignode.put("StructureID", dvh->getStructureID()); confignode.put("DoseID", dvh->getDoseID()); if (_printDVH) { FileNameString filename = "dvhfor" + _model->getModelType() + ".xml"; DVHType typeDiff = { DVHType::Differential }; io::other::DVHXMLFileWriter dvhWriter(filename, typeDiff); dvhWriter.writeDVH(dvh); confignode.put("DVHReference", filename); } pt.add_child(modelTag + "." + configTag, confignode); propertynode.put("", _model->getValue()); propertynode.put(xmlattrNameTag, valueTag); pt.add_child(modelTag + "." + resultsTag + "." + propertyTag, propertynode); std::map parameterMap = _model->getParameterMap(); for (std::map::const_iterator it = parameterMap.begin(); it != parameterMap.end(); ++it) { double value = it->second; if (value - static_cast(std::round(value)) < errorConstant) { propertynode.put("", static_cast(value)); } else { propertynode.put("", static_cast(value)); } propertynode.put(xmlattrNameTag, it->first); pt.add_child(modelTag + "." + resultsTag + "." + propertyTag, propertynode); } try { boost::property_tree::xml_parser::xml_writer_settings settings = boost::property_tree::xml_writer_make_settings('\t', 1); boost::property_tree::xml_parser::write_xml(_filename, pt, std::locale(), settings); } catch (const boost::property_tree::xml_parser_error& e) { std::cout << e.what(); throw core::InvalidParameterException("Write xml failed: xml_parser_error!"); } } } } } diff --git a/code/io/models/rttbModelXMLWriter.h b/code/io/models/rttbModelXMLWriter.h index 1dc3545..f21417c 100644 --- a/code/io/models/rttbModelXMLWriter.h +++ b/code/io/models/rttbModelXMLWriter.h @@ -1,66 +1,66 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1250 $ (last changed revision) // @date $Date: 2016-02-18 15:25:55 +0100 (Do, 18 Feb 2016) $ (last change date) // @author $Author: zhangl $ (last changed by) */ #ifndef __MODELS_XML_WRITER_H #define __MODELS_XML_WRITER_H #include "rttbBioModel.h" namespace rttb { namespace io { namespace models { /*! @class ModelXMLWriter @brief Writes a model (TCP, NTCP, ...) to an xml file */ class ModelXMLWriter { private: std::string _filename; - boost::shared_ptr _model; + rttb::models::BioModel::Pointer _model; bool _printDVH; public: - ModelXMLWriter(const std::string& filename, boost::shared_ptr model, + ModelXMLWriter(const std::string& filename, rttb::models::BioModel::Pointer model, bool printDVH = true); void setFilename(std::string filename); std::string getFilename() const; - void setModel(boost::shared_ptr model); - boost::shared_ptr getModel() const; + void setModel(rttb::models::BioModel::Pointer model); + rttb::models::BioModel::Pointer getModel() const; void setPrintDVH(bool printDVH); bool getPrintDVH() const; void writeModel(); }; } } } #endif diff --git a/code/io/other/rttbDVHXMLFileReader.cpp b/code/io/other/rttbDVHXMLFileReader.cpp index 5498007..506a671 100644 --- a/code/io/other/rttbDVHXMLFileReader.cpp +++ b/code/io/other/rttbDVHXMLFileReader.cpp @@ -1,154 +1,154 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include #include #include #include #include "rttbDVHXMLFileReader.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace io { namespace other { DVHXMLFileReader::DVHXMLFileReader(FileNameString aFileName) { _fileName = aFileName; _resetFile = true; } DVHXMLFileReader::~DVHXMLFileReader() = default; void DVHXMLFileReader::resetFileName(FileNameString aFileName) { _fileName = aFileName; _resetFile = true; } void DVHXMLFileReader::createDVH() { boost::property_tree::ptree pt; // Load the XML file into the property tree. If reading fails // (cannot open file, parse error), an exception is thrown. try { read_xml(_fileName, pt); } catch (boost::property_tree::xml_parser_error& /*e*/) { throw rttb::core::InvalidParameterException("DVH file name invalid: could not open the xml file!"); } std::string dvhType; std::deque dataDifferential, dataCumulative; DoseTypeGy deltaD = 0; DoseVoxelVolumeType deltaV = 0; IDType strID; IDType doseID; bool normalized; dvhType = pt.get("dvh.type"); deltaD = pt.get("dvh.deltaD"); deltaV = pt.get("dvh.deltaV"); strID = pt.get("dvh.structureID"); doseID = pt.get("dvh.doseID"); boost::optional dvhNormalized = pt.get_optional("dvh.normalized"); if (dvhNormalized) { normalized = dvhNormalized.get(); } else { normalized = false; } if (dvhType != "DIFFERENTIAL" && dvhType != "CUMULATIVE") { throw core::InvalidParameterException("DVH Type invalid! Only: DIFFERENTIAL/CUMULATIVE!"); } BOOST_FOREACH(boost::property_tree::ptree::value_type & v, pt.get_child("dvh.data")) { if (dvhType == "DIFFERENTIAL") { dataDifferential.push_back(boost::lexical_cast(v.second.data()) / (normalized ? deltaV : 1)); } else if (dvhType == "CUMULATIVE") { dataCumulative.push_back(boost::lexical_cast(v.second.data()) / (normalized ? deltaV : 1)); } } unsigned int numberOfBins = static_cast(std::max(dataDifferential.size(), dataCumulative.size())); if (dvhType == "CUMULATIVE") //dataDifferential should be calculated { DoseCalcType differentialDVHi = 0; std::deque::iterator it; for (it = dataCumulative.begin(); it != dataCumulative.end(); ++it) { if (dataDifferential.size() == numberOfBins - 1) { differentialDVHi = *it; } else { differentialDVHi = *it - *(it + 1); } dataDifferential.push_back(differentialDVHi); } } _dvh = boost::make_shared(dataDifferential, deltaD, deltaV, strID, doseID); _resetFile = false; } - DVHXMLFileReader::DVHPointer DVHXMLFileReader::generateDVH() + core::DVH::Pointer DVHXMLFileReader::generateDVH() { if (_resetFile) { this->createDVH(); } return _dvh; } }//end namespace other }//end namespace io }//end namespace rttb diff --git a/code/io/other/rttbDVHXMLFileReader.h b/code/io/other/rttbDVHXMLFileReader.h index f8f5c9d..6a7cf52 100644 --- a/code/io/other/rttbDVHXMLFileReader.h +++ b/code/io/other/rttbDVHXMLFileReader.h @@ -1,69 +1,69 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DVH_XML_FILE_READER_H #define __DVH_XML_FILE_READER_H #include "rttbBaseType.h" #include "rttbDVHGeneratorInterface.h" namespace rttb { namespace io { namespace other { /*! @class DVHXMLFileReader @brief Reads DVH data from xml files. */ class DVHXMLFileReader: public core::DVHGeneratorInterface { private: FileNameString _fileName; bool _resetFile; /*! @brief Create new DVH object using the info from dvh txt file @exception InvalidParameterException Thrown if _fileName invalid */ void createDVH(); public: /*! @brief Constructor. */ DVHXMLFileReader(FileNameString aFileName); ~DVHXMLFileReader(); /*! @brief Change file name. */ void resetFileName(FileNameString aFileName); /*! @brief Generate DVH, createDVH() will be called @return Return new shared pointer of DVH. @exception InvalidParameterException Thrown if _fileName invalid */ - DVHPointer generateDVH() override; + core::DVH::Pointer generateDVH() override; }; } } } #endif diff --git a/code/io/other/rttbDVHXMLFileWriter.cpp b/code/io/other/rttbDVHXMLFileWriter.cpp index 89b7234..1114ec3 100644 --- a/code/io/other/rttbDVHXMLFileWriter.cpp +++ b/code/io/other/rttbDVHXMLFileWriter.cpp @@ -1,146 +1,146 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbDVHXMLFileWriter.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "rttbException.h" #include #include namespace rttb { namespace io { namespace other { DVHXMLFileWriter::DVHXMLFileWriter(FileNameString aFileName, DVHType aDVHType) { this->setFileName(aFileName); this->setDVHType(aDVHType); } void DVHXMLFileWriter::setDVHType(DVHType aDVHType) { _dvhType = aDVHType; } FileNameString DVHXMLFileWriter::getFileName() const { return _fileName; } void DVHXMLFileWriter::setFileName(FileNameString aFileName) { _fileName = aFileName; } DVHType DVHXMLFileWriter::getDVHType() const { return _dvhType; } - void DVHXMLFileWriter::writeDVH(DVHPointer aDvh, bool normalized) + void DVHXMLFileWriter::writeDVH(core::DVH::Pointer aDvh, bool normalized) { if (aDvh == nullptr) { throw core::NullPointerException("aDvh must not be nullptr! "); } using boost::property_tree::ptree; ptree pt; DataDifferentialType data; std::map normalizedData; if (_dvhType.Type == DVHType::Differential) { pt.put("dvh.type", "DIFFERENTIAL"); if (normalized) { normalizedData = aDvh->getNormalizedDVH({ DVHType::Cumulative }); } else { data = aDvh->getDataDifferential(); } } else if (_dvhType.Type == DVHType::Cumulative) { pt.put("dvh.type", "CUMULATIVE"); if (normalized) { normalizedData = aDvh->getNormalizedDVH(); } else { data = aDvh->getDataCumulative(); } } else { throw core::InvalidParameterException("DVH Type not acceptable: Only: DIFFERENTIAL/CUMULATIVE!"); } pt.put("dvh.deltaD", aDvh->getDeltaD()); pt.put("dvh.deltaV", aDvh->getDeltaV()); pt.put("dvh.structureID", aDvh->getStructureID()); pt.put("dvh.doseID", aDvh->getDoseID()); pt.put("dvh.normalized", normalized); if (normalized) { for (auto elem : normalizedData) { boost::property_tree::ptree node; node.put("", elem.second); node.put(".doseGy", elem.first); pt.add_child("dvh.data.volumeInCcm", node); } } else { for (size_t i = 0; i < data.size(); i++) { boost::property_tree::ptree node; node.put("", data[i]); node.put(".dosebin", i); pt.add_child("dvh.data.volume", node); } } try { boost::property_tree::xml_parser::xml_writer_settings settings = boost::property_tree::xml_writer_make_settings ('\t', 1); boost::property_tree::xml_parser::write_xml(_fileName, pt, std::locale(), settings); } catch (boost::property_tree::xml_parser_error& /*e*/) { throw core::InvalidParameterException("Write xml failed: xml_parser_error!"); } } } } } diff --git a/code/io/other/rttbDVHXMLFileWriter.h b/code/io/other/rttbDVHXMLFileWriter.h index 23016c5..ecde0ff 100644 --- a/code/io/other/rttbDVHXMLFileWriter.h +++ b/code/io/other/rttbDVHXMLFileWriter.h @@ -1,75 +1,74 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DVH_XML_FILE_WRITER_H #define __DVH_XML_FILE_WRITER_H #include "rttbDVH.h" #include "../rttbDVHWriterInterface.h" #include "rttbBaseType.h" #include "RTTBOtherIOExports.h" namespace rttb { namespace io { namespace other { /*! @class DVHXMLFileWriter @brief Writes DVHs to xml files. */ class RTTBOtherIO_EXPORT DVHXMLFileWriter : public DVHWriterInterface { public: using DataDifferentialType = core::DVH::DataDifferentialType; - using DVHPointer = core::DVH::DVHPointer; private: FileNameString _fileName; DVHType _dvhType; public: /*! @brief Constructor @param aFileName a xml file name to write @param aDVHType: DIFFERENTIAL or CUMULATIVE. */ DVHXMLFileWriter(FileNameString aFileName, DVHType aDVHType); void setFileName(FileNameString aFileName); FileNameString getFileName() const; void setDVHType(DVHType aDVHType); DVHType getDVHType() const; /*! @brief Write aDvh to xml file with the name: _fileName @exception NullPointerException Thrown if _aDvh is nullptr @exception InvalidParameterException Thrown if _fileName invalid: could not open; or if _dvhType invalid: only DIFFERENTIAL or CUMULATIVE is accepted! @exception Exception thrown if dvh init error */ - void writeDVH(DVHPointer aDvh, bool normalized = false) override; + void writeDVH(core::DVH::Pointer aDvh, bool normalized = false) override; }; } } } #endif diff --git a/code/io/other/rttbDoseStatisticsXMLReader.cpp b/code/io/other/rttbDoseStatisticsXMLReader.cpp index 41c1293..63d35ed 100644 --- a/code/io/other/rttbDoseStatisticsXMLReader.cpp +++ b/code/io/other/rttbDoseStatisticsXMLReader.cpp @@ -1,222 +1,220 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1328 $ (last changed revision) // @date $Date: 2016-04-22 09:50:01 +0200 (Fr, 22 Apr 2016) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include #include #include #include #include #include #include "rttbDoseStatisticsXMLReader.h" #include "rttbInvalidParameterException.h" #include "rttbVolumeToDoseMeasureCollection.h" namespace rttb { namespace io { namespace other { - using DoseStatisticsPtr = boost::shared_ptr; - DoseStatisticsXMLReader::DoseStatisticsXMLReader(const std::string& filename) : _filename(filename), _newFile(true) { } DoseStatisticsXMLReader::~DoseStatisticsXMLReader() = default; void DoseStatisticsXMLReader::setFilename(const std::string& filename) { _filename = filename; _newFile = true; } - DoseStatisticsPtr DoseStatisticsXMLReader::generateDoseStatistic() + algorithms::DoseStatistics::Pointer DoseStatisticsXMLReader::generateDoseStatistic() { if (_newFile) { this->createDoseStatistic(); } return _doseStatistic; } void DoseStatisticsXMLReader::createDoseStatistic() { boost::property_tree::ptree pt; // Load the XML file into the property tree. If reading fails // (cannot open file, parse error), an exception is thrown. try { read_xml(_filename, pt); } catch (boost::property_tree::xml_parser_error& /*e*/) { throw rttb::core::InvalidParameterException("DoseStatistics file name invalid: could not open the xml file!"); } // data to fill the parameter for the DoseStatistics std::string name; std::string datum; unsigned int x; std::pair voxelid; std::vector < std::pair> vec; //initialize all parameters for the DoseStatistics double minimum=-1; double maximum=-1; double numVoxels=-1; double volume=-1; double referenceDose = -1; double mean=-1; double stdDeviation=-1; boost::shared_ptr > > minimumVoxelPositions = nullptr; boost::shared_ptr > > maximumVoxelPositions = nullptr; rttb::algorithms::VolumeToDoseMeasureCollection Dx(rttb::algorithms::VolumeToDoseMeasureCollection::Dx); rttb::algorithms::DoseToVolumeMeasureCollection Vx(rttb::algorithms::DoseToVolumeMeasureCollection::Vx); rttb::algorithms::VolumeToDoseMeasureCollection MOHx(rttb::algorithms::VolumeToDoseMeasureCollection::MOHx); rttb::algorithms::VolumeToDoseMeasureCollection MOCx(rttb::algorithms::VolumeToDoseMeasureCollection::MOCx); rttb::algorithms::VolumeToDoseMeasureCollection MaxOHx(rttb::algorithms::VolumeToDoseMeasureCollection::MaxOHx); rttb::algorithms::VolumeToDoseMeasureCollection MinOCx(rttb::algorithms::VolumeToDoseMeasureCollection::MinOCx); BOOST_FOREACH(boost::property_tree::ptree::value_type & data, pt.get_child("statistics.results")) { datum = data.second.data(); BOOST_FOREACH(boost::property_tree::ptree::value_type & middle, data.second) { BOOST_FOREACH(boost::property_tree::ptree::value_type & innernode, middle.second) { std::string mia = innernode.first; if (innernode.first == "name") { name = innernode.second.data(); } else if (innernode.first == "voxelGridID") { boost::replace_all(datum, "\r\n", ""); boost::replace_all(datum, "\n", ""); boost::trim(datum); voxelid.first = boost::lexical_cast(datum); voxelid.second = boost::lexical_cast(innernode.second.data()); vec.push_back(voxelid); } else if (innernode.first == "x") { x = boost::lexical_cast(innernode.second.data()); } } } // fill with the extracted data if (name == "numberOfVoxels") { numVoxels = boost::lexical_cast(datum); } else if (name == "volume") { volume = boost::lexical_cast(datum); Dx.setVolume(volume); MOHx.setVolume(volume); MOCx.setVolume(volume); MaxOHx.setVolume(volume); } else if (name == "referenceDose") { referenceDose = boost::lexical_cast(datum); Vx.setReferenceDose(referenceDose); } else if (name == "mean") { mean = boost::lexical_cast(datum); } else if (name == "standardDeviation") { stdDeviation = boost::lexical_cast(datum); } else if (name == "minimum") { minimum = boost::lexical_cast(datum); if (!vec.empty()) { minimumVoxelPositions = boost::make_shared>>(vec); vec.clear(); } } else if (name == "maximum") { maximum = boost::lexical_cast(datum); if (!vec.empty()) { maximumVoxelPositions = boost::make_shared>>(vec); vec.clear(); } } else if (name == "Dx") { Dx.insertValue(static_cast(x)*volume / 100, boost::lexical_cast(datum)); } else if (name == "Vx") { Vx.insertValue(static_cast(x)*referenceDose / 100, boost::lexical_cast(datum)); } else if (name == "MOHx") { MOHx.insertValue(static_cast(x)*volume / 100, boost::lexical_cast(datum)); } else if (name == "MOCx") { MOCx.insertValue(static_cast(x)*volume / 100, boost::lexical_cast(datum)); } else if (name == "MaxOHx") { MaxOHx.insertValue(static_cast(x)*volume / 100, boost::lexical_cast(datum)); } else if (name == "MinOCx") { MinOCx.insertValue(static_cast(x)*volume / 100, boost::lexical_cast(datum)); } } // make DoseStatistcs _doseStatistic = boost::make_shared( minimum, maximum, mean, stdDeviation, numVoxels, volume, minimumVoxelPositions, maximumVoxelPositions , Dx, Vx, MOHx, MOCx, MaxOHx, MinOCx, referenceDose); } }//end namespace other }//end namespace io }//end namespace rttb diff --git a/code/io/other/rttbDoseStatisticsXMLReader.h b/code/io/other/rttbDoseStatisticsXMLReader.h index fe78681..d214111 100644 --- a/code/io/other/rttbDoseStatisticsXMLReader.h +++ b/code/io/other/rttbDoseStatisticsXMLReader.h @@ -1,69 +1,63 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1250 $ (last changed revision) // @date $Date: 2016-02-18 15:25:55 +0100 (Do, 18 Feb 2016) $ (last change date) // @author $Author: zhangl $ (last changed by) */ #ifndef __DOSE_STATISTICS_XML_READER_H #define __DOSE_STATISTICS_XML_READER_H #include "rttbDoseStatistics.h" -/*boost includes*/ - -#include - namespace rttb { namespace io { namespace other { /*! @class DoseStatisticsXMLReader @brief Reads a dose statistics XML into a DoseStatistics object */ class DoseStatisticsXMLReader{ public: - using DoseStatisticsPtr = boost::shared_ptr; - DoseStatisticsXMLReader(const std::string& filename); ~DoseStatisticsXMLReader(); void setFilename(const std::string& filename); /*! @brief Generate a Model, createModel() will be called @return Return new shared pointer of a Model. @exception InvalidParameterException Thrown if _filename invalid */ - DoseStatisticsPtr generateDoseStatistic(); + algorithms::DoseStatistics::Pointer generateDoseStatistic(); private: std::string _filename; bool _newFile; - DoseStatisticsPtr _doseStatistic; + algorithms::DoseStatistics::Pointer _doseStatistic; /*! @brief Create new Model object using the info from model xml file @exception InvalidParameterException Thrown if _filename invalid */ void createDoseStatistic(); }; } } } #endif diff --git a/code/io/other/rttbDoseStatisticsXMLWriter.h b/code/io/other/rttbDoseStatisticsXMLWriter.h index bd9d195..f4a9dde 100644 --- a/code/io/other/rttbDoseStatisticsXMLWriter.h +++ b/code/io/other/rttbDoseStatisticsXMLWriter.h @@ -1,95 +1,94 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ #ifndef __DOSE_STATISTICS_XML_WRITER_H #define __DOSE_STATISTICS_XML_WRITER_H #include "rttbDoseStatistics.h" #include -#include #include "RTTBOtherIOExports.h" namespace rttb { namespace io { namespace other { class RTTBOtherIO_EXPORT DoseStatisticsXMLWriter { public: using DoseStatisticsPtr = boost::shared_ptr; /*! @brief Write statistics to boost::property_tree::ptree. @param aDoseStatistics DoseStatistics to write @pre aReferenceDose must >0 @exception rttb::core::InvalidParameterException Thrown if aReferenceDose<=0 or xml_parse_error @note The precision is float */ boost::property_tree::ptree writeDoseStatistics(DoseStatisticsPtr aDoseStatistics); /*! @brief Write statistics to String. @param aDoseStatistics DoseStatistics to write @pre aReferenceDose must >0 @exception rttb::core::InvalidParameterException Thrown if aReferenceDose<=0 or xml_parse_error @note The precision is float */ XMLString writerDoseStatisticsToString(DoseStatisticsPtr aDoseStatistics); /*! @brief Write statistics to xml file. @details includes the following statistics: - numberOfVoxels, - volume, - minimum, - maximum, - mean, - standard deviation, - variance, - D2,D5,D10,D90,D95,D98, - V2,V5,V10,V90,V95,V98, - MOH2,MOH5,MOH10, - MOC2,MOC5,MOC10, - MaxOH2,MaxOH5,MaxOH10, - MinOC2,MinOC5,MinOC10. @param aDoseStatistics DoseStatistics to write @param aFileName To write dose statistics @pre aReferenceDose must >0 @exception rttb::core::InvalidParameterException Thrown if aReferenceDose<=0 or xml_parse_error @note The precision is float */ void writeDoseStatistics(DoseStatisticsPtr aDoseStatistics, FileNameString aFileName); boost::property_tree::ptree createNodeWithNameAttribute(DoseTypeGy doseValue, const std::string& attributeName); boost::property_tree::ptree createNodeWithNameAndXAttribute(DoseTypeGy doseValue, const std::string& attributeName, int xValue); /*! @brief Write statistics to String to generate a table @details The table is: "Volume mm3@Max@Min@Mean@Std.Dev.@Variance@D2@D5@D10@D90@D95@D98@V2@V5@V10@V90@V95@V98@MOH2@MOH5@MOH10@MOC2@MOC5@MOC10@MaxOH2@MaxOH5@MaxOH10@MinOC2@MinOC5@MinOC10" @param aDoseStatistics DoseStatistics to write @pre aReferenceDose must >0 @exception rttb::core::InvalidParameterException Thrown if aReferenceDose<=0 or xml_parse_error @note is used for the Mevislab-Linking of RTTB @note The precision is float */ StatisticsString writerDoseStatisticsToTableString(DoseStatisticsPtr aDoseStatistics); double convertToPercent(double value, double maximum); }; } } } #endif diff --git a/code/io/rttbDVHWriterInterface.h b/code/io/rttbDVHWriterInterface.h index 1880b54..86b06a0 100644 --- a/code/io/rttbDVHWriterInterface.h +++ b/code/io/rttbDVHWriterInterface.h @@ -1,48 +1,47 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DVH_WRITER_INTERFACE_H #define __DVH_WRITER_INTERFACE_H #include "rttbDVH.h" #include "RTTBOtherIOExports.h" namespace rttb { namespace io { /*! @class DVHWriterInterface @brief Interface for classes that write DVH data to files. */ class RTTBOtherIO_EXPORT DVHWriterInterface { - using DVHPointer = core::DVH::DVHPointer; /*! @brief Write aDvh */ public: - virtual void writeDVH(DVHPointer aDvh, bool normalized = false) = 0; + virtual void writeDVH(core::DVH::Pointer aDvh, bool normalized = false) = 0; }; } } #endif diff --git a/code/io/utils/rttbDoseLoader.cpp b/code/io/utils/rttbDoseLoader.cpp index 6c03757..dfd892e 100644 --- a/code/io/utils/rttbDoseLoader.cpp +++ b/code/io/utils/rttbDoseLoader.cpp @@ -1,87 +1,87 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ #include "rttbDoseLoader.h" #include "rttbExceptionMacros.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomHelaxFileDoseAccessorGenerator.h" #include "rttbITKImageFileAccessorGenerator.h" namespace rttb { namespace io { namespace utils { - rttb::core::DoseAccessorInterface::DoseAccessorPointer + rttb::core::DoseAccessorInterface::Pointer loadDicomDose(const std::string& fileName) { rttb::io::dicom::DicomFileDoseAccessorGenerator generator(fileName); return generator.generateDoseAccessor(); } - rttb::core::DoseAccessorInterface::DoseAccessorPointer + rttb::core::DoseAccessorInterface::Pointer loadHelaxDose(const std::string& path) { rttb::io::helax::DicomHelaxFileDoseAccessorGenerator generator(path); return generator.generateDoseAccessor(); } - rttb::core::DoseAccessorInterface::DoseAccessorPointer + rttb::core::DoseAccessorInterface::Pointer loadITKDose(const std::string& fileName) { rttb::io::itk::ITKImageFileAccessorGenerator generator(fileName); return generator.generateDoseAccessor(); } - rttb::core::DoseAccessorInterface::DoseAccessorPointer loadITKDicomDose(const std::string& fileName) { + rttb::core::DoseAccessorInterface::Pointer loadITKDicomDose(const std::string& fileName) { rttb::io::itk::ITKImageFileAccessorGenerator generator(fileName, true); return generator.generateDoseAccessor(); } - rttb::core::DoseAccessorInterface::DoseAccessorPointer + rttb::core::DoseAccessorInterface::Pointer loadDose(const std::string& fileName, const std::string& loadStyle) { - rttb::core::DoseAccessorInterface::DoseAccessorPointer result; + rttb::core::DoseAccessorInterface::Pointer result; if (loadStyle == "" || loadStyle == "dicom") { result = loadDicomDose(fileName); } else if (loadStyle == "helax") { result = loadHelaxDose(fileName); } else if (loadStyle == "itk") { result = loadITKDose(fileName); } else if (loadStyle == "itkDicom") { result = loadITKDicomDose(fileName); } else { rttbDefaultExceptionStaticMacro(<< "Unknown io style selected. Cannot load data. Selected style: " << loadStyle); } return result; } } } } diff --git a/code/io/utils/rttbDoseLoader.h b/code/io/utils/rttbDoseLoader.h index 57ce35c..ac08b24 100644 --- a/code/io/utils/rttbDoseLoader.h +++ b/code/io/utils/rttbDoseLoader.h @@ -1,56 +1,56 @@ // ----------------------------------------------------------------------- // 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 __RTTB_DOSE_LOADER_H #define __RTTB_DOSE_LOADER_H #include "rttbDoseIteratorInterface.h" namespace rttb { namespace io { namespace utils { /*! @brief loads a dicom dose from a file. @exception Throws an rttb::Exception if loading fails @sa DicomFileDoseAccessorGenerator */ - rttb::core::DoseAccessorInterface::DoseAccessorPointer loadDicomDose(const std::string& fileName); + rttb::core::DoseAccessorInterface::Pointer loadDicomDose(const std::string& fileName); /*! @brief loads a helax dose from a file. @exception Throws an rttb::Exception if loading fails @sa DicomHelaxFileDoseAccessorGenerator */ - rttb::core::DoseAccessorInterface::DoseAccessorPointer loadHelaxDose(const std::string& path); + rttb::core::DoseAccessorInterface::Pointer loadHelaxDose(const std::string& path); /*! @brief loads an itk dose from a file. @exception Throws an rttb::Exception if loading fails. @details Might be of all formats that ITK know (*.mhd, *.nrrd, ...). The absolute image values are taken as dose. @sa ITKImageFileAccessorGenerator */ - rttb::core::DoseAccessorInterface::DoseAccessorPointer loadITKDose(const std::string& fileName); + rttb::core::DoseAccessorInterface::Pointer loadITKDose(const std::string& fileName); - rttb::core::DoseAccessorInterface::DoseAccessorPointer loadITKDicomDose(const std::string& fileName); + rttb::core::DoseAccessorInterface::Pointer loadITKDicomDose(const std::string& fileName); /*! @brief loads a dose from a file based on the loadingStyle. @params args[0]: determines the loadingStyle @exception Throws an rttb::Exception if loading fails */ - rttb::core::DoseAccessorInterface::DoseAccessorPointer loadDose(const std::string& fileName, const std::string& loadStyle = "dicom"); + rttb::core::DoseAccessorInterface::Pointer loadDose(const std::string& fileName, const std::string& loadStyle = "dicom"); } } } #endif diff --git a/code/io/utils/rttbStructLoader.cpp b/code/io/utils/rttbStructLoader.cpp index b7f71dd..d5e0165 100644 --- a/code/io/utils/rttbStructLoader.cpp +++ b/code/io/utils/rttbStructLoader.cpp @@ -1,59 +1,59 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ #include "rttbStructLoader.h" #include "rttbExceptionMacros.h" namespace rttb { namespace io { namespace utils { - rttb::core::StructureSetGeneratorInterface::StructureSetPointer + rttb::core::StructureSet::Pointer loadDicomStruct( const std::string& fileName, const std::string& structNameRegex) { rttb::io::dicom::DicomFileStructureSetGenerator generator(fileName); if (!structNameRegex.empty()) { generator.setStructureLabelFilterActive(true); generator.setFilterRegEx(structNameRegex); } return generator.generateStructureSet(); } - rttb::core::StructureSetGeneratorInterface::StructureSetPointer loadStruct( + rttb::core::StructureSet::Pointer loadStruct( const std::string& fileName, const std::string& loadStyle, const std::string& structNameRegex) { - rttb::core::StructureSetGeneratorInterface::StructureSetPointer result; + rttb::core::StructureSet::Pointer result; if (loadStyle == "" || loadStyle == "dicom") { result = rttb::io::utils::loadDicomStruct(fileName, structNameRegex); } else { rttbDefaultExceptionStaticMacro(<< "Unknown io style selected. Cannot load data. Selected style: " << loadStyle); } return result; } } } } diff --git a/code/io/utils/rttbStructLoader.h b/code/io/utils/rttbStructLoader.h index f9da50e..507bf8a 100644 --- a/code/io/utils/rttbStructLoader.h +++ b/code/io/utils/rttbStructLoader.h @@ -1,52 +1,52 @@ // ----------------------------------------------------------------------- // 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 __RTTB_STRUCT_LOADER_H #define __RTTB_STRUCT_LOADER_H #include "rttbDicomFileStructureSetGenerator.h" namespace rttb { namespace io { namespace utils { /*! @brief loads a dicom struct from a file. You may pass a structure name regex. If is not empty, it will be used to filter structure in the loading process. Only structures with a name matching the reg ex will be loaded. This speeds up the loading process significantly if you need only one structure out of a structure set. @exception Throws an rttb::Exception if loading fails @sa DicomFileStructureSetGenerator */ - rttb::core::StructureSetGeneratorInterface::StructureSetPointer loadDicomStruct(const std::string& fileName, const std::string& structNameRegex = ""); + rttb::core::StructureSet::Pointer loadDicomStruct(const std::string& fileName, const std::string& structNameRegex = ""); /*! @brief loads a struct from a file based on the loadingStyle. You may pass a structure name regex. If is not empty, it will be used to filter structure in the loading process. Only structures with a name matching the reg ex will be loaded. This speeds up the loading process significantly if you need only one structure out of a structure set. @exception Throws an rttb::Exception if loading fails @details voxelized itk images are read in generateMask() directly */ - rttb::core::StructureSetGeneratorInterface::StructureSetPointer loadStruct( + rttb::core::StructureSet::Pointer loadStruct( const std::string& fileName, const std::string& loadStyle = "dicom", const std::string& structNameRegex = "" ); } } } #endif diff --git a/code/masks/boost/rttbBoostMask.cpp b/code/masks/boost/rttbBoostMask.cpp index 1393521..bc8cf17 100644 --- a/code/masks/boost/rttbBoostMask.cpp +++ b/code/masks/boost/rttbBoostMask.cpp @@ -1,565 +1,565 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include #include #include #include "rttbBoostMask.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "rttbBoostMaskGenerateMaskVoxelListThread.h" #include "rttbBoostMaskVoxelizationThread.h" namespace rttb { namespace masks { namespace boost { - BoostMask::BoostMask(BoostMask::GeometricInfoPointer aDoseGeoInfo, - BoostMask::StructPointer aStructure, bool strict, unsigned int numberOfThreads) + BoostMask::BoostMask(core::GeometricInfo::Pointer aDoseGeoInfo, + core::Structure::Pointer aStructure, bool strict, unsigned int numberOfThreads) : _geometricInfo(aDoseGeoInfo), _structure(aStructure), _strict(strict), _numberOfThreads(numberOfThreads), _voxelizationThickness(0.0), _voxelInStructure(::boost::make_shared()) { _isUpToDate = false; if (_geometricInfo == nullptr) { throw rttb::core::NullPointerException("Error: Geometric info is nullptr!"); } else if (_structure == nullptr) { throw rttb::core::NullPointerException("Error: Structure is nullptr!"); } if (_numberOfThreads == 0) { _numberOfThreads = ::boost::thread::hardware_concurrency(); if (_numberOfThreads == 0) { throw rttb::core::InvalidParameterException("Error: detection of the number of hardware threads is not possible. Please specify number of threads for voxelization explicitly as parameter in BoostMask."); } } } BoostMask::MaskVoxelListPointer BoostMask::getRelevantVoxelVector() { if (!_isUpToDate) { calcMask(); } return _voxelInStructure; } void BoostMask::calcMask() { preprocessing(); voxelization(); generateMaskVoxelList(); _isUpToDate = true; } void BoostMask::preprocessing() { rttb::PolygonSequenceType polygonSequence = _structure->getStructureVector(); //Convert world coordinate polygons to the polygons with geometry coordinate rttb::PolygonSequenceType geometryCoordinatePolygonVector; rttb::PolygonSequenceType::iterator it; rttb::DoubleVoxelGridIndex3D globalMaxGridIndex(std::numeric_limits::min(), std::numeric_limits::min(), std::numeric_limits::min()); rttb::DoubleVoxelGridIndex3D globalMinGridIndex(_geometricInfo->getNumColumns(), _geometricInfo->getNumRows(), 0); for (it = polygonSequence.begin(); it != polygonSequence.end(); ++it) { PolygonType rttbPolygon = *it; PolygonType geometryCoordinatePolygon; //1. convert polygon to geometry coordinate polygons //2. calculate global min/max //3. check if polygon is planar if (!preprocessingPolygon(rttbPolygon, geometryCoordinatePolygon, globalMinGridIndex, globalMaxGridIndex, errorConstant)) { throw rttb::core::Exception("TiltedMaskPlaneException"); } geometryCoordinatePolygonVector.push_back(geometryCoordinatePolygon); } rttb::VoxelGridIndex3D minIndex = VoxelGridIndex3D(GridIndexType(globalMinGridIndex(0) ), GridIndexType(globalMinGridIndex(1) ), GridIndexType(globalMinGridIndex(2) )); rttb::VoxelGridIndex3D maxIndex = VoxelGridIndex3D(GridIndexType(globalMaxGridIndex(0) ), GridIndexType(globalMaxGridIndex(1) ), GridIndexType(globalMaxGridIndex(2) )); _globalBoundingBox.push_back(minIndex); _globalBoundingBox.push_back(maxIndex); //convert rttb polygon sequence to a map of z index and a vector of boost ring 2d (without holes) _ringMap = convertRTTBPolygonSequenceToBoostRingMap(geometryCoordinatePolygonVector); } void BoostMask::voxelization() { if (_globalBoundingBox.size() < 2) { throw rttb::core::InvalidParameterException("Bounding box calculation failed! "); } BoostRingMap::iterator itMap; size_t mapSizeInAThread = _ringMap.size() / _numberOfThreads; unsigned int count = 0; unsigned int countThread = 0; BoostPolygonMap polygonMap; std::vector polygonMapVector; //check donut and convert to a map of z index and a vector of boost polygon 2d (with or without holes) for (itMap = _ringMap.begin(); itMap != _ringMap.end(); ++itMap) { //the vector of all boost 2d polygons with the same z grid index(donut polygon is accepted). BoostPolygonVector polygonVector = checkDonutAndConvert((*itMap).second); if (count == mapSizeInAThread && countThread < (_numberOfThreads - 1)) { polygonMapVector.push_back(polygonMap); polygonMap.clear(); count = 0; countThread++; } polygonMap.insert(std::pair((*itMap).first, polygonVector)); count++; } _voxelizationMap = ::boost::make_shared >(); polygonMapVector.push_back(polygonMap); //insert the last one //generate voxelization map, multi-threading ::boost::thread_group threads; auto aMutex = ::boost::make_shared<::boost::shared_mutex>(); for (const auto & i : polygonMapVector) { BoostMaskVoxelizationThread t(i, _globalBoundingBox, _voxelizationMap, aMutex, _strict); threads.create_thread(t); } threads.join_all(); } void BoostMask::generateMaskVoxelList() { if (_globalBoundingBox.size() < 2) { throw rttb::core::InvalidParameterException("Bounding box calculation failed! "); } //check homogeneous of the voxelization plane (the contours plane) if (!calcVoxelizationThickness(_voxelizationThickness)) { throw rttb::core::InvalidParameterException("Error: The contour plane should be homogeneous!"); } ::boost::thread_group threads; auto aMutex = ::boost::make_shared<::boost::shared_mutex>(); unsigned int sliceNumberInAThread = _geometricInfo->getNumSlices() / _numberOfThreads; //generate mask voxel list, multi-threading for (unsigned int i = 0; i < _numberOfThreads; ++i) { unsigned int beginSlice = i * sliceNumberInAThread; unsigned int endSlice; if (i < _numberOfThreads - 1) { endSlice = (i + 1) * sliceNumberInAThread; } else { endSlice = _geometricInfo->getNumSlices(); } BoostMaskGenerateMaskVoxelListThread t(_globalBoundingBox, _geometricInfo, _voxelizationMap, _voxelizationThickness, beginSlice, endSlice, _voxelInStructure, aMutex); threads.create_thread(t); } threads.join_all(); } bool BoostMask::preprocessingPolygon(const rttb::PolygonType& aRTTBPolygon, rttb::PolygonType& geometryCoordinatePolygon, rttb::DoubleVoxelGridIndex3D& minimum, rttb::DoubleVoxelGridIndex3D& maximum, double aErrorConstant) const { double minZ = _geometricInfo->getNumSlices(); double maxZ = 0.0; for (auto worldCoordinatePoint : aRTTBPolygon) { //convert to geometry coordinate polygon rttb::DoubleVoxelGridIndex3D geometryCoordinatePoint; _geometricInfo->worldCoordinateToGeometryCoordinate(worldCoordinatePoint, geometryCoordinatePoint); geometryCoordinatePolygon.push_back(geometryCoordinatePoint); //calculate the current global min/max //min and max for x if (geometryCoordinatePoint(0) < minimum(0)) { minimum(0) = geometryCoordinatePoint(0); } if (geometryCoordinatePoint(0) > maximum(0)) { maximum(0) = geometryCoordinatePoint(0); } //min and max for y if (geometryCoordinatePoint(1) < minimum(1)) { minimum(1) = geometryCoordinatePoint(1); } if (geometryCoordinatePoint(1) > maximum(1)) { maximum(1) = geometryCoordinatePoint(1); } //min and max for z if (geometryCoordinatePoint(2) < minimum(2)) { minimum(2) = geometryCoordinatePoint(2); } if (geometryCoordinatePoint(2) > maximum(2)) { maximum(2) = geometryCoordinatePoint(2); } //check planar if (geometryCoordinatePoint(2) < minZ) { minZ = geometryCoordinatePoint(2); } if (geometryCoordinatePoint(2) > maxZ) { maxZ = geometryCoordinatePoint(2); } } return (std::abs(maxZ - minZ) <= aErrorConstant); } BoostMask::BoostRing2D BoostMask::convertRTTBPolygonToBoostRing(const rttb::PolygonType& aRTTBPolygon) const { BoostMask::BoostRing2D polygon2D; BoostPoint2D firstPoint; for (unsigned int i = 0; i < aRTTBPolygon.size(); i++) { rttb::WorldCoordinate3D rttbPoint = aRTTBPolygon.at(i); BoostPoint2D boostPoint(rttbPoint[0], rttbPoint[1]); if (i == 0) { firstPoint = boostPoint; } ::boost::geometry::append(polygon2D, boostPoint); } ::boost::geometry::append(polygon2D, firstPoint); return polygon2D; } BoostMask::BoostRingMap BoostMask::convertRTTBPolygonSequenceToBoostRingMap( const rttb::PolygonSequenceType& aRTTBPolygonVector) const { rttb::PolygonSequenceType::const_iterator it; BoostMask::BoostRingMap aRingMap; for (it = aRTTBPolygonVector.begin(); it != aRTTBPolygonVector.end(); ++it) { rttb::PolygonType rttbPolygon = *it; double zIndex = rttbPolygon.at(0)[2];//get the first z index of the polygon bool isFirstZ = true; if (!aRingMap.empty()) { auto findIt = findNearestKey(aRingMap, zIndex, errorConstant); //if the z index is found (same slice), add the polygon to vector if (findIt != aRingMap.end()) { //BoostRingVector ringVector = ; (*findIt).second.push_back(convertRTTBPolygonToBoostRing(rttbPolygon)); isFirstZ = false; } } //if it is the first z index in the map, insert vector with the polygon if (isFirstZ) { BoostRingVector ringVector; ringVector.push_back(convertRTTBPolygonToBoostRing(rttbPolygon)); aRingMap.insert(std::pair(zIndex, ringVector)); } } return aRingMap; } BoostMask::BoostRingMap::iterator BoostMask::findNearestKey(BoostMask::BoostRingMap& aBoostRingMap, double aIndex, double aErrorConstant) const { auto find = aBoostRingMap.find(aIndex); //if find a key equivalent to aIndex, found if (find != aBoostRingMap.end()) { return find; } else { auto lowerBound = aBoostRingMap.lower_bound(aIndex); //if all keys go before aIndex, check the last key if (lowerBound == aBoostRingMap.end()) { lowerBound = --aBoostRingMap.end(); } //if the lower bound very close to aIndex, found if (std::abs((*lowerBound).first - aIndex) <= aErrorConstant) { return lowerBound; } else { //if the lower bound is the beginning, not found if (lowerBound == aBoostRingMap.begin()) { return aBoostRingMap.end(); } else { auto lowerBound1 = --lowerBound;//the key before the lower bound //if the key before the lower bound very close to a Index, found if (std::abs((*lowerBound1).first - aIndex) <= aErrorConstant) { return lowerBound1; } //else, not found else { return aBoostRingMap.end(); } } } } } BoostMask::BoostPolygonVector BoostMask::checkDonutAndConvert(const BoostMask::BoostRingVector& aRingVector) const { //check donut BoostMask::BoostRingVector::const_iterator it1; BoostMask::BoostRingVector::const_iterator it2; BoostMask::BoostPolygonVector boostPolygonVector; std::vector donutIndexVector;//store the outer and inner ring index BoostMask::BoostPolygonVector donutVector;//store new generated donut polygon //Get donut index and donut polygon unsigned int index1 = 0; for (it1 = aRingVector.begin(); it1 != aRingVector.end(); ++it1, index1++) { bool it1IsDonut = false; //check if the ring is already determined as a donut for (unsigned int i : donutIndexVector) { if (i == index1) { it1IsDonut = true; break; } } //if not jet, check now if (!it1IsDonut) { bool it2IsDonut = false; unsigned int index2 = 0; for (it2 = aRingVector.begin(); it2 != aRingVector.end(); ++it2, index2++) { if (it2 != it1) { BoostMask::BoostPolygon2D polygon2D; if (::boost::geometry::within(*it1, *it2)) { ::boost::geometry::append(polygon2D, *it2);//append an outer ring to the polygon ::boost::geometry::interior_rings(polygon2D).resize(1);//create an interior ring ::boost::geometry::append(polygon2D, *it1, 0);//append a ring to the interior ring it2IsDonut = true; } //if donut else if (::boost::geometry::within(*it2, *it1)) { ::boost::geometry::append(polygon2D, *it1);//append an outer ring to the polygon ::boost::geometry::interior_rings(polygon2D).resize(1);//create an interior ring ::boost::geometry::append(polygon2D, *it2, 0);//append a ring to the interior ring it2IsDonut = true; } if (it2IsDonut) { donutIndexVector.push_back(index1); donutIndexVector.push_back(index2); donutVector.push_back(polygon2D);//store donut polygon break;//Only store the first donut! } } } } } //Store no donut polygon to boostPolygonVector index1 = 0; for (it1 = aRingVector.begin(); it1 != aRingVector.end(); ++it1, index1++) { bool it1IsDonut = false; //check if the ring is the outer or inner of a donut for (unsigned int i : donutIndexVector) { if (i == index1) { it1IsDonut = true; break; } } if (!it1IsDonut) { BoostMask::BoostPolygon2D polygon2D; ::boost::geometry::append(polygon2D, *it1); boostPolygonVector.push_back(polygon2D);//insert the ring, which is not a part of donut } } //Append donut polygon to boostPolygonVector BoostMask::BoostPolygonVector::iterator itDonut; for (itDonut = donutVector.begin(); itDonut != donutVector.end(); ++itDonut) { boostPolygonVector.push_back(*itDonut);//append donuts } return boostPolygonVector; } bool BoostMask::calcVoxelizationThickness(double& aThickness) const { if (_voxelizationMap->size() <= 1) { aThickness = 1; return true; } double thickness = 0; auto it = _voxelizationMap->cbegin(); auto it2 = ++_voxelizationMap->cbegin(); for (; it != _voxelizationMap->cend() && it2 != _voxelizationMap->cend(); ++it, ++it2) { if (thickness == 0) { thickness = it2->first - it->first; } else { double curThickness = it2->first - it->first; //if not homogeneous (leave out double imprecisions), return false if (std::abs(thickness-curThickness)>errorConstant) { //return false; std::cout << "Two polygons are far from each other?" << std::endl; } } } if (thickness != 0) { aThickness = thickness; } else { aThickness = 1; } return true; } } } } diff --git a/code/masks/boost/rttbBoostMask.h b/code/masks/boost/rttbBoostMask.h index 00c85a6..9481c17 100644 --- a/code/masks/boost/rttbBoostMask.h +++ b/code/masks/boost/rttbBoostMask.h @@ -1,204 +1,202 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __BOOST_MASK_R_H #define __BOOST_MASK_R_H #include "rttbBaseType.h" #include "rttbStructure.h" #include "rttbGeometricInfo.h" #include "rttbMaskAccessorInterface.h" #include #include #include #include namespace rttb { namespace masks { namespace boost { /*! @class BoostMask * @brief Implementation of voxelization using boost::geometry. * @attention If "strict" is set to true, an exception will be thrown when the given structure has self intersection. * (A structure without self intersection means all contours of the structure have no self intersection, and * the polygons on the same slice have no intersection between each other, unless the case of a donut. A donut is accepted.) * If "strict" is set to false, debug information will be displayed when the given structure has self intersection. Self intersections will be ignored * and the mask will be calculated, however, it may cause errors in the mask results. */ class BoostMask { public: - using GeometricInfoPointer = ::boost::shared_ptr; - using StructPointer = core::Structure::StructTypePointer; using MaskVoxelList = core::MaskAccessorInterface::MaskVoxelList; using MaskVoxelListPointer = core::MaskAccessorInterface::MaskVoxelListPointer; /*! @brief Constructor * @exception rttb::core::NullPointerException thrown if aDoseGeoInfo or aStructure is nullptr * @param aDoseGeoInfo the GeometricInfo * @param aStructure the structure set * @param strict indicates whether to allow self intersection in the structure. If it is set to true, an exception will be thrown when the given structure has self intersection. * @param numberOfThreads number of threads used for voxelization. default value 0 means automatic detection, using the number of Hardware thread/cores * @exception InvalidParameterException thrown if strict is true and the structure has self intersections */ - BoostMask(GeometricInfoPointer aDoseGeoInfo, StructPointer aStructure, + BoostMask(core::GeometricInfo::Pointer aDoseGeoInfo, core::Structure::Pointer aStructure, bool strict = true, unsigned int numberOfThreads = 0); /*! @brief Generate mask and return the voxels in the mask * @exception rttb::core::InvalidParameterException thrown if the structure has self intersections */ MaskVoxelListPointer getRelevantVoxelVector(); private: using BoostPoint2D = ::boost::geometry::model::d2::point_xy; using BoostPolygon2D = ::boost::geometry::model::polygon< ::boost::geometry::model::d2::point_xy >; using BoostRing2D = ::boost::geometry::model::ring< ::boost::geometry::model::d2::point_xy >; using BoostRingVector = std::vector;//polygon without holes using BoostPolygonVector = std::vector;//polygon with or without holes using VoxelIndexVector = std::vector; typedef std::map BoostPolygonMap;//map of the z index with the vector of boost 2d polygon typedef std::map BoostRingMap;//map of the z index with the vector of boost 2d ring typedef ::boost::multi_array BoostArray2D; using BoostArray2DPointer = ::boost::shared_ptr; typedef ::boost::shared_ptr > BoostArrayMapPointer; - GeometricInfoPointer _geometricInfo; + core::GeometricInfo::Pointer _geometricInfo; - StructPointer _structure; + core::Structure::Pointer _structure; bool _strict; /*! @brief The number of threads */ unsigned int _numberOfThreads; //@brief The thickness of the voxelization plane (the contour plane), in double dose grid index //@details for example, the first contour has the double grid index 0.1, the second 0.3, the third 0.5, then the thickness is 0.2 double _voxelizationThickness; //@brief vector of the MaskVoxel inside the structure MaskVoxelListPointer _voxelInStructure; /*! @brief The map of z index and a vector of boost ring 2d (without holes) * @details Key: the double z grid index * Value: the vector of boost ring 2d (without holes) */ BoostRingMap _ringMap; /*! @brief The min and max index of the global bounding box. * @details The first index has the minimum for x/y/z of the global bounding box. * The second index has the maximum for x/y/z of the global bounding index. */ VoxelIndexVector _globalBoundingBox; /*! @brief The voxelization map * @details key: the converted double z grid index of a contour plane * value: the 2d mask, array[i][j] = the mask value of the position (i,j) in the global bounding box, * i: 0 - (_globalBoundingBoxSize0-1), j: 0 - (_globalBoundingBoxSize1-1) */ BoostArrayMapPointer _voxelizationMap; /*! @brief If the mask is up to date */ bool _isUpToDate; /*! @brief Voxelization and generate mask */ void calcMask(); /*! @brief The preprocessing step, wich consists of the following logic and Sub setps: * @details For all contours in a struct: * 1) Transfer the contour polygons into boost::geometry structures * 1a) Convert the contur points from world coordinates into geometry coordinates. * 1b) get min and max for x/y/z of a contour * 2) Tilt check: if difference of z_min and z_max is larger then a tolerance value -> there is a tilt. Throw rttb::TiltedMaskPlaneException. * 3) Get struct-bounding-box: get x_min_struct, y_min_struct, x_max_struct, y_max_struct to define the bounding box that containes all contours of a struct in x-y-dimensions. */ void preprocessing(); /*! @brief The voxelization step, which computes the voxelization planes (in x/y) for all contours of an struct. * @details For each contour (that is in the z-Range of the reference geometry) of the struct: * 1) Allocate result array (voxelization plane) based on the bounding box (see Preprocessing Step 3) * 2) Generate voxelization plane for the contour (based on the x-y-raster of the reference geometry). * 3) Add result Array (key is the z-Value of the contour) */ void voxelization(); /*! @brief mask voxel Generation step which transfers the voxelization planes into the (z-)geometry of the reference geometry. * @details It consists of following Sub steps : * For all "slices" in the reference geometry : * 1) generate weight vector for all voxelization planes for a given z - value of a slice * Iterate over the bounding box of a struct.For each voxel : * 2) Compute weighted sum of all voxelization planes(use weight vector, step 1) * 2a) If sum > 0 : Add mask voxel for the current x / y(inner Loop) and z value(outer Loop). * 3) return mask voxel list. */ void generateMaskVoxelList(); /*! @brief Convert the rttb polygon with world coordinate to the rttb polygon with double geometry coordinate, calculate the current min/max * and check if the polygon is planar * @param minimum the current global minimum * @param maximum the current global maximum * @return Return true if the polygon is planar, which means that the minimal and maximal z-coordinate of the polygon is not larger than a error constant */ bool preprocessingPolygon(const rttb::PolygonType& aRTTBPolygon, rttb::PolygonType& geometryCoordinatePolygon, rttb::DoubleVoxelGridIndex3D& minimum, rttb::DoubleVoxelGridIndex3D& maximum, double aErrorConstant) const; /*! @brief Convert a rttb 3d polygon to a 2d boost ring*/ BoostRing2D convertRTTBPolygonToBoostRing(const rttb::PolygonType& aRTTBPolygon) const; /*! @brief Convert a rttb 3d polygon to a map of z index with a vector of boost 2d ring, because of tilt check use the first z index of the polygon as the map key*/ BoostRingMap convertRTTBPolygonSequenceToBoostRingMap(const rttb::PolygonSequenceType& aRTTBPolygonVector) const; /*! @brief Find the key with error constant to aIndex * @pre aBoostRingMap should not be empty * @return Return aBoostRingMap.end() if the key is not found */ BoostMask::BoostRingMap::iterator findNearestKey(BoostMask::BoostRingMap& aBoostRingMap, double aIndex, double aErrorConstant) const; /*! @brief If 2 rings in the vector build a donut, convert the 2 rings to a donut polygon, other rings unchanged*/ BoostPolygonVector checkDonutAndConvert(const BoostRingVector& aRingVector) const; /*! @brief Calculate the voxelization thickness. Return false, if the voxelization plane is not homogeneous */ bool calcVoxelizationThickness(double& aThickness) const; }; } } } #endif diff --git a/code/masks/boost/rttbBoostMaskAccessor.h b/code/masks/boost/rttbBoostMaskAccessor.h index 4e92fd8..759b50c 100644 --- a/code/masks/boost/rttbBoostMaskAccessor.h +++ b/code/masks/boost/rttbBoostMaskAccessor.h @@ -1,121 +1,121 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __BOOST_MASK_R_ACCESSOR__H #define __BOOST_MASK_R_ACCESSOR__H #include "rttbBaseType.h" #include "rttbGeometricInfo.h" #include "rttbMaskAccessorInterface.h" #include "rttbStructure.h" #include "RTTBBoostMaskExports.h" namespace rttb { namespace masks { namespace boost { /*! @class BoostMaskAccessor * @brief Using the voxelization based on boost::geometry and generate the mask accessor. * @attention If "strict" is set to true, an exception will be thrown when the given structure has self intersection. * (A structure without self intersection means all contours of the structure have no self intersection, and * the polygons on the same slice have no intersection between each other, unless the case of a donut. A donut is accepted.) * If "strict" is set to false, debug information will be displayed when the given structure has self intersection. Self intersections will be ignored * and the mask will be calculated, however, it may cause errors in the mask results. */ class RTTBBoostMask_EXPORT BoostMaskAccessor : public core::MaskAccessorInterface { public: using MaskVoxelList = core::MaskAccessorInterface::MaskVoxelList; using MaskVoxelListPointer = core::MaskAccessorInterface::MaskVoxelListPointer; - using StructTypePointer = core::Structure::StructTypePointer; + using StructTypePointer = core::Structure::Pointer; private: StructTypePointer _spStructure; core::GeometricInfo _geoInfo; bool _strict; /*! vector containing list of mask voxels*/ MaskVoxelListPointer _spRelevantVoxelVector; IDType _maskUID; public: /*! @brief Constructor with a structure pointer and a geometric info pointer * @param aStructurePointer smart pointer of the structure * @param aGeometricInfo smart pointer of the geometricInfo of the dose * @param strict indicates whether to allow self intersection in the structure. If it is set to true, an exception will be thrown when the given structure has self intersection. * @exception InvalidParameterException thrown if strict is true and the structure has self intersections */ BoostMaskAccessor(StructTypePointer aStructurePointer, const core::GeometricInfo& aGeometricInfo, bool strict = true); /*! @brief destructor*/ ~BoostMaskAccessor() override; /*! @brief voxelization of the given structures using boost algorithms*/ void updateMask() override; /*! @brief get vector containing all relevant voxels that are inside the given structure*/ MaskVoxelListPointer getRelevantVoxelVector() override; /*! @brief get vector containing all relevant voxels that have a relevant volume above the given threshold and are inside the given structure*/ MaskVoxelListPointer getRelevantVoxelVector(float lowerThreshold) override; /*!@brief determine how a given voxel on the dose grid is masked * @param aID ID of the voxel in grid. * @param voxel Reference to the voxel. * @post after a valid call voxel containes the information of the specified grid voxel. If aID is not valid, voxel values are undefined. * The relevant volume fraction will be set to zero. * @return Indicates of the voxel exists and therefore if parameter voxel containes valid values.*/ bool getMaskAt(const VoxelGridID aID, core::MaskVoxel& voxel) const override; /*!@brief determine how a given voxel on the dose grid is masked * @param aIndex 3d index of the voxel in grid. * @param voxel Reference to the voxel. * @return Indicates of the voxel exists and therefore if parameter voxel containes valid values.*/ bool getMaskAt(const VoxelGridIndex3D& aIndex, core::MaskVoxel& voxel) const override; /*! @brief give access to GeometricInfo*/ const core::GeometricInfo& getGeometricInfo() const override; /* @ brief is true if dose is on a homogeneous grid * @remark Inhomogeneous grids are not supported at the moment, but if they will be supported in the future the interface does not need to change.*/ bool isGridHomogeneous() const override { return true; }; IDType getMaskUID() const override { return _maskUID; }; }; } } } #endif diff --git a/code/masks/boost/rttbBoostMaskGenerateMaskVoxelListThread.cpp b/code/masks/boost/rttbBoostMaskGenerateMaskVoxelListThread.cpp index 8160747..cf0f169 100644 --- a/code/masks/boost/rttbBoostMaskGenerateMaskVoxelListThread.cpp +++ b/code/masks/boost/rttbBoostMaskGenerateMaskVoxelListThread.cpp @@ -1,156 +1,156 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1127 $ (last changed revision) // @date $Date: 2015-10-01 13:33:33 +0200 (Do, 01 Okt 2015) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "rttbBoostMaskGenerateMaskVoxelListThread.h" #include "rttbInvalidParameterException.h" #include namespace rttb { namespace masks { namespace boost { BoostMaskGenerateMaskVoxelListThread::BoostMaskGenerateMaskVoxelListThread( const VoxelIndexVector& aGlobalBoundingBox, - GeometricInfoPointer aGeometricInfo, + core::GeometricInfo::Pointer aGeometricInfo, BoostArrayMapPointer aVoxelizationMap, double aVoxelizationThickness, unsigned int aBeginSlice, unsigned int aEndSlice, MaskVoxelListPointer aMaskVoxelList, ::boost::shared_ptr<::boost::shared_mutex> aMutex) : _globalBoundingBox(aGlobalBoundingBox), _geometricInfo(aGeometricInfo), _voxelizationMap(aVoxelizationMap), _voxelizationThickness(aVoxelizationThickness), _beginSlice(aBeginSlice), _endSlice(aEndSlice), _resultMaskVoxelList(aMaskVoxelList), _mutex(aMutex) {} void BoostMaskGenerateMaskVoxelListThread::operator()() { rttb::VoxelGridIndex3D minIndex = _globalBoundingBox.at(0); rttb::VoxelGridIndex3D maxIndex = _globalBoundingBox.at(1); unsigned int globalBoundingBoxSize0 = maxIndex[0] - minIndex[0] + 1; unsigned int globalBoundingBoxSize1 = maxIndex[1] - minIndex[1] + 1; std::vector maskVoxelsInThread; for (unsigned int indexZ = _beginSlice; indexZ < _endSlice; ++indexZ) { //calculate weight vector std::map weightVectorForZ; calcWeightVector(indexZ, weightVectorForZ); //For each x,y, calc sum of all voxelization plane, use weight vector for (unsigned int x = 0; x < globalBoundingBoxSize0; ++x) { for (unsigned int y = 0; y < globalBoundingBoxSize1; ++y) { rttb::VoxelGridIndex3D currentIndex; currentIndex[0] = x + minIndex[0]; currentIndex[1] = y + minIndex[1]; currentIndex[2] = indexZ; rttb::VoxelGridID gridID; _geometricInfo->convert(currentIndex, gridID); double volumeFraction = 0; auto it = weightVectorForZ.cbegin(); auto itMap = _voxelizationMap->cbegin(); for (; it != weightVectorForZ.cend() && itMap != _voxelizationMap->cend(); ++it, ++itMap) { double weight = it->second; if (weight > 0){ BoostArray2DPointer voxelizationArray = itMap->second; //calc sum of all voxelization plane, use weight volumeFraction += (*voxelizationArray)[x][y] * weight; } } if (volumeFraction > 1 && (volumeFraction - 1) <= errorConstant) { volumeFraction = 1; } else if (volumeFraction < 0 || (volumeFraction - 1) > errorConstant) { throw rttb::core::InvalidParameterException("Mask calculation failed! The volume fraction should >= 0 and <= 1!"); } //insert mask voxel if volumeFraction > 0 if (volumeFraction > 0) { core::MaskVoxel maskVoxelPtr = core::MaskVoxel(gridID, volumeFraction); maskVoxelsInThread.push_back(maskVoxelPtr); } } } } ::boost::unique_lock<::boost::shared_mutex> lock(*_mutex); _resultMaskVoxelList->insert(_resultMaskVoxelList->end(), maskVoxelsInThread.begin(), maskVoxelsInThread.end()); } void BoostMaskGenerateMaskVoxelListThread::calcWeightVector(const rttb::VoxelGridID& aIndexZ, std::map& weightVector) const { double indexZMin = aIndexZ - 0.5; double indexZMax = aIndexZ + 0.5; for (auto & it : *_voxelizationMap) { double voxelizationPlaneIndexMin = it.first - 0.5 * _voxelizationThickness; double voxelizationPlaneIndexMax = it.first + 0.5 * _voxelizationThickness; double weight = 0; if ((voxelizationPlaneIndexMin < indexZMin) && (voxelizationPlaneIndexMax > indexZMin)) { if (voxelizationPlaneIndexMax < indexZMax) { weight = voxelizationPlaneIndexMax - indexZMin; } else { weight = 1; } } else if ((voxelizationPlaneIndexMin >= indexZMin) && (voxelizationPlaneIndexMin < indexZMax)) { if (voxelizationPlaneIndexMax < indexZMax) { weight = _voxelizationThickness; } else { weight = indexZMax - voxelizationPlaneIndexMin; } } weightVector.insert(std::pair(it.first, weight)); } } } } } diff --git a/code/masks/boost/rttbBoostMaskGenerateMaskVoxelListThread.h b/code/masks/boost/rttbBoostMaskGenerateMaskVoxelListThread.h index 3914f79..b77f70e 100644 --- a/code/masks/boost/rttbBoostMaskGenerateMaskVoxelListThread.h +++ b/code/masks/boost/rttbBoostMaskGenerateMaskVoxelListThread.h @@ -1,90 +1,89 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1127 $ (last changed revision) // @date $Date: 2015-10-01 13:33:33 +0200 (Do, 01 Okt 2015) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __BOOST_MASK_GENERATE_MASK_VOXEL_LIST_H #define __BOOST_MASK_GENERATE_MASK_VOXEL_LIST_H #include "rttbBaseType.h" #include "rttbGeometricInfo.h" #include "rttbMaskAccessorInterface.h" #include #include #include namespace rttb { namespace masks { namespace boost { /*! @class BoostMaskGenerateMaskVoxelListThread * */ class BoostMaskGenerateMaskVoxelListThread { public: - using GeometricInfoPointer = ::boost::shared_ptr; typedef ::boost::multi_array BoostArray2D; using BoostArray2DPointer = ::boost::shared_ptr; typedef ::boost::shared_ptr > BoostArrayMapPointer; using VoxelIndexVector = std::vector; using MaskVoxelListPointer = core::MaskAccessorInterface::MaskVoxelListPointer; BoostMaskGenerateMaskVoxelListThread(const VoxelIndexVector& aGlobalBoundingBox, - GeometricInfoPointer aGeometricInfo, + core::GeometricInfo::Pointer aGeometricInfo, BoostArrayMapPointer aVoxelizationMap, double aVoxelizationThickness, unsigned int aBeginSlice, unsigned int aEndSlice, MaskVoxelListPointer aMaskVoxelList, ::boost::shared_ptr<::boost::shared_mutex> aMutex); void operator()(); private: VoxelIndexVector _globalBoundingBox; - GeometricInfoPointer _geometricInfo; + core::GeometricInfo::Pointer _geometricInfo; BoostArrayMapPointer _voxelizationMap; //(for example, the first contour has the double grid index 0.1, the second 0.3, the third 0.5, then the thickness is 0.2) double _voxelizationThickness; unsigned int _beginSlice; /*! @brief _endSlice is the first index not to be processed (like a end iterator) */ unsigned int _endSlice; MaskVoxelListPointer _resultMaskVoxelList; ::boost::shared_ptr<::boost::shared_mutex> _mutex; /*! @brief For each dose grid index z, calculate the weight vector for each structure contour */ void calcWeightVector(const rttb::VoxelGridID& aIndexZ, std::map& weightVector) const; }; } } } #endif \ No newline at end of file diff --git a/code/models/rttbBioModel.h b/code/models/rttbBioModel.h index 8c3f0db..3d0d091 100644 --- a/code/models/rttbBioModel.h +++ b/code/models/rttbBioModel.h @@ -1,108 +1,110 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __BIO_MODEL_H #define __BIO_MODEL_H #include "rttbDVH.h" #include "rttbBaseTypeModels.h" +#include #include "RTTBModelsExports.h" #include namespace rttb { namespace models { /*! @class BioModel @brief This is the interface class for biological models */ class RTTBModels_EXPORT BioModel { public: + rttbClassMacroNoParent(BioModel) using ParamVectorType = std::vector; - using DVHPointer = core::DVH::DVHPointer; + using DVHPointer = core::DVH::Pointer; protected: DVHPointer _dvh; BioModelValueType _value{0}; /*! @brief Calculate the model value @param doseFactor scaling factor for the dose. The model calculation will use the dvh with each di=old di*doseFactor. */ virtual BioModelValueType calcModel(const double doseFactor = 1) = 0; /* Map of all parameters */ std::map parameterMap; std::string _name; public: BioModel() = default; BioModel(DVHPointer aDvh): _dvh(aDvh), _value(0) {}; virtual ~BioModel()= default; /*! @brief Start the calculation. If any parameter changed, init() should be called again and return =true before getValue() is called! @return Return true if successful */ bool init(const double doseFactor = 1); /*! @param aDVH must be a DVH calculated by a cumulative dose distribution, not a fraction DVH! */ void setDVH(const DVHPointer aDVH); const DVHPointer getDVH() const; /*! @brief Set parameter vector, where index of vector is the parameter ID. */ virtual void setParameterVector(const ParamVectorType& aParameterVector) = 0; virtual void setParameterByID(const int aParamId, const BioModelParamType aValue) = 0; /*! @brief Get parameter by ID. @return Return -1 if ID is not found. */ virtual const int getParameterID(const std::string& aParamName) const = 0; virtual std::map getParameterMap() const = 0; virtual void fillParameterMap() = 0 ; virtual std::string getModelType() const = 0; /*! @brief Get the value of biological model @pre init() must be called and =true! */ const BioModelValueType getValue() const; }; }//end namespace models }//end namespace rttb #endif diff --git a/code/models/rttbBioModelCurve.cpp b/code/models/rttbBioModelCurve.cpp index b73de95..a4565d2 100644 --- a/code/models/rttbBioModelCurve.cpp +++ b/code/models/rttbBioModelCurve.cpp @@ -1,94 +1,93 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include -#include #include "rttbBioModel.h" #include "rttbNTCPLKBModel.h" #include "rttbBioModelCurve.h" #include "rttbDvhBasedModels.h" namespace rttb { namespace models { CurveDataType getCurveDoseVSBioModel(BioModel& aModel, double normalisationDose, int aBin, double minDose, double maxDose) { CurveDataType _curveData; double minFactor = 0, maxFactor = 0; minFactor = minDose / normalisationDose; maxFactor = maxDose / normalisationDose; double lastValue = 0; for (int i = 0; i < aBin; i++) { double factor = minFactor + i * (maxFactor - minFactor) / (aBin - 1); if (lastValue < 1) { aModel.init(factor); BioModelValueType value = aModel.getValue(); lastValue = value; _curveData.insert(CurvePointType(factor * normalisationDose, value)); } else { _curveData.insert(CurvePointType(factor * normalisationDose, 1)); } } return _curveData; } CurveDataType getCurveEUDVSBioModel(NTCPLKBModel& aModel, DoseCalcType maxFactor, DoseCalcType minFactor, int aBin) { CurveDataType _curveData; BioModel::DVHPointer _dvh = aModel.getDVH(); for (int i = 0; i < aBin; i++) { DoseCalcType factor = minFactor + i * (maxFactor - minFactor) / (aBin - 1); core::DVH variantDVH = core::DVH(_dvh->getDataDifferential(), _dvh->getDeltaD() * factor, _dvh->getDeltaV(), "temporary", "temporary"); - boost::shared_ptr spDVH = boost::make_shared(variantDVH); + auto spDVH = boost::make_shared(variantDVH); double eud = getEUD(spDVH, aModel.getA()); aModel.init(factor); BioModelValueType value = aModel.getValue(); _curveData.insert(CurvePointType(eud, value)); } return _curveData; } } } \ No newline at end of file diff --git a/code/models/rttbDvhBasedModels.cpp b/code/models/rttbDvhBasedModels.cpp index 185d8e3..f72f97b 100644 --- a/code/models/rttbDvhBasedModels.cpp +++ b/code/models/rttbDvhBasedModels.cpp @@ -1,177 +1,177 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision $ (last changed revision) // @date $Date $ (last change date) // @author $Author $ (last changed by) */ #include "rttbDvhBasedModels.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace models { - DoseStatisticType getEUD(const DVHPointer dvh, const DoseCalcType aA) + DoseStatisticType getEUD(core::DVH::ConstPointer dvh, const DoseCalcType aA) { if (aA == 0) { throw core::InvalidParameterException("Parameter invalid: aA should not be zero!"); } DataDifferentialType dataDifferential = dvh->getDataDifferential(); if (dataDifferential.empty()) { throw core::InvalidParameterException("Parameter invalid: DVH data differential should not be empty!"); } double eud = 0; DoseTypeGy deltaD = dvh->getDeltaD(); DVHVoxelNumber numberOfVoxels = dvh->getNumberOfVoxels(); for (GridIndexType i = 0; i < dataDifferential.size(); i++) { double doseGyi = (i + 0.5) * deltaD; double relativeVolumei = dataDifferential[i] / numberOfVoxels; eud += pow((double)doseGyi, (double)aA) * relativeVolumei; } eud = pow((double)eud, (double)(1 / aA)); return eud; } - BEDDVHType calcBEDDVH(const DVHPointer dvh, const int numberOfFractions, + BEDDVHType calcBEDDVH(core::DVH::ConstPointer dvh, const int numberOfFractions, const DoseCalcType alpha_beta, const bool relativeVolume) { std::map dataBED; std::map dataBEDRelative; DataDifferentialType dataDifferential = dvh->getDataDifferential(); if (dataDifferential.empty()) { throw core::InvalidParameterException("Parameter invalid: DVH data differential should not be empty!"); } if (alpha_beta <= 0) { throw core::InvalidParameterException("Parameter invalid: alpha_beta must be >0!"); } if (numberOfFractions <= 0) { throw core::InvalidParameterException("Parameter invalid: numberOfFractions must be >1! The dvh should be an accumulated-dvh of all fractions, not a single fraction-dvh!"); } DoseTypeGy deltaD = dvh->getDeltaD(); DVHVoxelNumber numberOfVoxels = dvh->getNumberOfVoxels(); std::deque::iterator it; int i = 0; for (it = dataDifferential.begin(); it != dataDifferential.end(); ++it) { DoseTypeGy doseGyi = ((i + 0.5) * deltaD); DoseTypeGy bedi = 0; bedi = (doseGyi * (1 + doseGyi / (numberOfFractions * alpha_beta))); if (!relativeVolume) { dataBED.insert(std::pair(bedi, (*it))); } else { dataBEDRelative.insert(std::pair(bedi, (*it) / numberOfVoxels)); } i++; } if (!relativeVolume) { return dataBED; } else { return dataBEDRelative; } } - LQEDDVHType calcLQED2DVH(const DVHPointer dvh, const int numberOfFractions, + LQEDDVHType calcLQED2DVH(core::DVH::ConstPointer dvh, const int numberOfFractions, const DoseCalcType alpha_beta, const bool relativeVolume) { std::map dataLQED2; std::map dataLQED2Relative; DataDifferentialType dataDifferential = dvh->getDataDifferential(); if (dataDifferential.empty()) { throw core::InvalidParameterException("Parameter invalid: DVH data differential should not be empty!"); } if (alpha_beta <= 0) { throw core::InvalidParameterException("Parameter invalid: alpha_beta must be >0!"); } if (numberOfFractions <= 1) { throw core::InvalidParameterException("Parameter invalid: numberOfFractions must be >1! The dvh should be an accumulated-dvh of all fractions, not a single fraction-dvh!"); } DoseTypeGy deltaD = dvh->getDeltaD(); DVHVoxelNumber numberOfVoxels = dvh->getNumberOfVoxels(); std::deque::iterator it; int i = 0; for (it = dataDifferential.begin(); it != dataDifferential.end(); ++it) { DoseTypeGy doseGyi = ((i + 0.5) * deltaD); DoseTypeGy lqed2i = 0; lqed2i = (doseGyi * ((alpha_beta + doseGyi / numberOfFractions) / (alpha_beta + 2))); if (!relativeVolume) { dataLQED2.insert(std::pair(lqed2i, *it)); } else { dataLQED2Relative.insert(std::pair(lqed2i, (*it) / numberOfVoxels)); } i++; } if (!relativeVolume) { return dataLQED2; } else { return dataLQED2Relative; } } } } \ No newline at end of file diff --git a/code/models/rttbDvhBasedModels.h b/code/models/rttbDvhBasedModels.h index 559d83f..875f927 100644 --- a/code/models/rttbDvhBasedModels.h +++ b/code/models/rttbDvhBasedModels.h @@ -1,51 +1,50 @@ #include #include "rttbDVH.h" #include "rttbBaseType.h" namespace rttb { namespace models { using DataDifferentialType = core::DVH::DataDifferentialType; - using DVHPointer = core::DVH::DVHPointer; typedef std::map BEDDVHType; typedef std::map LQEDDVHType; /*! @brief Get Equivalent Uniform Dose (EUD) @pre dvh data differential is not empty, @pre aA is not zero, @return Return calculated EUD value, @exception InvalidParameterException Thrown if parameters were not set correctly. */ - DoseStatisticType getEUD(const DVHPointer dvh, const DoseCalcType aA); + DoseStatisticType getEUD(core::DVH::ConstPointer dvh, const DoseCalcType aA); /*! @brief Calculate Biological Effective/Equivalent Dose (BED) of dvh @param relativeVolume default false-> the corresponding volume value is the voxel number of the dose bin; if true-> the corresponding volume value is the relative volume % between 0 and 1, (the voxel number of this dose bin)/(number of voxels) @pre dvh should be an accumulated dvh of all fractions, not a single fraction dvh @pre dvh data differential is not empty @pre alpha_beta > 0 @pre numberOfFractions > 1 @return Return map: keys are BEDi in Gy, values are the volume of the dose bin @exception InvalidParameterException Thrown if parameters were not set correctly. */ - BEDDVHType calcBEDDVH(const DVHPointer dvh, const int numberOfFractions, + BEDDVHType calcBEDDVH(core::DVH::ConstPointer dvh, const int numberOfFractions, const DoseCalcType alpha_beta, const bool relativeVolume = false); /*! @brief Calculate Linear-quadratic equivalent dose for 2-Gy (LQED2) of dvh @param relativeVolume default false-> the corresponding volume value is the voxel number of the dose bin; if true-> the corresponding volume value is the relative volume % between 0 and 1, (the voxel number of this dose bin)/(number of voxels) @pre dvh should be an accumulated dvh of all fractions, not a single fraction dvh @pre dvh data differential is not empty @pre alpha_beta > 0 @pre numberOfFractions > 1 @return Return map: keys are LQED2 in Gy, values are the volume of the dose bin; return empty map if not initialized @exception InvalidParameterException Thrown if parameters were not set correctly. */ - LQEDDVHType calcLQED2DVH(const DVHPointer dvh, const int numberOfFractions, + LQEDDVHType calcLQED2DVH(core::DVH::ConstPointer dvh, const int numberOfFractions, const DoseCalcType alpha_beta, const bool relativeVolume = false); } } \ No newline at end of file diff --git a/code/models/rttbLQModelAccessor.h b/code/models/rttbLQModelAccessor.h index 535ca66..3c6ab46 100644 --- a/code/models/rttbLQModelAccessor.h +++ b/code/models/rttbLQModelAccessor.h @@ -1,92 +1,92 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __LQ_MODEL_ACCESSOR_H #define __LQ_MODEL_ACCESSOR_H #include "rttbAccessorWithGeoInfoBase.h" #include "rttbDoseAccessorInterface.h" #include "rttbBaseTypeModels.h" namespace rttb { namespace models { /*! @class LQModelAccessor @brief This class gives access to the LQ Model information in an image */ class LQModelAccessor: public core::AccessorWithGeoInfoBase { public: - using DoseAccessorPointer = core::DoseAccessorInterface::DoseAccessorPointer; + using DoseAccessorPointer = core::DoseAccessorInterface::Pointer; private: DoseAccessorPointer _dose; BioModelParamType _alpha; BioModelParamType _beta; unsigned int _nFractions; DoseAccessorPointer _alphaMap; DoseAccessorPointer _betaMap; double _doseScaling; bool _withAlphaBetaMaps; IDType _bioModelUID; LQModelAccessor() = delete; /*! @brief get all required data from the dose geometric info */ void assembleGeometricInfo() override; public: ~LQModelAccessor() override; /*! @brief Constructor. @pre dose must be a valid instance (and != nullptr) @exception InvalidDoseException if _dose is nullptr */ LQModelAccessor(DoseAccessorPointer dose, BioModelParamType alpha, BioModelParamType beta, unsigned int nFractions=1, double doseScaling = 1.0); /*! @brief Constructor. @pre dose must be a valid instance (and != nullptr) @exception InvalidDoseException if dose is nullptr, if alphaMap is nullptr or if betaMap is nullptr */ LQModelAccessor(DoseAccessorPointer dose, DoseAccessorPointer alphaMap, DoseAccessorPointer betaMap, unsigned int nFractions = 1, double doseScaling = 1.0); /*! @brief returns the LQ Model value for an id */ GenericValueType getValueAt(const VoxelGridID aID) const override; /*! @brief returns the LQ Model value for an index */ GenericValueType getValueAt(const VoxelGridIndex3D& aIndex) const override; const IDType getUID() const override { return _bioModelUID; }; }; } } #endif diff --git a/code/models/rttbNTCPLKBModel.cpp b/code/models/rttbNTCPLKBModel.cpp index 0a3eb9d..34fd4ad 100644 --- a/code/models/rttbNTCPLKBModel.cpp +++ b/code/models/rttbNTCPLKBModel.cpp @@ -1,182 +1,181 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #define _USE_MATH_DEFINES #include #include #include #include -#include #include #include "rttbIntegration.h" #include "rttbNTCPLKBModel.h" #include "rttbDvhBasedModels.h" #include "rttbInvalidParameterException.h" #include "rttbExceptionMacros.h" namespace rttb { namespace models { NTCPLKBModel::NTCPLKBModel() : NTCPModel(){ _name = "NTCPLKBModel"; fillParameterMap(); } NTCPLKBModel::NTCPLKBModel(DVHPointer aDvh, BioModelParamType aD50, BioModelParamType aM, BioModelParamType aA): NTCPModel(aDvh, aD50), _m(aM), _a(aA) { _name = "NTCPLKBModel"; fillParameterMap(); } void NTCPLKBModel::setA(const BioModelParamType aA) { _a = aA; } const BioModelParamType NTCPLKBModel::getA() { return _a; } void NTCPLKBModel::setM(const BioModelParamType aM) { _m = aM; } const BioModelParamType NTCPLKBModel::getM() { return _m; } void NTCPLKBModel::setParameterVector(const ParamVectorType& aParameterVector) { if (aParameterVector.size() != 3) { throw core::InvalidParameterException("Parameter invalid: aParameterVector.size must be 3! "); } else { _d50 = aParameterVector.at(0); _m = aParameterVector.at(1); _a = aParameterVector.at(2); } } void NTCPLKBModel::setParameterByID(const int aParamId, const BioModelParamType aValue) { if (aParamId == 0) { _d50 = aValue; } else if (aParamId == 1) { _m = aValue; } else if (aParamId == 2) { _a = aValue; } else { throw core::InvalidParameterException("Parameter invalid: aParamID must be 0(for d50) or 1(for m) or 2(for a)! "); } } const int NTCPLKBModel::getParameterID(const std::string& aParamName) const { if (aParamName == "d50") { return 0; } else if (aParamName == "m") { return 1; } else if (aParamName == "a") { return 2; } else { rttbExceptionMacro(core::InvalidParameterException, << "Parameter name " << aParamName << " invalid: it should be d50 or m or a!"); } } std::map NTCPLKBModel::getParameterMap() const{ return parameterMap; } void NTCPLKBModel::fillParameterMap(){ parameterMap["d50"] = getD50(); parameterMap["m"] = getM(); parameterMap["a"] = getA(); } std::string NTCPLKBModel::getModelType() const{ return _name; } BioModelValueType NTCPLKBModel::calcModel(const double doseFactor) { if (_a == 0) { throw core::InvalidParameterException("_a must not be zero"); } if (_m == 0) { throw core::InvalidParameterException("_m must not be zero"); } core::DVH variantDVH = core::DVH(_dvh->getDataDifferential(), (DoseTypeGy)(_dvh->getDeltaD() * doseFactor), _dvh->getDeltaV(), "temporary", "temporary"); - boost::shared_ptr spDVH = boost::make_shared(variantDVH); + auto spDVH = boost::make_shared(variantDVH); double eud = getEUD(spDVH, this->_a); //_m must not be zero double t = (eud - this->_d50) / (this->_m * this->_d50); double value = 1 / pow(2 * M_PI, 0.5); double result = integrateLKB(t); if (result != -100) { value *= result; return value; } else { return false; } } }//end namespace models }//end namespace rttb diff --git a/code/models/rttbNTCPLKBModel.h b/code/models/rttbNTCPLKBModel.h index 815f095..23c6c71 100644 --- a/code/models/rttbNTCPLKBModel.h +++ b/code/models/rttbNTCPLKBModel.h @@ -1,105 +1,104 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __NTCP_LKB_MODEL_H #define __NTCP_LKB_MODEL_H #include #include "rttbNTCPModel.h" #include "rttbBaseTypeModels.h" namespace rttb { namespace models { /*! @class NTCPLKBModel @brief This class represents a NTCP(Normal Tissue Complication Probability) LKB model (Lyman 1985, Kutcher and Burman 1989) @see NTCPModel */ class NTCPLKBModel: public NTCPModel { public: using ParamVectorType = NTCPModel::ParamVectorType; - using DVHPointer = NTCPModel::DVHPointer; private: /*! The steepness of the dose-response curve. Must not be zero on model evaluation. */ BioModelParamType _m{0}; /*! Tumor or normal tissue-specific parameter that describes the dose-volume effect, e.g. -10 for prostate (Wu 2002). Must not be zero on model evaluation, because EUD calculation will fail. */ BioModelParamType _a{0}; protected: /*! @brief Calculate the model value * @param doseFactor: scaling factor for the dose. The model calculation will use the dvh with each di=old di*doseFactor. * @throw if either _a or _m is zero for the model calculation */ BioModelValueType calcModel(const double doseFactor = 1) override; public: NTCPLKBModel(); - NTCPLKBModel(DVHPointer aDvh, BioModelParamType aD50, BioModelParamType aM, BioModelParamType aA); + NTCPLKBModel(core::DVH::Pointer aDvh, BioModelParamType aD50, BioModelParamType aM, BioModelParamType aA); void setM(const BioModelParamType aM); const BioModelParamType getM(); void setA(const BioModelParamType aA); const BioModelParamType getA(); /*! @brief Set parameter with ID. "d50":0,"m":1,"a":2 @exception InvalidParameterException Thrown if aParamId is not 0 or 1 or 2. */ void setParameterByID(const int aParamId, const BioModelParamType aValue) override; /*! @brief Set parameter vector, where index of vector is the parameter ID. "d50":0,"m":1,"a":2 @exception InvalidParameterException Thrown if aParamterVector.size()!=3. */ void setParameterVector(const ParamVectorType& aParameterVector) override; /*! @brief Get parameter ID. "d50":0,"m":1,"a":2 @return 0 for "d50", 1 for "m", 2 for "a" @exception InvalidParameterException Thrown if aParamName is not d50 or m or a. */ const int getParameterID(const std::string& aParamName) const override; std::map getParameterMap() const override; void fillParameterMap() override; std::string getModelType() const override; }; } } #endif diff --git a/code/models/rttbNTCPModel.h b/code/models/rttbNTCPModel.h index 3364297..6e509d8 100644 --- a/code/models/rttbNTCPModel.h +++ b/code/models/rttbNTCPModel.h @@ -1,67 +1,66 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __NTCP_MODEL_H #define __NTCP_MODEL_H #include "rttbBioModel.h" #include "rttbBaseTypeModels.h" namespace rttb { namespace models { /*! @class NTCPModel @brief This is the interface class for NTCP(Normal Tissue Complication Probability) models */ class NTCPModel: public BioModel { public: using ParamVectorType = BioModel::ParamVectorType; - using DVHPointer = BioModel::DVHPointer; protected: BioModelParamType _d50{0}; public: NTCPModel(): BioModel() {} NTCPModel(const BioModelParamType aD50): BioModel(), _d50(aD50) {} - NTCPModel(DVHPointer aDvh, const BioModelParamType aD50): BioModel(aDvh), _d50(aD50) {} + NTCPModel(core::DVH::Pointer aDvh, const BioModelParamType aD50): BioModel(aDvh), _d50(aD50) {} const BioModelParamType getD50() { return _d50; } void setD50(const BioModelParamType aD50) { _d50 = aD50; } }; }//end namespace models }//end namespace rttb #endif diff --git a/code/models/rttbTCPLQModel.cpp b/code/models/rttbTCPLQModel.cpp index d677375..ac82e94 100644 --- a/code/models/rttbTCPLQModel.cpp +++ b/code/models/rttbTCPLQModel.cpp @@ -1,311 +1,311 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #define _USE_MATH_DEFINES #include #include #include #include #include #include "rttbTCPLQModel.h" #include "rttbDvhBasedModels.h" #include "rttbIntegration.h" #include "rttbInvalidParameterException.h" #include "rttbExceptionMacros.h" namespace rttb { namespace models { TCPLQModel::TCPLQModel(): TCPModel() { _name = "TCPLQModel"; fillParameterMap(); } TCPLQModel::TCPLQModel(DVHPointer aDVH, BioModelParamType aAlphaMean, BioModelParamType aBeta, BioModelParamType aRho, int aNumberOfFractions): TCPModel(aDVH, aNumberOfFractions), _alphaMean(aAlphaMean), _alphaVariance(0), _alpha_beta(aAlphaMean / aBeta), _rho(aRho) { _name = "TCPLQModel"; fillParameterMap(); } TCPLQModel::TCPLQModel(DVHPointer aDVH, BioModelParamType aRho, int aNumberOfFractions, BioModelParamType aAlpha_Beta, BioModelParamType aAlphaMean, BioModelParamType aAlphaVariance): TCPModel(aDVH, aNumberOfFractions), _alphaMean(aAlphaMean), _alphaVariance(aAlphaVariance), _alpha_beta(aAlpha_Beta), _rho(aRho) { fillParameterMap(); _name = "TCPLQModel"; } void TCPLQModel::setParameters(const BioModelParamType aAlphaMean, const BioModelParamType aAlpha_Beta, const BioModelParamType aRho, const BioModelParamType aAlphaVariance) { _alphaMean = aAlphaMean; _alphaVariance = aAlphaVariance; _alpha_beta = aAlpha_Beta; _rho = aRho; //reset _value, because parameters have changed. _value = 0; } void TCPLQModel::setAlpha(const BioModelParamType aAlphaMean, const BioModelParamType aAlphaVariance) { _alphaVariance = aAlphaVariance; _alphaMean = aAlphaMean; } void TCPLQModel::setAlphaBeta(const BioModelParamType aAlpha_Beta) { _alpha_beta = aAlpha_Beta; } void TCPLQModel::setRho(const BioModelParamType aRho) { _rho = aRho; } const BioModelParamType TCPLQModel::getAlphaBeta() { return _alpha_beta; } const BioModelParamType TCPLQModel::getAlphaMean() { return _alphaMean; } const BioModelParamType TCPLQModel::getAlphaVariance() { return _alphaVariance; } const BioModelParamType TCPLQModel::getRho() { return _rho; } long double TCPLQModel::calcTCPi(BioModelParamType aRho, BioModelParamType aAlphaMean, double vj, double bedj) { return exp(-aRho * vj * exp(-aAlphaMean * bedj)); } long double TCPLQModel::calcTCP(std::map aBEDDVH, BioModelParamType aRho, BioModelParamType aAlphaMean, double aDeltaV) { std::map::iterator it; long double tcp = 1; for (it = aBEDDVH.begin(); it != aBEDDVH.end(); ++it) { long double tcpi = this->calcTCPi(aRho, aAlphaMean, (*it).second * aDeltaV, (*it).first); tcp = tcp * tcpi; } return tcp; } long double TCPLQModel::calcTCPAlphaNormalDistribution( std::map aBEDDVH, BioModelParamType aRho, BioModelParamType aAlphaMean, BioModelParamType aAlphaVariance, double aDeltaV) { std::map::iterator it; std::vector volumeV2; std::vector bedV2; int i = 0; for (it = aBEDDVH.begin(); it != aBEDDVH.end(); ++it) { volumeV2.push_back((*it).second * aDeltaV); bedV2.push_back((*it).first); i++; } struct TcpParams params = {aAlphaMean, aAlphaVariance, aRho, volumeV2, bedV2}; double result = integrateTCP(0, params); if (result == -100) { std::cerr << "Integration error!\n"; return -1; } else { long double tcp = 1 / (pow(2 * M_PI, 0.5) * _alphaVariance) * result; return tcp; } } BioModelValueType TCPLQModel::calcModel(const double doseFactor) { core::DVH variantDVH = core::DVH(_dvh->getDataDifferential(), (DoseTypeGy)(_dvh->getDeltaD() * doseFactor), _dvh->getDeltaV(), "temporary", "temporary"); - boost::shared_ptr spDVH = boost::make_shared(variantDVH); + auto spDVH = boost::make_shared(variantDVH); BioModelValueType value = 0; if (_alphaVariance == 0) { if (_alphaMean <= 0 || _alpha_beta <= 0 || _rho <= 0) { throw core::InvalidParameterException("Parameter invalid: alpha, alpha/beta, rho and number of fractions must >0!"); } if (_numberOfFractions <= 1) { throw core::InvalidParameterException("Parameter invalid: numberOfFractions must be >1! The dvh should be an accumulated-dvh of all fractions, not a single fraction-dvh!"); } std::map dataBED = calcBEDDVH(spDVH, _numberOfFractions, _alpha_beta); value = (BioModelValueType)this->calcTCP(dataBED, _rho, _alphaMean, variantDVH.getDeltaV()); return value; } //if alpha normal distribution else { if (this->_alpha_beta <= 0 || this->_alphaMean <= 0 || this->_alphaVariance < 0 || _rho <= 0) { throw core::InvalidParameterException("Parameter invalid: alpha/beta, alphaMean, rho and number of fractions must >0!"); } if (_numberOfFractions <= 1) { throw core::InvalidParameterException("Parameter invalid: numberOfFractions must be >1! The dvh should be an accumulated-dvh of all fractions, not a single fraction-dvh!"); } std::map dataBED = calcBEDDVH(spDVH, _numberOfFractions, _alpha_beta); value = (BioModelValueType)(this->calcTCPAlphaNormalDistribution(dataBED, _rho, _alphaMean, _alphaVariance, variantDVH.getDeltaV())); return value; } } void TCPLQModel::setParameterVector(const ParamVectorType& aParameterVector) { if (aParameterVector.size() != 4) { throw core::InvalidParameterException("Parameter invalid: aParameterVector.size must be 4! "); } else { _alphaMean = aParameterVector.at(0); _alphaVariance = aParameterVector.at(1); _alpha_beta = aParameterVector.at(2); _rho = aParameterVector.at(3); } } void TCPLQModel::setParameterByID(const int aParamId, const BioModelParamType aValue) { if (aParamId == 0) { _alphaMean = aValue; } else if (aParamId == 1) { _alphaVariance = aValue; } else if (aParamId == 2) { _alpha_beta = aValue; } else if (aParamId == 3) { _rho = aValue; } else { throw core::InvalidParameterException("Parameter invalid: aParamID must be 0(alphaMean) or 1(alphaVariance) or 2(alpha_beta) or 3(rho)! "); } } const int TCPLQModel::getParameterID(const std::string& aParamName) const { if (aParamName == "alphaMean") { return 0; } else if (aParamName == "alphaVariance") { return 1; } else if (aParamName == "alpha_beta") { return 2; } else if (aParamName == "rho") { return 3; } else { rttbExceptionMacro(core::InvalidParameterException, << "Parameter name " << aParamName << " invalid: it should be alphaMean or alphaVariance or alpha_beta or rho!"); } } std::map TCPLQModel::getParameterMap() const{ return parameterMap; } void TCPLQModel::fillParameterMap(){ parameterMap["numberOfFraction"] = getNumberOfFractions(); parameterMap["alphaMean"] = getAlphaMean(); parameterMap["alphaVariance"] = getAlphaVariance(); parameterMap["alpha_beta"] = getAlphaBeta(); parameterMap["rho"] = getRho(); } std::string TCPLQModel::getModelType() const{ return _name; } }//end namespace models }//end namespace rttb diff --git a/code/models/rttbTCPLQModel.h b/code/models/rttbTCPLQModel.h index adada5e..3a96812 100644 --- a/code/models/rttbTCPLQModel.h +++ b/code/models/rttbTCPLQModel.h @@ -1,169 +1,169 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __TCP_LQ_MODEL_H #define __TCP_LQ_MODEL_H #include #include #include "rttbTCPModel.h" #include "rttbBaseTypeModels.h" namespace rttb { namespace models { /*! @class TCPLQModel @brief This class represents a TCP(Tumor Control Probability) LQ model (Nahum and Sanchez-Nieto 2001, Hall and Giaccia 2006) @see TCPModel */ class TCPLQModel: public TCPModel { public: using ParamVectorType = TCPModel::ParamVectorType; - using DVHPointer = TCPModel::DVHPointer; + using DVHPointer = core::DVH::Pointer; private: /*! @brief Calculate intermediate tcp using alpha constant. This is a helper function for calcTCP() @see calcTCP */ long double calcTCPi(BioModelParamType aRho, BioModelParamType aAlphaMean, double vj, double bedj); /*! @brief Calculate tcp using alpha constant. */ long double calcTCP(std::map aBEDDVH, BioModelParamType aRho, BioModelParamType aAlphaMean, double aDeltaV); /*! @brief Calculate tcp using a normal distribution for alpha. */ long double calcTCPAlphaNormalDistribution(std::map aBEDDVH, BioModelParamType aRho, BioModelParamType aAlphaMean, BioModelParamType aAlphaVariance, double aDeltaV); protected: BioModelParamType _alphaMean{0}; BioModelParamType _alphaVariance{0}; BioModelParamType _alpha_beta{0}; /*! Roh is the initial clonogenic cell density */ BioModelParamType _rho{0}; /*! @brief Calculate the model value @param doseFactor scaling factor for prescribed dose. The model calculation will use the dvh with each di=old di*doseFactor. @pre _alphaMean >0 @pre _alphaVariance >= 0 @pre _alpha_beta > 0 @pre _rho > 0 @pre _numberOfFractions > 1 @exception InvalidParameterException Thrown if parameters were not set correctly. */ BioModelValueType calcModel(const double doseFactor = 1) override; public: TCPLQModel(); /*! @brief Constructor initializes member variables with given parameters. @pre aAlphaMean >0 @pre aBeta > 0 @pre aRho > 0 @pre aNumberOfFractions > 1 */ TCPLQModel(DVHPointer aDVH, BioModelParamType aAlphaMean, BioModelParamType aBeta, BioModelParamType aRho, int aNumberOfFractions); /*! @brief Constructor for alpha distribution initializes member variables with given parameters. @pre aAlphaMean >0 @pre aAlphaVariance >0 @pre aAlpha_Beta > 0 @pre aRho > 0 @pre aNumberOfFractions > 1 */ TCPLQModel(DVHPointer aDVH, BioModelParamType aRho, int aNumberOfFractions, BioModelParamType aAlpha_Beta, BioModelParamType aAlphaMean, BioModelParamType aAlphaVariance); const BioModelParamType getRho(); void setRho(const BioModelParamType aRho); const BioModelParamType getAlphaMean(); const BioModelParamType getAlphaVariance(); /*! @brief The distribution of the parameter alpha, which is characteristic for a population of cells, is described by the its mean and variance. If alpha is constant the variance is 0. @param aAlphaVariance The variance of alpha can be given, the default value is 0 resulting in constant alpha. */ void setAlpha(const BioModelParamType aAlphaMean, const BioModelParamType aAlphaVariance = 0); const BioModelParamType getAlphaBeta(); void setAlphaBeta(const BioModelParamType aAlpha_Beta); /*! @brief Set parameters for the TCP model. _value will be reset to 0. @param aAlpha_Beta alpha/beta constant . @param aAlphaMean mean of alpha distribution. @param aAlphaVariance variance of alpha distribution. */ void setParameters(const BioModelParamType aAlphaMean, const BioModelParamType aAlpha_Beta, const BioModelParamType aRho, const BioModelParamType aAlphaVariance = 0); /*! @brief Set parameter with ID. "alphaMean":0,"alphaVariance":1,"alpha_beta":2, "rho":3 @exception InvalidParameterException Thrown if aParamId is not 0 or 1 or 2 or 3. */ void setParameterByID(const int aParamId, const BioModelParamType aValue) override; /*! @brief Set parameter vector, where index of vector is the parameter id. "alphaMean":0,"alphaVariance":1,"alpha_beta":2, "rho":3 @exception InvalidParameterException Thrown if aParamterVector.size()!=4. */ void setParameterVector(const ParamVectorType& aParameterVector) override; /*! @brief Get parameter id. "alphaMean":0,"alphaVariance":1,"alpha_beta":2, "rho":3 @return 0 for "alphaMean", 1 for "alphaVariance", 2 for "alpha_beta", 3 for "rho" @exception InvalidParameterException Thrown if aParamName is not alphaMean or alphaVariance or alpha_beta or rho. */ const int getParameterID(const std::string& aParamName) const override; std::map getParameterMap() const override; void fillParameterMap() override; std::string getModelType() const override; }; }//end algorithms }//end rttb #endif diff --git a/code/models/rttbTCPModel.h b/code/models/rttbTCPModel.h index b2ba8b3..b82577d 100644 --- a/code/models/rttbTCPModel.h +++ b/code/models/rttbTCPModel.h @@ -1,63 +1,62 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __TCP_MODEL_H #define __TCP_MODEL_H #include "rttbBioModel.h" namespace rttb { namespace models { /*! @class TCPModel @brief This is the interface class for TCP(Tumor Control Probability) models */ class TCPModel: public BioModel { public: using ParamVectorType = BioModel::ParamVectorType; - using DVHPointer = BioModel::DVHPointer; protected: int _numberOfFractions{0}; public: TCPModel(): BioModel() {}; TCPModel(int aNum): BioModel(), _numberOfFractions(aNum) {}; - TCPModel(DVHPointer aDvh, int aNum): BioModel(aDvh), _numberOfFractions(aNum) {}; + TCPModel(core::DVH::Pointer aDvh, int aNum): BioModel(aDvh), _numberOfFractions(aNum) {}; void setNumberOfFractions(const int aNumberOfFractions); const int getNumberOfFractions(); }; }//end namespace models }//end namespace rttb #endif diff --git a/testing/algorithms/ArithmeticTest.cpp b/testing/algorithms/ArithmeticTest.cpp index 0329b65..763f6d2 100644 --- a/testing/algorithms/ArithmeticTest.cpp +++ b/testing/algorithms/ArithmeticTest.cpp @@ -1,358 +1,358 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "../core/DummyDoseAccessor.h" #include "../core/DummyMaskAccessor.h" #include "../core/DummyMutableDoseAccessor.h" #include "rttbDoseAccessorInterface.h" #include "rttbMutableDoseAccessorInterface.h" #include "rttbMutableMaskAccessorInterface.h" #include "rttbArithmetic.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "rttbGenericMutableMaskAccessor.h" #include "rttbMaskAccessorInterface.h" namespace rttb { namespace testing { - typedef core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; - typedef core::MutableDoseAccessorInterface::MutableDoseAccessorPointer MutableDoseAccessorPointer; + typedef core::DoseAccessorInterface::Pointer DoseAccessorPointer; + typedef core::MutableDoseAccessorInterface::Pointer MutableDoseAccessorPointer; typedef DummyMaskAccessor::MaskVoxelListPointer MaskVoxelListPointer; typedef DummyMaskAccessor::MaskVoxelList MaskVoxelList; - typedef core::MaskAccessorInterface::MaskAccessorPointer MaskAccessorPointer; - typedef core::MutableMaskAccessorInterface::MutableMaskAccessorPointer MutableMaskAccessorPointer; + typedef core::MaskAccessorInterface::Pointer MaskAccessorPointer; + typedef core::MutableMaskAccessorInterface::Pointer MutableMaskAccessorPointer; /*! @brief ArithmeticTest - tests arithmetic combinations of accessors 1) test dose-dose operations 2) test dose-mask operations 3) test mask-mask operations 4) test convenience functions */ int ArithmeticTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; // initialize accessors for arithmetic //DOSE: //Null pointers DoseAccessorPointer spDoseNull; MutableDoseAccessorPointer spMutableDoseNull; //dose with random values between 0 and 100 boost::shared_ptr spTestDoseAccessor1 = boost::make_shared(); DoseAccessorPointer spDoseAccessor1(spTestDoseAccessor1); //generate a 2nd dose with fixed values core::GeometricInfo geoInfo = spDoseAccessor1->getGeometricInfo(); DoseTypeGy valFix = 101; // to ensure values are larger than 100 on adding std::vector dose2Vals(geoInfo.getNumberOfVoxels(), valFix); boost::shared_ptr spTestDoseAccessor2 = boost::make_shared (dose2Vals, geoInfo); DoseAccessorPointer spDoseAccessor2(spTestDoseAccessor2); //generate result acessor std::vector doseResultVals(geoInfo.getNumberOfVoxels(), -1); boost::shared_ptr spTestMutableDoseAccessor = boost::make_shared(doseResultVals, geoInfo); MutableDoseAccessorPointer spMutableDoseAccessor(spTestMutableDoseAccessor); // different geometricInfo core::GeometricInfo geoInfo2 = geoInfo; geoInfo2.setNumColumns(5); geoInfo2.setNumRows(5); geoInfo2.setNumSlices(5); std::vector dose3Vals(geoInfo2.getNumberOfVoxels(), valFix); boost::shared_ptr spTestDoseAccessor3 = boost::make_shared (dose3Vals, geoInfo2); DoseAccessorPointer spDoseAccessorDiffGeoInfo(spTestDoseAccessor3); boost::shared_ptr spTestMutableDoseAccessor2 = boost::make_shared(dose3Vals, geoInfo2); MutableDoseAccessorPointer spMutableDoseAccessorDiffGeoInfo(spTestMutableDoseAccessor2); //MASK: //null pointer MaskAccessorPointer spMaskAccessorNull; MutableMaskAccessorPointer spMutableMaskAccessorNull; MaskVoxelList voxelList; FractionType aVolumeFraction = 1; VoxelGridID aVoxelGridID = 10; //generate a dummy mask while (aVoxelGridID < geoInfo.getNumberOfVoxels() && aVoxelGridID <= 30) { voxelList.push_back(core::MaskVoxel(aVoxelGridID, aVolumeFraction)); ++aVoxelGridID; } MaskVoxelListPointer voxelListPtr = boost::make_shared(voxelList); boost::shared_ptr dummyMask1 = boost::make_shared(geoInfo, voxelListPtr); MaskAccessorPointer spMaskAccessor1(dummyMask1); MaskVoxelList voxelList2; aVoxelGridID = 20; //generate a 2nd dummy mask that partly overlaps with the 1st one while (aVoxelGridID < geoInfo.getNumberOfVoxels() && aVoxelGridID <= 40) { voxelList2.push_back(core::MaskVoxel(aVoxelGridID, aVolumeFraction)); ++aVoxelGridID; } MaskVoxelListPointer voxelListPtr2 = boost::make_shared(voxelList2); boost::shared_ptr dummyMask2 = boost::make_shared(geoInfo, voxelListPtr2); MaskAccessorPointer spMaskAccessor2(dummyMask2); // result accessor boost::shared_ptr mMask1 = boost::make_shared(geoInfo); MutableMaskAccessorPointer spMutableMask(mMask1); // different geometricInfo boost::shared_ptr spDummyMaskDiffGeoInfo = boost::make_shared (geoInfo2, voxelListPtr2); MaskAccessorPointer spMaskAccessorDiffGeoInfo(spDummyMaskDiffGeoInfo); boost::shared_ptr mMask2 = boost::make_shared(geoInfo2); MutableMaskAccessorPointer spMutableMaskDiffGeoInfo(mMask2); // 1) test dose-dose operations //ADD algorithms::arithmetic::doseOp::Add addOP; CHECK_NO_THROW(algorithms::arithmetic::arithmetic(spDoseAccessor1, spDoseAccessor2, spMutableDoseAccessor, addOP)); VoxelGridID id = 5; CHECK(spMutableDoseAccessor->getValueAt(id) > 100); CHECK_EQUAL(spDoseAccessor1->getValueAt(id) + valFix, spMutableDoseAccessor->getValueAt(id)); id = 10; CHECK(spMutableDoseAccessor->getValueAt(id) > 100); CHECK_EQUAL(spDoseAccessor1->getValueAt(id) + valFix, spMutableDoseAccessor->getValueAt(id)); //handling exceptions is tested once for dose-dose operations, because this does not change if the operation changes. //handling null pointers CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor1, spDoseNull, spMutableDoseAccessor, addOP), core::NullPointerException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseNull, spDoseAccessor2, spMutableDoseAccessor, addOP), core::NullPointerException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor1, spDoseAccessor2, spMutableDoseNull, addOP), core::NullPointerException); //handle different geometricInfos CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor1, spDoseAccessorDiffGeoInfo, spMutableDoseAccessor, addOP), core::InvalidParameterException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessorDiffGeoInfo, spDoseAccessor2, spMutableDoseAccessor, addOP), core::InvalidParameterException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor1, spDoseAccessor2, spMutableDoseAccessorDiffGeoInfo, addOP), core::InvalidParameterException); //ADD_WEIGHTED algorithms::arithmetic::doseOp::AddWeighted addWOP(1, 2); CHECK_NO_THROW(algorithms::arithmetic::arithmetic(spDoseAccessor1, spDoseAccessor2, spMutableDoseAccessor, addWOP)); id = 5; CHECK(spMutableDoseAccessor->getValueAt(id) > 201); CHECK_EQUAL(spDoseAccessor1->getValueAt(id) + 2 * valFix, spMutableDoseAccessor->getValueAt(id)); id = 10; CHECK(spMutableDoseAccessor->getValueAt(id) > 201); CHECK_EQUAL(spDoseAccessor1->getValueAt(id) + 2 * valFix, spMutableDoseAccessor->getValueAt(id)); //MULTIPLY algorithms::arithmetic::doseOp::Multiply multiplyOP; CHECK_NO_THROW(algorithms::arithmetic::arithmetic(spDoseAccessor1, spDoseAccessor2, spMutableDoseAccessor, multiplyOP)); id = 5; CHECK(spMutableDoseAccessor->getValueAt(id) > 201); CHECK_EQUAL(spDoseAccessor1->getValueAt(id) * valFix, spMutableDoseAccessor->getValueAt(id)); id = 10; CHECK(spMutableDoseAccessor->getValueAt(id) > 201); CHECK_EQUAL(spDoseAccessor1->getValueAt(id) * valFix, spMutableDoseAccessor->getValueAt(id)); // 2) test dose-mask operations //MULTIPLY algorithms::arithmetic::doseMaskOp::Multiply multOP; CHECK_NO_THROW(algorithms::arithmetic::arithmetic(spDoseAccessor2, spMaskAccessor1, spMutableDoseAccessor, multOP)); core::MaskVoxel mVoxel(0); id = 5; CHECK_EQUAL(0, spMutableDoseAccessor->getValueAt(id)); spMaskAccessor1->getMaskAt(id, mVoxel); CHECK_EQUAL(spMutableDoseAccessor->getValueAt(id), mVoxel.getRelevantVolumeFraction()); id = 15; CHECK_EQUAL(valFix, spMutableDoseAccessor->getValueAt(id)); id = 35; CHECK_EQUAL(0, spMutableDoseAccessor->getValueAt(id)); //handling exceptions is tested once for dose-dose operations, because this does not change if the operation changes. //handling null pointers CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor1, spMaskAccessorNull, spMutableDoseAccessor, multOP), core::NullPointerException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseNull, spDoseAccessor2, spMutableDoseAccessor, multOP), core::NullPointerException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor2, spMaskAccessor1, spMutableDoseNull, multOP), core::NullPointerException); //handle different geometricInfos CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor2, spMaskAccessorDiffGeoInfo, spMutableDoseAccessor, multOP), core::InvalidParameterException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessorDiffGeoInfo, spMaskAccessor1, spMutableDoseAccessor, multOP), core::InvalidParameterException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spDoseAccessor2, spMaskAccessor1, spMutableDoseAccessorDiffGeoInfo, multOP), core::InvalidParameterException); // 3) test mask-mask operations //ADD algorithms::arithmetic::maskOp::Add maskAddOP; CHECK_NO_THROW(algorithms::arithmetic::arithmetic(spMaskAccessor1, spMaskAccessor2, spMutableMask, maskAddOP)); id = 5; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); id = 15; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(1, mVoxel.getRelevantVolumeFraction()); id = 35; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(1, mVoxel.getRelevantVolumeFraction()); id = 45; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); //handling exceptions is tested once for dose-dose operations, because this does not change if the operation changes. //handling null pointers CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spMaskAccessor1, spMaskAccessorNull, spMutableMask, maskAddOP), core::NullPointerException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spMaskAccessorNull, spMaskAccessor2, spMutableMask, maskAddOP), core::NullPointerException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spMaskAccessor1, spMaskAccessor1, spMutableMaskAccessorNull, maskAddOP), core::NullPointerException); //handle different geometricInfos CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spMaskAccessor1, spMaskAccessorDiffGeoInfo, spMutableMask, maskAddOP), core::InvalidParameterException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spMaskAccessorDiffGeoInfo, spMaskAccessor2, spMutableMask, maskAddOP), core::InvalidParameterException); CHECK_THROW_EXPLICIT(algorithms::arithmetic::arithmetic(spMaskAccessor1, spMaskAccessor1, spMutableMaskDiffGeoInfo, maskAddOP), core::InvalidParameterException); //SUBTRACT algorithms::arithmetic::maskOp::Subtract maskSubOP; CHECK_NO_THROW(algorithms::arithmetic::arithmetic(spMaskAccessor1, spMaskAccessor2, spMutableMask, maskSubOP)); id = 5; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); id = 15; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(1, mVoxel.getRelevantVolumeFraction()); id = 35; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); id = 45; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); // 4) test convenience functions // tests are similar to explicit calls CHECK_NO_THROW(algorithms::arithmetic::add(spDoseAccessor1, spDoseAccessor2, spMutableDoseAccessor)); id = 5; CHECK(spMutableDoseAccessor->getValueAt(id) > 100); CHECK_EQUAL(spDoseAccessor1->getValueAt(id) + valFix, spMutableDoseAccessor->getValueAt(id)); id = 10; CHECK(spMutableDoseAccessor->getValueAt(id) > 100); CHECK_EQUAL(spDoseAccessor1->getValueAt(id) + valFix, spMutableDoseAccessor->getValueAt(id)); CHECK_NO_THROW(algorithms::arithmetic::add(spMaskAccessor1, spMaskAccessor2, spMutableMask)); id = 5; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); id = 15; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(1, mVoxel.getRelevantVolumeFraction()); id = 35; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(1, mVoxel.getRelevantVolumeFraction()); id = 45; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); CHECK_NO_THROW(algorithms::arithmetic::subtract(spMaskAccessor1, spMaskAccessor2, spMutableMask)); id = 5; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); id = 15; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(1, mVoxel.getRelevantVolumeFraction()); id = 35; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); id = 45; spMutableMask->getMaskAt(id, mVoxel); CHECK_EQUAL(0, mVoxel.getRelevantVolumeFraction()); CHECK_NO_THROW(algorithms::arithmetic::multiply(spDoseAccessor2, spMaskAccessor1, spMutableDoseAccessor)); id = 5; CHECK_EQUAL(0, spMutableDoseAccessor->getValueAt(id)); spMaskAccessor1->getMaskAt(id, mVoxel); CHECK_EQUAL(spMutableDoseAccessor->getValueAt(id), mVoxel.getRelevantVolumeFraction()); id = 15; CHECK_EQUAL(valFix, spMutableDoseAccessor->getValueAt(id)); id = 35; CHECK_EQUAL(0, spMutableDoseAccessor->getValueAt(id)); RETURN_AND_REPORT_TEST_SUCCESS; } } } \ No newline at end of file diff --git a/testing/algorithms/BinaryFunctorAccessorTest.cpp b/testing/algorithms/BinaryFunctorAccessorTest.cpp index 8abb4d9..8aea246 100644 --- a/testing/algorithms/BinaryFunctorAccessorTest.cpp +++ b/testing/algorithms/BinaryFunctorAccessorTest.cpp @@ -1,131 +1,131 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbDoseAccessorInterface.h" #include "rttbDicomDoseAccessor.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbArithmetic.h" #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "rttbBinaryFunctorAccessor.h" namespace rttb { namespace testing { - typedef core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; + typedef core::DoseAccessorInterface::Pointer DoseAccessorPointer; typedef algorithms::BinaryFunctorAccessor BinaryFunctorAccessorAddType; typedef algorithms::BinaryFunctorAccessor BinaryFunctorAccessorAddWeightedType; /*! @brief BinaryFunctorAccessorTest - tests functors of two accessors 1) test constructor 2) test getDoseAt */ int BinaryFunctorAccessorTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; std::string RTDOSE_FILENAME; std::string RTDOSE2_FILENAME; if (argc > 1) { RTDOSE_FILENAME = argv[1]; } if (argc > 2) { RTDOSE2_FILENAME = argv[2]; } DoseAccessorPointer spDoseAccessorNull; DoseAccessorPointer spDoseAccessor = io::dicom::DicomFileDoseAccessorGenerator( RTDOSE_FILENAME.c_str()).generateDoseAccessor(); DoseAccessorPointer spDoseAccessor2 = io::dicom::DicomFileDoseAccessorGenerator( RTDOSE2_FILENAME.c_str()).generateDoseAccessor(); algorithms::arithmetic::doseOp::Add addOP; algorithms::arithmetic::doseOp::AddWeighted addWeightedOP(1.0, 10.0); algorithms::arithmetic::doseOp::AddWeighted addWeightedTwoOP(2.0, 2.0); //1) Check constructor CHECK_THROW_EXPLICIT(BinaryFunctorAccessorAddType(spDoseAccessorNull, spDoseAccessor, addOP), core::NullPointerException); CHECK_THROW_EXPLICIT(BinaryFunctorAccessorAddType(spDoseAccessor, spDoseAccessorNull, addOP), core::NullPointerException); CHECK_THROW_EXPLICIT(BinaryFunctorAccessorAddType(spDoseAccessorNull, spDoseAccessorNull, addOP), core::NullPointerException); CHECK_THROW_EXPLICIT(BinaryFunctorAccessorAddType(spDoseAccessor, spDoseAccessor2, addOP), core::InvalidParameterException); CHECK_NO_THROW(BinaryFunctorAccessorAddType(spDoseAccessor, spDoseAccessor, addOP)); CHECK_NO_THROW(BinaryFunctorAccessorAddWeightedType(spDoseAccessor, spDoseAccessor, addWeightedOP)); auto spBinaryFunctorDoseAccessorAdd = boost::make_shared(spDoseAccessor, spDoseAccessor, addOP); auto spBinaryFunctorDoseAccessorAddWeighted = boost::make_shared(spDoseAccessor, spDoseAccessor, addWeightedOP); auto spBinaryFunctorDoseAccessorAddWeightedTwo = boost::make_shared(spDoseAccessor, spDoseAccessor, addWeightedTwoOP); //2) Test getDoseAt() int lastIndex = spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumberOfVoxels() - 1; VoxelGridID aId[3] = { 5, 6067, lastIndex }; VoxelGridIndex3D aIndex[3] = {VoxelGridIndex3D(5, 0, 0), VoxelGridIndex3D(37, 0, 2), VoxelGridIndex3D(spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumColumns() - 1, spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumRows() - 1, spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumSlices() - 1)}; for (int i = 0; i < 3; ++i) { CHECK_EQUAL(spBinaryFunctorDoseAccessorAdd->getValueAt(aId[i]), 4.0); CHECK_EQUAL(spBinaryFunctorDoseAccessorAddWeighted->getValueAt(aId[i]), 22.0); CHECK_EQUAL(spBinaryFunctorDoseAccessorAdd->getValueAt(aIndex[i]), spBinaryFunctorDoseAccessorAdd->getValueAt(aId[i])); CHECK_EQUAL(spBinaryFunctorDoseAccessorAddWeighted->getValueAt(aIndex[i]), spBinaryFunctorDoseAccessorAddWeighted->getValueAt(aId[i])); CHECK_EQUAL(spBinaryFunctorDoseAccessorAdd->getValueAt(aId[i]) * 2.0, spBinaryFunctorDoseAccessorAddWeightedTwo->getValueAt(aId[i])); } VoxelGridID aIdInvalid(spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumberOfVoxels()); VoxelGridIndex3D aIndexInvalid(spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumColumns(), spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumRows(), spBinaryFunctorDoseAccessorAdd->getGeometricInfo().getNumSlices()); CHECK_EQUAL(spBinaryFunctorDoseAccessorAdd->getValueAt(aIdInvalid), -1.0); CHECK_EQUAL(spBinaryFunctorDoseAccessorAdd->getValueAt(aIndexInvalid), -1.0); CHECK_EQUAL(spBinaryFunctorDoseAccessorAddWeighted->getValueAt(aIdInvalid), -1.0); CHECK_EQUAL(spBinaryFunctorDoseAccessorAddWeighted->getValueAt(aIndexInvalid), -1.0); RETURN_AND_REPORT_TEST_SUCCESS; } } } \ No newline at end of file diff --git a/testing/algorithms/DoseStatisticsCalculatorTest.cpp b/testing/algorithms/DoseStatisticsCalculatorTest.cpp index e8d3627..cfb6c49 100644 --- a/testing/algorithms/DoseStatisticsCalculatorTest.cpp +++ b/testing/algorithms/DoseStatisticsCalculatorTest.cpp @@ -1,391 +1,391 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbGenericDoseIterator.h" #include "rttbDoseIteratorInterface.h" #include "rttbNullPointerException.h" #include "rttbDoseStatisticsCalculator.h" #include "rttbInvalidDoseException.h" #include "rttbInvalidParameterException.h" #include "rttbDataNotAvailableException.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomFileStructureSetGenerator.h" #include "rttbBoostMaskAccessor.h" #include "rttbGenericMaskedDoseIterator.h" #include "../io/other/CompareDoseStatistic.h" #include "../../code/io/other/rttbDoseStatisticsXMLReader.h" #include "../core/DummyDoseAccessor.h" namespace rttb { namespace testing { typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; - typedef core::DoseIteratorInterface::DoseIteratorPointer DoseIteratorPointer; + typedef core::DoseIteratorInterface::Pointer DoseIteratorPointer; typedef rttb::algorithms::DoseStatistics::ResultListPointer ResultListPointer; - typedef rttb::algorithms::DoseStatistics::DoseStatisticsPointer DoseStatisticsPointer; + typedef rttb::algorithms::DoseStatistics::Pointer DoseStatisticsPointer; /*! @brief DoseStatisticsCalculatorTest - test the API of DoseStatisticsCalculator 1) test constructors 2) test setDoseIterator 3) test calculateDoseSatistics 4) get statistical values */ int DoseStatisticsCalculatorTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; std::string referenceXMLFilename; std::string doseFilename, structFilename; boost::shared_ptr spTestDoseAccessor = boost::make_shared(); DoseAccessorPointer spDoseAccessor(spTestDoseAccessor); const std::vector* doseVals = spTestDoseAccessor->getDoseVector(); boost::shared_ptr spTestDoseIterator = boost::make_shared(spDoseAccessor); DoseIteratorPointer spDoseIterator(spTestDoseIterator); DoseIteratorPointer spDoseIteratorNull; if (argc > 3) { referenceXMLFilename = argv[1]; doseFilename = argv[2]; structFilename = argv[3]; } //1) test constructors // the values cannot be accessed from outside, therefore correct default values are not tested CHECK_THROW_EXPLICIT(rttb::algorithms::DoseStatisticsCalculator myDoseStatsCalculator( spDoseIteratorNull), core::NullPointerException); CHECK_NO_THROW(rttb::algorithms::DoseStatisticsCalculator myDoseStatsCalculator(spDoseIterator)); rttb::algorithms::DoseStatisticsCalculator myDoseStatsCalculator(spDoseIterator); //2) test setDoseIterator //3) test calculateDoseStatistics DoseStatisticsPointer theStatistics; //simple dose statistics CHECK_NO_THROW(theStatistics = myDoseStatsCalculator.calculateDoseStatistics()); CHECK_EQUAL(theStatistics->getMinimumVoxelPositions()->empty(), false); CHECK_EQUAL(theStatistics->getMaximumVoxelPositions()->empty(), false); CHECK_EQUAL(theStatistics->getVx().getAllValues().empty(), true); CHECK_EQUAL(theStatistics->getDx().getAllValues().empty(), true); CHECK_EQUAL(theStatistics->getVx().getAllValues().empty(), true); CHECK_EQUAL(theStatistics->getMaxOHx().getAllValues().empty(), true); CHECK_EQUAL(theStatistics->getMOHx().getAllValues().empty(), true); CHECK_EQUAL(theStatistics->getMOCx().getAllValues().empty(), true); CHECK_EQUAL(theStatistics->getMinOCx().getAllValues().empty(), true); //check default values for computeComplexMeasures=true DoseStatisticsPointer theStatisticsDefault; myDoseStatsCalculator.setMultiThreading(true); CHECK_NO_THROW(theStatisticsDefault = myDoseStatsCalculator.calculateDoseStatistics(true)); CHECK_NO_THROW(theStatisticsDefault->getVx().getValue(0.02 * theStatisticsDefault->getMaximum())); CHECK_NO_THROW(theStatisticsDefault->getVx().getValue(0.05 * theStatisticsDefault->getMaximum())); CHECK_NO_THROW(theStatisticsDefault->getVx().getValue(0.1 * theStatisticsDefault->getMaximum())); CHECK_NO_THROW(theStatisticsDefault->getVx().getValue(0.9 * theStatisticsDefault->getMaximum())); CHECK_NO_THROW(theStatisticsDefault->getVx().getValue(0.95 * theStatisticsDefault->getMaximum())); CHECK_NO_THROW(theStatisticsDefault->getVx().getValue(0.98 * theStatisticsDefault->getMaximum())); CHECK_NO_THROW(theStatisticsDefault->getDx().getValue(0.02 * theStatisticsDefault->getVolume())); CHECK_NO_THROW(theStatisticsDefault->getDx().getValue(0.05 * theStatisticsDefault->getVolume())); CHECK_NO_THROW(theStatisticsDefault->getDx().getValue(0.1 * theStatisticsDefault->getVolume())); CHECK_NO_THROW(theStatisticsDefault->getDx().getValue(0.9 * theStatisticsDefault->getVolume())); CHECK_NO_THROW(theStatisticsDefault->getDx().getValue(0.95 * theStatisticsDefault->getVolume())); CHECK_NO_THROW(theStatisticsDefault->getDx().getValue(0.98 * theStatisticsDefault->getVolume())); //check manually set reference dose and the default x values CHECK_NO_THROW(theStatistics = myDoseStatsCalculator.calculateDoseStatistics(100.0)); CHECK_THROW_EXPLICIT(theStatistics->getVx().getValue(0.1 * theStatistics->getMaximum()), core::DataNotAvailableException); CHECK_NO_THROW(theStatistics->getVx().getValue(0.1 * 100.0)); CHECK_NO_THROW(theStatistics->getDx().getValue(0.1 * theStatistics->getVolume())); CHECK_NO_THROW(theStatistics->getDx().getValue(0.9 * theStatistics->getVolume())); CHECK_NO_THROW(theStatistics->getMOHx().getValue(0.95 * theStatistics->getVolume())); CHECK_NO_THROW(theStatistics->getMOCx().getValue(0.98 * theStatistics->getVolume())); CHECK_EQUAL(theStatistics->getReferenceDose(), 100.0); //check manually set x values std::vector precomputeDoseValues, precomputeVolumeValues, additionalValues, faultyValues; precomputeDoseValues.push_back(0.01); precomputeDoseValues.push_back(0.02); precomputeDoseValues.push_back(0.05); precomputeVolumeValues.push_back(0.9); precomputeVolumeValues.push_back(0.95); precomputeVolumeValues.push_back(0.99); additionalValues.push_back(0.03); additionalValues.push_back(0.04); faultyValues.push_back(2); CHECK_THROW_EXPLICIT(theStatistics = myDoseStatsCalculator.calculateDoseStatistics(precomputeDoseValues, faultyValues), core::InvalidParameterException); CHECK_THROW_EXPLICIT(theStatistics = myDoseStatsCalculator.calculateDoseStatistics(faultyValues, precomputeVolumeValues), core::InvalidParameterException); CHECK_NO_THROW(theStatistics = myDoseStatsCalculator.calculateDoseStatistics(precomputeDoseValues, precomputeVolumeValues)); CHECK_NO_THROW(theStatistics->getVx().getValue(0.01 * theStatistics->getMaximum())); CHECK_NO_THROW(theStatistics->getVx().getValue(0.02 * theStatistics->getMaximum())); CHECK_NO_THROW(theStatistics->getVx().getValue(0.05 * theStatistics->getMaximum())); CHECK_THROW_EXPLICIT(theStatistics->getVx().getValue(0.03 * theStatistics->getMaximum()), core::DataNotAvailableException); CHECK_NO_THROW(theStatistics->getDx().getValue(0.9 * theStatistics->getVolume())); CHECK_NO_THROW(theStatistics->getDx().getValue(0.95 * theStatistics->getVolume())); CHECK_NO_THROW(theStatistics->getDx().getValue(0.99 * theStatistics->getVolume())); CHECK_THROW_EXPLICIT(theStatistics->getDx().getValue(0.04 * theStatistics->getVolume()), core::DataNotAvailableException); CHECK_THROW_EXPLICIT(myDoseStatsCalculator.addPrecomputeValues(faultyValues), core::InvalidParameterException); CHECK_NO_THROW(myDoseStatsCalculator.addPrecomputeValues(additionalValues)); CHECK_NO_THROW(myDoseStatsCalculator.recalculateDoseStatistics()); CHECK_NO_THROW(theStatistics->getVx().getValue(0.03 * theStatistics->getMaximum())); CHECK_NO_THROW(theStatistics->getDx().getValue(0.04 * theStatistics->getVolume())); CHECK_EQUAL(theStatistics->getVx().getValue(0.02 * theStatistics->getMaximum()), theStatisticsDefault->getVx().getValue(0.02 * theStatistics->getMaximum())); CHECK_EQUAL(theStatistics->getVx().getValue(0.05 * theStatistics->getMaximum()), theStatisticsDefault->getVx().getValue(0.05 * theStatistics->getMaximum())); CHECK_EQUAL(theStatistics->getDx().getValue(0.9 * theStatistics->getVolume()), theStatisticsDefault->getDx().getValue(0.9 * theStatistics->getVolume())); CHECK_EQUAL(theStatistics->getDx().getValue(0.95 * theStatistics->getVolume()), theStatisticsDefault->getDx().getValue(0.95 * theStatistics->getVolume())); //check manually set reference dose and x values CHECK_NO_THROW(theStatistics = myDoseStatsCalculator.calculateDoseStatistics(precomputeDoseValues, precomputeVolumeValues, 100.0)); CHECK_THROW_EXPLICIT(theStatistics->getVx().getValue(0.01 * theStatistics->getMaximum()), core::DataNotAvailableException); CHECK_NO_THROW(theStatistics->getVx().getValue(0.01 * 100.0)); CHECK_NO_THROW(theStatistics->getDx().getValue(0.9 * theStatistics->getVolume())); CHECK_EQUAL(theStatistics->getReferenceDose(), 100.0); //MOHx, MOCx, MaxOHx and MinOCx are computed analogous to Dx, they will not be checked. //4) get statistical values CHECK_EQUAL(theStatistics->getNumberOfVoxels(), doseVals->size()); //compute simple statistical values (min, mean, max, stddev) for comparison DoseStatisticType maximum = 0; DoseStatisticType minimum = 1000000; DoseStatisticType mean = 0; DoseStatisticType variance = 0; std::vector::const_iterator doseIt = doseVals->begin(); while (doseIt != doseVals->end()) { if (maximum < *doseIt) { maximum = *doseIt; } if (minimum > *doseIt) { minimum = *doseIt; } mean += *doseIt; ++doseIt; } mean /= doseVals->size(); doseIt = doseVals->begin(); while (doseIt != doseVals->end()) { variance += pow(*doseIt - mean, 2); ++doseIt; } variance /= doseVals->size(); DoseStatisticType stdDev = pow(variance, 0.5); //we have some precision problems here... double errorConstantLarger = 1e-2; CHECK_EQUAL(theStatistics->getMaximum(), maximum); CHECK_EQUAL(theStatistics->getMinimum(), minimum); CHECK_CLOSE(theStatistics->getMean(), mean, errorConstantLarger); CHECK_CLOSE(theStatistics->getStdDeviation(), stdDev, errorConstantLarger); CHECK_CLOSE(theStatistics->getVariance(), variance, errorConstantLarger); //check for complex doseStatistics (maximumPositions, minimumPositions, Vx, Dx, MOHx, MOCx, MAXOHx, MinOCx) unsigned int nMax = 0, nMin = 0; doseIt = doseVals->begin(); while (doseIt != doseVals->end()) { if (*doseIt == theStatistics->getMaximum()) { nMax++; } if (*doseIt == theStatistics->getMinimum()) { nMin++; } ++doseIt; } //only 100 positions are stored if (nMax > 100) { nMax = 100; } if (nMin > 100) { nMin = 100; } auto maximaPositions = theStatistics->getMaximumVoxelPositions(); auto minimaPositions = theStatistics->getMinimumVoxelPositions(); CHECK_EQUAL(maximaPositions->size(), nMax); CHECK_EQUAL(minimaPositions->size(), nMin); for (auto maximaPositionsIterator = std::begin(*maximaPositions); maximaPositionsIterator != std::end(*maximaPositions); ++maximaPositionsIterator) { CHECK_EQUAL(maximaPositionsIterator->first, theStatistics->getMaximum()); } for (auto minimaPositionsIterator = std::begin(*minimaPositions); minimaPositionsIterator != std::end(*minimaPositions); ++minimaPositionsIterator) { CHECK_EQUAL(minimaPositionsIterator->first, theStatistics->getMinimum()); } //generate specific example dose maximum = 9.5; minimum = 2.5; mean = 6; int sizeTemplate = 500; std::vector aDoseVector; for (int i = 0; i < sizeTemplate; i++) { aDoseVector.push_back(maximum); aDoseVector.push_back(minimum); } core::GeometricInfo geoInfo = spTestDoseAccessor->getGeometricInfo(); geoInfo.setNumRows(20); geoInfo.setNumColumns(10); geoInfo.setNumSlices(5); boost::shared_ptr spTestDoseAccessor2 = boost::make_shared(aDoseVector, geoInfo); DoseAccessorPointer spDoseAccessor2(spTestDoseAccessor2); boost::shared_ptr spTestDoseIterator2 = boost::make_shared(spDoseAccessor2); DoseIteratorPointer spDoseIterator2(spTestDoseIterator2); rttb::algorithms::DoseStatisticsCalculator myDoseStatsCalculator2(spDoseIterator2); DoseStatisticsPointer theStatistics3 = myDoseStatsCalculator2.calculateDoseStatistics(); CHECK_EQUAL(theStatistics3->getMaximum(), maximum); CHECK_EQUAL(theStatistics3->getMinimum(), minimum); CHECK_EQUAL(theStatistics3->getMean(), mean); maximaPositions = theStatistics3->getMaximumVoxelPositions(); minimaPositions = theStatistics3->getMinimumVoxelPositions(); CHECK_EQUAL(maximaPositions->empty(), false); CHECK_EQUAL(minimaPositions->empty(), false); for (auto maximaPositionsIterator = std::begin(*maximaPositions); maximaPositionsIterator != std::end(*maximaPositions); ++maximaPositionsIterator) { CHECK_EQUAL(maximaPositionsIterator->first, theStatistics3->getMaximum()); } for (auto minimaPositionsIterator = std::begin(*minimaPositions); minimaPositionsIterator != std::end(*minimaPositions); ++minimaPositionsIterator) { CHECK_EQUAL(minimaPositionsIterator->first, theStatistics3->getMinimum()); } // compare with actual XML io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator(doseFilename.c_str()); - core::DoseAccessorInterface::DoseAccessorPointer doseAccessorPointer(doseAccessorGenerator.generateDoseAccessor()); + core::DoseAccessorInterface::Pointer doseAccessorPointer(doseAccessorGenerator.generateDoseAccessor()); rttb::io::dicom::DicomFileStructureSetGenerator structAccessorGenerator(structFilename.c_str()); structAccessorGenerator.setStructureLabelFilterActive(true); structAccessorGenerator.setFilterRegEx("Heart"); - core::StructureSetGeneratorInterface::StructureSetPointer structureSetGeneratorPointer = structAccessorGenerator.generateStructureSet(); + core::StructureSet::Pointer structureSetGeneratorPointer = structAccessorGenerator.generateStructureSet(); CHECK_EQUAL(structureSetGeneratorPointer->getNumberOfStructures(), 1); - core::MaskAccessorInterface::MaskAccessorPointer maskAccessorPointer = boost::make_shared + core::MaskAccessorInterface::Pointer maskAccessorPointer = boost::make_shared (structureSetGeneratorPointer->getStructure(0), doseAccessorPointer->getGeometricInfo(), true); maskAccessorPointer->updateMask(); boost::shared_ptr maskedDoseIterator = boost::make_shared(maskAccessorPointer, doseAccessorPointer); - rttb::core::DoseIteratorInterface::DoseIteratorPointer doseIteratorPointer(maskedDoseIterator); + rttb::core::DoseIteratorInterface::Pointer doseIteratorPointer(maskedDoseIterator); rttb::algorithms::DoseStatisticsCalculator doseStatisticsCalculator(doseIteratorPointer); DoseStatisticsPointer doseStatisticsActual = doseStatisticsCalculator.calculateDoseStatistics(14.0); io::other::DoseStatisticsXMLReader readerDefaultExpected(referenceXMLFilename); auto doseStatisticsExpected = readerDefaultExpected.generateDoseStatistic(); CHECK(checkEqualDoseStatistic(doseStatisticsExpected, doseStatisticsActual)); RETURN_AND_REPORT_TEST_SUCCESS; } }//end namespace testing }//end namespace rttb diff --git a/testing/apps/DoseTool/DoseToolDicomDoseTest.cpp b/testing/apps/DoseTool/DoseToolDicomDoseTest.cpp index 19e2a17..1ec561d 100644 --- a/testing/apps/DoseTool/DoseToolDicomDoseTest.cpp +++ b/testing/apps/DoseTool/DoseToolDicomDoseTest.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. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1221 $ (last changed revision) // @date $Date: 2015-12-01 13:43:31 +0100 (Di, 01 Dez 2015) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "rttbDoseStatisticsXMLReader.h" #include "rttbDVHXMLFileReader.h" #include "../../io/other/CompareDoseStatistic.h" #include "../../io/other/CompareDVH.h" #include "litCheckMacros.h" #include "boost/filesystem.hpp" namespace rttb { namespace testing { //path to the current running directory. DoseTool is in the same directory (Debug/Release) extern const char* _callingAppPath; int DoseToolDicomDoseTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; std::string doseToolExecutable; std::string doseFilename; std::string structFilename; std::string structName; std::string referenceXMLFilename; std::string referenceDVHXMLFilename; std::string referenceXMLComplexFilename; boost::filesystem::path callingPath(_callingAppPath); if (argc > 7) { doseToolExecutable = argv[1]; doseFilename = argv[2]; structFilename = argv[3]; structName = argv[4]; referenceXMLFilename = argv[5]; referenceDVHXMLFilename = argv[6]; referenceXMLComplexFilename = argv[7]; } std::string doseToolExeWithPath = callingPath.parent_path().string() + "/" + doseToolExecutable; std::string defaultOutputFilename = "dicomDoseOutput.xml"; std::string defaultDVHOutputFilename = "dicomDoseDVHOutput.xml"; std::string complexOutputFilename = "dicomDoseOutputComplex.xml"; std::string baseCommand = doseToolExeWithPath; baseCommand += " -d \"" + doseFilename + "\""; baseCommand += " -s \"" + structFilename + "\""; if (structName != "") { baseCommand += " -n " + structName; } else { baseCommand += " -u itk "; } std::string defaultDoseStatisticsCommand = baseCommand + " -y " + defaultOutputFilename; std::cout << "Command line call: " + defaultDoseStatisticsCommand << std::endl; CHECK_EQUAL(system(defaultDoseStatisticsCommand.c_str()), 0); std::string defaultDoseStatisticsAndDVHCommand = defaultDoseStatisticsCommand + " -z " + defaultDVHOutputFilename; std::cout << "Command line call: " + defaultDoseStatisticsAndDVHCommand << std::endl; CHECK_EQUAL(system(defaultDoseStatisticsAndDVHCommand.c_str()), 0); std::string complexDoseStatisticsCommand = baseCommand + " -y " + complexOutputFilename; //prescribed dose is 14 Gy complexDoseStatisticsCommand += " -f -p 14"; std::cout << "Command line call: " + complexDoseStatisticsCommand << std::endl; CHECK_EQUAL(system(complexDoseStatisticsCommand.c_str()), 0); //check if file exists CHECK_EQUAL(boost::filesystem::exists(defaultOutputFilename), true); CHECK_EQUAL(boost::filesystem::exists(complexOutputFilename), true); CHECK_EQUAL(boost::filesystem::exists(defaultDVHOutputFilename), true); //check if file has dose statistics that are same than these in than reference file io::other::DoseStatisticsXMLReader readerDefaultExpected(referenceXMLFilename); auto doseStatisticsDefaultExpected = readerDefaultExpected.generateDoseStatistic(); io::other::DoseStatisticsXMLReader readerDefaultActual(defaultOutputFilename); auto doseStatisticsDefaultActual = readerDefaultActual.generateDoseStatistic(); CHECK(checkEqualDoseStatistic(doseStatisticsDefaultExpected, doseStatisticsDefaultActual)); io::other::DoseStatisticsXMLReader readerComplexExpected(complexOutputFilename); auto doseStatisticsComplexExpected = readerComplexExpected.generateDoseStatistic(); io::other::DoseStatisticsXMLReader readerComplexActual(referenceXMLComplexFilename); auto doseStatisticsComplexActual = readerComplexActual.generateDoseStatistic(); CHECK(checkEqualDoseStatistic(doseStatisticsComplexExpected, doseStatisticsComplexActual)); //check DVH files io::other::DVHXMLFileReader xmlDVHDefaultReaderActual(defaultDVHOutputFilename); - DVHPointer defaultDVHActual = xmlDVHDefaultReaderActual.generateDVH(); + core::DVH::Pointer defaultDVHActual = xmlDVHDefaultReaderActual.generateDVH(); io::other::DVHXMLFileReader xmlDVHDefaultReaderExpected(referenceDVHXMLFilename); - DVHPointer defaultDVHExpected = xmlDVHDefaultReaderExpected.generateDVH(); + core::DVH::Pointer defaultDVHExpected = xmlDVHDefaultReaderExpected.generateDVH(); CHECK(checkEqualDVH(defaultDVHActual, defaultDVHExpected)); //delete file again CHECK_EQUAL(std::remove(defaultOutputFilename.c_str()), 0); CHECK_EQUAL(std::remove(defaultDVHOutputFilename.c_str()), 0); CHECK_EQUAL(std::remove(complexOutputFilename.c_str()), 0); RETURN_AND_REPORT_TEST_SUCCESS; } } //namespace testing } //namespace rttb diff --git a/testing/core/DVHCalculatorTest.cpp b/testing/core/DVHCalculatorTest.cpp index 917e18e..eb782e3 100644 --- a/testing/core/DVHCalculatorTest.cpp +++ b/testing/core/DVHCalculatorTest.cpp @@ -1,154 +1,154 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbDVHCalculator.h" #include "rttbGenericMaskedDoseIterator.h" #include "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[]) { 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::DVHCalculator::DVHPointer dvh; + 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/StrVectorStructureSetGeneratorTest.cpp b/testing/core/StrVectorStructureSetGeneratorTest.cpp index d15c611..0eb0622 100644 --- a/testing/core/StrVectorStructureSetGeneratorTest.cpp +++ b/testing/core/StrVectorStructureSetGeneratorTest.cpp @@ -1,95 +1,95 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbStrVectorStructureSetGenerator.h" #include "DummyStructure.h" #include "DummyDoseAccessor.h" #include "rttbInvalidParameterException.h" #include "rttbStructure.h" namespace rttb { namespace testing { /*! @brief StrVectorStructureSetGeneratorTest - tests the API for Structure 1) empty structure vector 2) dummy structure 3) with regex */ int StrVectorStructureSetGeneratorTest(int argc, char* argv[]) { - typedef core::StructureSet::StructTypePointer StructTypePointer; + typedef core::Structure::Pointer StructTypePointer; PREPARE_DEFAULT_TEST_REPORTING; //1) empty structure vector std::vector strVector; CHECK_NO_THROW(core::StrVectorStructureSetGenerator generator1(strVector)); CHECK_NO_THROW(core::StrVectorStructureSetGenerator(strVector).generateStructureSet()); CHECK_EQUAL(core::StrVectorStructureSetGenerator( strVector).generateStructureSet()->getNumberOfStructures(), 0); CHECK_THROW_EXPLICIT(core::StrVectorStructureSetGenerator( strVector).generateStructureSet()->getStructure(0), core::InvalidParameterException); //2) dummy structure boost::shared_ptr spTestDoseAccessor = boost::make_shared(); DummyStructure myStructGenerator(spTestDoseAccessor->getGeometricInfo()); GridIndexType zPlane = 4; core::Structure rect = myStructGenerator.CreateRectangularStructureCentered(zPlane); StructTypePointer rectStrPtr = boost::make_shared(rect); rectStrPtr->setLabel("test"); strVector.push_back(rectStrPtr); CHECK_NO_THROW(core::StrVectorStructureSetGenerator generator2(strVector)); CHECK_NO_THROW(core::StrVectorStructureSetGenerator(strVector).generateStructureSet()); CHECK_EQUAL(core::StrVectorStructureSetGenerator( strVector).generateStructureSet()->getNumberOfStructures(), 1); CHECK_NO_THROW(core::StrVectorStructureSetGenerator(strVector).generateStructureSet()->getStructure( 0)); //3) with regex StructTypePointer rectStrPtr2 = boost::make_shared(rect); rectStrPtr2->setLabel("none"); strVector.push_back(rectStrPtr2); core::StrVectorStructureSetGenerator generator(strVector); generator.setStructureLabelFilterActive(true); generator.setFilterRegEx("test"); CHECK_NO_THROW(generator.generateStructureSet()); CHECK_EQUAL(generator.generateStructureSet()->getNumberOfStructures(), 1); CHECK_EQUAL(generator.generateStructureSet()->getStructure(0)->getLabel(), "test"); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb \ No newline at end of file diff --git a/testing/core/StructureSetTest.cpp b/testing/core/StructureSetTest.cpp index 35e4187..add189c 100644 --- a/testing/core/StructureSetTest.cpp +++ b/testing/core/StructureSetTest.cpp @@ -1,82 +1,82 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include "litCheckMacros.h" #include "DummyStructure.h" #include "DummyDoseAccessor.h" #include "rttbInvalidParameterException.h" #include "rttbStructure.h" #include "rttbStructureSet.h" namespace rttb { namespace testing { /*! @brief StructureSet - tests the API for StructureSet 1) constructor 2) getters */ int StructureSetTest(int argc, char* argv[]) { - typedef core::StructureSet::StructTypePointer StructTypePointer; + typedef core::Structure::Pointer StructTypePointer; PREPARE_DEFAULT_TEST_REPORTING; boost::shared_ptr spTestDoseAccessor = boost::make_shared(); DummyStructure myStructGenerator(spTestDoseAccessor->getGeometricInfo()); GridIndexType zPlane = 4; core::Structure rect = myStructGenerator.CreateRectangularStructureCentered(zPlane); StructTypePointer rectStrPtr = boost::make_shared(rect); rectStrPtr->setLabel("test"); StructTypePointer rectStrPtr2 = boost::make_shared(rect); rectStrPtr2->setLabel("test2"); const IDType patientUID("patientUID"); const IDType UID("UID"); //1) constructor CHECK_NO_THROW(core::StructureSet({ })); core::StructureSet structureSetDefault({ }); CHECK_NO_THROW(core::StructureSet({ rectStrPtr, rectStrPtr2 }, patientUID, UID)); core::StructureSet structureSet({rectStrPtr, rectStrPtr2}, patientUID, UID); //2) getters CHECK_EQUAL(structureSetDefault.getNumberOfStructures(), 0); CHECK_EQUAL(structureSet.getNumberOfStructures(), 2); CHECK_EQUAL(structureSet.getStructure(0)->getLabel(), "test"); CHECK_EQUAL(structureSet.getStructure(1)->getLabel(), "test2"); CHECK_THROW_EXPLICIT(structureSet.getStructure(2), core::InvalidParameterException); CHECK_EQUAL(structureSet.getUID(), UID); CHECK_EQUAL(structureSet.getPatientUID(), patientUID); CHECK_NO_THROW(structureSetDefault.getUID()); CHECK_NO_THROW(structureSetDefault.getPatientUID()); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb \ No newline at end of file diff --git a/testing/examples/RTBioModelExampleTest.cpp b/testing/examples/RTBioModelExampleTest.cpp index 23c9d6b..fab0183 100644 --- a/testing/examples/RTBioModelExampleTest.cpp +++ b/testing/examples/RTBioModelExampleTest.cpp @@ -1,415 +1,415 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include "litCheckMacros.h" #include "rttbBioModel.h" #include "rttbDVH.h" #include "rttbTCPLQModel.h" #include "rttbNTCPLKBModel.h" #include "rttbNTCPRSModel.h" #include "rttbBioModelScatterPlots.h" #include "rttbBioModelCurve.h" #include "rttbDvhBasedModels.h" #include "rttbDoseIteratorInterface.h" #include "rttbDVHXMLFileReader.h" namespace rttb { namespace testing { /*! @brief RTBioModelTest. TCP calculated using a DVH PTV and LQ Model. NTCP tested using 3 Normal Tissue DVHs and LKB/RS Model. 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 RTBioModelExampleTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; typedef rttb::models::CurveDataType CurveDataType; typedef std::multimap > ScatterPlotType; - typedef core::DVH::DVHPointer DVHPointer; + typedef core::DVH::Pointer DVHPointer; //increased accuracy requires double values in the calculation (rttbBaseType.h) double toleranceEUD = 1e-5; double tolerance = 1e-7; //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 //...........5: Virtuos MPM_LR_ah dvh lung file name //...........6: Virtuos MPM_LR_ah dvh target file name std::string DVH_FILENAME_PTV; std::string DVH_FILENAME_NT1; std::string DVH_FILENAME_NT2; std::string DVH_FILENAME_NT3; std::string DVH_FILENAME_TV_TEST; std::string DVH_Virtuos_Target; std::string DVH_Virtuos_Lung; 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]; } if (argc > 5) { DVH_FILENAME_TV_TEST = argv[5]; } if (argc > 6) { DVH_Virtuos_Lung = argv[6]; } if (argc > 7) { DVH_Virtuos_Target = argv[7]; } //DVH PTV rttb::io::other::DVHXMLFileReader dvhReader = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_PTV); DVHPointer dvhPtr = dvhReader.generateDVH(); CHECK_CLOSE(6.04759613161786830000e+001, models::getEUD(dvhPtr, 10), toleranceEUD); rttb::io::other::DVHXMLFileReader dvhReader_test_tv = rttb::io::other::DVHXMLFileReader( DVH_FILENAME_TV_TEST); DVHPointer dvh_test_tv = dvhReader_test_tv.generateDVH(); //test TCP LQ Model models::BioModelParamType alpha = 0.35; models::BioModelParamType beta = 0.023333333333333; models::BioModelParamType roh = 10000000; int numFractions = 2; DoseTypeGy normalizationDose = 68; rttb::models::TCPLQModel tcplq = rttb::models::TCPLQModel(dvhPtr, alpha, beta, roh, numFractions); CHECK_EQUAL(alpha, tcplq.getAlphaMean()); CHECK_EQUAL(alpha / beta, tcplq.getAlphaBeta()); CHECK_EQUAL(roh, tcplq.getRho()); CHECK_NO_THROW(tcplq.init()); if (tcplq.init()) { CHECK_CLOSE(1.00497232941856940000e-127, tcplq.getValue(), tolerance); } CurveDataType curve = models::getCurveDoseVSBioModel(tcplq, normalizationDose); CurveDataType::iterator it; for (it = curve.begin(); it != curve.end(); ++it) { if ((*it).first < 72) { CHECK_EQUAL(0, (*it).second); } else if ((*it).first > 150) { CHECK((*it).second > 0.9); } } models::BioModelParamType alphaBeta = 10; tcplq.setParameters(alpha, alphaBeta, roh, 0.08); CHECK_EQUAL(alpha, tcplq.getAlphaMean()); CHECK_EQUAL(alphaBeta, tcplq.getAlphaBeta()); CHECK_EQUAL(roh, tcplq.getRho()); if (tcplq.init()) { CHECK_CLOSE(1.84e-005, tcplq.getValue(), tolerance); } normalizationDose = 40; curve = models::getCurveDoseVSBioModel(tcplq, normalizationDose); alpha = 1; alphaBeta = 14.5; tcplq.setAlpha(alpha); tcplq.setAlphaBeta(alphaBeta); tcplq.setRho(roh); CHECK_EQUAL(alpha, tcplq.getAlphaMean()); CHECK_EQUAL(alphaBeta, tcplq.getAlphaBeta()); CHECK_EQUAL(roh, tcplq.getRho()); if (tcplq.init()) { CHECK_CLOSE(0.954885, tcplq.getValue(), toleranceEUD); } alpha = 0.9; alphaBeta = 1; tcplq.setAlpha(alpha); tcplq.setAlphaBeta(alphaBeta); tcplq.setRho(roh); CHECK_EQUAL(alpha, tcplq.getAlphaMean()); CHECK_EQUAL(alphaBeta, tcplq.getAlphaBeta()); CHECK_EQUAL(roh, tcplq.getRho()); if (tcplq.init()) { CHECK_EQUAL(1, tcplq.getValue()); } //TCP LQ Test alpha = 0.3; beta = 0.03; roh = 10000000; numFractions = 20; rttb::models::TCPLQModel tcplq_test = rttb::models::TCPLQModel(dvh_test_tv, alpha, beta, roh, numFractions); CHECK_EQUAL(alpha, tcplq_test.getAlphaMean()); CHECK_EQUAL(alpha / beta, tcplq_test.getAlphaBeta()); CHECK_EQUAL(roh, tcplq_test.getRho()); CHECK_NO_THROW(tcplq_test.init()); if (tcplq_test.init()) { CHECK_CLOSE(9.79050278878883180000e-001, tcplq_test.getValue(), tolerance); } normalizationDose = 60; curve = models::getCurveDoseVSBioModel(tcplq_test, normalizationDose); //DVH HT 1 rttb::io::other::DVHXMLFileReader dvhReader2 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT1); DVHPointer dvhPtr2 = dvhReader2.generateDVH(); CHECK_CLOSE(1.07920836034015810000e+001, models::getEUD(dvhPtr2, 10), toleranceEUD); //test RTNTCPLKBModel rttb::models::NTCPLKBModel lkb = rttb::models::NTCPLKBModel(); models::BioModelParamType aVal = 10; models::BioModelParamType mVal = 0.16; models::BioModelParamType d50Val = 55; CHECK_EQUAL(0, lkb.getA()); CHECK_EQUAL(0, lkb.getM()); CHECK_EQUAL(0, lkb.getD50()); lkb.setDVH(dvhPtr2); CHECK_EQUAL(dvhPtr2, lkb.getDVH()); lkb.setA(aVal); CHECK_EQUAL(aVal, lkb.getA()); lkb.setM(mVal); CHECK_EQUAL(mVal, lkb.getM()); lkb.setD50(d50Val); CHECK_EQUAL(d50Val, lkb.getD50()); CHECK_NO_THROW(lkb.init()); if (lkb.init()) { CHECK_CLOSE(2.53523522831366570000e-007, lkb.getValue(), tolerance); } //test RTNTCPRSModel rttb::models::NTCPRSModel rs = rttb::models::NTCPRSModel(); models::BioModelParamType gammaVal = 1.7; models::BioModelParamType sVal = 1; CHECK_EQUAL(0, rs.getGamma()); CHECK_EQUAL(0, rs.getS()); CHECK_EQUAL(0, rs.getD50()); rs.setDVH(dvhPtr2); CHECK_EQUAL(dvhPtr2, rs.getDVH()); rs.setD50(d50Val); CHECK_EQUAL(d50Val, rs.getD50()); rs.setGamma(gammaVal); CHECK_EQUAL(gammaVal, rs.getGamma()); rs.setS(sVal); CHECK_EQUAL(sVal, rs.getS()); CHECK_NO_THROW(rs.init()); if (rs.init()) { CHECK_CLOSE(3.70385888626145740000e-009, rs.getValue(), tolerance); } //DVH HT 2 rttb::io::other::DVHXMLFileReader dvhReader3 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT2); DVHPointer dvhPtr3 = dvhReader3.generateDVH(); CHECK_CLOSE(1.26287047025885110000e+001, models::getEUD(dvhPtr3, 10), toleranceEUD); //test RTNTCPLKBModel aVal = 10; mVal = 0.16; d50Val = 55; lkb.setDVH(dvhPtr3); CHECK_EQUAL(dvhPtr3, lkb.getDVH()); lkb.setA(aVal); CHECK_EQUAL(aVal, lkb.getA()); lkb.setM(mVal); CHECK_EQUAL(mVal, lkb.getM()); lkb.setD50(d50Val); CHECK_EQUAL(d50Val, lkb.getD50()); if (lkb.init()) { CHECK_CLOSE(7.36294657754956700000e-007, lkb.getValue(), tolerance); } //test RTNTCPRSModel rs = rttb::models::NTCPRSModel(); gammaVal = 1.7; sVal = 1; CHECK_EQUAL(0, rs.getGamma()); CHECK_EQUAL(0, rs.getS()); CHECK_EQUAL(0, rs.getD50()); rs.setDVH(dvhPtr3); CHECK_EQUAL(dvhPtr3, rs.getDVH()); rs.setD50(d50Val); CHECK_EQUAL(d50Val, rs.getD50()); rs.setGamma(gammaVal); CHECK_EQUAL(gammaVal, rs.getGamma()); rs.setS(sVal); CHECK_EQUAL(sVal, rs.getS()); if (rs.init()) { CHECK_CLOSE(1.76778795490939440000e-007, rs.getValue(), tolerance); } //DVH HT 3 rttb::io::other::DVHXMLFileReader dvhReader4 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT3); DVHPointer dvhPtr4 = dvhReader4.generateDVH(); CHECK_CLOSE(2.18212982041056310000e+001, models::getEUD(dvhPtr4, 10), toleranceEUD); //test RTNTCPLKBModel aVal = 10; mVal = 0.16; d50Val = 55; lkb.setDVH(dvhPtr4); CHECK_EQUAL(dvhPtr4, lkb.getDVH()); lkb.setA(aVal); CHECK_EQUAL(aVal, lkb.getA()); lkb.setM(mVal); CHECK_EQUAL(mVal, lkb.getM()); lkb.setD50(d50Val); CHECK_EQUAL(d50Val, lkb.getD50()); if (lkb.init()) { CHECK_CLOSE(8.15234192641929420000e-005, lkb.getValue(), tolerance); } //test RTNTCPRSModel rs = rttb::models::NTCPRSModel(); gammaVal = 1.7; sVal = 1; CHECK_EQUAL(0, rs.getGamma()); CHECK_EQUAL(0, rs.getS()); CHECK_EQUAL(0, rs.getD50()); rs.setDVH(dvhPtr4); CHECK_EQUAL(dvhPtr4, rs.getDVH()); rs.setD50(d50Val); CHECK_EQUAL(d50Val, rs.getD50()); rs.setGamma(gammaVal); CHECK_EQUAL(gammaVal, rs.getGamma()); rs.setS(sVal); CHECK_EQUAL(sVal, rs.getS()); if (rs.init()) { CHECK_CLOSE(2.02607985020919480000e-004, rs.getValue(), tolerance); } //test using Virtuos Pleuramesotheliom MPM_LR_ah //DVH PTV rttb::io::other::DVHXMLFileReader dR_Target = rttb::io::other::DVHXMLFileReader(DVH_Virtuos_Target); DVHPointer dvhPtrTarget = dR_Target.generateDVH(); rttb::io::other::DVHXMLFileReader dR_Lung = rttb::io::other::DVHXMLFileReader(DVH_Virtuos_Lung); DVHPointer dvhPtrLung = dR_Lung.generateDVH(); //test TCP LQ Model models::BioModelParamType alphaMean = 0.34; models::BioModelParamType alphaVarianz = 0.02; models::BioModelParamType alpha_beta = 28; models::BioModelParamType rho = 1200; int numFractionsVirtuos = 27; rttb::models::TCPLQModel tcplqVirtuos = rttb::models::TCPLQModel(dvhPtrTarget, rho, numFractionsVirtuos, alpha_beta, alphaMean, alphaVarianz); if (tcplqVirtuos.init()) { CHECK_CLOSE(0.8894, tcplqVirtuos.getValue(), 1e-4); } models::BioModelParamType d50Mean = 20; models::BioModelParamType m = 0.36; models::BioModelParamType a = 1.06; rttb::models::NTCPLKBModel lkbVirtuos = rttb::models::NTCPLKBModel(dvhPtrLung, d50Mean, m, a); if (lkbVirtuos.init()) { CHECK_CLOSE(0.0397, lkbVirtuos.getValue(), 1e-4); } RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/examples/RTBioModelScatterPlotExampleTest.cpp b/testing/examples/RTBioModelScatterPlotExampleTest.cpp index 1fce076..a70f583 100644 --- a/testing/examples/RTBioModelScatterPlotExampleTest.cpp +++ b/testing/examples/RTBioModelScatterPlotExampleTest.cpp @@ -1,479 +1,479 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include "litCheckMacros.h" #include "rttbBioModel.h" #include "rttbDVH.h" #include "rttbTCPLQModel.h" #include "rttbNTCPLKBModel.h" #include "rttbNTCPRSModel.h" #include "rttbBioModelScatterPlots.h" #include "rttbBioModelCurve.h" #include "rttbDvhBasedModels.h" #include "../models/rttbScatterTester.h" #include "rttbInvalidParameterException.h" #include "rttbDVHXmlFileReader.h" namespace rttb { namespace testing { /*! @brief RTBioModelScatterPlotExampleTest. calculating Curves and Scatterplots for TCP and NTCP models. The values on curve and scatterplot need to be similar for similar dose values. The range of difference is given by the variance used to generate the scatter. WARNING: The values for comparison need to be adjusted if the input files are changed! */ int RTBioModelScatterPlotExampleTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; typedef rttb::models::CurveDataType CurveDataType; typedef rttb::models::ScatterPlotType ScatterPlotType; - typedef core::DVH::DVHPointer DVHPointer; + typedef core::DVH::Pointer DVHPointer; //increased accuracy requires double values in the calculation (rttbBaseType.h) double toleranceEUD = 1e-5; //ARGUMENTS: 1: ptv dvh file name // 2: normal tissue 1 dvh file name // 3: TV dvh file name std::string DVH_FILENAME_PTV; std::string DVH_FILENAME_NT1; std::string DVH_FILENAME_TV_TEST; if (argc > 1) { DVH_FILENAME_PTV = argv[1]; } if (argc > 2) { DVH_FILENAME_NT1 = argv[2]; } if (argc > 3) { DVH_FILENAME_TV_TEST = argv[3]; } //DVH PTV rttb::io::other::DVHXMLFileReader dvhReader = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_PTV); DVHPointer dvhPtr = dvhReader.generateDVH(); rttb::io::other::DVHXMLFileReader dvhReader_test_tv = rttb::io::other::DVHXMLFileReader( DVH_FILENAME_TV_TEST); DVHPointer dvh_test_tv = dvhReader_test_tv.generateDVH(); //test TCP LQ Model models::BioModelParamType alpha = 0.35; models::BioModelParamType beta = 0.023333333333333; models::BioModelParamType roh = 10000000; int numFractions = 2; DoseTypeGy normalizationDose = 68; rttb::models::TCPLQModel tcplq = rttb::models::TCPLQModel(dvhPtr, alpha, beta, roh, numFractions); CHECK_NO_THROW(tcplq.init()); CurveDataType curve = models::getCurveDoseVSBioModel(tcplq, normalizationDose); CHECK_NO_THROW(models::getScatterPlotVary1Parameter(tcplq, 0, alpha, 0, normalizationDose, 100)); ScatterPlotType tcpScatter = models::getScatterPlotVary1Parameter(tcplq, 0, alpha, 0, normalizationDose, 100); CHECK_EQUAL(100, tcpScatter.size()); ScatterTester scatterCompare(curve, tcpScatter); CHECK_TESTER(scatterCompare); //test also with other parameter tcpScatter = models::getScatterPlotVary1Parameter(tcplq, 3, roh, 0, normalizationDose, 100); scatterCompare.setCompareScatter(tcpScatter); CHECK_TESTER(scatterCompare); std::vector paramIdVec; models::BioModel::ParamVectorType meanVec; models::BioModel::ParamVectorType meanVecTest; meanVecTest.push_back(alpha); models::BioModel::ParamVectorType varianceVec; //"alphaMean":0,"alphaVariance":1,"alpha_beta":2, "rho":3 paramIdVec.push_back(0); meanVec.push_back(tcplq.getAlphaMean()); varianceVec.push_back(0); //setting parameter 1 will change the resulting scatter plot dramatically - is it meant to? //this is unexpected since the value was taken from the original calculation //paramIdVec.push_back(1); meanVec.push_back(tcplq.getAlphaVariance()); varianceVec.push_back(0); paramIdVec.push_back(2); meanVec.push_back(tcplq.getAlphaBeta()); varianceVec.push_back(0); paramIdVec.push_back(3); meanVec.push_back(tcplq.getRho()); varianceVec.push_back(0); CHECK_THROW_EXPLICIT(models::getScatterPlotVaryParameters(tcplq, paramIdVec, meanVecTest, varianceVec, normalizationDose, 50), core::InvalidParameterException); ScatterPlotType scatterVary = models::getScatterPlotVaryParameters(tcplq, paramIdVec, meanVec, varianceVec, normalizationDose, 50); CHECK_EQUAL(50, scatterVary.size()); scatterCompare.setCompareScatter(scatterVary); CHECK_TESTER(scatterCompare); models::BioModelParamType variance = 0.00015; CHECK_NO_THROW(models::getScatterPlotVary1Parameter(tcplq, 0, alpha, variance, normalizationDose, 100)); tcpScatter = models::getScatterPlotVary1Parameter(tcplq, 0, alpha, variance, normalizationDose, 100); scatterCompare.setVariance(variance); scatterCompare.setCompareScatter(tcpScatter); //allow 5% of the points to deviate more scatterCompare.setAllowExceptions(true); CHECK_TESTER(scatterCompare); //test also with other parameter tcpScatter = models::getScatterPlotVary1Parameter(tcplq, 3, roh, variance, normalizationDose, 100); scatterCompare.setCompareScatter(tcpScatter); //allow 5% of the points to deviate more scatterCompare.setAllowExceptions(true); CHECK_TESTER(scatterCompare); paramIdVec.clear(); meanVec.clear(); varianceVec.clear(); paramIdVec.push_back(0); meanVec.push_back(tcplq.getAlphaMean()); varianceVec.push_back(variance); //paramIdVec.push_back(1); meanVec.push_back(tcplq.getAlphaVariance()); varianceVec.push_back(variance); paramIdVec.push_back(2); meanVec.push_back(tcplq.getAlphaBeta()); varianceVec.push_back(variance); paramIdVec.push_back(3); meanVec.push_back(tcplq.getRho()); varianceVec.push_back(variance); scatterVary = models::getScatterPlotVaryParameters(tcplq, paramIdVec, meanVec, varianceVec, normalizationDose, 50); scatterCompare.setCompareScatter(scatterVary); //allow 5% of the points to deviate more scatterCompare.setAllowExceptions(true); CHECK_TESTER(scatterCompare); models::BioModelParamType alphaBeta = 10; tcplq.setParameters(alpha, alphaBeta, roh, 0.08); tcplq.init(); normalizationDose = 40; curve = models::getCurveDoseVSBioModel(tcplq, normalizationDose); CHECK_NO_THROW(models::getScatterPlotVary1Parameter(tcplq, 0, alpha, 0, normalizationDose, 100)); tcpScatter = models::getScatterPlotVary1Parameter(tcplq, 0, alpha, 0, normalizationDose, 100); scatterCompare.setReferenceCurve(curve); scatterCompare.setVariance(0); //do not allow larger deviations scatterCompare.setAllowExceptions(false); scatterCompare.setCompareScatter(tcpScatter); CHECK_TESTER(scatterCompare); variance = 0.25; CHECK_NO_THROW(models::getScatterPlotVary1Parameter(tcplq, 0, alpha, variance, normalizationDose, 100)); tcpScatter = models::getScatterPlotVary1Parameter(tcplq, 0, alpha, variance, normalizationDose, 100); scatterCompare.setCompareScatter(tcpScatter); scatterCompare.setVariance(variance); //allow 5% of the points to deviate more scatterCompare.setAllowExceptions(true); CHECK_TESTER(scatterCompare); /*TCP LQ Test*/ alpha = 0.3; beta = 0.03; roh = 10000000; numFractions = 20; rttb::models::TCPLQModel tcplq_test = rttb::models::TCPLQModel(dvh_test_tv, alpha, beta, roh, numFractions); CHECK_NO_THROW(tcplq_test.init()); normalizationDose = 60; curve = models::getCurveDoseVSBioModel(tcplq_test, normalizationDose); CHECK_NO_THROW(models::getScatterPlotVary1Parameter(tcplq_test, 0, alpha, 0, normalizationDose, 100)); tcpScatter = models::getScatterPlotVary1Parameter(tcplq_test, 0, alpha, 0, normalizationDose, 100); scatterCompare.setReferenceCurve(curve); scatterCompare.setVariance(0); scatterCompare.setCompareScatter(tcpScatter); CHECK_TESTER(scatterCompare); //test also with other parameter tcpScatter = models::getScatterPlotVary1Parameter(tcplq_test, 3, roh, 0, normalizationDose, 100); scatterCompare.setCompareScatter(tcpScatter); CHECK_TESTER(scatterCompare); paramIdVec.clear(); meanVec.clear(); varianceVec.clear(); paramIdVec.push_back(0); meanVec.push_back(tcplq_test.getAlphaMean()); varianceVec.push_back(0); //paramIdVec.push_back(1); meanVec.push_back(tcplq_test.getAlphaVariance()); varianceVec.push_back(0); paramIdVec.push_back(2); meanVec.push_back(tcplq_test.getAlphaBeta()); varianceVec.push_back(0); paramIdVec.push_back(3); meanVec.push_back(tcplq_test.getRho()); varianceVec.push_back(0); scatterVary = models::getScatterPlotVaryParameters(tcplq_test, paramIdVec, meanVec, varianceVec, normalizationDose, 50); scatterCompare.setCompareScatter(scatterVary); CHECK_TESTER(scatterCompare); variance = 0.00025; CHECK_NO_THROW(models::getScatterPlotVary1Parameter(tcplq_test, 0, alpha, variance, normalizationDose, 100)); tcpScatter = models::getScatterPlotVary1Parameter(tcplq_test, 0, alpha, variance, normalizationDose, 100); scatterCompare.setCompareScatter(tcpScatter); scatterCompare.setVariance(variance); CHECK_TESTER(scatterCompare); //test also with other parameter tcpScatter = models::getScatterPlotVary1Parameter(tcplq_test, 3, roh, variance, normalizationDose, 100); scatterCompare.setCompareScatter(tcpScatter); scatterCompare.setAllowExceptions(true); CHECK_TESTER(scatterCompare); scatterCompare.setAllowExceptions(false); paramIdVec.clear(); meanVec.clear(); varianceVec.clear(); paramIdVec.push_back(0); meanVec.push_back(tcplq_test.getAlphaMean()); varianceVec.push_back(variance); //paramIdVec.push_back(1); meanVec.push_back(tcplq_test.getAlphaVariance()); varianceVec.push_back(variance); paramIdVec.push_back(2); meanVec.push_back(tcplq_test.getAlphaBeta()); varianceVec.push_back(variance); paramIdVec.push_back(3); meanVec.push_back(tcplq_test.getRho()); varianceVec.push_back(variance); scatterVary = models::getScatterPlotVaryParameters(tcplq_test, paramIdVec, meanVec, varianceVec, normalizationDose, 50); scatterCompare.setCompareScatter(scatterVary); //allow 5% of the points to deviate more scatterCompare.setAllowExceptions(true); CHECK_TESTER(scatterCompare); //DVH HT 1 rttb::io::other::DVHXMLFileReader dvhReader2 = rttb::io::other::DVHXMLFileReader(DVH_FILENAME_NT1); DVHPointer dvhPtr2 = dvhReader2.generateDVH(); CHECK_CLOSE(1.07920836034015810000e+001, models::getEUD(dvhPtr2, 10), toleranceEUD); //test RTNTCPLKBModel rttb::models::NTCPLKBModel lkb = rttb::models::NTCPLKBModel(); models::BioModelParamType aVal = 10; models::BioModelParamType mVal = 0.16; models::BioModelParamType d50Val = 55; lkb.setDVH(dvhPtr2); lkb.setA(aVal); lkb.setM(mVal); lkb.setD50(d50Val); CHECK_NO_THROW(lkb.init()); normalizationDose = 60; curve = models::getCurveDoseVSBioModel(lkb, normalizationDose); CHECK_NO_THROW(models::getScatterPlotVary1Parameter(lkb, 2, aVal, 0, normalizationDose, 100)); ScatterPlotType scatter = models::getScatterPlotVary1Parameter(lkb, 2, aVal, 0, normalizationDose, 100); scatterCompare.setReferenceCurve(curve); scatterCompare.setVariance(0); scatterCompare.setCompareScatter(scatter); CHECK_TESTER(scatterCompare); //"d50":0,"m":1,"a":2 //test also with other parameter scatter = models::getScatterPlotVary1Parameter(lkb, 0, d50Val, 0, normalizationDose, 100); scatterCompare.setCompareScatter(scatter); CHECK_TESTER(scatterCompare); paramIdVec.clear(); meanVec.clear(); varianceVec.clear(); paramIdVec.push_back(0); meanVec.push_back(lkb.getD50()); varianceVec.push_back(0); paramIdVec.push_back(1); meanVec.push_back(lkb.getM()); varianceVec.push_back(0); paramIdVec.push_back(2); meanVec.push_back(lkb.getA()); varianceVec.push_back(0); scatterVary = models::getScatterPlotVaryParameters(lkb, paramIdVec, meanVec, varianceVec, normalizationDose, 50); scatterCompare.setCompareScatter(scatterVary); CHECK_TESTER(scatterCompare); variance = 0.00025; CHECK_NO_THROW(models::getScatterPlotVary1Parameter(lkb, 2, aVal, variance, normalizationDose, 100)); scatter = models::getScatterPlotVary1Parameter(lkb, 2, aVal, variance, normalizationDose, 100); scatterCompare.setCompareScatter(scatter); scatterCompare.setVariance(variance); CHECK_TESTER(scatterCompare); //test also with other parameter scatter = models::getScatterPlotVary1Parameter(lkb, 0, d50Val, variance, normalizationDose, 100); scatterCompare.setCompareScatter(scatter); CHECK_TESTER(scatterCompare); paramIdVec.clear(); meanVec.clear(); varianceVec.clear(); paramIdVec.push_back(0); meanVec.push_back(lkb.getD50()); varianceVec.push_back(variance); paramIdVec.push_back(1); meanVec.push_back(lkb.getM()); varianceVec.push_back(variance); paramIdVec.push_back(2); meanVec.push_back(lkb.getA()); varianceVec.push_back(variance); scatterVary = models::getScatterPlotVaryParameters(lkb, paramIdVec, meanVec, varianceVec, normalizationDose, 50); scatterCompare.setCompareScatter(scatterVary); CHECK_TESTER(scatterCompare); //test RTNTCPRSModel rttb::models::NTCPRSModel rs = rttb::models::NTCPRSModel(); models::BioModelParamType gammaVal = 1.7; models::BioModelParamType sVal = 1; rs.setDVH(dvhPtr2); rs.setD50(d50Val); rs.setGamma(gammaVal); rs.setS(sVal); CHECK_NO_THROW(rs.init()); normalizationDose = 60; curve = models::getCurveDoseVSBioModel(rs, normalizationDose); CHECK_NO_THROW(models::getScatterPlotVary1Parameter(rs, 0, d50Val, 0, normalizationDose, 100)); scatter = models::getScatterPlotVary1Parameter(rs, 0, d50Val, 0, normalizationDose, 100); scatterCompare.setReferenceCurve(curve); scatterCompare.setVariance(0); scatterCompare.setCompareScatter(scatter); CHECK_TESTER(scatterCompare); //"d50":0,"gamma":1,"s":2 //test also with other parameter scatter = models::getScatterPlotVary1Parameter(rs, 1, gammaVal, 0, normalizationDose, 100); scatterCompare.setCompareScatter(scatter); CHECK_TESTER(scatterCompare); paramIdVec.clear(); meanVec.clear(); varianceVec.clear(); paramIdVec.push_back(0); meanVec.push_back(rs.getD50()); varianceVec.push_back(0); paramIdVec.push_back(1); meanVec.push_back(rs.getGamma()); varianceVec.push_back(0); paramIdVec.push_back(2); meanVec.push_back(rs.getS()); varianceVec.push_back(0); scatterVary = models::getScatterPlotVaryParameters(rs, paramIdVec, meanVec, varianceVec, normalizationDose, 50); scatterCompare.setCompareScatter(scatterVary); CHECK_TESTER(scatterCompare); variance = 0.0075; CHECK_NO_THROW(models::getScatterPlotVary1Parameter(rs, 0, d50Val, variance, normalizationDose, 100)); scatter = models::getScatterPlotVary1Parameter(rs, 0, d50Val, variance, normalizationDose, 100); scatterCompare.setCompareScatter(scatter); scatterCompare.setVariance(variance); CHECK_TESTER(scatterCompare); //test also with other parameter scatter = models::getScatterPlotVary1Parameter(rs, 2, sVal, variance, normalizationDose, 100); scatterCompare.setCompareScatter(scatter); CHECK_TESTER(scatterCompare); paramIdVec.clear(); meanVec.clear(); varianceVec.clear(); paramIdVec.push_back(0); meanVec.push_back(rs.getD50()); varianceVec.push_back(variance); paramIdVec.push_back(1); meanVec.push_back(rs.getGamma()); varianceVec.push_back(variance); paramIdVec.push_back(2); meanVec.push_back(rs.getS()); varianceVec.push_back(variance); scatterVary = models::getScatterPlotVaryParameters(rs, paramIdVec, meanVec, varianceVec, normalizationDose, 50); scatterCompare.setCompareScatter(scatterVary); CHECK_TESTER(scatterCompare); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/examples/RTDVHTest.cpp b/testing/examples/RTDVHTest.cpp index 0c3258d..d040b8e 100644 --- a/testing/examples/RTDVHTest.cpp +++ b/testing/examples/RTDVHTest.cpp @@ -1,110 +1,108 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ // 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 "rttbDVH.h" #include "rttbBaseType.h" #include "rttbDvhBasedModels.h" #include "rttbDVHXMLFileReader.h" namespace rttb { namespace testing { /*! @brief RTDVHTest. Max, min, mean, modal, median, Vx, Dx, EUD, BED, LQED2 are tested. Test if calculation in new architecture returns similar results to the original implementation. Comparison of actual DVH values is performed in DVHCalculatorComparisonTest.cpp. WARNING: The values for comparison need to be adjusted if the input files are changed! */ int RTDVHTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: 1: dvh file name std::string RTDVH_FILENAME_PTV; if (argc > 1) { RTDVH_FILENAME_PTV = argv[1]; } - typedef core::DVH::DVHPointer DVHPointer; - /*test RT dvh*/ rttb::io::other::DVHXMLFileReader dvhReader = rttb::io::other::DVHXMLFileReader(RTDVH_FILENAME_PTV); const DoseCalcType expectedValue = 0.01305; //dvhReader - DVHPointer dvh = dvhReader.generateDVH(); + core::DVH::Pointer dvh = dvhReader.generateDVH(); CHECK_CLOSE(expectedValue, models::getEUD(dvh, 10), errorConstant); std::cout << models::getEUD(dvh, 10) << std::endl; CHECK_NO_THROW(models::calcBEDDVH(dvh, 15, 15)); CHECK_NO_THROW(models::calcLQED2DVH(dvh, 15, 10)); CHECK_NO_THROW(dvh->getDataDifferential()); CHECK_EQUAL(1, dvh->convertAbsoluteToRelative().at(0)); CHECK_NO_THROW(models::calcBEDDVH(dvh, 15, 15, true)); CHECK_NO_THROW(models::calcLQED2DVH(dvh, 15, 10, true)); //test statistics (relative cumulative data) CHECK_CLOSE(expectedValue, dvh->getMaximum(), errorConstant); CHECK_CLOSE(expectedValue, dvh->getMinimum(), errorConstant); CHECK_CLOSE(expectedValue, dvh->getMean(), errorConstant); CHECK_CLOSE(expectedValue, dvh->getMedian(), errorConstant); CHECK_CLOSE(expectedValue, dvh->getModal(), errorConstant); CHECK_EQUAL(0, dvh->getVx(0.014)); CHECK_EQUAL(250, dvh->getVx(0.01)); CHECK_CLOSE(0.0131, dvh->getDx(100), errorConstant + errorConstant * 10); CHECK_CLOSE(0.013, dvh->getDx(249), errorConstant); CHECK_EQUAL(0, dvh->getDx(251)); //test statistics (absolute cumulative data) CHECK_EQUAL(2000, dvh->getDataCumulative().at(0)); CHECK_EQUAL(0, dvh->getVx(0.014)); CHECK_EQUAL(250, dvh->getVx(0.01)); CHECK_CLOSE(0.0131, dvh->getDx(100), errorConstant + errorConstant * 10); CHECK_CLOSE(0.013, dvh->getDx(249), errorConstant); CHECK_EQUAL(0, dvh->getDx(251)); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/examples/RTDoseStatisticsDicomTest.cpp b/testing/examples/RTDoseStatisticsDicomTest.cpp index f052b0f..c9bf63e 100644 --- a/testing/examples/RTDoseStatisticsDicomTest.cpp +++ b/testing/examples/RTDoseStatisticsDicomTest.cpp @@ -1,118 +1,118 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1328 $ (last changed revision) // @date $Date: 2016-04-22 09:50:01 +0200 (Fr, 22 Apr 2016) $ (last change date) // @author $Author: hentsch $ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include "litCheckMacros.h" #include "rttbDoseStatistics.h" #include "rttbDoseStatisticsCalculator.h" #include "rttbDicomDoseAccessor.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbBoostMaskAccessor.h" #include "rttbGenericMaskedDoseIterator.h" #include "rttbGenericDoseIterator.h" #include "rttbBaseType.h" namespace rttb { namespace testing { /*! @brief RTDoseStatisticsTest. Max, min, mean, standard deviation, variance, Vx, Dx, MOHx, MOCx, MaxOHx, MinOCx are tested. 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 RTDoseStatisticsDicomTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; std::string RTDOSE_FILENAME; if (argc > 1) { RTDOSE_FILENAME = argv[1]; } else { std::cout << "at least one arguments required for RTDoseStatisticsDicomTest" << std::endl; return -1; } double expectedVal = 5.64477e-005; double volume = 24120.; typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; typedef core::GenericDoseIterator::DoseIteratorPointer DoseIteratorPointer; typedef algorithms::DoseStatisticsCalculator::ResultListPointer ResultListPointer; io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1(RTDOSE_FILENAME.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); //create corresponding DoseIterator ::boost::shared_ptr spDoseIteratorTmp = ::boost::make_shared(doseAccessor1); DoseIteratorPointer spDoseIterator(spDoseIteratorTmp); rttb::algorithms::DoseStatisticsCalculator doseStatisticsCalculator(spDoseIterator); std::vector precomputedDoseValues; precomputedDoseValues.push_back(0); precomputedDoseValues.push_back(0.5); precomputedDoseValues.push_back(1); std::vector precomputedVolumeValues; precomputedVolumeValues.push_back(20000 / volume); precomputedVolumeValues.push_back(1); - rttb::algorithms::DoseStatistics::DoseStatisticsPointer doseStatistics = + auto doseStatistics = doseStatisticsCalculator.calculateDoseStatistics(precomputedDoseValues, precomputedVolumeValues); CHECK_CLOSE(doseStatistics->getMean(), expectedVal, errorConstant); CHECK_CLOSE(doseStatistics->getStdDeviation(), 0, errorConstant); CHECK_CLOSE(doseStatistics->getVariance(), 0, errorConstant); double dummy; DoseTypeGy vx = doseStatistics->getVx().getValue(expectedVal, true, dummy); CHECK_EQUAL(vx, doseStatistics->getVx().getValue(0)); CHECK_CLOSE(expectedVal, doseStatistics->getDx().getValue(vx), reducedErrorConstant); CHECK_CLOSE(doseStatistics->getMaximum(), expectedVal, errorConstant); CHECK_CLOSE(doseStatistics->getMinimum(), expectedVal, errorConstant); ResultListPointer minListPtr = doseStatistics->getMinimumVoxelPositions(); ResultListPointer maxListPtr = doseStatistics->getMaximumVoxelPositions(); CHECK_EQUAL(maxListPtr->size(), 10); CHECK_EQUAL(minListPtr->size(), 10); CHECK_CLOSE(doseStatistics->getDx().getValue(24120), doseStatistics->getMinimum(), 0.001); CHECK_CLOSE(doseStatistics->getMOHx().getValue(24120), doseStatistics->getMean(), reducedErrorConstant); CHECK_CLOSE(doseStatistics->getMOCx().getValue(20000), doseStatistics->getMean(), reducedErrorConstant); CHECK_CLOSE(doseStatistics->getMinOCx().getValue(20000), doseStatistics->getMean(), reducedErrorConstant); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/dicom/DicomDoseAccessorConverterTest.cpp b/testing/io/dicom/DicomDoseAccessorConverterTest.cpp index 5204887..56c43e0 100644 --- a/testing/io/dicom/DicomDoseAccessorConverterTest.cpp +++ b/testing/io/dicom/DicomDoseAccessorConverterTest.cpp @@ -1,130 +1,130 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbDicomDoseAccessor.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomFileDoseAccessorWriter.h" #include "rttbInvalidDoseException.h" #include "rttbDcmrtException.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace testing { /*!@brief DicomDoseAccessorGeneratorTest - test the generators for dicom data 1) test dicom file generator generateDoseAccessor() 2) test dicom IOD generator generateDoseAccessor() */ int DicomDoseAccessorConverterTest(int argc, char* argv[]) { - typedef rttb::io::dicom::DicomDoseAccessor::DoseAccessorPointer DoseAccessorPointer; + typedef rttb::core::DoseAccessorInterface::Pointer DoseAccessorPointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: // 1: the file name of the dose to read // 2: the file name of the dose to write std::string RTDOSE_FILENAME_R; std::string RTDOSE_FILENAME_W; if (argc > 2) { RTDOSE_FILENAME_R = argv[1]; RTDOSE_FILENAME_W = argv[2]; } double errorConstantDDA = 1e-3; DoseAccessorPointer doseAccessor_r = io::dicom::DicomFileDoseAccessorGenerator( RTDOSE_FILENAME_R.c_str()).generateDoseAccessor(); CHECK_NO_THROW(io::dicom::DicomFileDoseAccessorWriter()); io::dicom::DicomFileDoseAccessorWriter doseConverter; CHECK_NO_THROW(doseConverter.setDoseAccessor(doseAccessor_r)); CHECK_NO_THROW(doseConverter.setFileName(RTDOSE_FILENAME_W)); CHECK_EQUAL(doseConverter.process(), true); DoseAccessorPointer doseAccessor_w = io::dicom::DicomFileDoseAccessorGenerator( RTDOSE_FILENAME_W).generateDoseAccessor(); //Check geometricinfo CHECK(doseAccessor_r->getGeometricInfo().getImagePositionPatient().equalsAlmost( doseAccessor_w->getGeometricInfo().getImagePositionPatient(), errorConstantDDA)); CHECK(doseAccessor_r->getGeometricInfo().getOrientationMatrix().equalsAlmost( doseAccessor_w->getGeometricInfo().getOrientationMatrix(), errorConstantDDA)); CHECK(doseAccessor_r->getGeometricInfo().getSpacing().equalsAlmost( doseAccessor_w->getGeometricInfo().getSpacing(), errorConstantDDA)); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getNumColumns(), doseAccessor_w->getGeometricInfo().getNumColumns(), errorConstantDDA); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getNumRows(), doseAccessor_w->getGeometricInfo().getNumRows(), errorConstantDDA); CHECK_CLOSE(doseAccessor_r->getGeometricInfo().getNumSlices(), doseAccessor_w->getGeometricInfo().getNumSlices(), errorConstantDDA); //Check pixel data unsigned int size = doseAccessor_r->getGeometricInfo().getNumColumns() * doseAccessor_r->getGeometricInfo().getNumRows() * doseAccessor_r->getGeometricInfo().getNumSlices() ; for (unsigned int index = 0; index < 30; index++) { CHECK_CLOSE(doseAccessor_r->getValueAt(index), doseAccessor_w->getValueAt(index), errorConstantDDA); if (size / 2 - index >= 0 && size / 2 - index < size) { CHECK_CLOSE(doseAccessor_r->getValueAt(size / 2 - index), doseAccessor_w->getValueAt(size / 2 - index), errorConstantDDA); } CHECK_CLOSE(doseAccessor_r->getValueAt(size - index - 1), doseAccessor_w->getValueAt(size - index - 1), errorConstantDDA); } RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/dicom/DicomIOTest.cpp b/testing/io/dicom/DicomIOTest.cpp index 77b693e..6e303c5 100644 --- a/testing/io/dicom/DicomIOTest.cpp +++ b/testing/io/dicom/DicomIOTest.cpp @@ -1,241 +1,241 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbGeometricInfo.h" #include "rttbDoseIteratorInterface.h" #include "rttbDicomDoseAccessor.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomIODDoseAccessorGenerator.h" #include "rttbDicomFileStructureSetGenerator.h" namespace rttb { namespace testing { /*!@brief DicomIOTest - test the IO for dicom data 1) test dicom dose import if geometric info was set correctly 2) test dicom dose import accessing dose data and converting 3) check if dicom tags are correctly read 4) test structure import WARNING: The values for comparison need to be adjusted if the input files are changed! */ int DicomIOTest(int argc, char* argv[]) { typedef core::DoseIteratorInterface::DoseAccessorPointer DoseAccessorPointer; - typedef core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; + typedef core::StructureSet::Pointer StructureSetPointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: 1: structure file name // 2: dose1 file name // 3: dose2 file name // 4: dose3 file name // 5: dose4 file name // 6: dose5 file name std::string RTSTRUCT_FILENAME; std::string RTDOSE_FILENAME; std::string RTDOSE2_FILENAME; std::string RTDOSE3_FILENAME; std::string RTDOSE4_FILENAME; std::string RTDOSE5_FILENAME; if (argc > 1) { RTSTRUCT_FILENAME = argv[1]; } if (argc > 2) { RTDOSE_FILENAME = argv[2]; } if (argc > 3) { RTDOSE2_FILENAME = argv[3]; } if (argc > 4) { RTDOSE3_FILENAME = argv[4]; } if (argc > 5) { RTDOSE4_FILENAME = argv[5]; } if (argc > 6) { RTDOSE5_FILENAME = argv[6]; } OFCondition status; DcmFileFormat fileformat; /* read dicom-rt dose */ io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1(RTDOSE_FILENAME.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); //1) test dicom dose import if geometric info was set correctly core::GeometricInfo geoInfo = doseAccessor1->getGeometricInfo(); CHECK_EQUAL(45, geoInfo.getNumRows()); CHECK_EQUAL(67, geoInfo.getNumColumns()); CHECK_EQUAL(64, geoInfo.getNumSlices()); CHECK_EQUAL(OrientationMatrix(), geoInfo.getOrientationMatrix()); SpacingVectorType3D pixelSpacing(5, 5, 5); CHECK_EQUAL(pixelSpacing, geoInfo.getSpacing()); WorldCoordinate3D imagePositionPatient(-170.556642, -273.431642, -674); CHECK_EQUAL(imagePositionPatient, geoInfo.getImagePositionPatient()); //test geometric info of an inhomogeneous dose grid io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator5(RTDOSE5_FILENAME.c_str()); DoseAccessorPointer doseAccessor5(doseAccessorGenerator5.generateDoseAccessor()); SpacingVectorType3D pixelSpacing5(2, 3, 2); CHECK_EQUAL(pixelSpacing5, doseAccessor5->getGeometricInfo().getSpacing()); const VoxelGridID start = 0; const VoxelGridIndex3D start3D(0); VoxelGridID end, inbetween; VoxelGridIndex3D end3D, inbetween3D; //2) test dicom dose import accessing dose data and converting CHECK_EQUAL(2, doseAccessor1->getValueAt(start)); CHECK_EQUAL(2, doseAccessor1-> getValueAt(start3D)); CHECK_EQUAL(doseAccessor1->getValueAt(start), doseAccessor1-> getValueAt(start3D)); inbetween = int(std::floor(doseAccessor1->getGridSize() / 2.0)); doseAccessor1->getGeometricInfo().convert(inbetween, inbetween3D); CHECK_EQUAL(2, doseAccessor1->getValueAt(inbetween)); CHECK_EQUAL(2, doseAccessor1-> getValueAt(inbetween3D)); CHECK_EQUAL(doseAccessor1->getValueAt(inbetween), doseAccessor1-> getValueAt(inbetween3D)); end = doseAccessor1->getGridSize() - 1; doseAccessor1->getGeometricInfo().convert(end, end3D); CHECK_EQUAL(2, doseAccessor1->getValueAt(end)); CHECK_EQUAL(2, doseAccessor1-> getValueAt(end3D)); CHECK_EQUAL(doseAccessor1->getValueAt(end), doseAccessor1-> getValueAt(end3D)); ::DRTDoseIOD rtdose2; io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator2(RTDOSE2_FILENAME.c_str()); DoseAccessorPointer doseAccessor2(doseAccessorGenerator2.generateDoseAccessor()); //2) test dicom dose import accessing dose data and converting CHECK_EQUAL(50, doseAccessor2->getValueAt(start)); CHECK_EQUAL(50, doseAccessor2-> getValueAt(start3D)); CHECK_EQUAL(doseAccessor2->getValueAt(start), doseAccessor2-> getValueAt(start3D)); inbetween = int(std::floor(doseAccessor2->getGridSize() / 2.0)); doseAccessor2->getGeometricInfo().convert(inbetween, inbetween3D); CHECK_EQUAL(50, doseAccessor2->getValueAt(inbetween)); CHECK_EQUAL(50, doseAccessor2-> getValueAt(inbetween3D)); CHECK_EQUAL(doseAccessor2->getValueAt(inbetween), doseAccessor2-> getValueAt(inbetween3D)); end = doseAccessor2->getGridSize() - 1; doseAccessor2->getGeometricInfo().convert(end, end3D); CHECK_EQUAL(50, doseAccessor2->getValueAt(end)); CHECK_EQUAL(50, doseAccessor2-> getValueAt(end3D)); CHECK_EQUAL(doseAccessor2->getValueAt(end), doseAccessor2-> getValueAt(end3D)); ::DRTDoseIOD rtdose3; io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator3(RTDOSE3_FILENAME.c_str()); DoseAccessorPointer doseAccessor3(doseAccessorGenerator3.generateDoseAccessor()); //2) test dicom dose import accessing dose data and converting CHECK_EQUAL(0, doseAccessor3->getValueAt(start)); CHECK_EQUAL(0, doseAccessor3-> getValueAt(start3D)); CHECK_EQUAL(doseAccessor3->getValueAt(start), doseAccessor3-> getValueAt(start3D)); inbetween = int(std::floor(doseAccessor3->getGridSize() / 2.0)); doseAccessor3->getGeometricInfo().convert(inbetween, inbetween3D); CHECK_EQUAL(0, doseAccessor3->getValueAt(inbetween)); CHECK_EQUAL(0, doseAccessor3-> getValueAt(inbetween3D)); CHECK_EQUAL(doseAccessor3->getValueAt(inbetween), doseAccessor3-> getValueAt(inbetween3D)); end = doseAccessor3->getGridSize() - 1; doseAccessor3->getGeometricInfo().convert(end, end3D); CHECK_CLOSE(1.46425, doseAccessor3->getValueAt(end), errorConstant); CHECK_CLOSE(1.46425, doseAccessor3-> getValueAt(end3D), errorConstant); CHECK_EQUAL(doseAccessor3->getValueAt(end), doseAccessor3-> getValueAt(end3D)); /* structure set */ StructureSetPointer rtStructureSet = io::dicom::DicomFileStructureSetGenerator( RTSTRUCT_FILENAME.c_str()).generateStructureSet(); //4) test structure import CHECK_EQUAL(10, rtStructureSet->getNumberOfStructures()); CHECK_EQUAL("Aussenkontur", (rtStructureSet->getStructure(0))->getLabel()); CHECK_EQUAL("Rueckenmark", (rtStructureSet->getStructure(1))->getLabel()); CHECK_EQUAL("Niere re.", (rtStructureSet->getStructure(2))->getLabel()); CHECK_EQUAL("Niere li.", (rtStructureSet->getStructure(3))->getLabel()); CHECK_EQUAL("Magen/DD", (rtStructureSet->getStructure(4))->getLabel()); CHECK_EQUAL("Leber", (rtStructureSet->getStructure(5))->getLabel()); CHECK_EQUAL("Darm", (rtStructureSet->getStructure(6))->getLabel()); CHECK_EQUAL("Ref.Pkt.", (rtStructureSet->getStructure(7))->getLabel()); CHECK_EQUAL("PTV", (rtStructureSet->getStructure(8))->getLabel()); CHECK_EQUAL("Boost", (rtStructureSet->getStructure(9))->getLabel()); //4) Test other tags (GridFrameOffsetVector(3004,000c) and PixelSpacingBetweenSlices(0018, 0088)) to compute dose slicing io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator4(RTDOSE4_FILENAME.c_str()); DoseAccessorPointer doseAccessor4(doseAccessorGenerator4.generateDoseAccessor()); rttb::SpacingVectorType3D spacingVec = doseAccessor4->getGeometricInfo().getSpacing(); CHECK_EQUAL(2.5, spacingVec.x()); CHECK_EQUAL(2.5, spacingVec.y()); CHECK_EQUAL(3, spacingVec.z()); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/dicom/DicomStructureSetGeneratorTest.cpp b/testing/io/dicom/DicomStructureSetGeneratorTest.cpp index 29c5920..4aea224 100644 --- a/testing/io/dicom/DicomStructureSetGeneratorTest.cpp +++ b/testing/io/dicom/DicomStructureSetGeneratorTest.cpp @@ -1,104 +1,104 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbDicomFileStructureSetGenerator.h" #include "rttbDicomIODStructureSetGenerator.h" #include "rttbDcmrtException.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace testing { /*!@brief DicomIOTest - test structure set generator for dicom data 1) test dicom file structure set generator 2) test dicom IOD structure set generator */ int DicomStructureSetGeneratorTest(int argc, char* argv[]) { - typedef core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; + typedef core::StructureSet::Pointer StructureSetPointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: 1: structure file name std::string RTSTRUCT_FILENAME; if (argc > 1) { RTSTRUCT_FILENAME = argv[1]; } /* structure set */ //1) test dicom file structure set generator CHECK_NO_THROW(io::dicom::DicomFileStructureSetGenerator("")); CHECK_NO_THROW(io::dicom::DicomFileStructureSetGenerator("Test.test")); CHECK_THROW_EXPLICIT(io::dicom::DicomFileStructureSetGenerator("Test.test").generateStructureSet(), rttb::core::InvalidParameterException); CHECK_NO_THROW(io::dicom::DicomFileStructureSetGenerator(RTSTRUCT_FILENAME.c_str())); StructureSetPointer rtStructureSet = io::dicom::DicomFileStructureSetGenerator( RTSTRUCT_FILENAME.c_str()).generateStructureSet(); //2) test dicom IOD structure set generator OFCondition status; DcmFileFormat fileformat; boost::shared_ptr drtStrSetIOD = boost::make_shared(); CHECK_NO_THROW(io::dicom::DicomIODStructureSetGenerator generator1(drtStrSetIOD)); CHECK_THROW_EXPLICIT(io::dicom::DicomIODStructureSetGenerator(drtStrSetIOD).generateStructureSet(), core::InvalidParameterException); fileformat.loadFile(RTSTRUCT_FILENAME.c_str()); drtStrSetIOD->read(*fileformat.getDataset()); CHECK_NO_THROW(io::dicom::DicomIODStructureSetGenerator generator2(drtStrSetIOD)); CHECK_NO_THROW(io::dicom::DicomIODStructureSetGenerator(drtStrSetIOD).generateStructureSet()); StructureSetPointer rtStructureSet2 = io::dicom::DicomIODStructureSetGenerator( drtStrSetIOD).generateStructureSet(); CHECK_EQUAL(rtStructureSet2->getNumberOfStructures(), rtStructureSet->getNumberOfStructures()); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/helax/DicomHelaxIOTest.cpp b/testing/io/helax/DicomHelaxIOTest.cpp index 761b35c..e27dba4 100644 --- a/testing/io/helax/DicomHelaxIOTest.cpp +++ b/testing/io/helax/DicomHelaxIOTest.cpp @@ -1,128 +1,128 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbGeometricInfo.h" #include "rttbDoseIteratorInterface.h" #include "rttbDicomHelaxFileDoseAccessorGenerator.h" #include "rttbDicomHelaxIODVecDoseAccessorGenerator.h" #include "rttbDicomHelaxDoseAccessor.h" #include "rttbDicomFileStructureSetGenerator.h" namespace rttb { namespace testing { /*!@brief DicomHelaxIOTest - test the IO for dicom helax data 1) test dicom helax dose import if geometric info was set correctly 2) test dicom helax dose import accessing dose data and converting 3) test dicom helax structure import WARNING: The values for comparison need to be adjusted if the input files are changed! */ int DicomHelaxIOTest(int argc, char* argv[]) { typedef core::DoseIteratorInterface::DoseAccessorPointer DoseAccessorPointer; - typedef core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; + typedef core::StructureSet::Pointer StructureSetPointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: 1: directory name std::string RT_DIRNAME; if (argc > 1) { RT_DIRNAME = argv[1]; } OFCondition status; DcmFileFormat fileformat; /* read dicom-rt dose */ io::helax::DicomHelaxFileDoseAccessorGenerator doseAccessorGenerator1(RT_DIRNAME.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); //1) test dicom dose import if geometric info was set correctly core::GeometricInfo geoInfo = doseAccessor1->getGeometricInfo(); CHECK_EQUAL(64, geoInfo.getNumRows()); CHECK_EQUAL(54, geoInfo.getNumColumns()); CHECK_EQUAL(52, geoInfo.getNumSlices()); CHECK_EQUAL(OrientationMatrix(), geoInfo.getOrientationMatrix()); const VoxelGridID start = 0; const VoxelGridIndex3D start3D(0); VoxelGridID end, inbetween; VoxelGridIndex3D end3D, inbetween3D; //2) test dicom dose import accessing dose data and converting CHECK_EQUAL(doseAccessor1->getValueAt(start), doseAccessor1-> getValueAt(start3D)); inbetween = int(std::floor(doseAccessor1->getGridSize() / 2.0)); doseAccessor1->getGeometricInfo().convert(inbetween, inbetween3D); CHECK_EQUAL(doseAccessor1->getValueAt(inbetween), doseAccessor1-> getValueAt(inbetween3D)); end = doseAccessor1->getGridSize() - 1; doseAccessor1->getGeometricInfo().convert(end, end3D); CHECK_EQUAL(doseAccessor1->getValueAt(end), doseAccessor1-> getValueAt(end3D)); /* structure set */ StructureSetPointer rtStructureSet = io::dicom::DicomFileStructureSetGenerator( RT_DIRNAME.c_str()).generateStructureSet(); //3) test structure import CHECK_EQUAL(8, rtStructureSet->getNumberOfStructures()); CHECK_EQUAL("Patient outline", (rtStructureSet->getStructure(0))->getLabel()); CHECK_EQUAL("boost", (rtStructureSet->getStructure(1))->getLabel()); CHECK_EQUAL("Chiasma", (rtStructureSet->getStructure(2))->getLabel()); CHECK_EQUAL("Sehnerv li.", (rtStructureSet->getStructure(3))->getLabel()); CHECK_EQUAL("Sehnerv re.", (rtStructureSet->getStructure(4))->getLabel()); CHECK_EQUAL("Auge li.", (rtStructureSet->getStructure(5))->getLabel()); CHECK_EQUAL("Auge re.", (rtStructureSet->getStructure(6))->getLabel()); CHECK_EQUAL("Hirnstamm", (rtStructureSet->getStructure(7))->getLabel()); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/itk/ITKBioModelAccessorConverterTest.cpp b/testing/io/itk/ITKBioModelAccessorConverterTest.cpp index 0d4c0c5..000ee32 100644 --- a/testing/io/itk/ITKBioModelAccessorConverterTest.cpp +++ b/testing/io/itk/ITKBioModelAccessorConverterTest.cpp @@ -1,112 +1,112 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include "litCheckMacros.h" #include "itkImage.h" #include "itkImageFileReader.h" #include "rttbBaseType.h" #include "rttbDoseIteratorInterface.h" #include "rttbAccessorInterface.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomDoseAccessor.h" #include "rttbLQModelAccessor.h" #include "rttbITKImageAccessor.h" #include "rttbITKImageFileAccessorGenerator.h" #include "rttbITKImageAccessorGenerator.h" #include "rttbITKImageAccessorConverter.h" #include "rttbDoseAccessorProcessorBase.h" #include "rttbDoseAccessorConversionSettingInterface.h" #include "rttbInvalidDoseException.h" namespace rttb { namespace testing { /*!@brief ITKBioModelAccessorConverterTest - test the conversion rttb BioModel accessor ->itk 1) test with dicom file (DicomDoseAccessorGenerator) */ int ITKBioModelAccessorConverterTest(int argc, char* argv[]) { - typedef core::AccessorInterface::AccessorPointer AccessorPointer; - typedef core::DoseAccessorInterface::DoseAccessorPointer DoseAccessorPointer; + typedef core::AccessorInterface::Pointer AccessorPointer; + typedef core::DoseAccessorInterface::Pointer DoseAccessorPointer; PREPARE_DEFAULT_TEST_REPORTING; std::string RTDOSE_FILENAME; if (argc > 1) { RTDOSE_FILENAME = argv[1]; } //1) Read dicomFile and test process() and getITKImage() io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator(RTDOSE_FILENAME.c_str()); DoseAccessorPointer doseAccessor(doseAccessorGenerator.generateDoseAccessor()); AccessorPointer LQWithConstantDose = boost::make_shared(doseAccessor, 0.2, 0.02); io::itk::ITKImageAccessorConverter itkConverter(LQWithConstantDose); CHECK_NO_THROW(itkConverter.process()); CHECK_NO_THROW(itkConverter.getITKImage()); io::itk::ITKImageAccessor::ITKImageType::IndexType itkIndex; itkIndex[0] = itkIndex[1] = itkIndex[2] = 0; VoxelGridIndex3D rttbIndex(0, 0, 0); CHECK_EQUAL(itkConverter.getITKImage()->GetPixel(itkIndex), LQWithConstantDose->getValueAt(rttbIndex)); itkIndex[0] = rttbIndex[0] = doseAccessor->getGeometricInfo().getNumColumns() / 2; itkIndex[1] = rttbIndex[1] = doseAccessor->getGeometricInfo().getNumRows() / 2; itkIndex[2] = rttbIndex[2] = doseAccessor->getGeometricInfo().getNumSlices() / 2; CHECK_EQUAL(itkConverter.getITKImage()->GetPixel(itkIndex), LQWithConstantDose->getValueAt(rttbIndex)); itkIndex[0] = rttbIndex[0] = doseAccessor->getGeometricInfo().getNumColumns() - 1; itkIndex[1] = rttbIndex[1] = doseAccessor->getGeometricInfo().getNumRows() - 1; itkIndex[2] = rttbIndex[2] = doseAccessor->getGeometricInfo().getNumSlices() - 1; CHECK_EQUAL(itkConverter.getITKImage()->GetPixel(itkIndex), LQWithConstantDose->getValueAt(rttbIndex)); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/itk/ITKIOTest.cpp b/testing/io/itk/ITKIOTest.cpp index 1a7997e..caae969 100644 --- a/testing/io/itk/ITKIOTest.cpp +++ b/testing/io/itk/ITKIOTest.cpp @@ -1,217 +1,217 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbGeometricInfo.h" #include "rttbDoseIteratorInterface.h" #include "rttbITKImageAccessorConverter.h" #include "rttbITKImageAccessorGenerator.h" #include "rttbITKImageFileAccessorGenerator.h" #include "rttbITKImageFileMaskAccessorGenerator.h" #include "rttbITKImageAccessor.h" #include "rttbITKImageMaskAccessor.h" #include "rttbInvalidDoseException.h" #include "itkImageFileReader.h" namespace rttb { namespace testing { /*!@brief ITKIOTest - test the IO for ITK data 1) test ITK dose import if geometric info was set correctly 2) test ITKImageFileDoseAccessorGenerator accessing dose data and converting (*.mhd file) 3) test ITKImageDoseAccessorGenerator accessing dose data and converting (*.mhd file) WARNING: The values for comparison need to be adjusted if the input files are changed! */ int ITKIOTest(int argc, char* argv[]) { typedef core::DoseIteratorInterface::DoseAccessorPointer DoseAccessorPointer; - typedef core::MaskAccessorInterface::MaskAccessorPointer MaskAccessorPointer; + typedef core::MaskAccessorInterface::Pointer MaskAccessorPointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: // 1: mhd file name // 2: mask file name std::string RTDOSE_FILENAME, VOXELIZEDMASK_FILENAME; if (argc > 2) { RTDOSE_FILENAME = argv[1]; VOXELIZEDMASK_FILENAME = argv[2]; } /* read dose in *.mhd file */ io::itk::ITKImageFileAccessorGenerator doseAccessorGenerator1(RTDOSE_FILENAME.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); //1) test ITK dose import if geometric info was set correctly core::GeometricInfo geoInfo = doseAccessor1->getGeometricInfo(); CHECK_EQUAL(25, geoInfo.getNumRows()); CHECK_EQUAL(25, geoInfo.getNumColumns()); CHECK_EQUAL(15, geoInfo.getNumSlices()); //orientation matrix equals identity matrix CHECK_EQUAL(OrientationMatrix(), geoInfo.getOrientationMatrix()); const VoxelGridID start = 0; const VoxelGridIndex3D start3D(0); VoxelGridID end, inbetween, inbetween2, outside; VoxelGridIndex3D end3D, inbetween3D, inbetween23D, outside3D; //2) test ITK dose import accessing dose data and converting (*.mhd file) CHECK(doseAccessor1->getGeometricInfo().validID(start)); CHECK(doseAccessor1->getGeometricInfo().validIndex(start3D)); CHECK(!(doseAccessor1->getGeometricInfo().validID(doseAccessor1->getGridSize()))); CHECK(!(doseAccessor1->getGeometricInfo().validIndex(VoxelGridIndex3D( doseAccessor1->getGridSize())))); CHECK_EQUAL(0, doseAccessor1->getValueAt(start)); CHECK_EQUAL(doseAccessor1->getValueAt(start), doseAccessor1-> getValueAt(start3D)); CHECK_NO_THROW(doseAccessor1->getUID()); inbetween = 4039; doseAccessor1->getGeometricInfo().convert(inbetween, inbetween3D); CHECK(doseAccessor1->getGeometricInfo().validID(inbetween)); CHECK(doseAccessor1->getGeometricInfo().validIndex(inbetween3D)); CHECK_EQUAL(162.0, doseAccessor1->getValueAt(inbetween)); CHECK_EQUAL(doseAccessor1->getValueAt(inbetween), doseAccessor1-> getValueAt(inbetween3D)); inbetween2 = 6086; doseAccessor1->getGeometricInfo().convert(inbetween2, inbetween23D); CHECK(doseAccessor1->getGeometricInfo().validID(inbetween2)); CHECK(doseAccessor1->getGeometricInfo().validIndex(inbetween23D)); CHECK_EQUAL(7.0, doseAccessor1->getValueAt(inbetween2)); CHECK_EQUAL(doseAccessor1->getValueAt(inbetween2), doseAccessor1-> getValueAt(inbetween23D)); end = doseAccessor1->getGridSize() - 1; outside = end + 1; doseAccessor1->getGeometricInfo().convert(end, end3D); outside3D = VoxelGridIndex3D(end3D.x() + 2, end3D.y(), end3D.z()); CHECK(doseAccessor1->getGeometricInfo().validID(end)); CHECK(doseAccessor1->getGeometricInfo().validIndex(end3D)); CHECK_EQUAL(0, doseAccessor1->getValueAt(end)); CHECK_EQUAL(doseAccessor1->getValueAt(end), doseAccessor1-> getValueAt(end3D)); CHECK_EQUAL(-1, doseAccessor1->getValueAt(outside)); CHECK_EQUAL(-1, doseAccessor1->getValueAt(outside3D)); typedef itk::Image< DoseTypeGy, 3 > DoseImageType; typedef itk::ImageFileReader ReaderType; ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(RTDOSE_FILENAME); //important to update the reader (won't work without) reader->Update(); io::itk::ITKImageAccessorGenerator doseAccessorGenerator2(reader->GetOutput()); DoseAccessorPointer doseAccessor2(doseAccessorGenerator2.generateDoseAccessor()); //3) test ITK dose import accessing dose data and converting (ITKImageDoseAccessor) CHECK(doseAccessor2->getGeometricInfo().validID(start)); CHECK(doseAccessor2->getGeometricInfo().validIndex(start3D)); CHECK(!(doseAccessor2->getGeometricInfo().validID(doseAccessor2->getGridSize()))); CHECK(!(doseAccessor2->getGeometricInfo().validIndex(VoxelGridIndex3D( doseAccessor2->getGridSize())))); CHECK_EQUAL(0, doseAccessor2->getValueAt(start)); CHECK_EQUAL(doseAccessor2->getValueAt(start), doseAccessor2->getValueAt(start3D)); CHECK(doseAccessor2->getGeometricInfo().validID(inbetween)); CHECK(doseAccessor2->getGeometricInfo().validIndex(inbetween3D)); CHECK_EQUAL(162.0, doseAccessor2->getValueAt(inbetween)); CHECK_EQUAL(doseAccessor2->getValueAt(inbetween), doseAccessor2->getValueAt(inbetween3D)); CHECK(doseAccessor2->getGeometricInfo().validID(inbetween2)); CHECK(doseAccessor2->getGeometricInfo().validIndex(inbetween23D)); CHECK_EQUAL(7.0, doseAccessor2->getValueAt(inbetween2)); CHECK_EQUAL(doseAccessor2->getValueAt(inbetween2), doseAccessor2->getValueAt(inbetween23D)); end = doseAccessor2->getGridSize() - 1; doseAccessor2->getGeometricInfo().convert(end, end3D); CHECK(doseAccessor2->getGeometricInfo().validID(end)); CHECK(doseAccessor2->getGeometricInfo().validIndex(end3D)); CHECK_EQUAL(0, doseAccessor2->getValueAt(end)); CHECK_EQUAL(doseAccessor2->getValueAt(end), doseAccessor2-> getValueAt(end3D)); /* test ITKImageAccessor*/ typedef itk::Image< DoseTypeGy, 3 > DoseImageType; DoseImageType::Pointer invalidDose = DoseImageType::New(); CHECK_THROW_EXPLICIT(io::itk::ITKImageAccessor(invalidDose.GetPointer()), core::InvalidDoseException); /* test ITKImageMaskAccessor*/ CHECK_THROW_EXPLICIT(io::itk::ITKImageMaskAccessor(invalidDose.GetPointer()), core::InvalidDoseException); io::itk::ITKImageFileMaskAccessorGenerator maskAccessorGenerator(VOXELIZEDMASK_FILENAME.c_str()); MaskAccessorPointer maskAccessor(maskAccessorGenerator.generateMaskAccessor()); auto imageSize = maskAccessor->getGeometricInfo().getImageSize(); end = imageSize.x()*imageSize.y()*imageSize.z() - 1; outside = end + 1; maskAccessor->getGeometricInfo().convert(end, end3D); outside3D = VoxelGridIndex3D(end3D.x() + 2, end3D.y(), end3D.z()); inbetween3D = VoxelGridIndex3D(139, 61, 57); maskAccessor->getGeometricInfo().convert(inbetween3D, inbetween); core::MaskVoxel aVoxel(0); CHECK_EQUAL(maskAccessor->getMaskAt(start, aVoxel), true); CHECK_EQUAL(aVoxel.getRelevantVolumeFraction(), 0.0); CHECK_EQUAL(maskAccessor->getMaskAt(end, aVoxel), true); CHECK_EQUAL(aVoxel.getRelevantVolumeFraction(), 0.0); CHECK_EQUAL(maskAccessor->getMaskAt(end3D, aVoxel), true); CHECK_EQUAL(aVoxel.getRelevantVolumeFraction(), 0.0); CHECK_EQUAL(maskAccessor->getMaskAt(outside, aVoxel), false); CHECK_EQUAL(maskAccessor->getMaskAt(outside3D, aVoxel), false); CHECK_EQUAL(maskAccessor->getMaskAt(inbetween, aVoxel), true); CHECK_EQUAL(aVoxel.getRelevantVolumeFraction(), 1.0); CHECK_EQUAL(maskAccessor->getMaskAt(inbetween3D, aVoxel), true); CHECK_EQUAL(aVoxel.getRelevantVolumeFraction(), 1.0); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/itk/ITKMaskAccessorConverterTest.cpp b/testing/io/itk/ITKMaskAccessorConverterTest.cpp index 770190d..83f4884 100644 --- a/testing/io/itk/ITKMaskAccessorConverterTest.cpp +++ b/testing/io/itk/ITKMaskAccessorConverterTest.cpp @@ -1,178 +1,178 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include "litCheckMacros.h" #include "litImageTester.h" #include "litTestImageIO.h" #include "itkImage.h" #include "itkImageFileReader.h" #include "rttbBaseType.h" #include "rttbDoseIteratorInterface.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomDoseAccessor.h" #include "rttbInvalidDoseException.h" #include "rttbDicomFileStructureSetGenerator.h" #include "rttbITKImageMaskAccessorConverter.h" #include "rttbITKImageFileMaskAccessorGenerator.h" #include "rttbBoostMaskAccessor.h" namespace rttb { namespace testing { /*!@brief MaskAccessorConverterTest - test the conversion rttb dose accessor ->itk 1) test with dicom file (DicomDoseAccessorGenerator) 2) test with mhd file (ITKImageFileDoseAccessorGenerator) */ int ITKMaskAccessorConverterTest(int argc, char* argv[]) { typedef core::DoseIteratorInterface::DoseAccessorPointer DoseAccessorPointer; - typedef core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; - typedef core::MaskAccessorInterface::MaskAccessorPointer MaskAccessorPointer; + typedef core::StructureSet::Pointer StructureSetPointer; + typedef core::MaskAccessorInterface::Pointer MaskAccessorPointer; typedef io::itk::ITKImageMaskAccessor::ITKMaskImageType::Pointer ITKImageTypePointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: //ARGUMENTS: 1: structure file name // 2: dose1 file name std::string RTStr_FILENAME; std::string RTDose_FILENAME; std::string Mask_FILENAME; if (argc > 3) { RTStr_FILENAME = argv[1]; RTDose_FILENAME = argv[2]; Mask_FILENAME = argv[3]; } //1) Read dicomFile and test getITKImage() io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1(RTDose_FILENAME.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); StructureSetPointer rtStructureSet = io::dicom::DicomFileStructureSetGenerator( RTStr_FILENAME.c_str()).generateStructureSet(); MaskAccessorPointer maskAccessorPtr = boost::make_shared (rtStructureSet->getStructure(9), doseAccessor1->getGeometricInfo()); maskAccessorPtr->updateMask();//!Important: Update the mask before conversion. io::itk::ITKImageMaskAccessorConverter maskAccessorConverter(maskAccessorPtr); CHECK_NO_THROW(maskAccessorConverter.process()); CHECK_NO_THROW(maskAccessorConverter.getITKImage()); //2) Read itk image, generate mask and convert it back to itk image, check equal MaskAccessorPointer maskAccessorPtr2 = io::itk::ITKImageFileMaskAccessorGenerator( Mask_FILENAME.c_str()).generateMaskAccessor(); maskAccessorPtr2->updateMask();//!Important: Update the mask before conversion. io::itk::ITKImageMaskAccessorConverter maskAccessorConverter2(maskAccessorPtr2); maskAccessorConverter2.process(); typedef itk::Image< DoseTypeGy, 3 > MaskImageType; ITKImageTypePointer convertedImagePtr = maskAccessorConverter2.getITKImage(); io::itk::ITKImageMaskAccessor::ITKMaskImageType::Pointer expectedImage = lit::TestImageIO::readImage( Mask_FILENAME); CHECK_EQUAL(convertedImagePtr->GetOrigin()[0], expectedImage->GetOrigin()[0]); CHECK_EQUAL(convertedImagePtr->GetOrigin()[1], expectedImage->GetOrigin()[1]); CHECK_EQUAL(convertedImagePtr->GetOrigin()[2], expectedImage->GetOrigin()[2]); CHECK_EQUAL(convertedImagePtr->GetSpacing()[0], expectedImage->GetSpacing()[0]); CHECK_EQUAL(convertedImagePtr->GetSpacing()[1], expectedImage->GetSpacing()[1]); CHECK_EQUAL(convertedImagePtr->GetSpacing()[2], expectedImage->GetSpacing()[2]); CHECK_EQUAL(convertedImagePtr->GetLargestPossibleRegion().GetSize()[0], expectedImage->GetLargestPossibleRegion().GetSize()[0]); CHECK_EQUAL(convertedImagePtr->GetLargestPossibleRegion().GetSize()[1], expectedImage->GetLargestPossibleRegion().GetSize()[1]); CHECK_EQUAL(convertedImagePtr->GetLargestPossibleRegion().GetSize()[2], expectedImage->GetLargestPossibleRegion().GetSize()[2]); unsigned int sizeX = convertedImagePtr->GetLargestPossibleRegion().GetSize()[0]; unsigned int sizeY = convertedImagePtr->GetLargestPossibleRegion().GetSize()[1]; unsigned int sizeZ = convertedImagePtr->GetLargestPossibleRegion().GetSize()[2]; io::itk::ITKImageMaskAccessor::ITKMaskImageType::IndexType index; for (unsigned int i = 0; i < 20 && i < sizeX && i < sizeY && i < sizeZ; i++) { index[0] = i; index[1] = i; index[2] = i; if (expectedImage->GetPixel(index) >= 0 && expectedImage->GetPixel(index) <= 1) { CHECK_EQUAL(convertedImagePtr->GetPixel(index), expectedImage->GetPixel(index)); } } for (unsigned int i = 0; i < 20; i++) { index[0] = sizeX - 1 - i; index[1] = sizeY - 1 - i; index[2] = sizeZ - 1 - i; if (expectedImage->GetPixel(index) >= 0 && expectedImage->GetPixel(index) <= 1) { CHECK_EQUAL(convertedImagePtr->GetPixel(index), expectedImage->GetPixel(index)); } } for (unsigned int i = 0; i < 20 && (sizeX / 2 - i) < sizeX && (sizeY / 2 - i) < sizeY && (sizeZ / 2 - i) < sizeZ; i++) { index[0] = sizeX / 2 - i; index[1] = sizeY / 2 - i; index[2] = sizeZ / 2 - i; if (expectedImage->GetPixel(index) >= 0 && expectedImage->GetPixel(index) <= 1) { CHECK_EQUAL(convertedImagePtr->GetPixel(index), expectedImage->GetPixel(index)); } } RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/models/ModelsIOTest.cpp b/testing/io/models/ModelsIOTest.cpp index 6324d00..3c73890 100644 --- a/testing/io/models/ModelsIOTest.cpp +++ b/testing/io/models/ModelsIOTest.cpp @@ -1,142 +1,142 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // (c) Copyright 2007, DKFZ, Heidelberg, Germany // ALL RIGHTS RESERVED // // THIS FILE CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION OF DKFZ. // ANY DUPLICATION, MODIFICATION, DISTRIBUTION, OR // DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY PROHIBITED // WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF DKFZ. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1221 $ (last changed revision) // @date $Date: 2015-12-01 13:43:31 +0100 (Di, 01 Dez 2015) $ (last change date) // @author zhangl (last changed by) // @author *none* (Reviewer) // @author zhangl (Programmer) // // Subversion HeadURL: $HeadURL: http://sidt-hpc1/dkfz_repository/NotMeVisLab/SIDT/RTToolbox/trunk/testing/core/DVHCalculatorTest.cpp $ */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include "litCheckMacros.h" #include "rttbBioModel.h" #include "rttbTCPLQModel.h" #include "rttbNTCPLKBModel.h" #include #include #include "boost/filesystem.hpp" #include "rttbModelXMLWriter.h" namespace rttb { namespace testing { static std::string readFile(const std::string& filename); int ModelsIOTest(int argc, char* argv[]) { std::string expectedxmlfilenametcpleq; std::string expectedxmlfilenamentcplk; if (argc > 2) { expectedxmlfilenametcpleq = argv[1]; expectedxmlfilenamentcplk = argv[2]; } typedef core::DVH::DataDifferentialType DataDifferentialType; PREPARE_DEFAULT_TEST_REPORTING; //generate artificial DVH and corresponding statistical values DoseTypeGy binSize = DoseTypeGy(0.1); DoseVoxelVolumeType voxelVolume = 8; DataDifferentialType aDataDifferential; DoseCalcType value = 0; DVHVoxelNumber numberOfVoxels = 0; // creat default values for (int i = 0; i < 98; i++) { value = 0; numberOfVoxels += value; aDataDifferential.push_back(value); } aDataDifferential.push_back(10); aDataDifferential.push_back(20); const IDType structureID = "myStructure"; const IDType doseID = "myDose"; const IDType voxelizationID = "myVoxelization"; - core::DVH::DVHPointer dvhPtr = boost::make_shared(aDataDifferential, binSize, + core::DVH::Pointer dvhPtr = boost::make_shared(aDataDifferential, binSize, voxelVolume, structureID, doseID, voxelizationID); //test TCP LQ Model models::BioModelParamType alpha = 0.35; models::BioModelParamType beta = 0.023333333333333; models::BioModelParamType roh = 10000000; int numFractions = 8; boost::shared_ptr tcplq = boost::make_shared (dvhPtr, roh, numFractions, alpha / beta, alpha, 0.08); std::string filename = "BioModeltcpleqIOTest.xml"; rttb::io::models::ModelXMLWriter writer = rttb::io::models::ModelXMLWriter(filename, tcplq, false); CHECK_NO_THROW(writer.writeModel()); CHECK_EQUAL(boost::filesystem::exists(filename), true); std::string defaultAsIs = readFile(filename); std::string defaultExpected = readFile(expectedxmlfilenametcpleq); //Does not work due to double imprecisions. As long as we don't have a ModelXMLReader, a check does not makes sense. See T21832 //CHECK_EQUAL(defaultAsIs, defaultExpected); CHECK_EQUAL(std::remove(filename.c_str()), 0); //test NTCPLKBModel models::BioModelParamType aVal = 10; models::BioModelParamType mVal = 0.16; models::BioModelParamType d50Val = 35; boost::shared_ptr ntcplk = boost::make_shared(dvhPtr, d50Val, mVal, aVal); filename = "BioModelntcplkIOTest.xml"; rttb::io::models::ModelXMLWriter writer2 = rttb::io::models::ModelXMLWriter(filename, ntcplk); CHECK_NO_THROW(writer2.writeModel()); CHECK_EQUAL(boost::filesystem::exists(filename), true); defaultAsIs = readFile(filename); defaultExpected = readFile(expectedxmlfilenamentcplk); //Does not work due to double imprecisions. As long as we don't have a ModelXMLReader, a check does not makes sense. See T21832 //CHECK_EQUAL(defaultAsIs, defaultExpected); CHECK_EQUAL(std::remove(filename.c_str()), 0); std::string dvhFilename = "dvhfor" + ntcplk->getModelType() + ".xml"; CHECK_EQUAL(std::remove(dvhFilename.c_str()), 0); RETURN_AND_REPORT_TEST_SUCCESS; } std::string readFile(const std::string& filename) { std::ifstream fileStream(filename.c_str()); std::string content((std::istreambuf_iterator(fileStream)), (std::istreambuf_iterator())); return content; } } } diff --git a/testing/io/other/CompareDVH.h b/testing/io/other/CompareDVH.h index 2ac33c6..bd5ce71 100644 --- a/testing/io/other/CompareDVH.h +++ b/testing/io/other/CompareDVH.h @@ -1,46 +1,46 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "litCheckMacros.h" #include "rttbDVH.h" #ifndef __DVH_COMPARER_H #define __DVH_COMPARER_H namespace rttb { namespace testing { - typedef core::DVH::DVHPointer DVHPointer; + typedef core::DVH::Pointer DVHPointer; /*! Compare 2 DVHs and return the results. @result Indicates if the test was successful (true) or if it failed (false) */ bool checkEqualDVH(DVHPointer aDVH1, DVHPointer aDVH2); DVHPointer computeDiffDVH(DVHPointer aDVH1, DVHPointer aDVH2); }//testing }//rttb #endif diff --git a/testing/io/other/DVHXMLIOTest.cpp b/testing/io/other/DVHXMLIOTest.cpp index ba254bb..f7c4d97 100644 --- a/testing/io/other/DVHXMLIOTest.cpp +++ b/testing/io/other/DVHXMLIOTest.cpp @@ -1,107 +1,107 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbDVH.h" #include "rttbDVHSet.h" #include "rttbDVHXMLFileReader.h" #include "rttbDVHXMLFileWriter.h" #include "rttbInvalidParameterException.h" #include "rttbNullPointerException.h" #include "../../core/DummyDVHGenerator.h" #include "CompareDVH.h" namespace rttb { namespace testing { /*! @brief DVHXMLIOTest - test the IO for DVH xml data 1) test writing dvh to xml file 2) test reading DVH from xml file */ int DVHXMLIOTest(int argc, char* argv[]) { - typedef core::DVH::DVHPointer DVHPointer; + typedef core::DVH::Pointer DVHPointer; PREPARE_DEFAULT_TEST_REPORTING; /* generate dummy DVH */ const IDType structureIDPrefix = "myStructure"; const IDType doseID = "myDose"; DummyDVHGenerator dvhGenerator; DVHPointer spMyDVH = boost::make_shared(dvhGenerator.generateDVH(structureIDPrefix, doseID)); // 1) test writing DVH to xml file DVHType typeCum = {DVHType::Cumulative}; DVHType typeDiff = {DVHType::Differential}; FileNameString fN1 = "test.xml"; CHECK_NO_THROW(io::other::DVHXMLFileWriter(fN1, typeDiff)); CHECK_NO_THROW(io::other::DVHXMLFileWriter(fN1, typeCum)); io::other::DVHXMLFileWriter dvhWriter(fN1, typeCum); CHECK_EQUAL(fN1, dvhWriter.getFileName()); FileNameString fN2 = "otherFile.xml"; CHECK_NO_THROW(dvhWriter.setFileName(fN2)); CHECK_EQUAL(fN2, dvhWriter.getFileName()); CHECK_EQUAL(DVHType::Cumulative, dvhWriter.getDVHType().Type); CHECK_NO_THROW(dvhWriter.setDVHType(typeDiff)); CHECK_EQUAL(DVHType::Differential, dvhWriter.getDVHType().Type); DVHPointer emptyDvh; CHECK_THROW_EXPLICIT(dvhWriter.writeDVH(emptyDvh), core::NullPointerException); //CHECK_THROW_EXPLICIT(dvhWriter.writeDVH(spMyDVH), core::InvalidParameterException); CHECK_NO_THROW(dvhWriter.setDVHType(typeDiff)); CHECK_NO_THROW(dvhWriter.writeDVH(spMyDVH)); // 2) test reading DVH from xml file io::other::DVHXMLFileReader dvhReader(fN2); DVHPointer importedDVH = dvhReader.generateDVH(); CHECK_EQUAL(*importedDVH, *spMyDVH); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/io/other/DoseStatisticsIOTest.cpp b/testing/io/other/DoseStatisticsIOTest.cpp index 8eed4a7..74a3f44 100644 --- a/testing/io/other/DoseStatisticsIOTest.cpp +++ b/testing/io/other/DoseStatisticsIOTest.cpp @@ -1,138 +1,138 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include #include #include #include "litCheckMacros.h" #include "rttbDoseStatistics.h" #include "rttbDoseStatisticsCalculator.h" #include "rttbDoseStatisticsXMLWriter.h" #include "rttbDoseStatisticsXMLReader.h" #include "rttbGenericDoseIterator.h" #include "rttbDoseIteratorInterface.h" #include "rttbInvalidParameterException.h" #include "rttbNullPointerException.h" #include "../../core/DummyDoseAccessor.h" #include "CompareDoseStatistic.h" namespace rttb { namespace testing { /*! @brief DoseStatisticsIOTest - test the DoseStatisticsIO for dose statistics 1) test writing statistics to xml file 2) test reading statistics from XML file and compare DoseStatistics 3) test writing statistics to string */ int DoseStatisticsIOTest(int argc, char* argv[]) { typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; - typedef core::DoseIteratorInterface::DoseIteratorPointer DoseIteratorPointer; + typedef core::DoseIteratorInterface::Pointer DoseIteratorPointer; PREPARE_DEFAULT_TEST_REPORTING; /* generate dummy dose */ boost::shared_ptr spTestDoseAccessor = boost::make_shared(); DoseAccessorPointer spDoseAccessor(spTestDoseAccessor); boost::shared_ptr spTestDoseIterator = boost::make_shared(spDoseAccessor); DoseIteratorPointer spDoseIterator(spTestDoseIterator); rttb::algorithms::DoseStatisticsCalculator myDoseStatsCalculator(spDoseIterator); auto myDoseStatsSimple = myDoseStatsCalculator.calculateDoseStatistics(); auto myDoseStatsComplex = myDoseStatsCalculator.calculateDoseStatistics(true); auto doseStatisticsXMLWriter = io::other::DoseStatisticsXMLWriter(); //1) test writing statistics to xml file CHECK_THROW_EXPLICIT(doseStatisticsXMLWriter.writeDoseStatistics(nullptr, "aFilename.txt"), core::NullPointerException); FileNameString filenameSimple = "testStatisticsSimple.xml"; CHECK_NO_THROW(doseStatisticsXMLWriter.writeDoseStatistics(myDoseStatsSimple, filenameSimple)); CHECK(boost::filesystem::exists(filenameSimple)); FileNameString filenameComplex = "testStatisticsComplex.xml"; CHECK_NO_THROW(doseStatisticsXMLWriter.writeDoseStatistics(myDoseStatsComplex, filenameComplex)); CHECK(boost::filesystem::exists(filenameComplex)); //2) test reading statistics from XML file and compare DoseStatistics io::other::DoseStatisticsXMLReader readerSimple= io::other::DoseStatisticsXMLReader(filenameSimple); boost::shared_ptr rereadSimplyDose; CHECK_NO_THROW(rereadSimplyDose = readerSimple.generateDoseStatistic()); CHECK(checkEqualDoseStatistic(myDoseStatsSimple, rereadSimplyDose)); io::other::DoseStatisticsXMLReader readerComplex = io::other::DoseStatisticsXMLReader(filenameComplex); boost::shared_ptr rereadComplexDose; CHECK_NO_THROW(rereadComplexDose = readerComplex.generateDoseStatistic()); CHECK(checkEqualDoseStatistic(myDoseStatsComplex, rereadComplexDose)); io::other::DoseStatisticsXMLReader readerInvalidFilename = io::other::DoseStatisticsXMLReader("invalidFilename.xml"); CHECK_THROW_EXPLICIT(readerInvalidFilename.generateDoseStatistic(), core::InvalidParameterException); //delete files again CHECK_EQUAL(std::remove(filenameSimple.c_str()), 0); CHECK_EQUAL(std::remove(filenameComplex.c_str()),0); //3) test writing statistics to string boost::property_tree::ptree ptSimple = doseStatisticsXMLWriter.writeDoseStatistics(myDoseStatsSimple); XMLString strSimple = doseStatisticsXMLWriter.writerDoseStatisticsToString(myDoseStatsSimple); CHECK_THROW_EXPLICIT(doseStatisticsXMLWriter.writerDoseStatisticsToString(nullptr), core::NullPointerException); boost::property_tree::ptree ptComplex = doseStatisticsXMLWriter.writeDoseStatistics(myDoseStatsComplex); XMLString strComplex = doseStatisticsXMLWriter.writerDoseStatisticsToString(myDoseStatsComplex); std::stringstream sstrSimple; boost::property_tree::xml_parser::write_xml(sstrSimple, ptSimple, boost::property_tree::xml_writer_make_settings('\t', 1)); CHECK_EQUAL(strSimple, sstrSimple.str()); std::stringstream sstrComplex; boost::property_tree::xml_parser::write_xml(sstrComplex, ptComplex, boost::property_tree::xml_writer_make_settings('\t', 1)); CHECK_EQUAL(strComplex, sstrComplex.str()); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/masks/boost/BoostMaskTest.cpp b/testing/masks/boost/BoostMaskTest.cpp index 1ff12ab..9582a2d 100644 --- a/testing/masks/boost/BoostMaskTest.cpp +++ b/testing/masks/boost/BoostMaskTest.cpp @@ -1,255 +1,255 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1127 $ (last changed revision) // @date $Date: 2015-10-01 13:33:33 +0200 (Do, 01 Okt 2015) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "../../core/DummyStructure.h" #include "../../core/DummyDoseAccessor.h" #include "rttbDicomDoseAccessor.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomFileStructureSetGenerator.h" #include "rttbDicomFileStructureSetGenerator.h" #include "rttbGenericDoseIterator.h" #include "rttbDVHCalculator.h" #include "rttbGenericMaskedDoseIterator.h" #include "rttbBoostMask.h" #include "rttbBoostMaskAccessor.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace testing { /*! @brief BoostMaskRedesignTest. 1) test constructors 2) test getRelevantVoxelVector 3) test getMaskAt */ int BoostMaskTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; - typedef core::Structure::StructTypePointer StructTypePointer; + typedef core::Structure::Pointer StructTypePointer; // generate test dose. geometric info: patient position (-25, -2, 35), center of the 1st.voxel boost::shared_ptr spTestDoseAccessor = boost::make_shared(); boost::shared_ptr geometricPtr = boost::make_shared (spTestDoseAccessor->getGeometricInfo()); DummyStructure myStructGenerator(spTestDoseAccessor->getGeometricInfo()); //generate test structure. contours are (-20,0.5,38.75); (-12.5,0.5,38.75); (-12.5,10.5,38.75); (-20,10.5,38.75); //(-20, 0.5, 41.25); (-12.5, 0.5, 41.25); (-12.5, 10.5, 41.25); (-20, 10.5, 41.25); core::Structure myTestStruct = myStructGenerator.CreateRectangularStructureCentered(2,3); StructTypePointer spMyStruct = boost::make_shared(myTestStruct); //generate test structure 2. contours are (-20,0.5,38.75); (-12.5,0.5,38.75); (-12.5,10.5,38.75); (-20,10.5,38.75); //(-20, 0.5, 40); (-12.5, 0.5, 40); (-12.5, 10.5, 40); (-20, 10.5, 40); core::Structure myTestStruct2 = myStructGenerator.CreateRectangularStructureCenteredContourPlaneThicknessNotEqualDosePlaneThickness(2); StructTypePointer spMyStruct2 = boost::make_shared(myTestStruct2); //generate test structure. contours are //(-20,0.5,38.75); (-12.5,0.5,38.75); (-12.5,10.5,38.75); (-20,10.5,38.75); //(-20, 0.5, 41.25); (-12.5, 0.5, 41.25); (-12.5, 10.5, 41.25); (-20, 10.5, 41.25); //(-20, 0.5, 48.75); (-12.5, 0.5, 48.75); (-12.5, 10.5, 48.75); (-20, 10.5, 48.75); //(-20, 0.5, 51.25); (-12.5, 0.5, 51.25); (-12.5, 10.5, 51.25); (-20, 10.5, 51.25); //to test calcVoxelizationThickness bug core::Structure myTestStruct3 = myStructGenerator.CreateRectangularStructureCentered(2, 3, 6, 7); StructTypePointer spMyStruct3 = boost::make_shared(myTestStruct3); //1) test BoostMask & BoostMaskAccessor constructor CHECK_NO_THROW(rttb::masks::boost::BoostMask(geometricPtr, spMyStruct)); rttb::masks::boost::BoostMask boostMask = rttb::masks::boost::BoostMask( geometricPtr, spMyStruct); CHECK_NO_THROW(rttb::masks::boost::BoostMaskAccessor(spMyStruct, spTestDoseAccessor->getGeometricInfo(), true)); rttb::masks::boost::BoostMaskAccessor boostMaskAccessor(spMyStruct, spTestDoseAccessor->getGeometricInfo(), true); //2) test getRelevantVoxelVector CHECK_NO_THROW(boostMask.getRelevantVoxelVector()); CHECK_NO_THROW(boostMaskAccessor.getRelevantVoxelVector()); //3) test getMaskAt const VoxelGridIndex3D inMask1(2, 1, 2); //corner between two contours slice -> volumeFraction = 0.25 const VoxelGridIndex3D inMask2(3, 4, 2); //inside between two contours slice ->volumeFraction = 1 const VoxelGridIndex3D inMask3(4, 5, 2); //side between two contours slice -> volumeFraction = 0.5 const VoxelGridIndex3D inMask4(2, 1, 1); //corner on the first contour slice -> volumeFraction = 0.25/2 = 0.125 const VoxelGridIndex3D inMask5(2, 1, 3); //corner on the last contour slice -> volumeFraction = 0.25/2 = 0.125 const VoxelGridIndex3D inMask6(3, 4, 1); //inside on the first contour slice ->volumeFraction = 1 /2 = 0.5 const VoxelGridIndex3D outMask1(7, 5, 4); const VoxelGridIndex3D outMask2(2, 1, 0); const VoxelGridIndex3D outMask3(2, 1, 4); VoxelGridID testId; double errorConstantBoostMask = 1e-7; core::MaskVoxel tmpMV1(0), tmpMV2(0); CHECK(boostMaskAccessor.getMaskAt(inMask1, tmpMV1)); geometricPtr->convert(inMask1, testId); CHECK(boostMaskAccessor.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); CHECK_CLOSE(0.25, tmpMV1.getRelevantVolumeFraction(), errorConstantBoostMask); CHECK_EQUAL(testId, tmpMV1.getVoxelGridID()); CHECK(boostMaskAccessor.getMaskAt(inMask2, tmpMV1)); CHECK(geometricPtr->convert(inMask2, testId)); CHECK(boostMaskAccessor.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); CHECK_EQUAL(1, tmpMV1.getRelevantVolumeFraction()); CHECK_EQUAL(testId, tmpMV1.getVoxelGridID()); CHECK(boostMaskAccessor.getMaskAt(inMask3, tmpMV1)); CHECK(geometricPtr->convert(inMask3, testId)); CHECK(boostMaskAccessor.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); CHECK_CLOSE(0.5, tmpMV1.getRelevantVolumeFraction(), errorConstantBoostMask); CHECK_EQUAL(testId, tmpMV1.getVoxelGridID()); CHECK(boostMaskAccessor.getMaskAt(inMask4, tmpMV1)); CHECK(geometricPtr->convert(inMask4, testId)); CHECK(boostMaskAccessor.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); CHECK_CLOSE(0.125, tmpMV1.getRelevantVolumeFraction(), errorConstantBoostMask); CHECK_EQUAL(testId, tmpMV1.getVoxelGridID()); CHECK(boostMaskAccessor.getMaskAt(inMask5, tmpMV1)); CHECK(geometricPtr->convert(inMask5, testId)); CHECK(boostMaskAccessor.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); CHECK_CLOSE(0.125, tmpMV1.getRelevantVolumeFraction(), errorConstantBoostMask); CHECK_EQUAL(testId, tmpMV1.getVoxelGridID()); CHECK(boostMaskAccessor.getMaskAt(inMask6, tmpMV1)); CHECK(geometricPtr->convert(inMask6, testId)); CHECK(boostMaskAccessor.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); CHECK_CLOSE(0.5, tmpMV1.getRelevantVolumeFraction(), errorConstantBoostMask); CHECK_EQUAL(testId, tmpMV1.getVoxelGridID()); CHECK(!boostMaskAccessor.getMaskAt(outMask1, tmpMV1)); CHECK(geometricPtr->convert(outMask1, testId)); CHECK(!boostMaskAccessor.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); CHECK_EQUAL(0, tmpMV1.getRelevantVolumeFraction()); CHECK(!boostMaskAccessor.getMaskAt(outMask2, tmpMV1)); CHECK(geometricPtr->convert(outMask2, testId)); CHECK(!boostMaskAccessor.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); CHECK_EQUAL(0, tmpMV1.getRelevantVolumeFraction()); CHECK(!boostMaskAccessor.getMaskAt(outMask3, tmpMV1)); CHECK(geometricPtr->convert(outMask3, testId)); CHECK(!boostMaskAccessor.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); CHECK_EQUAL(0, tmpMV1.getRelevantVolumeFraction()); rttb::masks::boost::BoostMask boostMask2 = rttb::masks::boost::BoostMask( geometricPtr, spMyStruct2); CHECK_NO_THROW(boostMask2.getRelevantVoxelVector()); rttb::masks::boost::BoostMaskAccessor boostMaskAccessor2(spMyStruct2, spTestDoseAccessor->getGeometricInfo(), true); CHECK_NO_THROW(boostMaskAccessor2.getRelevantVoxelVector()); CHECK(boostMaskAccessor2.getMaskAt(inMask1, tmpMV1)); geometricPtr->convert(inMask1, testId); CHECK(boostMaskAccessor2.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); //corner, the first contour weight 0.25, the second contour weights 0.5 -> volumeFraction = 0.25*0.25 + 1.25*0.5 = 0.1875 CHECK_CLOSE(0.1875, tmpMV1.getRelevantVolumeFraction(), errorConstantBoostMask); CHECK_EQUAL(testId, tmpMV1.getVoxelGridID()); CHECK(boostMaskAccessor2.getMaskAt(inMask2, tmpMV1)); CHECK(geometricPtr->convert(inMask2, testId)); CHECK(boostMaskAccessor2.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); //inside, the first contour weight 0.25, the second contour weights 0.5 -> ->volumeFraction = 1*0.25 + 1*0.5 = 0.75 CHECK_EQUAL(0.75, tmpMV1.getRelevantVolumeFraction()); CHECK_EQUAL(testId, tmpMV1.getVoxelGridID()); CHECK(boostMaskAccessor2.getMaskAt(inMask3, tmpMV1)); CHECK(geometricPtr->convert(inMask3, testId)); CHECK(boostMaskAccessor2.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); //side the first contour weight 0.25, the second contour weights 0.5 -> ->volumeFraction = 0.5*0.25 + 0.5*0.5 = 0.75 CHECK_CLOSE(0.375, tmpMV1.getRelevantVolumeFraction(), errorConstantBoostMask); CHECK_EQUAL(testId, tmpMV1.getVoxelGridID()); CHECK(boostMaskAccessor2.getMaskAt(inMask4, tmpMV1)); CHECK(geometricPtr->convert(inMask4, testId)); CHECK(boostMaskAccessor2.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); //corner on the first contour slice, weight 0.25 -> volumeFraction = 0.25*0.25 = 0.0625 CHECK_CLOSE(0.0625, tmpMV1.getRelevantVolumeFraction(), errorConstantBoostMask); CHECK_EQUAL(testId, tmpMV1.getVoxelGridID()); CHECK(boostMaskAccessor2.getMaskAt(inMask6, tmpMV1)); CHECK(geometricPtr->convert(inMask6, testId)); CHECK(boostMaskAccessor2.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); //inside on the first contour slice, weight 0.25 ->volumeFraction = 1 * 0.25 = 0.25 CHECK_CLOSE(0.25, tmpMV1.getRelevantVolumeFraction(), errorConstantBoostMask); CHECK_EQUAL(testId, tmpMV1.getVoxelGridID()); CHECK(!boostMaskAccessor2.getMaskAt(outMask1, tmpMV1)); CHECK(geometricPtr->convert(outMask1, testId)); CHECK(!boostMaskAccessor2.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); CHECK_EQUAL(0, tmpMV1.getRelevantVolumeFraction()); //CHECK_EQUAL(testId,tmpMV1.getVoxelGridID()); -> return value will not be valid outside the mask CHECK(!boostMaskAccessor2.getMaskAt(outMask2, tmpMV1)); CHECK(geometricPtr->convert(outMask2, testId)); CHECK(!boostMaskAccessor2.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); CHECK_EQUAL(0, tmpMV1.getRelevantVolumeFraction()); //CHECK_EQUAL(testId,tmpMV1.getVoxelGridID()); -> return value will not be valid outside the mask CHECK(!boostMaskAccessor2.getMaskAt(outMask3, tmpMV1)); CHECK(geometricPtr->convert(outMask3, testId)); CHECK(!boostMaskAccessor2.getMaskAt(testId, tmpMV2)); CHECK_EQUAL(tmpMV1, tmpMV2); CHECK_EQUAL(0, tmpMV1.getRelevantVolumeFraction()); //CHECK_EQUAL(testId,tmpMV1.getVoxelGridID()); -> return value will not be valid outside the mask //3) test calcVoxelizationThickness bug rttb::masks::boost::BoostMask boostMask3 = rttb::masks::boost::BoostMask( geometricPtr, spMyStruct3); CHECK_NO_THROW(boostMask3.getRelevantVoxelVector()); rttb::masks::boost::BoostMaskAccessor boostMaskAccessor3(spMyStruct3, spTestDoseAccessor->getGeometricInfo(), true); CHECK_NO_THROW(boostMaskAccessor3.getRelevantVoxelVector()); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/models/BioModelScatterPlotTest.cpp b/testing/models/BioModelScatterPlotTest.cpp index 6e068d8..f620327 100644 --- a/testing/models/BioModelScatterPlotTest.cpp +++ b/testing/models/BioModelScatterPlotTest.cpp @@ -1,239 +1,239 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbBaseTypeModels.h" #include "rttbBioModel.h" #include "rttbBioModelScatterPlots.h" #include "../core/DummyDVHGenerator.h" #include "DummyModel.h" #include "rttbIntegration.h" #include #include #include namespace rttb { namespace testing { typedef models::ScatterPlotType ScatterPlotType; /*! @brief BioModelScatterPlotTest. Test the scatterplot methods. 1) test if parameters are set correctly 2) test if scatterData contain each model value exactly once */ int BioModelScatterPlotTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; //generate artificial DVH and corresponding statistical values DummyDVHGenerator dummyDVH; const IDType structureID = "myStructure"; const IDType doseID = "myDose"; - core::DVH::DVHPointer dvhPtr = boost::make_shared(dummyDVH.generateDVH(structureID, + core::DVH::Pointer dvhPtr = boost::make_shared(dummyDVH.generateDVH(structureID, doseID, 0, 2000)); //test Dummy Model models::BioModelParamType param1 = 0.35; models::BioModelParamType param2 = 0.023333333333333; models::BioModelParamType param3 = 10000000; //model values will be dose/normalisationDose DoseTypeGy normalisationDose = 10; rttb::models::DummyModel model(dvhPtr); model.resetCounters(); //default number of points is 100 CHECK_NO_THROW(models::getScatterPlotVary1Parameter(model, 0, param1, 0.5, normalisationDose)); model.resetCounters(); ScatterPlotType scatter = models::getScatterPlotVary1Parameter(model, 0, param1, 0.5, normalisationDose); //only 1st parameter should gave been changed CHECK_EQUAL(100, model.getSetParam1Count()); CHECK_EQUAL(0, model.getSetParam2Count()); CHECK_EQUAL(0, model.getSetParam3Count()); CHECK_EQUAL(100, model.getCalcCount()); // all model values should match the corresponding dose/normalizationDose ScatterPlotType::iterator iter; for (iter = scatter.begin(); iter != scatter.end(); ++iter) { double currentKey = iter->first; if ((currentKey / normalisationDose) != iter->second.first) { CHECK_EQUAL((currentKey / normalisationDose), iter->second.first); } } model.resetCounters(); //number of points is 50 CHECK_NO_THROW(models::getScatterPlotVary1Parameter(model, 1, param2, 0.25, normalisationDose, 50)); model.resetCounters(); scatter = models::getScatterPlotVary1Parameter(model, 1, param2, 0.25, normalisationDose, 50); //only 1st parameter should gave been changed CHECK_EQUAL(0, model.getSetParam1Count()); CHECK_EQUAL(50, model.getSetParam2Count()); CHECK_EQUAL(0, model.getSetParam3Count()); CHECK_EQUAL(50, model.getCalcCount()); // all model values should match the corresponding dose/normalizationDose for (iter = scatter.begin(); iter != scatter.end(); ++iter) { double currentKey = iter->first; if ((currentKey / normalisationDose) != iter->second.first) { CHECK_EQUAL((currentKey / normalisationDose), iter->second.first); } } model.resetCounters(); //number of points is 150 CHECK_NO_THROW(models::getScatterPlotVary1Parameter(model, 2, param3, 0.75, normalisationDose, 150)); model.resetCounters(); scatter = models::getScatterPlotVary1Parameter(model, 2, param3, 0.75, normalisationDose, 150); //only 1st parameter should gave been changed CHECK_EQUAL(0, model.getSetParam1Count()); CHECK_EQUAL(0, model.getSetParam2Count()); CHECK_EQUAL(150, model.getSetParam3Count()); CHECK_EQUAL(150, model.getCalcCount()); // all model values should match the corresponding dose/normalizationDose for (iter = scatter.begin(); iter != scatter.end(); ++iter) { double currentKey = iter->first; if ((currentKey / normalisationDose) != iter->second.first) { CHECK_EQUAL((currentKey / normalisationDose), iter->second.first); } } model.resetCounters(); std::vector paramIDVec; models::BioModel::ParamVectorType meanVec; models::BioModel::ParamVectorType varianceVec; paramIDVec.push_back(0); meanVec.push_back(1); varianceVec.push_back(0.6); paramIDVec.push_back(1); meanVec.push_back(10); varianceVec.push_back(0.5); paramIDVec.push_back(2); meanVec.push_back(100); varianceVec.push_back(0.4); //number of points is 50 CHECK_NO_THROW(models::getScatterPlotVaryParameters(model, paramIDVec, meanVec, varianceVec, normalisationDose, 50)); model.resetCounters(); scatter = models::getScatterPlotVaryParameters(model, paramIDVec, meanVec, varianceVec, normalisationDose, 50); //only 1st parameter should gave been changed CHECK_EQUAL(50, model.getSetParam1Count()); CHECK_EQUAL(50, model.getSetParam2Count()); CHECK_EQUAL(50, model.getSetParam3Count()); CHECK_EQUAL(50, model.getCalcCount()); // all model values should match the corresponding dose/normalizationDose for (iter = scatter.begin(); iter != scatter.end(); ++iter) { double currentKey = iter->first; if ((currentKey / normalisationDose) != iter->second.first) { CHECK_EQUAL((currentKey / normalisationDose), iter->second.first); } } model.resetCounters(); //test 2000 points CHECK_NO_THROW(models::getScatterPlotVaryParameters(model, paramIDVec, meanVec, varianceVec, normalisationDose, 10000)); //test iterativeIntegration /*std::string bedFileName="d:/Temp/bed.txt"; std::ifstream dvh_ifstr(bedFileName,std::ios::in); std::vector volumeV2; std::vector bedV2; //std::cout << "iterative integration"<< std::endl; if ( !dvh_ifstr.is_open() ) { std::cerr<< "DVH file name invalid: could not open the dvh file!"<> volume; volumeV2.push_back(volume); //std::cout << "("<< volume << ","; std::string lineSub2 = line.substr(found2+1,found3-found2-1); //std::cout << lineSub2 << std::endl; std::stringstream ss2(lineSub2); double bed; ss2 >> bed; bedV2.push_back(bed); //std::cout << bed << ");"; } } } struct rttb::models::TcpParams params={0.302101,0.08,10000000,volumeV2,bedV2}; double result = rttb::models::integrateTCP(0, params);*/ RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/models/BioModelTest.cpp b/testing/models/BioModelTest.cpp index d6d6416..a4a6a36 100644 --- a/testing/models/BioModelTest.cpp +++ b/testing/models/BioModelTest.cpp @@ -1,306 +1,306 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbBaseTypeModels.h" #include "rttbBioModel.h" #include "rttbDVH.h" #include "rttbTCPLQModel.h" #include "rttbNTCPLKBModel.h" #include "rttbNTCPRSModel.h" #include "rttbBaseTypeModels.h" #include "rttbBioModelCurve.h" #include "rttbInvalidParameterException.h" #include "rttbBioModelScatterPlots.h" namespace rttb { namespace testing { typedef core::DVH::DataDifferentialType DataDifferentialType; /*! @brief RTBioModelTest. TCP calculated using a DVH PTV and LQ Model. NTCP tested using 3 Normal Tissue DVHs and LKB/RS Model. TCPLQ: 1) test constructors (values as expected?) 2) test init (calcTCPxxx) 3) test set/get NTCP (LKB): 1) test constructors (values as expected?) 2) test init (calcxxx) 3) test set/get NTCP (RS): 1) test constructors (values as expected?) 2) test init (calcxxx) 3) test set/get */ int BioModelTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; //generate artificial DVH and corresponding statistical values DoseTypeGy binSize = DoseTypeGy(0.1); DoseVoxelVolumeType voxelVolume = 8; DataDifferentialType aDataDifferential; DoseCalcType value = 0; DVHVoxelNumber numberOfVoxels = 0; // creat default values for (int i = 0; i < 98; i++) { value = 0; numberOfVoxels += value; aDataDifferential.push_back(value); } aDataDifferential.push_back(10); aDataDifferential.push_back(20); const IDType structureID = "myStructure"; const IDType doseID = "myDose"; const IDType voxelizationID = "myVoxelization"; - core::DVH::DVHPointer dvhPtr = boost::make_shared(aDataDifferential, binSize, + core::DVH::Pointer dvhPtr = boost::make_shared(aDataDifferential, binSize, voxelVolume, structureID, doseID, voxelizationID); //test TCP LQ Model models::BioModelParamType alpha = 0.35; models::BioModelParamType beta = 0.023333333333333; models::BioModelParamType roh = 10000000; int numFractions = 8; DoseTypeGy normalizationDose = 50; //1) test constructors (values as expected?) rttb::models::TCPLQModel tcplq = rttb::models::TCPLQModel(); CHECK_EQUAL(0, tcplq.getAlphaMean()); CHECK_EQUAL(0, tcplq.getAlphaBeta()); CHECK_EQUAL(0, tcplq.getRho()); CHECK_EQUAL(0, tcplq.getValue()); tcplq = rttb::models::TCPLQModel(dvhPtr, roh, numFractions, alpha / beta, alpha, 0.08); CHECK_EQUAL(alpha, tcplq.getAlphaMean()); CHECK_EQUAL(alpha / beta, tcplq.getAlphaBeta()); CHECK_EQUAL(roh, tcplq.getRho()); CHECK_EQUAL(0, tcplq.getValue()); tcplq = rttb::models::TCPLQModel(); CHECK_EQUAL(0, tcplq.getAlphaMean()); CHECK_EQUAL(0, tcplq.getAlphaBeta()); CHECK_EQUAL(0, tcplq.getRho()); CHECK_EQUAL(0, tcplq.getValue()); tcplq = rttb::models::TCPLQModel(dvhPtr, alpha, beta, roh, numFractions); CHECK_EQUAL(alpha, tcplq.getAlphaMean()); CHECK_EQUAL(alpha / beta, tcplq.getAlphaBeta()); CHECK_EQUAL(roh, tcplq.getRho()); CHECK_EQUAL(0, tcplq.getValue()); //2) test init (calcTCPxxx) CHECK_NO_THROW(tcplq.init(1)); //3) test set/get CHECK_EQUAL(0, tcplq.getValue()); CHECK_NO_THROW(tcplq.setParameters(alpha, 10, roh, 0.08)); CHECK_EQUAL(10, tcplq.getAlphaBeta()); CHECK_EQUAL(0.08, tcplq.getAlphaVariance()); CHECK_EQUAL(alpha, tcplq.getAlphaMean()); CHECK_EQUAL(roh, tcplq.getRho()); CHECK_NO_THROW(models::getCurveDoseVSBioModel(tcplq, normalizationDose)); std::vector aParameterVector; aParameterVector.push_back(alpha + 0.02); CHECK_THROW_EXPLICIT(tcplq.setParameterVector(aParameterVector), core::InvalidParameterException); aParameterVector.push_back(0.06); aParameterVector.push_back(8); aParameterVector.push_back(roh / 10); CHECK_NO_THROW(tcplq.setParameterVector(aParameterVector)); CHECK_EQUAL(8, tcplq.getAlphaBeta()); CHECK_EQUAL(0.06, tcplq.getAlphaVariance()); CHECK_EQUAL(alpha + 0.02, tcplq.getAlphaMean()); CHECK_EQUAL(roh / 10, tcplq.getRho()); for (int i = 0; i < 4; i++) { CHECK_NO_THROW(tcplq.setParameterByID(i, models::BioModelParamType(i))); } CHECK_THROW_EXPLICIT(tcplq.setParameterByID(4, 4.0), core::InvalidParameterException); CHECK_EQUAL(0, tcplq.getParameterID("alphaMean")); CHECK_EQUAL(0, tcplq.getAlphaMean()); CHECK_EQUAL(1, tcplq.getParameterID("alphaVariance")); CHECK_EQUAL(1, tcplq.getAlphaVariance()); CHECK_EQUAL(2, tcplq.getParameterID("alpha_beta")); CHECK_EQUAL(2, tcplq.getAlphaBeta()); CHECK_EQUAL(3, tcplq.getParameterID("rho")); CHECK_EQUAL(3, tcplq.getRho()); //test NTCPLKBModel //1) test constructors (values as expected?) models::BioModelParamType aVal = 10; models::BioModelParamType mVal = 0.16; models::BioModelParamType d50Val = 35; CHECK_NO_THROW(rttb::models::NTCPLKBModel()); rttb::models::NTCPLKBModel lkb = rttb::models::NTCPLKBModel(); CHECK_EQUAL(0, lkb.getA()); CHECK_EQUAL(0, lkb.getM()); CHECK_EQUAL(0, lkb.getD50()); CHECK_EQUAL(0, lkb.getValue()); CHECK_NO_THROW(rttb::models::NTCPLKBModel(dvhPtr, d50Val, mVal, aVal)); lkb = rttb::models::NTCPLKBModel(dvhPtr, d50Val, mVal, aVal); CHECK_EQUAL(0, lkb.getValue()); CHECK_EQUAL(dvhPtr, lkb.getDVH()); CHECK_EQUAL(aVal, lkb.getA()); CHECK_EQUAL(mVal, lkb.getM()); CHECK_EQUAL(d50Val, lkb.getD50()); //2) test init (calcxxx) CHECK_NO_THROW(lkb.init(1)); lkb.getValue(); //3) test set/get lkb = rttb::models::NTCPLKBModel(); CHECK_EQUAL(0, lkb.getA()); CHECK_EQUAL(0, lkb.getM()); CHECK_EQUAL(0, lkb.getD50()); lkb.setDVH(dvhPtr); CHECK_EQUAL(dvhPtr, lkb.getDVH()); lkb.setA(aVal); CHECK_EQUAL(aVal, lkb.getA()); lkb.setM(mVal); CHECK_EQUAL(mVal, lkb.getM()); lkb.setD50(d50Val); CHECK_EQUAL(d50Val, lkb.getD50()); CHECK_NO_THROW(models::getCurveEUDVSBioModel(lkb)); aParameterVector.clear(); aParameterVector.push_back(d50Val + 5); CHECK_THROW_EXPLICIT(lkb.setParameterVector(aParameterVector), core::InvalidParameterException); aParameterVector.push_back(mVal + 0.2); aParameterVector.push_back(aVal + 0.5); CHECK_NO_THROW(lkb.setParameterVector(aParameterVector)); CHECK_EQUAL(aVal + 0.5, lkb.getA()); CHECK_EQUAL(mVal + 0.2, lkb.getM()); CHECK_EQUAL(d50Val + 5, lkb.getD50()); for (int i = 0; i < 3; i++) { CHECK_NO_THROW(lkb.setParameterByID(i, models::BioModelParamType(i))); } CHECK_THROW_EXPLICIT(lkb.setParameterByID(3, 4.0), core::InvalidParameterException); CHECK_EQUAL(0, lkb.getParameterID("d50")); CHECK_EQUAL(0, lkb.getD50()); CHECK_EQUAL(1, lkb.getParameterID("m")); CHECK_EQUAL(1, lkb.getM()); CHECK_EQUAL(2, lkb.getParameterID("a")); CHECK_EQUAL(2, lkb.getA()); //test NTCPRSModel //1) test constructors (values as expected?) CHECK_NO_THROW(rttb::models::NTCPRSModel()); models::BioModelParamType gammaVal = 1.7; models::BioModelParamType sVal = 1; CHECK_NO_THROW(rttb::models::NTCPRSModel(dvhPtr, d50Val, gammaVal, sVal)); rttb::models::NTCPRSModel rs = rttb::models::NTCPRSModel(dvhPtr, d50Val, gammaVal, sVal); CHECK_EQUAL(dvhPtr, rs.getDVH()); CHECK_EQUAL(d50Val, rs.getD50()); CHECK_EQUAL(gammaVal, rs.getGamma()); CHECK_EQUAL(sVal, rs.getS()); rs = rttb::models::NTCPRSModel(); CHECK_EQUAL(0, rs.getGamma()); CHECK_EQUAL(0, rs.getS()); CHECK_EQUAL(0, rs.getD50()); //3) test set/get rs.setDVH(dvhPtr); CHECK_EQUAL(dvhPtr, rs.getDVH()); rs.setD50(d50Val); CHECK_EQUAL(d50Val, rs.getD50()); rs.setGamma(gammaVal); CHECK_EQUAL(gammaVal, rs.getGamma()); rs.setS(sVal); CHECK_EQUAL(sVal, rs.getS()); //2) test init (calcxxx) CHECK_NO_THROW(rs.init(1)); //3) test set/get continued aParameterVector.clear(); aParameterVector.push_back(d50Val + 5); CHECK_THROW_EXPLICIT(rs.setParameterVector(aParameterVector), core::InvalidParameterException); aParameterVector.push_back(gammaVal + 0.2); aParameterVector.push_back(sVal + 0.5); CHECK_NO_THROW(rs.setParameterVector(aParameterVector)); CHECK_EQUAL(gammaVal + 0.2, rs.getGamma()); CHECK_EQUAL(sVal + 0.5, rs.getS()); CHECK_EQUAL(d50Val + 5, rs.getD50()); for (int i = 0; i < 3; i++) { CHECK_NO_THROW(rs.setParameterByID(i, models::BioModelParamType(i))); } CHECK_THROW_EXPLICIT(rs.setParameterByID(3, 4.0), core::InvalidParameterException); CHECK_EQUAL(0, rs.getParameterID("d50")); CHECK_EQUAL(0, rs.getD50()); CHECK_EQUAL(1, rs.getParameterID("gamma")); CHECK_EQUAL(1, rs.getGamma()); CHECK_EQUAL(2, rs.getParameterID("s")); CHECK_EQUAL(2, rs.getS()); //Scatter plot tests CHECK_NO_THROW(models::getScatterPlotVary1Parameter(tcplq, 0, alpha, 0, normalizationDose)); //variance=0, will be set to 1e-30 CHECK_THROW_EXPLICIT(models::getScatterPlotVary1Parameter(tcplq, 0, alpha, alpha * 0.1, 0), core::InvalidParameterException);//normalisationdose=0 CHECK_THROW_EXPLICIT(models::getScatterPlotVary1Parameter(tcplq, 0, alpha, alpha * 0.1, normalizationDose, 10000, 0, 0), core::InvalidParameterException);//maxDose-minDose=0 RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb \ No newline at end of file diff --git a/testing/models/DvhBasedModelsTest.cpp b/testing/models/DvhBasedModelsTest.cpp index 347d252..ee4ea26 100644 --- a/testing/models/DvhBasedModelsTest.cpp +++ b/testing/models/DvhBasedModelsTest.cpp @@ -1,110 +1,110 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include "litCheckMacros.h" #include "rttbDVH.h" #include "rttbDvhBasedModels.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace testing { typedef core::DVH::DataDifferentialType DataDifferentialType; /*! @brief DvhBasedModelsTest. 1) Test bed und lqed2 */ int DvhBasedModelsTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; //1) test calcBEDDVH and calcLQED2DVH //generate artificial DVH and corresponding statistical values DoseTypeGy binSize = DoseTypeGy(0.1); DoseVoxelVolumeType voxelVolume = 8; const IDType structureID = "myStructure"; const IDType doseID = "myDose"; const IDType voxelizationID = "myVoxelization"; DataDifferentialType aDataDifferential; std::vector bedVector; std::vector lqed2Vector; int numberOfFractions = 2; double alpha_beta = 10; for (int i = 0; i < 100; i++) { double volume = DoseCalcType((double(rand()) / RAND_MAX) * 1000); double dose = (i + 0.5) * binSize; aDataDifferential.push_back(volume); bedVector.push_back(dose * (1 + dose / (numberOfFractions * alpha_beta))); lqed2Vector.push_back(dose * ((alpha_beta + (dose / numberOfFractions)) / (alpha_beta + 2))); } core::DVH myDVH(aDataDifferential, binSize, voxelVolume, structureID, doseID, voxelizationID); - core::DVH::DVHPointer dvhPtr = boost::make_shared(myDVH); + core::DVH::Pointer dvhPtr = boost::make_shared(myDVH); CHECK_THROW_EXPLICIT(rttb::models::calcBEDDVH(dvhPtr, 0, 10), core::InvalidParameterException); CHECK_THROW_EXPLICIT(rttb::models::calcBEDDVH(dvhPtr, 10, -1), core::InvalidParameterException); CHECK_NO_THROW(rttb::models::calcBEDDVH(dvhPtr, 10, 10)); CHECK_EQUAL(rttb::models::calcBEDDVH(dvhPtr, 2, 10).size(), myDVH.getDataDifferential().size()); rttb::models::BEDDVHType bedDVH = rttb::models::calcBEDDVH(dvhPtr, numberOfFractions, alpha_beta); CHECK_THROW_EXPLICIT(rttb::models::calcLQED2DVH(dvhPtr, 1, 10), core::InvalidParameterException); CHECK_THROW_EXPLICIT(rttb::models::calcLQED2DVH(dvhPtr, 10, -1), core::InvalidParameterException); CHECK_NO_THROW(rttb::models::calcLQED2DVH(dvhPtr, 10, 10, true)); CHECK_EQUAL(rttb::models::calcLQED2DVH(dvhPtr, 2, 10).size(), myDVH.getDataDifferential().size()); rttb::models::BEDDVHType lqed2DVH = rttb::models::calcLQED2DVH(dvhPtr, numberOfFractions, alpha_beta); //check the calculation rttb::models::BEDDVHType::iterator itBED, itLQED2; std::vector::iterator itBEDVec, itLQED2Vec; DataDifferentialType::iterator itDiff; for (itBED = bedDVH.begin(), itLQED2 = lqed2DVH.begin(), itBEDVec = bedVector.begin(), itLQED2Vec = lqed2Vector.begin(), itDiff = aDataDifferential.begin(); itBED != bedDVH.end(), itLQED2 != lqed2DVH.end(), itBEDVec != bedVector.end(), itLQED2Vec != lqed2Vector.end(), itDiff != aDataDifferential.end(); ++itBED, ++itLQED2, ++itBEDVec, ++itLQED2Vec, ++itDiff) { //check volume CHECK_EQUAL(*itDiff, (*itBED).second); CHECK_EQUAL((*itBED).second, (*itLQED2).second); //check bed CHECK_EQUAL(*itBEDVec, (*itBED).first); //check lqed2 CHECK_EQUAL(*itLQED2Vec, (*itLQED2).first); } RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb \ No newline at end of file diff --git a/testing/models/LQModelAccessorTest.cpp b/testing/models/LQModelAccessorTest.cpp index b0457c3..58627e7 100644 --- a/testing/models/LQModelAccessorTest.cpp +++ b/testing/models/LQModelAccessorTest.cpp @@ -1,155 +1,155 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "litCheckMacros.h" #include #include "rttbLQModelAccessor.h" #include "rttbGenericDoseIterator.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbInvalidDoseException.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace testing { /*! @brief LQModelAccessorTest. 1) Test constructors 2) Test getGeometricInfo() 3) Test getValueAt() */ int LQModelAccessorTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; std::string RTDOSE_FILENAME_CONSTANT_TWO; std::string RTDOSE_FILENAME_INCREASE_X; if (argc > 2) { RTDOSE_FILENAME_CONSTANT_TWO = argv[1]; RTDOSE_FILENAME_INCREASE_X = argv[2]; } else { std::cout << "at least two parameters for LQModelAccessorTest are expected" << std::endl; return -1; } typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1( RTDOSE_FILENAME_CONSTANT_TWO.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator2( RTDOSE_FILENAME_INCREASE_X.c_str()); DoseAccessorPointer doseAccessor2(doseAccessorGenerator2.generateDoseAccessor()); core::GeometricInfo doseAccessor1GeometricInfo = doseAccessor1->getGeometricInfo(); core::GeometricInfo doseAccessor2GeometricInfo = doseAccessor2->getGeometricInfo(); DoseAccessorPointer doseAccessorNull; - core::AccessorInterface::AccessorPointer LQWithConstantDose, LQWithConstantDoseDoseScalingTwo, LQWithConstantNFractionsTwo, LQWithIncreaseXDose, LQWithConstantDoseAndMap; + core::AccessorInterface::Pointer LQWithConstantDose, LQWithConstantDoseDoseScalingTwo, LQWithConstantNFractionsTwo, LQWithIncreaseXDose, LQWithConstantDoseAndMap; //1) test constructor CHECK_THROW_EXPLICIT(models::LQModelAccessor(doseAccessorNull, 0, 0), core::InvalidDoseException); CHECK_THROW_EXPLICIT(models::LQModelAccessor(doseAccessor1, 0.2, 0.02, 1, -1), core::InvalidParameterException); CHECK_THROW_EXPLICIT(models::LQModelAccessor(doseAccessorNull, doseAccessorNull, doseAccessorNull), core::InvalidDoseException); CHECK_THROW_EXPLICIT(models::LQModelAccessor(doseAccessor1, doseAccessor1, doseAccessorNull), core::InvalidDoseException); CHECK_THROW_EXPLICIT(models::LQModelAccessor(doseAccessor1, doseAccessorNull, doseAccessor1), core::InvalidDoseException); CHECK_THROW_EXPLICIT(models::LQModelAccessor(doseAccessorNull, doseAccessor1, doseAccessor1), core::InvalidDoseException); CHECK_NO_THROW(LQWithConstantDose = boost::make_shared(doseAccessor1, 0.2, 0.02)); CHECK_NO_THROW(LQWithConstantNFractionsTwo = boost::make_shared(doseAccessor1, 0.2, 0.02, 2)); CHECK_NO_THROW(LQWithConstantDoseDoseScalingTwo = boost::make_shared (doseAccessor1, 0.2, 0.02, 1, 2.0)); CHECK_NO_THROW(LQWithIncreaseXDose = boost::make_shared(doseAccessor2, 0.3, 0.01)); CHECK_NO_THROW(LQWithConstantDoseAndMap = boost::make_shared(doseAccessor1, doseAccessor2, doseAccessor2)); //2) Test getGeometricInfo() CHECK_EQUAL(LQWithConstantDose->getGeometricInfo(), doseAccessor1GeometricInfo); CHECK_EQUAL(LQWithIncreaseXDose->getGeometricInfo(), doseAccessor2GeometricInfo); //3) Test getValueAt() models::BioModelParamType expectedLQWithDoseTwo = exp(-(0.2 * 2 + (0.02 * 2 * 2))); CHECK_EQUAL(LQWithConstantDose->getValueAt(0), expectedLQWithDoseTwo); CHECK_EQUAL(LQWithConstantDose->getValueAt(LQWithConstantDose->getGridSize() - 1), expectedLQWithDoseTwo); CHECK_EQUAL(LQWithConstantDose->getValueAt(VoxelGridIndex3D(1, 2, 6)), expectedLQWithDoseTwo); CHECK_EQUAL(LQWithConstantDose->getValueAt(VoxelGridIndex3D(65, 40, 60)), expectedLQWithDoseTwo); models::BioModelParamType expectedLQWithDoseTwoNFractionsTwo = exp(-(0.2 * 2 + (0.02 * 2 * 2/2))); CHECK_EQUAL(LQWithConstantNFractionsTwo->getValueAt(0), expectedLQWithDoseTwoNFractionsTwo); CHECK_EQUAL(LQWithConstantNFractionsTwo->getValueAt(LQWithConstantNFractionsTwo->getGridSize() - 1), expectedLQWithDoseTwoNFractionsTwo); CHECK_EQUAL(LQWithConstantNFractionsTwo->getValueAt(VoxelGridIndex3D(1, 2, 6)), expectedLQWithDoseTwoNFractionsTwo); CHECK_EQUAL(LQWithConstantNFractionsTwo->getValueAt(VoxelGridIndex3D(65, 40, 60)), expectedLQWithDoseTwoNFractionsTwo); models::BioModelParamType expectedLQWithDoseFour = exp(-(0.2 * 4 + (0.02 * 4 * 4))); CHECK_EQUAL(LQWithConstantDoseDoseScalingTwo->getValueAt(0), expectedLQWithDoseFour); CHECK_EQUAL(LQWithConstantDoseDoseScalingTwo->getValueAt(LQWithConstantDose->getGridSize() - 1), expectedLQWithDoseFour); CHECK_EQUAL(LQWithConstantDoseDoseScalingTwo->getValueAt(VoxelGridIndex3D(1, 2, 6)), expectedLQWithDoseFour); CHECK_EQUAL(LQWithConstantDoseDoseScalingTwo->getValueAt(VoxelGridIndex3D(65, 40, 60)), expectedLQWithDoseFour); models::BioModelParamType expectedLQWithIncreaseX = exp(-(0.3 * 66 * 2.822386e-5 + (0.01 * 66 * 2.822386e-5 * 66 * 2.822386e-5))); CHECK_EQUAL(LQWithIncreaseXDose->getValueAt(0), 1); CHECK_CLOSE(LQWithIncreaseXDose->getValueAt(LQWithIncreaseXDose->getGridSize() - 1), expectedLQWithIncreaseX, errorConstant); expectedLQWithIncreaseX = exp(-(0.3 * 1 * 2.822386e-5 + (0.01 * 1 * 2.822386e-5 * 1 * 2.822386e-5))); CHECK_CLOSE(LQWithIncreaseXDose->getValueAt(VoxelGridIndex3D(1, 2, 6)), expectedLQWithIncreaseX, errorConstant); expectedLQWithIncreaseX = exp(-(0.3 * 45 * 2.822386e-5 + (0.01 * 45 * 2.822386e-5 * 45 * 2.822386e-5))); CHECK_CLOSE(LQWithIncreaseXDose->getValueAt(VoxelGridIndex3D(45, 40, 60)), expectedLQWithIncreaseX, errorConstant); models::BioModelParamType expectedLQWithDoseAndMap = exp(-(66 * 2.822386e-5 * 2 + (66 * 2.822386e-5 * 2 * 2))); CHECK_EQUAL(LQWithConstantDoseAndMap->getValueAt(0), 1); CHECK_CLOSE(LQWithConstantDoseAndMap->getValueAt(LQWithIncreaseXDose->getGridSize() - 1), expectedLQWithDoseAndMap, errorConstant); CHECK_EQUAL(LQWithConstantDoseAndMap->getValueAt(0), LQWithConstantDoseAndMap->getValueAt(VoxelGridIndex3D(0, 0, 0))); RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb \ No newline at end of file diff --git a/testing/validation/VoxelizationDVHComparisonTest.cpp b/testing/validation/VoxelizationDVHComparisonTest.cpp index 83409b6..11260a3 100644 --- a/testing/validation/VoxelizationDVHComparisonTest.cpp +++ b/testing/validation/VoxelizationDVHComparisonTest.cpp @@ -1,176 +1,176 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1333 $ (last changed revision) // @date $Date: 2016-04-22 11:12:14 +0200 (Fr, 22 Apr 2016) $ (last change date) // @author $Author: hentsch $ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include #include #include "litCheckMacros.h" #include "rttbGenericMaskedDoseIterator.h" #include "rttbGenericDoseIterator.h" #include "rttbDicomDoseAccessor.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomFileStructureSetGenerator.h" #include "rttbDVHCalculator.h" #include "rttbBoostMaskAccessor.h" #include "rttbDVHXMLFileWriter.h" #include "rttbDVHXMLFileReader.h" #include "../io/other/CompareDVH.h" namespace rttb { namespace testing { /*! @brief VoxelizationDVHComparisonTests. Computes the DVH difference of different voxelizations (OTB/Boost legacy/Boost) Writes the difference in a DVH and saves in a file */ - core::DoseIteratorInterface::DoseIteratorPointer createMaskDoseIterator(masks::boost::BoostMaskAccessor::StructTypePointer rtstruct, + core::DoseIteratorInterface::Pointer createMaskDoseIterator(masks::boost::BoostMaskAccessor::StructTypePointer rtstruct, core::GenericDoseIterator::DoseAccessorPointer doseAccessor, const std::string& voxelizationType) { core::GenericMaskedDoseIterator::MaskAccessorPointer spMaskAccessor; if (voxelizationType == "Boost"){ auto spBoostRedesignMaskAccessor = ::boost::make_shared(rtstruct, doseAccessor->getGeometricInfo()); spBoostRedesignMaskAccessor->updateMask(); spMaskAccessor = spBoostRedesignMaskAccessor; } auto spMaskedDoseIteratorTmp = ::boost::make_shared(spMaskAccessor, doseAccessor); - core::DoseIteratorInterface::DoseIteratorPointer spMaskedDoseIterator(spMaskedDoseIteratorTmp); + core::DoseIteratorInterface::Pointer spMaskedDoseIterator(spMaskedDoseIteratorTmp); return spMaskedDoseIterator; } rttb::core::DVH calcDVH(core::DVHCalculator::DoseIteratorPointer doseIterator, const IDType& structUID, const IDType& doseUID) { rttb::core::DVHCalculator calc(doseIterator, structUID, doseUID); rttb::core::DVH dvh = *(calc.generateDVH()); return dvh; } void writeCumulativeDVH(const std::string& filename, rttb::core::DVH dvh) { DVHType typeCum = { DVHType::Cumulative }; io::other::DVHXMLFileWriter dvhWriter(filename, typeCum); dvhWriter.writeDVH(boost::make_shared(dvh)); } int VoxelizationDVHComparisonTest(int argc, char* argv[]) { typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; - typedef core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; + typedef core::StructureSet::Pointer StructureSetPointer; PREPARE_DEFAULT_TEST_REPORTING; std::string RTSTRUCT_FILENAME; std::string RTDOSE_FILENAME; std::string RTDVH_XML_OTB_DIRECTORY; std::string RTDVH_XML_BOOST_LEGACY_DIRECTORY; std::string RTDVH_XML_BOOST_DIRECTORY; if (argc > 5) { RTSTRUCT_FILENAME = argv[1]; RTDOSE_FILENAME = argv[2]; RTDVH_XML_OTB_DIRECTORY = argv[3]; RTDVH_XML_BOOST_LEGACY_DIRECTORY = argv[4]; RTDVH_XML_BOOST_DIRECTORY = argv[5]; } // read dicom-rt dose io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1(RTDOSE_FILENAME.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); //create a vector of MaskAccessors (one for each structure) StructureSetPointer rtStructureSet = io::dicom::DicomFileStructureSetGenerator( RTSTRUCT_FILENAME.c_str()).generateStructureSet(); //create directory boost::filesystem::create_directories(RTDVH_XML_BOOST_DIRECTORY); //start evaluation clock_t start(clock()); if (rtStructureSet->getNumberOfStructures() > 0) { for (int j = 0; j < static_cast(rtStructureSet->getNumberOfStructures()); j++) { std::cout << rtStructureSet->getStructure(j)->getLabel() << std::endl; auto spMaskedDoseIteratorBoostRedesign = createMaskDoseIterator(rtStructureSet->getStructure(j), doseAccessor1, "Boost"); auto label = rtStructureSet->getStructure(j)->getLabel(); ::boost::replace_all(label, "/", "_"); boost::filesystem::path dvhOTBFilename(RTDVH_XML_OTB_DIRECTORY); dvhOTBFilename /= "DVH_" + label + ".xml"; boost::filesystem::path dvhBoostFilename(RTDVH_XML_BOOST_LEGACY_DIRECTORY); dvhBoostFilename /= "DVH_" + label + ".xml"; io::other::DVHXMLFileReader dvhReaderOTB(dvhOTBFilename.string()); auto dvhOTB = dvhReaderOTB.generateDVH(); io::other::DVHXMLFileReader dvhReaderBoost(dvhBoostFilename.string()); auto dvhBoost = dvhReaderBoost.generateDVH(); auto dvhBoostRedesign = calcDVH(spMaskedDoseIteratorBoostRedesign, (rtStructureSet->getStructure(j))->getUID(), doseAccessor1->getUID()); boost::filesystem::path dvhBoostRedesignFilename(RTDVH_XML_BOOST_DIRECTORY); dvhBoostRedesignFilename /= "DVH_" + label + ".xml"; writeCumulativeDVH(dvhBoostRedesignFilename.string(), dvhBoostRedesign); std::cout << "=== Dose 1 Structure " << j << "===" << std::endl; std::cout << "with OTB voxelization: " << std::endl; std::cout << dvhOTB << std::endl; std::cout << "with Boost_LEGACY voxelization: " << std::endl; std::cout << dvhBoost << std::endl; std::cout << "with Boost voxelization: " << std::endl; std::cout << dvhBoostRedesign << std::endl; //compare DVH for different voxelizations auto diffDVH = computeDiffDVH(dvhOTB, boost::make_shared(dvhBoostRedesign)); boost::filesystem::path dvhBoostRedesignDiffFilename(RTDVH_XML_BOOST_DIRECTORY); dvhBoostRedesignDiffFilename /= "DVHDiff_" + label + ".xml"; writeCumulativeDVH(dvhBoostRedesignDiffFilename.string(), *diffDVH); } } clock_t finish(clock()); std::cout << "DVH Calculation time: " << finish - start << " ms" << std::endl; RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/validation/VoxelizationValidationTest.cpp b/testing/validation/VoxelizationValidationTest.cpp index 03fcf29..2d3ff95 100644 --- a/testing/validation/VoxelizationValidationTest.cpp +++ b/testing/validation/VoxelizationValidationTest.cpp @@ -1,160 +1,160 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 1495 $ (last changed revision) // @date $Date: 2016-09-29 16:17:47 +0200 (Do, 29 Sep 2016) $ (last change date) // @author $Author: hentsch $ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbGenericMaskedDoseIterator.h" #include "rttbGenericDoseIterator.h" #include "rttbDicomDoseAccessor.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomFileStructureSetGenerator.h" #include "rttbBoostMaskAccessor.h" #include "rttbITKImageMaskAccessorConverter.h" #include "rttbImageWriter.h" #include "rttbBoostMask.h" #include "rttbBoostMaskAccessor.h" #include "rttbITKImageAccessorGenerator.h" #include "rttbITKImageFileAccessorGenerator.h" #include "rttbInvalidParameterException.h" #include "itkSubtractImageFilter.h" #include "itkImageFileReader.h" namespace rttb { namespace testing { io::itk::ITKImageMaskAccessor::ITKMaskImageType::Pointer subtractImages(const io::itk::ITKImageMaskAccessor::ITKMaskImageType::Pointer image1, const io::itk::ITKImageMaskAccessor::ITKMaskImageType::Pointer image2) { typedef itk::SubtractImageFilter SubtractImageFilterType; SubtractImageFilterType::Pointer subtractFilter = SubtractImageFilterType::New(); subtractFilter->SetInput1(image1); subtractFilter->SetInput2(image2); //since the image origin may be modified through the writing process a bit subtractFilter->SetCoordinateTolerance(5e-2); subtractFilter->Update(); return subtractFilter->GetOutput(); } /*! @brief VoxelizationValidationTest. Compare the new boost voxelization to the OTB voxelization Check the creating of new boost masks for files where the old boost voxelization failed. */ int VoxelizationValidationTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; typedef core::GenericMaskedDoseIterator::MaskAccessorPointer MaskAccessorPointer; - typedef core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; + typedef core::StructureSet::Pointer StructureSetPointer; std::string RTSTRUCT_FILENAME; std::string RTDOSE_FILENAME; std::string BoostMask_DIRNAME; std::string OTBMask_DIRNAME; if (argc > 4) { RTSTRUCT_FILENAME = argv[1]; RTDOSE_FILENAME = argv[2]; BoostMask_DIRNAME = argv[3]; OTBMask_DIRNAME = argv[4]; } //create directory boost::filesystem::create_directories(BoostMask_DIRNAME); /* read dicom-rt dose */ io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1(RTDOSE_FILENAME.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); //create a vector of MaskAccessors (one for each structure) StructureSetPointer rtStructureSet = io::dicom::DicomFileStructureSetGenerator( RTSTRUCT_FILENAME.c_str()).generateStructureSet(); if (rtStructureSet->getNumberOfStructures() > 0) { //do not compute structure "Aussenkontur" since it is very large (15000 cm³) for (size_t j = 1; j < rtStructureSet->getNumberOfStructures(); j++) { std::cout << j << ": " << rtStructureSet->getStructure(j)->getLabel() << std::endl; //read OTB mask image boost::filesystem::path otbMaskFilename(OTBMask_DIRNAME); otbMaskFilename /= boost::lexical_cast(j)+".mhd"; typedef itk::ImageFileReader ReaderType; ReaderType::Pointer readerOTB = ReaderType::New(); readerOTB->SetFileName(otbMaskFilename.string()); readerOTB->Update(); const io::itk::ITKImageMaskAccessor::ITKMaskImageType::Pointer otbMaskImage = readerOTB->GetOutput(); //create Boost MaskAccessor clock_t startR(clock()); MaskAccessorPointer boostMaskRPtr = ::boost::make_shared (rtStructureSet->getStructure(j), doseAccessor1->getGeometricInfo()); CHECK_NO_THROW(boostMaskRPtr->updateMask()); clock_t finishR(clock()); std::cout << "Boost Mask Calculation: " << finishR - startR << " ms" << std::endl; rttb::io::itk::ITKImageMaskAccessorConverter itkConverterR(boostMaskRPtr); CHECK(itkConverterR.process()); boost::filesystem::path redesignFilename(BoostMask_DIRNAME); redesignFilename /= boost::lexical_cast(j)+".nrrd"; rttb::io::itk::ImageWriter writerR(redesignFilename.string(), itkConverterR.getITKImage().GetPointer()); CHECK(writerR.writeFile()); auto subtractedRedesignImage = subtractImages(otbMaskImage, itkConverterR.getITKImage()); boost::filesystem::path subtractRedesignFilename(BoostMask_DIRNAME); subtractRedesignFilename /= boost::lexical_cast(j)+"_subtracted.nrrd"; rttb::io::itk::ImageWriter writerRSubtracted(subtractRedesignFilename.string(), subtractedRedesignImage.GetPointer()); CHECK(writerRSubtracted.writeFile()); } } RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb