diff --git a/apps/BioModelCalc/BioModelCalc.cpp b/apps/BioModelCalc/BioModelCalc.cpp index 47551be..0cb4fad 100644 --- a/apps/BioModelCalc/BioModelCalc.cpp +++ b/apps/BioModelCalc/BioModelCalc.cpp @@ -1,150 +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: 1334 $ (last changed revision) // @date $Date: 2016-04-22 11:13:22 +0200 (Fr, 22 Apr 2016) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "BioModelCalcApplicationData.h" #include "BioModelCalcHelper.h" #include "BioModelCmdLineParser.h" #include "boost/shared_ptr.hpp" #include "boost/make_shared.hpp" #include "RTToolboxConfigure.h" #include "rttbException.h" +#include "rttbDoseLoader.cpp" + int main(int argc, const char** argv) { int result = 0; rttb::apps::bioModelCalc::ApplicationData appData; boost::shared_ptr argParser; const std::string appCategory = "RT-Toolbox App"; const std::string appName = "BioModelCalc"; const std::string appDesc = "An App to calculate the Linear quadratic (LQ) BioModel. The GUI for this app is currently under development and in an experimental state."; const std::string appContributor = "SIDT@DKFZ"; const std::string appVersion = RTTB_FULL_VERSION_STRING; try { argParser = boost::make_shared(argc, argv, appName, appVersion, appDesc, appContributor, appCategory); } catch (const std::exception& e) { std::cerr << e.what() << std::endl; return -1; } // This is vital. The application needs to exit if the "help" or "version" parameter is set // because this means the other parameters won't be parsed. if (argParser->isSet(argParser->OPTION_HELP) || argParser->isSet(argParser->OPTION_VERSION) || argParser->isSet(argParser->OPTION_XML)) { return 0; } rttb::apps::bioModelCalc::populateAppData(argParser, appData); std::cout << std::endl << "*******************************************" << std::endl; std::cout << "Dose file: " << appData._doseFileName << std::endl; std::cout << "Bio model output file: " << appData._outputFileName << std::endl; std::cout << "Model: " << appData._model << std::endl; std::cout << "Model parameters: "; for (size_t i = 0; i < appData._modelParameters.size(); i++) { if (i != 0) { std::cout << ", "; } std::cout << appData._modelParameters.at(i); } for (size_t i = 0; i < appData._modelParameterMapsFilename.size(); i++) { if (i != 0) { std::cout << ", "; } std::cout << appData._modelParameterMapsFilename.at(i); } std::cout << std::endl; std::cout << "Dose scaling: " << appData._doseScaling << std::endl; if (argParser->isSet(argParser->OPTION_N_FRACTIONS)){ std::cout << "#Fractions: " << appData._nFractions << std::endl; } std::cout << std::endl; + std::cout << std::endl << "read dose file... "; + try { - appData._dose = rttb::apps::bioModelCalc::loadDose(appData._doseFileName, appData._doseLoadStyle); + appData._dose = rttb::io::utils::loadDose(appData._doseFileName, appData._doseLoadStyle); for (const auto& filename : appData._modelParameterMapsFilename){ - appData._modelParameterMaps.push_front(rttb::apps::bioModelCalc::loadDose(filename, appData._parameterMapsLoadStyle)); + appData._modelParameterMaps.push_front(rttb::io::utils::loadDose(filename, appData._parameterMapsLoadStyle)); } + std::cout << "done." << std::endl; } catch (rttb::core::Exception& e) { std::cerr << "RTTB Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 1; } catch (const std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 1; } catch (...) { std::cerr << "Error!!! unknown error while reading input image." << std::endl; return 1; } try { rttb::apps::bioModelCalc::processData(appData); } catch (rttb::core::Exception& e) { std::cerr << "RTTB Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 2; } catch (std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 2; } catch (...) { std::cerr << "Error!!! unknown error while calculating the bioModel or writing the image." << std::endl; return 2; } return result; } diff --git a/apps/BioModelCalc/BioModelCalcHelper.cpp b/apps/BioModelCalc/BioModelCalcHelper.cpp index aeb716e..53de684 100644 --- a/apps/BioModelCalc/BioModelCalcHelper.cpp +++ b/apps/BioModelCalc/BioModelCalcHelper.cpp @@ -1,155 +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 "rttbDicomFileDoseAccessorGenerator.h" -#include "rttbDicomHelaxFileDoseAccessorGenerator.h" -#include "rttbITKImageFileAccessorGenerator.h" #include "rttbITKImageAccessorConverter.h" #include "rttbImageWriter.h" #include "rttbLQModelAccessor.h" -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::bioModelCalc::loadDose(const std::string& fileName, - const rttb::apps::bioModelCalc::ApplicationData::LoadingStyleArgType& args) -{ - rttb::core::DoseAccessorInterface::DoseAccessorPointer result; - - std::cout << std::endl << "read dose file... "; - - if (args.empty() || args[0] == "dicom") - { - std::cout << "use RTTB dicom IO... "; - result = loadDicomDose(fileName); - } - else if (args[0] == "helax") - { - std::cout << "use RTTB Helax IO... "; - result = loadHelaxDose(fileName); - } - else if (args[0] == "itk") - { - std::cout << "use RTTB itk IO... "; - result = loadITKDose(fileName); - } - else - { - rttbDefaultExceptionStaticMacro( << "Unknown io style selected. Cannot load data. Selected style: " - << args[0]); - } - - std::cout << "done." << std::endl; - - return result; -} - -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::bioModelCalc::loadDicomDose(const std::string& fileName) -{ - rttb::io::dicom::DicomFileDoseAccessorGenerator generator(fileName); - return generator.generateDoseAccessor(); -} - -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::bioModelCalc::loadHelaxDose(const std::string& path) -{ - rttb::io::helax::DicomHelaxFileDoseAccessorGenerator generator(path); - return generator.generateDoseAccessor(); -} - -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::bioModelCalc::loadITKDose(const std::string& fileName) -{ - rttb::io::itk::ITKImageFileAccessorGenerator generator(fileName); - return generator.generateDoseAccessor(); -} - - void rttb::apps::bioModelCalc::processData(rttb::apps::bioModelCalc::ApplicationData& appData) { rttb::core::DoseAccessorInterface::DoseAccessorPointer outputAccessor; std::cout << std::endl << "generate biomodel... "; rttb::core::AccessorInterface::AccessorPointer 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, 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) { 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 a717243..c1c84f2 100644 --- a/apps/BioModelCalc/BioModelCalcHelper.h +++ b/apps/BioModelCalc/BioModelCalcHelper.h @@ -1,77 +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; - typedef std::vector LoadingStyleArgType; - /*! @brief loads a dose from a file based on the loadingStyle. - @details Throws an rttb::Exception if loading fails - */ - core::DoseAccessorInterface::DoseAccessorPointer loadDose(const std::string& fileName, - const LoadingStyleArgType& args); - /*! @brief loads a dicom dose from a file. - @details Throws an rttb::Exception if loading fails - @sa DicomFileDoseAccessorGenerator - */ - core::DoseAccessorInterface::DoseAccessorPointer loadDicomDose(const std::string& fileName); - /*! @brief loads a helax dose from a file. - @details Throws an rttb::Exception if loading fails - @sa DicomHelaxFileDoseAccessorGenerator - */ - core::DoseAccessorInterface::DoseAccessorPointer loadHelaxDose(const std::string& path); - /*! @brief loads an itk dose from a file. - @details Throws an rttb::Exception if loading fails. Might be of all formats that ITK know (*.mhd, *.nrrd, ...). The absolute image values are taken as dose. - @sa ITKImageFileAccessorGenerator - */ - core::DoseAccessorInterface::DoseAccessorPointer loadITKDose(const std::string& fileName); - - /*! @brief Contains the business logic of processing all information to calculate a bioModel from the dose and writing it back to an image. - @details Uses appData for the input data and the correct configuration. - */ + class ApplicationData; + void processData(ApplicationData& appData); core::AccessorInterface::AccessorPointer generateBioModel( core::DoseAccessorInterface::DoseAccessorPointer 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); } } } #endif diff --git a/apps/BioModelCalc/CMakeLists.txt b/apps/BioModelCalc/CMakeLists.txt index 0044b4f..4b646fa 100644 --- a/apps/BioModelCalc/CMakeLists.txt +++ b/apps/BioModelCalc/CMakeLists.txt @@ -1,5 +1,5 @@ MESSAGE (STATUS "generating app: BioModelCalc - calculating the radiobiological effect based on dose") SET(RTTB_Boost_ADDITIONAL_COMPONENT program_options) -RTTB_CREATE_APPLICATION(BioModelCalc DEPENDS RTTBCore RTTBITKIO RTTBDicomIO RTTBHelaxIO RTTBModels PACKAGE_DEPENDS ArgumentParsingLib BoostBinaries) +RTTB_CREATE_APPLICATION(BioModelCalc DEPENDS RTTBCore RTTBModels RTTBUtilsIO PACKAGE_DEPENDS ArgumentParsingLib BoostBinaries) diff --git a/apps/DoseAcc/CMakeLists.txt b/apps/DoseAcc/CMakeLists.txt index cea0a09..7260432 100644 --- a/apps/DoseAcc/CMakeLists.txt +++ b/apps/DoseAcc/CMakeLists.txt @@ -1,4 +1,4 @@ MESSAGE (STATUS "generating app: DoseAcc - simple dose accumulation tool") SET(RTTB_Boost_ADDITIONAL_COMPONENT program_options) -RTTB_CREATE_APPLICATION(DoseAcc DEPENDS RTTBCore RTTBAlgorithms RTTBInterpolation RTTBInterpolationMatchPointTransformation RTTBITKIO RTTBDicomIO RTTBHelaxIO PACKAGE_DEPENDS ArgumentParsingLib MatchPoint ITK BoostBinaries) +RTTB_CREATE_APPLICATION(DoseAcc DEPENDS RTTBCore RTTBAlgorithms RTTBInterpolation RTTBInterpolationMatchPointTransformation RTTBUtilsIO PACKAGE_DEPENDS ArgumentParsingLib MatchPoint ITK BoostBinaries) diff --git a/apps/DoseAcc/DoseAcc.cpp b/apps/DoseAcc/DoseAcc.cpp index 9e59e41..d068d6f 100644 --- a/apps/DoseAcc/DoseAcc.cpp +++ b/apps/DoseAcc/DoseAcc.cpp @@ -1,174 +1,179 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed 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: 1107 $ (last changed revision) // @date $Date: 2015-09-17 12:47:41 +0200 (Do, 17 Sep 2015) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "DoseAccApplicationData.h" #include "DoseAccHelper.h" #include "DoseAccCmdLineParser.h" #include "boost/shared_ptr.hpp" #include "boost/make_shared.hpp" #include "RTToolboxConfigure.h" +#include "rttbDoseLoader.cpp" + int main(int argc, const char** argv) { int result = 0; rttb::apps::doseAcc::ApplicationData appData; boost::shared_ptr argParser; const std::string appCategory = "RT-Toolbox App"; const std::string appName = "DoseAcc"; const std::string appDesc = "An App to accumulate two doses. The GUI for this app is currently under development and in an experimental state."; const std::string appContributor = "SIDT@DKFZ"; const std::string appVersion = RTTB_FULL_VERSION_STRING; try { argParser = boost::make_shared(argc, argv, appName, appVersion, appDesc, appContributor, appCategory); } catch (const std::exception& e) { std::cerr << e.what() << std::endl; return 5; } // This is vital. The application needs to exit if the "help" or "version" parameter is set // because this means the other parameters won't be parsed. if (argParser->isSet(argParser->OPTION_HELP) || argParser->isSet(argParser->OPTION_VERSION) || argParser->isSet(argParser->OPTION_XML)) { return 0; } rttb::apps::doseAcc::populateAppData(argParser, appData); std::cout << std::endl << "*******************************************" << std::endl; std::cout << "Dose 1 file: " << appData._dose1FileName << std::endl; std::cout << "Dose 2 file: " << appData._dose2FileName << std::endl; std::cout << "Dose output file: " << appData._outputFileName << std::endl; if (!(appData._regFileName.empty())) { std::cout << "Registration file: " << appData._regFileName << std::endl; } std::cout << "Dose 1 weight: " << appData._weightDose1 << std::endl; std::cout << "Dose 2 weight: " << appData._weightDose2 << std::endl; std::cout << "Operator: " << appData._operator << std::endl; + std::cout << std::endl << "read dose file... "; + try { - appData._dose1 = rttb::apps::doseAcc::loadDose(appData._dose1FileName, appData._dose1LoadStyle); + appData._dose1 = rttb::io::utils::loadDose(appData._dose1FileName, appData._dose1LoadStyle); } catch (::itk::ExceptionObject& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e << std::endl; return 4; } catch (std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 4; } catch (...) { std::cerr << "Error!!! unknown error while reading input image." << std::endl; return 4; } try { - appData._dose2 = rttb::apps::doseAcc::loadDose(appData._dose2FileName, appData._dose2LoadStyle); + appData._dose2 = rttb::io::utils::loadDose(appData._dose2FileName, appData._dose2LoadStyle); + std::cout << "done." << std::endl; } catch (::itk::ExceptionObject& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e << std::endl; return 4; } catch (std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 4; } catch (...) { std::cerr << "Error!!! unknown error while reading input image." << std::endl; return 4; } if (!(appData._regFileName.empty())) { try { appData._spReg = rttb::apps::doseAcc::loadRegistration(appData._regFileName); } catch (::itk::ExceptionObject& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e << std::endl; return 5; } catch (std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 5; } catch (...) { std::cerr << "Error!!! unknown error while reading registration file." << std::endl; return 5; } } try { rttb::apps::doseAcc::processData(appData); } catch (::itk::ExceptionObject& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e << std::endl; return 9; } catch (std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 9; } catch (...) { std::cerr << "Error!!! unknown error while mapping and writing image." << std::endl; return 9; } std::cout << std::endl; return result; } diff --git a/apps/DoseAcc/DoseAccHelper.cpp b/apps/DoseAcc/DoseAccHelper.cpp index f8e197b..2ee9211 100644 --- a/apps/DoseAcc/DoseAccHelper.cpp +++ b/apps/DoseAcc/DoseAccHelper.cpp @@ -1,231 +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 "rttbDicomFileDoseAccessorGenerator.h" -#include "rttbDicomHelaxFileDoseAccessorGenerator.h" - #include "rttbITKImageAccessorConverter.h" #include "rttbSimpleMappableDoseAccessor.h" #include "rttbMatchPointTransformation.h" #include "rttbLinearInterpolation.h" #include "rttbNearestNeighborInterpolation.h" #include "rttbRosuMappableDoseAccessor.h" -#include "rttbITKImageFileAccessorGenerator.h" #include "rttbArithmetic.h" #include "rttbBinaryFunctorAccessor.h" #include "rttbImageWriter.h" -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::doseAcc::loadDose(const std::string& fileName, - const rttb::apps::doseAcc::ApplicationData::LoadingStyleArgType& args) -{ - rttb::core::DoseAccessorInterface::DoseAccessorPointer result; - - std::cout << std::endl << "read dose file... "; - - if (args.empty() || args[0] == "dicom") - { - std::cout << "use RTTB dicom IO... "; - result = loadDicomDose(fileName); - } - else if (args[0] == "helax") - { - std::cout << "use RTTB Helax IO... "; - result = loadHelaxDose(fileName); - } - else if (args[0] == "itk") - { - std::cout << "use RTTB itk IO... "; - result = loadITKDose(fileName); - } - else - { - rttbDefaultExceptionStaticMacro( << "Unknown io style selected. Cannot load data. Selected style: " - << args[0]); - } - - std::cout << "done." << std::endl; - - return result; -}; - -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::doseAcc::loadDicomDose(const std::string& fileName) -{ - rttb::io::dicom::DicomFileDoseAccessorGenerator generator(fileName); - return generator.generateDoseAccessor(); -}; - -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::doseAcc::loadHelaxDose(const std::string& path) -{ - rttb::io::helax::DicomHelaxFileDoseAccessorGenerator generator(path); - return generator.generateDoseAccessor(); -}; - -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::doseAcc::loadITKDose(const std::string& fileName) -{ - rttb::io::itk::ITKImageFileAccessorGenerator generator(fileName); - return generator.generateDoseAccessor(); -}; - rttb::apps::doseAcc::ApplicationData::RegistrationType::Pointer rttb::apps::doseAcc::loadRegistration(const std::string& fileName) { map::io::RegistrationFileReader::Pointer spRegReader = map::io::RegistrationFileReader::New(); map::io::RegistrationFileReader::LoadedRegistrationPointer spReg; std::cout << std::endl << "read registration file... "; spReg = spRegReader->read(fileName); std::cout << "done." << std::endl; ApplicationData::RegistrationType::Pointer resultPtr = dynamic_cast(spReg.GetPointer()); if (resultPtr.IsNull()) { rttbDefaultExceptionStaticMacro( << "Loaded registration cannot be used. Only 3D 3D registrations are allowed."); } return resultPtr; }; rttb::core::DoseAccessorInterface::DoseAccessorPointer generateNNMappableAccessor( const rttb::core::GeometricInfo& geoInfoTargetImage, const rttb::core::DoseAccessorInterface::DoseAccessorPointer doseMovingImage, const rttb::interpolation::TransformationInterface::Pointer aTransformation) { auto interpolate = boost::make_shared(); return boost::make_shared(geoInfoTargetImage, doseMovingImage, aTransformation, interpolate); } rttb::core::DoseAccessorInterface::DoseAccessorPointer generateLinearMappableAccessor( const rttb::core::GeometricInfo& geoInfoTargetImage, const rttb::core::DoseAccessorInterface::DoseAccessorPointer doseMovingImage, const rttb::interpolation::TransformationInterface::Pointer aTransformation) { auto interpolate = boost::make_shared(); return boost::make_shared(geoInfoTargetImage, doseMovingImage, aTransformation, interpolate); } rttb::core::DoseAccessorInterface::DoseAccessorPointer generateRosuMappableAccessor( const rttb::core::GeometricInfo& geoInfoTargetImage, const rttb::core::DoseAccessorInterface::DoseAccessorPointer doseMovingImage, const rttb::interpolation::TransformationInterface::Pointer aTransformation) { return 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 assembleOutputAccessor(rttb::apps::doseAcc::ApplicationData& appData) { rttb::core::DoseAccessorInterface::DoseAccessorPointer 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; 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( 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/DoseAcc/DoseAccHelper.h b/apps/DoseAcc/DoseAccHelper.h index 35bb56f..8fb43be 100644 --- a/apps/DoseAcc/DoseAccHelper.h +++ b/apps/DoseAcc/DoseAccHelper.h @@ -1,60 +1,49 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed 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 __DOSE_ACC_HELPER_H #define __DOSE_ACC_HELPER_H #include #include #include "rttbDoseAccessorInterface.h" #include "DoseAccApplicationData.h" namespace rttb { namespace apps { namespace doseAcc - { - typedef std::vector LoadingStyleArgType; - /**loads the dose from a file. Throws exception if loading fails*/ - core::DoseAccessorInterface::DoseAccessorPointer loadDose(const std::string& fileName, - const LoadingStyleArgType& args); - - /**loads the dose from a file using the dicom dose generator. Throws exception if loading fails*/ - core::DoseAccessorInterface::DoseAccessorPointer loadDicomDose(const std::string& fileName); - /**loads the dose from a path using the helax io dose generator. Throws exception if loading fails*/ - core::DoseAccessorInterface::DoseAccessorPointer loadHelaxDose(const std::string& path); - /**loads the dose from a file stored in an ITK supported data format. Throws exception if loading fails*/ - core::DoseAccessorInterface::DoseAccessorPointer loadITKDose(const std::string& fileName); + { ApplicationData::RegistrationType::Pointer loadRegistration(const std::string& fileName); /**Contains the business logic for the accumulation of the doses and the storing of the result. Uses appData for the input data and the correct configuration.*/ void processData(ApplicationData& appData); } } } #endif diff --git a/apps/DoseMap/CMakeLists.txt b/apps/DoseMap/CMakeLists.txt index 9c77f73..3c4a1b7 100644 --- a/apps/DoseMap/CMakeLists.txt +++ b/apps/DoseMap/CMakeLists.txt @@ -1,3 +1,3 @@ MESSAGE (STATUS "generating app: DoseMap - simple dose mapping tool") SET(RTTB_Boost_ADDITIONAL_COMPONENT program_options) -RTTB_CREATE_APPLICATION(DoseMap DEPENDS RTTBCore RTTBAlgorithms RTTBInterpolation RTTBInterpolationMatchPointTransformation RTTBITKIO RTTBDicomIO RTTBHelaxIO PACKAGE_DEPENDS MatchPoint ITK ArgumentParsingLib BoostBinaries) +RTTB_CREATE_APPLICATION(DoseMap DEPENDS RTTBCore RTTBAlgorithms RTTBInterpolation RTTBInterpolationMatchPointTransformation RTTBUtilsIO PACKAGE_DEPENDS MatchPoint ITK ArgumentParsingLib BoostBinaries) diff --git a/apps/DoseMap/DoseMap.cpp b/apps/DoseMap/DoseMap.cpp index 3a43014..fa7349d 100644 --- a/apps/DoseMap/DoseMap.cpp +++ b/apps/DoseMap/DoseMap.cpp @@ -1,209 +1,214 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed 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 "DoseMapApplicationData.h" #include "DoseMapHelper.h" #include "DoseMapCmdLineParser.h" #include "boost/shared_ptr.hpp" #include "boost/make_shared.hpp" #include "RTToolboxConfigure.h" #include "rttbException.h" #include "mapDummyRegistrationAlgorithm.h" +#include "rttbDoseLoader.cpp" + /** Main function of dose mapper. @retval 0 normal program execution @retval 2 not enough required input files. @retval 4 Error loading input dose file @retval 5 Error loading reference dose file @retval 6 Error loading registration @retval 9 Error while mapping or storing result. */ int main(int argc, const char** argv) { int result = 0; rttb::apps::doseMap::ApplicationData appData; boost::shared_ptr argParser; try { std::string appName = "DoseMap"; std::string appVersion = RTTB_FULL_VERSION_STRING; argParser = boost::make_shared(argc, argv, appName, appVersion); } catch (const std::exception& e) { std::cerr << e.what() << std::endl; return 2; } // This is vital. The application needs to exit if the "help" or "version" parameter is set // because this means the other parameters won't be parsed. if (argParser->isSet(argParser->OPTION_HELP) || argParser->isSet(argParser->OPTION_VERSION)) { return 0; } try{ rttb::apps::doseMap::populateAppData(argParser, appData); } catch (const std::exception& e) { std::cerr << e.what() << std::endl; } std::cout << std::endl << "*******************************************" << std::endl; std::cout << "Input dose file: " << appData._inputDoseFileName << std::endl; std::cout << "Input dose file load style: " << appData._inputDoseLoadStyle.at(0) << std::endl; std::cout << "Output file: " << appData._outputFileName << std::endl; if (!(appData._regFileName.empty())) { std::cout << "Registration file: " << appData._regFileName << std::endl; } if (!(appData._refDoseFileName.empty())) { std::cout << "Reference dose file: " << appData._refDoseFileName << std::endl; std::cout << "Reference dose style: " << appData._refDoseLoadStyle.at(0) << std::endl; } + std::cout << std::endl << "read dose file... "; + try { - appData._inputDose = rttb::apps::doseMap::loadDose(appData._inputDoseFileName, + appData._inputDose = rttb::io::utils::loadDose(appData._inputDoseFileName, appData._inputDoseLoadStyle); + std::cout << "done." << std::endl; } catch (::itk::ExceptionObject& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e << std::endl; return 4; } catch (std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 4; } catch (...) { std::cerr << "Error!!! unknown error while reading input image." << std::endl; return 4; } if (!(appData._refDoseFileName.empty())) { try { - appData._refDose = rttb::apps::doseMap::loadDose(appData._refDoseFileName, + appData._refDose = rttb::io::utils::loadDose(appData._refDoseFileName, appData._refDoseLoadStyle); } catch (::itk::ExceptionObject& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e << std::endl; return 5; } catch (std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 5; } catch (...) { std::cerr << "Error!!! unknown error while reading reference image." << std::endl; return 5; } } else { appData._refDose = appData._inputDose; } if (!(appData._regFileName.empty())) { try { appData._spReg = rttb::apps::doseMap::loadRegistration(appData._regFileName); } catch (::itk::ExceptionObject& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e << std::endl; return 6; } catch (std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 6; } catch (...) { std::cerr << "Error!!! unknown error while reading registration file." << std::endl; return 6; } } else { //generate dummy identity registration typedef map::algorithm::DummyRegistrationAlgorithm<3> DummyRegType; DummyRegType::Pointer regAlg = DummyRegType::New(); appData._spReg = regAlg->getRegistration(); } try { rttb::apps::doseMap::processData(appData); } catch (::itk::ExceptionObject& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e << std::endl; return 9; } catch (std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 9; } catch (...) { std::cerr << "Error!!! unknown error while mapping and writing image." << std::endl; return 9; } std::cout << std::endl; return result; } diff --git a/apps/DoseMap/DoseMapHelper.cpp b/apps/DoseMap/DoseMapHelper.cpp index 9327e63..4670e43 100644 --- a/apps/DoseMap/DoseMapHelper.cpp +++ b/apps/DoseMap/DoseMapHelper.cpp @@ -1,179 +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 "rttbDicomFileDoseAccessorGenerator.h" -#include "rttbDicomHelaxFileDoseAccessorGenerator.h" #include "rttbITKImageAccessorConverter.h" #include "rttbSimpleMappableDoseAccessor.h" #include "rttbMatchPointTransformation.h" #include "rttbLinearInterpolation.h" #include "rttbNearestNeighborInterpolation.h" #include "rttbRosuMappableDoseAccessor.h" -#include "rttbITKImageFileAccessorGenerator.h" #include "rttbArithmetic.h" #include "rttbBinaryFunctorAccessor.h" #include "rttbExceptionMacros.h" #include "rttbImageWriter.h" - -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::doseMap::loadDose(const std::string& fileName, - const rttb::apps::doseMap::ApplicationData::LoadingStyleArgType& args) -{ - rttb::core::DoseAccessorInterface::DoseAccessorPointer result; - - std::cout << std::endl << "read dose file... "; - - if (args.empty() || args[0] == "dicom") - { - std::cout << "use RTTB dicom IO... "; - result = loadDicomDose(fileName); - } - else if (args[0] == "helax") - { - std::cout << "use RTTB Helax IO... "; - result = loadHelaxDose(fileName); - } - else if (args[0] == "itk") - { - std::cout << "use RTTB itk IO... "; - result = loadITKDose(fileName); - } - else - { - rttbDefaultExceptionStaticMacro( << "Unknown io style selected. Cannot load data. Selected style: " - << args[0]); - } - - std::cout << "done." << std::endl; - - return result; -}; - -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::doseMap::loadDicomDose(const std::string& fileName) -{ - rttb::io::dicom::DicomFileDoseAccessorGenerator generator(fileName); - return generator.generateDoseAccessor(); -}; - -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::doseMap::loadHelaxDose(const std::string& path) -{ - rttb::io::helax::DicomHelaxFileDoseAccessorGenerator generator(path); - return generator.generateDoseAccessor(); -}; - -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::doseMap::loadITKDose(const std::string& fileName) -{ - rttb::io::itk::ITKImageFileAccessorGenerator generator(fileName); - return generator.generateDoseAccessor(); -}; - rttb::apps::doseMap::ApplicationData::RegistrationType::Pointer rttb::apps::doseMap::loadRegistration(const std::string& fileName) { map::io::RegistrationFileReader::Pointer spRegReader = map::io::RegistrationFileReader::New(); map::io::RegistrationFileReader::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 assembleOutputAccessor(rttb::apps::doseMap::ApplicationData& appData) { rttb::core::DoseAccessorInterface::DoseAccessorPointer 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( 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/DoseMapHelper.h b/apps/DoseMap/DoseMapHelper.h index 3d737b7..047e577 100644 --- a/apps/DoseMap/DoseMapHelper.h +++ b/apps/DoseMap/DoseMapHelper.h @@ -1,58 +1,44 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 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 __DOSE_MAP_HELPER_H #define __DOSE_MAP_HELPER_H #include "DoseMapApplicationData.h" namespace rttb { namespace apps { namespace doseMap { - - /**loads the dose from a file. Throws exception if loading fails*/ - core::DoseAccessorInterface::DoseAccessorPointer loadDose(const std::string& fileName, - const rttb::apps::doseMap::ApplicationData::LoadingStyleArgType& args); - - /**loads the dose from a file using the dicom dose generator. Throws exception if loading fails*/ - core::DoseAccessorInterface::DoseAccessorPointer loadDicomDose(const std::string& fileName); - - /**loads the dose from a path using the helax io dose generator. Throws exception if loading fails*/ - core::DoseAccessorInterface::DoseAccessorPointer loadHelaxDose(const std::string& path); - - /**loads the dose from a file stored in an ITK supported data format. Throws exception if loading fails*/ - core::DoseAccessorInterface::DoseAccessorPointer loadITKDose(const std::string& fileName); - ApplicationData::RegistrationType::Pointer loadRegistration(const std::string& fileName); /**Contains the business logic for the accumulation of the doses and the storing of the result. Uses appData for the input data and the correct configuration.*/ void processData(ApplicationData& appData); } } } #endif diff --git a/apps/DoseTool/CMakeLists.txt b/apps/DoseTool/CMakeLists.txt index a78eca0..d99c129 100644 --- a/apps/DoseTool/CMakeLists.txt +++ b/apps/DoseTool/CMakeLists.txt @@ -1,4 +1,4 @@ MESSAGE (STATUS "generating app: DoseTool - calculating dose statistics and DVH") SET(RTTB_Boost_ADDITIONAL_COMPONENT program_options) -RTTB_CREATE_APPLICATION(DoseTool DEPENDS RTTBCore RTTBITKIO RTTBDicomIO RTTBHelaxIO RTTBMasks RTTBMasks RTTBBoostMask RTTBOtherIO RTTBAlgorithms PACKAGE_DEPENDS ArgumentParsingLib BoostBinaries) +RTTB_CREATE_APPLICATION(DoseTool DEPENDS RTTBCore RTTBMasks RTTBMasks RTTBBoostMask RTTBOtherIO RTTBAlgorithms RTTBUtilsIO PACKAGE_DEPENDS ArgumentParsingLib BoostBinaries) diff --git a/apps/DoseTool/DoseTool.cpp b/apps/DoseTool/DoseTool.cpp index 0004de0..24d8b73 100644 --- a/apps/DoseTool/DoseTool.cpp +++ b/apps/DoseTool/DoseTool.cpp @@ -1,164 +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: 1315 $ (last changed revision) // @date $Date: 2016-04-12 14:18:24 +0200 (Di, 12 Apr 2016) $ (last change date) // @author $Author: floca $ (last changed by) */ #include "DoseToolApplicationData.h" #include "DoseToolHelper.h" #include "DoseToolCmdLineParser.h" #include "boost/shared_ptr.hpp" #include "boost/make_shared.hpp" #include "RTToolboxConfigure.h" #include "rttbException.h" +#include "rttbDoseLoader.cpp" + /*! \file DoseTool.cpp main function for DoseTool */ int main(int argc, const char** argv) { int result = 0; rttb::apps::doseTool::ApplicationData appData; boost::shared_ptr argParser; const std::string appCategory = "RT-Toolbox App"; const std::string appName = "DoseTool"; const std::string appDesc = "An App to calculate the dose statistics and compute the DVH. The GUI for this app is currently under development and in an experimental state."; const std::string appContributor = "SIDT@DKFZ"; const std::string appVersion = RTTB_FULL_VERSION_STRING; try { argParser = boost::make_shared(argc, argv, appName, appVersion, appDesc, appContributor, appCategory); } catch (const std::exception& e) { std::cerr << e.what() << std::endl; return 5; } // This is vital. The application needs to exit if the "help" or "version" parameter is set // because this means the other parameters won't be parsed. if (argParser->isSet(argParser->OPTION_HELP) || argParser->isSet(argParser->OPTION_VERSION) || argParser->isSet(argParser->OPTION_XML)) { return 0; } rttb::apps::doseTool::populateAppData(argParser, appData); std::cout << std::endl << "*******************************************" << std::endl; std::cout << "Dose file: " << appData._doseFileName << std::endl; std::cout << "Struct file: " << appData._structFileName << std::endl; std::cout << "Struct name: " << appData._structNameRegex << std::endl; if (appData._computeDoseStatistics) { std::cout << "Dose statistic output file: " << appData._doseStatisticOutputFileName << std::endl; std::cout << "Compute complex statistics: " << appData._computeComplexDoseStatistics << std::endl; if (appData._computeComplexDoseStatistics) { std::cout << "Prescribed dose: " << appData._prescribedDose << std::endl; } std::cout << "Allow self intersections: " << appData._allowSelfIntersection << std::endl; } if (appData._computeDVH) { std::cout << "DVH output file: " << appData._dvhOutputFilename << std::endl; } + std::cout << std::endl << "read dose file... "; + try { - appData._dose = rttb::apps::doseTool::loadDose(appData._doseFileName, appData._doseLoadStyle); + appData._dose = rttb::io::utils::loadDose(appData._doseFileName, appData._doseLoadStyle); + std::cout << "done." << std::endl; } catch (rttb::core::Exception& e) { std::cerr << "RTTB Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 1; } catch (const std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 1; } catch (...) { std::cerr << "Error!!! unknown error while reading dose image." << std::endl; return 1; } //loading of structure file not necessary in ITK case as it can be used directly as mask input. if (appData._structLoadStyle.front() != "itk") { try { appData._struct = rttb::apps::doseTool::loadStruct(appData._structFileName, appData._structLoadStyle, appData._structNameRegex); } catch (rttb::core::Exception& e) { std::cerr << "RTTB Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 2; } catch (const std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 2; } catch (...) { std::cerr << "Error!!! unknown error while reading struct image." << std::endl; return 2; } } try { rttb::apps::doseTool::processData(appData); } catch (rttb::core::Exception& e) { std::cerr << "RTTB Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 3; } catch (std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; return 3; } catch (...) { std::cerr << "Error!!! unknown error while processing the data or writing the image." << std::endl; return 3; } return result; } diff --git a/apps/DoseTool/DoseToolHelper.cpp b/apps/DoseTool/DoseToolHelper.cpp index edd598a..a28ce0d 100644 --- a/apps/DoseTool/DoseToolHelper.cpp +++ b/apps/DoseTool/DoseToolHelper.cpp @@ -1,353 +1,295 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed 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 "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 "rttbExceptionMacros.h" #include "DoseToolApplicationData.h" -#include "rttbDicomFileDoseAccessorGenerator.h" -#include "rttbDicomHelaxFileDoseAccessorGenerator.h" -#include "rttbITKImageFileAccessorGenerator.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" #include "rttbVOIindexIdentifier.h" -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::doseTool::loadDose(const std::string& fileName, - const LoadingStyleArgType& args) -{ - rttb::core::DoseAccessorInterface::DoseAccessorPointer result; - - std::cout << std::endl << "read dose file... "; - - if (args.empty() || args[0] == "dicom") - { - std::cout << "use RTTB dicom IO... "; - result = loadDicomDose(fileName); - } - else if (args[0] == "helax") - { - std::cout << "use RTTB Helax IO... "; - result = loadHelaxDose(fileName); - } - else if (args[0] == "itk") - { - std::cout << "use RTTB itk IO... "; - result = loadITKDose(fileName); - } - else - { - rttbDefaultExceptionStaticMacro( << "Unknown io style selected. Cannot load data. Selected style: " - << args[0]); - } - - std::cout << "done." << std::endl; - - return result; -} - -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::doseTool::loadDicomDose(const std::string& fileName) -{ - rttb::io::dicom::DicomFileDoseAccessorGenerator generator(fileName); - return generator.generateDoseAccessor(); -} - -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::doseTool::loadHelaxDose(const std::string& path) -{ - rttb::io::helax::DicomHelaxFileDoseAccessorGenerator generator(path); - return generator.generateDoseAccessor(); -} - -rttb::core::DoseAccessorInterface::DoseAccessorPointer -rttb::apps::doseTool::loadITKDose(const std::string& fileName) -{ - rttb::io::itk::ITKImageFileAccessorGenerator generator(fileName); - return generator.generateDoseAccessor(); -} - rttb::core::StructureSetGeneratorInterface::StructureSetPointer rttb::apps::doseTool::loadStruct( const std::string& fileName, const ApplicationData::LoadingStyleArgType& args, const std::string& structNameRegex) { rttb::core::StructureSetGeneratorInterface::StructureSetPointer result; std::cout << std::endl << "read struct file... "; if (args.empty() || args[0] == "dicom") { std::cout << "use RTTB dicom IO... "; result = loadDicomStruct(fileName, structNameRegex); } else { rttbDefaultExceptionStaticMacro( << "Unknown io style selected. Cannot load data. Selected style: " << args[0]); } std::cout << "done." << std::endl; return result; } rttb::core::StructureSetGeneratorInterface::StructureSetPointer rttb::apps::doseTool::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(); } std::vector rttb::apps::doseTool::generateMasks( rttb::apps::doseTool::ApplicationData& appData) { std::vector maskAccessorPtrVector; if (appData._structLoadStyle.front() == "itk") { maskAccessorPtrVector.push_back(rttb::io::itk::ITKImageFileMaskAccessorGenerator( appData._structFileName).generateMaskAccessor()); appData._structNames.push_back(appData._structNameRegex); } else { auto foundIndices = rttb::masks::VOIindexIdentifier::getIndicesByVoiRegex( appData._struct, appData._structNameRegex); std::vector relevantIndices; if (appData._multipleStructsMode) { relevantIndices = foundIndices; } else { if (!foundIndices.empty()) { relevantIndices.push_back(foundIndices.front()); } } appData._structIndices = relevantIndices; bool strict = !appData._allowSelfIntersection; for (size_t i = 0; i < appData._structIndices.size(); i++) { maskAccessorPtrVector.push_back( boost::make_shared (appData._struct->getStructure(appData._structIndices.at(i)), appData._dose->getGeometricInfo(), strict)); maskAccessorPtrVector.at(i)->updateMask(); appData._structNames.push_back(appData._struct->getStructure(appData._structIndices.at( i))->getLabel()); } } 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); return doseIterator; } rttb::algorithms::DoseStatistics::DoseStatisticsPointer calculateDoseStatistics( rttb::core::DoseIteratorInterface::DoseIteratorPointer 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::DVHCalculator calc(doseIterator, structUID, doseUID); rttb::core::DVH::DVHPointer 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) { boost::property_tree::ptree originalTree = rttb::io::other::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) { 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::cout << "done." << std::endl; for (size_t i = 0; i < maskAccessorPtrVector.size(); i++) { core::DoseIteratorInterface::DoseIteratorPointer spDoseIterator(generateMaskedDoseIterator( maskAccessorPtrVector.at(i), appData._dose)); if (appData._computeDoseStatistics) { std::cout << std::endl << "computing dose statistics... "; algorithms::DoseStatistics::DoseStatisticsPointer 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.front() == "itk"){ structUID = "struct42"; doseUID = "dose42"; } else { structUID = appData._struct->getUID(); doseUID = appData._dose->getUID(); } core::DVH::DVHPointer 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 1706c41..e83095e 100644 --- a/apps/DoseTool/DoseToolHelper.h +++ b/apps/DoseTool/DoseToolHelper.h @@ -1,110 +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: 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; typedef std::vector LoadingStyleArgType; - /*! @brief loads a dose from a file based on the loadingStyle. - @exception Throws an rttb::Exception if loading fails - */ - core::DoseAccessorInterface::DoseAccessorPointer loadDose(const std::string& fileName, - const LoadingStyleArgType& args); - /*! @brief loads a dicom dose from a file. - @exception Throws an rttb::Exception if loading fails - @sa DicomFileDoseAccessorGenerator - */ - core::DoseAccessorInterface::DoseAccessorPointer loadDicomDose(const std::string& fileName); - /*! @brief loads a helax dose from a file. - @exception Throws an rttb::Exception if loading fails - @sa DicomHelaxFileDoseAccessorGenerator - */ - core::DoseAccessorInterface::DoseAccessorPointer loadHelaxDose(const std::string& path); - /*! @brief loads an itk dose from a file. - @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 - */ - core::DoseAccessorInterface::DoseAccessorPointer loadITKDose(const std::string& fileName); - + /*! @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 */ core::StructureSetGeneratorInterface::StructureSetPointer loadStruct(const std::string& fileName, const LoadingStyleArgType& args, const std::string& structNameRegex = ""); /*! @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 */ core::StructureSetGeneratorInterface::StructureSetPointer loadDicomStruct( const std::string& fileName, const std::string& structNameRegex = ""); /*! @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( 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); std::string assembleFilenameWithStruct(const std::string& originalFilename, const std::string& structName); } } } #endif diff --git a/code/io/CMakeLists.txt b/code/io/CMakeLists.txt index 2365e7f..05cb9d1 100644 --- a/code/io/CMakeLists.txt +++ b/code/io/CMakeLists.txt @@ -1,23 +1,27 @@ MESSAGE (STATUS "processing RTToolbox io") ADD_SUBDIRECTORY (other) OPTION(BUILD_IO_Dicom "Determine if the IO class wrappers for DICOM format will be generated." ON) IF(BUILD_All_Modules OR BUILD_IO_Dicom) ADD_SUBDIRECTORY(dicom) OPTION(BUILD_IO_HELAX "Determine if the IO class wrappers for HELAX format will be generated." OFF) IF(BUILD_All_Modules OR BUILD_IO_HELAX) ADD_SUBDIRECTORY(helax) SET(BUILD_IO_HELAX ON CACHE BOOL ON FORCE) ENDIF() ENDIF() OPTION(BUILD_IO_ITK "Determine if the IO class wrappers for ITK image formats will be generated." OFF) IF(BUILD_All_Modules OR BUILD_IO_ITK) ADD_SUBDIRECTORY(itk) SET(BUILD_IO_ITK ON CACHE BOOL ON FORCE) ENDIF() IF(BUILD_All_Modules OR BUILD_Models) ADD_SUBDIRECTORY(models) ENDIF() +IF(BUILD_All_Modules OR (BUILD_IO_Dicom AND BUILD_IO_HELAX AND BUILD_IO_ITK)) + ADD_SUBDIRECTORY (utils) +ENDIF() + diff --git a/code/io/utils/CMakeLists.txt b/code/io/utils/CMakeLists.txt new file mode 100644 index 0000000..f513adb --- /dev/null +++ b/code/io/utils/CMakeLists.txt @@ -0,0 +1 @@ +RTTB_CREATE_MODULE(RTTBUtilsIO DEPENDS RTTBCore RTTBDicomIO RTTBHelaxIO RTTBITKIO PACKAGE_DEPENDS ITK DCMTK) diff --git a/code/io/utils/files.cmake b/code/io/utils/files.cmake new file mode 100644 index 0000000..e5632e4 --- /dev/null +++ b/code/io/utils/files.cmake @@ -0,0 +1,6 @@ +SET(CPP_FILES + rttbDoseLoader.cpp +) + +SET(H_FILES +) diff --git a/code/io/utils/rttbDoseLoader.cpp b/code/io/utils/rttbDoseLoader.cpp new file mode 100644 index 0000000..0596cbe --- /dev/null +++ b/code/io/utils/rttbDoseLoader.cpp @@ -0,0 +1,105 @@ +// ----------------------------------------------------------------------- +// RTToolbox - DKFZ radiotherapy quantitative evaluation library +// +// Copyright (c) German Cancer Research Center (DKFZ), +// Software development for Integrated Diagnostics and Therapy (SIDT). +// ALL RIGHTS RESERVED. +// See rttbCopyright.txt or +// http://www.dkfz.de/en/sidt/projects/rttb/copyright.html +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notices for more information. +// +//------------------------------------------------------------------------ +/*! +// @file +// @version $Revision: 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 __RTTB_DOSE_LOADER_H +#define __RTTB_DOSE_LOADER_H + +#include "rttbDoseIteratorInterface.h" +#include "rttbExceptionMacros.h" + +#include "rttbDicomFileDoseAccessorGenerator.h" +#include "rttbDicomHelaxFileDoseAccessorGenerator.h" +#include "rttbITKImageFileAccessorGenerator.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::io::dicom::DicomFileDoseAccessorGenerator generator(fileName); + return generator.generateDoseAccessor(); + } + + /*! @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::io::helax::DicomHelaxFileDoseAccessorGenerator generator(path); + return generator.generateDoseAccessor(); + } + + /*! @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::io::itk::ITKImageFileAccessorGenerator generator(fileName); + return generator.generateDoseAccessor(); + } + + /*! @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::vector& args) + { + rttb::core::DoseAccessorInterface::DoseAccessorPointer result; + + if (args.empty() || args[0] == "dicom") + { + result = loadDicomDose(fileName); + } + else if (args[0] == "helax") + { + result = loadHelaxDose(fileName); + } + else if (args[0] == "itk") + { + result = loadITKDose(fileName); + } + else + { + rttbDefaultExceptionStaticMacro(<< "Unknown io style selected. Cannot load data. Selected style: " + << args[0]); + } + + return result; + } + } + } +} +#endif diff --git a/testing/apps/DoseTool/DoseToolITKDoseTest.cpp b/testing/apps/DoseTool/DoseToolITKDoseTest.cpp index 6099a8d..cd2ec21 100644 --- a/testing/apps/DoseTool/DoseToolITKDoseTest.cpp +++ b/testing/apps/DoseTool/DoseToolITKDoseTest.cpp @@ -1,115 +1,115 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed 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 "litCheckMacros.h" #include "rttbDoseStatisticsXMLReader.h" #include "../../io/other/CompareDoseStatistic.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 DoseToolITKDoseTest(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 referenceXMLComplexFilename; std::string defaultOutputFilename; std::string complexOutputFilename; boost::filesystem::path callingPath(_callingAppPath); if (argc > 8) { doseToolExecutable = argv[1]; doseFilename = argv[2]; structFilename = argv[3]; structName = argv[4]; referenceXMLFilename = argv[5]; referenceXMLComplexFilename = argv[6]; defaultOutputFilename = argv[7]; complexOutputFilename = argv[8]; } std::string doseToolExeWithPath = callingPath.parent_path().string() + "/" + doseToolExecutable; std::string baseCommand = doseToolExeWithPath; baseCommand += " -d \"" + doseFilename + "\""; baseCommand += " -s \"" + structFilename + "\""; baseCommand += " -t itk "; if (structName != "") { baseCommand += " -n " + structName; } if (boost::filesystem::extension(structFilename).compare(".nrrd") == 0) { - baseCommand += " -u itk "; + 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 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 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(referenceXMLComplexFilename); auto doseStatisticsComplexExpected = readerComplexExpected.generateDoseStatistic(); io::other::DoseStatisticsXMLReader readerComplexActual(complexOutputFilename); auto doseStatisticsComplexActual = readerComplexActual.generateDoseStatistic(); CHECK(checkEqualDoseStatistic(doseStatisticsComplexExpected, doseStatisticsComplexActual)); //delete file again CHECK_EQUAL(std::remove(defaultOutputFilename.c_str()), 0); CHECK_EQUAL(std::remove(complexOutputFilename.c_str()), 0); RETURN_AND_REPORT_TEST_SUCCESS; } } //namespace testing } //namespace rttb