diff --git a/apps/BioModelCalc/BioModelCalcApplicationData.h b/apps/BioModelCalc/BioModelCalcApplicationData.h index 886c535..165e3e9 100644 --- a/apps/BioModelCalc/BioModelCalcApplicationData.h +++ b/apps/BioModelCalc/BioModelCalcApplicationData.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: 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_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: /**Vector of arguments used to specify the loading style (always the first argument) - * and, if needed, additional arguments for the specified loading style (e.g. location of the - * Virtuos plan file for the Virtuos IO style). + * and, if needed, additional arguments for the specified loading style. */ typedef std::vector LoadingStyleArgType; core::DoseAccessorInterface::DoseAccessorPointer _dose; std::deque _modelParameterMaps; std::string _doseFileName; LoadingStyleArgType _doseLoadStyle; LoadingStyleArgType _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.h b/apps/BioModelCalc/BioModelCalcHelper.h index 7ede511..a717243 100644 --- a/apps/BioModelCalc/BioModelCalcHelper.h +++ b/apps/BioModelCalc/BioModelCalcHelper.h @@ -1,83 +1,77 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 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 loads a virtuos dose from a file. - @details Throws an rttb::Exception if loading fails - @sa VirtuosPlanFileDoseAccessorGenerator - */ - core::DoseAccessorInterface::DoseAccessorPointer loadVirtuosDose(const std::string& fileName, - const std::string& planFileName); /*! @brief Contains the business logic of processing all information to calculate a bioModel from the dose and writing it back to an image. @details Uses appData for the input data and the correct configuration. */ void processData(ApplicationData& appData); core::AccessorInterface::AccessorPointer generateBioModel( core::DoseAccessorInterface::DoseAccessorPointer dose, const std::string& model, const std::vector& modelParameters, 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/BioModelCmdLineParser.cpp b/apps/BioModelCalc/BioModelCmdLineParser.cpp index cd5e5b6..6738c9a 100644 --- a/apps/BioModelCalc/BioModelCmdLineParser.cpp +++ b/apps/BioModelCalc/BioModelCmdLineParser.cpp @@ -1,140 +1,125 @@ #include "BioModelCmdLineParser.h" namespace rttb { namespace apps { namespace bioModelCalc { BioModelCmdLineParser::BioModelCmdLineParser(int argc, const char** argv, const std::string& name, const std::string& version, - const std::string& description, const std::string& contributor, const std::string& category, bool virtuosSupport) : - CmdLineParserBase(name, version, description, contributor, category), _virtuosSupport(virtuosSupport) + const std::string& description, const std::string& contributor, const std::string& category) : + CmdLineParserBase(name, version, description, contributor, category) { //REQUIRED addOption(OPTION_DOSE_FILE, OPTION_GROUP_REQUIRED, "The name of the dose file. Can be omitted if used as " "positional argument (see above).", 'd', true); addInformationForXML(OPTION_DOSE_FILE, cmdlineparsing::XMLGenerator::paramType::INPUT, { "*" }); addOption(OPTION_OUTPUT_FILE, OPTION_GROUP_REQUIRED, "The name of the output file. Can be omitted if used as " "positional argument (see above).", 'o', true); addInformationForXML(OPTION_OUTPUT_FILE, cmdlineparsing::XMLGenerator::paramType::OUTPUT, { "*" }); addPositionalOption(OPTION_DOSE_FILE, 1); addPositionalOption(OPTION_OUTPUT_FILE, 1); addOptionWithDefaultValue(OPTION_MODEL, OPTION_GROUP_REQUIRED, "The used radiobiological model the dose should be analyzed with. Available models are:\n \"LQ\", Formula: exp(-(alpha * D + beta * D^2/n))", "LQ", "LQ", 'm'); addInformationForXML(OPTION_MODEL, cmdlineparsing::XMLGenerator::paramType::STRINGENUMERATION, { "LQ" }); addOptionWithDefaultValue(OPTION_DOSE_SCALING, OPTION_GROUP_REQUIRED, "Dose scaling that should be applied.", 1.0, "1.0", 'e'); addInformationForXML(OPTION_DOSE_SCALING, cmdlineparsing::XMLGenerator::paramType::DOUBLE); std::vector defaultLoadingStyle; defaultLoadingStyle.push_back("itk"); std::string doseLoadStyleDescription = "The loading style for the dose. Available styles are:\n" "\"dicom\": normal dicom dose\n" "\"itk\": use itk image loading\n" "\"helax\": load a helax dose (choosing this style, the dose path should only be a directory)."; - - if (_virtuosSupport) - { - doseLoadStyleDescription += "\n" - "\"virtuos\": load of a virtuos dose (This style is a multi argument. The second argument specifies the virtuos plan file, e.g. : \"--" - + OPTION_LOAD_STYLE + " virtuos myFavorite.pln\")"; - } - addOptionWithDefaultValue >(OPTION_LOAD_STYLE, OPTION_GROUP_REQUIRED, doseLoadStyleDescription, defaultLoadingStyle, defaultLoadingStyle.at(0), 't', true, true); addInformationForXML(OPTION_LOAD_STYLE, cmdlineparsing::XMLGenerator::paramType::STRINGENUMERATION, { "itk", "dicom", "helax" }); //OPTIONAL addOption >(OPTION_MODEL_PARAMETERS, OPTION_GROUP_OPTIONAL, "The parameters for the radiobiological model.", 'p', false, true); addInformationForXML(OPTION_MODEL_PARAMETERS, cmdlineparsing::XMLGenerator::paramType::STRING); addOption >(OPTION_MODEL_PARAMETER_MAPS, OPTION_GROUP_OPTIONAL, "The parameters maps as itk readable image files for the radiobiological model.", 'a', false, true); addInformationForXML(OPTION_MODEL_PARAMETER_MAPS, cmdlineparsing::XMLGenerator::paramType::INPUT, { "*" }); addOption(OPTION_N_FRACTIONS, OPTION_GROUP_OPTIONAL, "The number of fractions (n in the formula).", 'f'); addInformationForXML(OPTION_N_FRACTIONS, cmdlineparsing::XMLGenerator::paramType::INTEGER); addOptionWithDefaultValue >(OPTION_LOAD_STYLE_PARAMETER_MAPS, OPTION_GROUP_OPTIONAL, doseLoadStyleDescription, defaultLoadingStyle, defaultLoadingStyle.at(0), 'u', true, true); addInformationForXML(OPTION_LOAD_STYLE_PARAMETER_MAPS, cmdlineparsing::XMLGenerator::paramType::STRINGENUMERATION, { "itk", "dicom", "helax" }); parse(argc, argv); } void BioModelCmdLineParser::validateInput() const { std::string model = get(OPTION_MODEL); if (model != "LQ") { throw cmdlineparsing::InvalidConstraintException("Unknown model: " + model + ".\nPlease refer to the help for valid models."); } else { if (!isSet(OPTION_MODEL_PARAMETERS) && !isSet(OPTION_MODEL_PARAMETER_MAPS)){ throw cmdlineparsing::InvalidConstraintException("Either the model parameters or model parameter maps must be specified!"); } if ((isSet(OPTION_MODEL_PARAMETERS) && get >(OPTION_MODEL_PARAMETERS).size() != 2) || (isSet(OPTION_MODEL_PARAMETER_MAPS) && get >(OPTION_MODEL_PARAMETER_MAPS).size() != 2)) { throw cmdlineparsing::InvalidConstraintException("The LQ Model requires two parameters or parameter maps!"); } } std::vector loadStyle = get >(OPTION_LOAD_STYLE); std::string loadStyleAbbreviation = loadStyle.at(0); - if (loadStyleAbbreviation != "dicom" && (!_virtuosSupport || loadStyleAbbreviation != "virtuos") + if (loadStyleAbbreviation != "dicom" && loadStyleAbbreviation != "itk" && loadStyleAbbreviation != "helax") { throw cmdlineparsing::InvalidConstraintException("Unknown load style: " + loadStyleAbbreviation + ".\nPlease refer to the help for valid loading style settings."); } - else if (_virtuosSupport && loadStyleAbbreviation == "virtuos") - { - if (loadStyle.size() < 2) - { - throw cmdlineparsing::InvalidConstraintException("Cannot load virtuos dose. Plan file is missing. Specify plan file as 2nd io style argument."); - } - } double doseScaling = get(OPTION_DOSE_SCALING); if (doseScaling <= 0) { throw cmdlineparsing::InvalidConstraintException("Negative dose scaling is not allowed. Dose scaling has to be >0."); } } void BioModelCmdLineParser::printHelp() const { cmdlineparsing::CmdLineParserBase::printHelp(); std::cout << "Example:" << std::endl << std::endl; std::cout << m_programName << " dose.mhd result.mhd -m LQ -p 0.2 0.02" << std::endl << std::endl; std::cout << "This will calculate the Linear quadratic (LQ) BioModel from \"dose.mhd\" and will write the result to \"result.mhd\". " "The alpha and beta parameters for the LQ model are 0.2 and 0.02, respectively." << std::endl; } } } } diff --git a/apps/BioModelCalc/BioModelCmdLineParser.h b/apps/BioModelCalc/BioModelCmdLineParser.h index 60096df..355f939 100644 --- a/apps/BioModelCalc/BioModelCmdLineParser.h +++ b/apps/BioModelCalc/BioModelCmdLineParser.h @@ -1,45 +1,43 @@ #ifndef __BIO_MODEL_CMD_LINE_PARSER #define __BIO_MODEL_CMD_LINE_PARSER #include "CmdLineParserBase.h" namespace rttb { namespace apps { namespace bioModelCalc { /*! @class BioModelCmdLineParser @brief Argument parsing is parametrized here based on ArgParserLib @see cmdlineparsing::CmdLineParserBase */ class BioModelCmdLineParser : public cmdlineparsing::CmdLineParserBase { public: BioModelCmdLineParser(int argc, const char** argv, const std::string& name, const std::string& version, - const std::string& description, const std::string& contributor, const std::string& category, bool virtuosSupport = false); + const std::string& description, const std::string& contributor, const std::string& category); void validateInput() const; void printHelp() const; // Option groups const std::string OPTION_GROUP_REQUIRED = "Required Arguments"; const std::string OPTION_GROUP_OPTIONAL = "Optional Arguments"; // Parameters const std::string OPTION_DOSE_FILE = "dose"; const std::string OPTION_OUTPUT_FILE = "outputFile"; const std::string OPTION_MODEL = "model"; const std::string OPTION_MODEL_PARAMETERS = "modelParameters"; const std::string OPTION_MODEL_PARAMETER_MAPS = "modelParameterMaps"; const std::string OPTION_LOAD_STYLE = "loadStyle"; const std::string OPTION_LOAD_STYLE_PARAMETER_MAPS = "loadStyleParameterMaps"; const std::string OPTION_DOSE_SCALING = "doseScaling"; const std::string OPTION_N_FRACTIONS = "nFractions"; - - bool _virtuosSupport; }; } } } #endif \ No newline at end of file diff --git a/apps/DoseAcc/DoseAcc.cpp b/apps/DoseAcc/DoseAcc.cpp index 6898159..9e59e41 100644 --- a/apps/DoseAcc/DoseAcc.cpp +++ b/apps/DoseAcc/DoseAcc.cpp @@ -1,174 +1,174 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 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" 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, false); + 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; try { appData._dose1 = rttb::apps::doseAcc::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); } 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/DoseAccApplicationData.h b/apps/DoseAcc/DoseAccApplicationData.h index b467fab..2fbed4a 100644 --- a/apps/DoseAcc/DoseAccApplicationData.h +++ b/apps/DoseAcc/DoseAccApplicationData.h @@ -1,79 +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: 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) */ #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; /**Vector of arguments used to specify the loading style (always the first argument) - * and, if needed, additional arguments for the specified loading style (e.g. location of the - * Virtuos plan file for the Virtuos IO style). + * and, if needed, additional arguments for the specified loading style. */ typedef std::vector LoadingStyleArgType; /** Loaded Dose.*/ core::DoseAccessorInterface::DoseAccessorPointer _dose1; std::string _dose1FileName; LoadingStyleArgType _dose1LoadStyle; core::DoseAccessorInterface::DoseAccessorPointer _dose2; std::string _dose2FileName; LoadingStyleArgType _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/DoseAccCmdLineParser.cpp b/apps/DoseAcc/DoseAccCmdLineParser.cpp index 6b2f1a7..93e6bcb 100644 --- a/apps/DoseAcc/DoseAccCmdLineParser.cpp +++ b/apps/DoseAcc/DoseAccCmdLineParser.cpp @@ -1,191 +1,162 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed 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 "DoseAccCmdLineParser.h" namespace rttb { namespace apps { namespace doseAcc { DoseAccCmdLineParser::DoseAccCmdLineParser(int argc, const char** argv, const std::string& name, const std::string& version, - const std::string& description, const std::string& contributor, const std::string& category, bool virtuosSupport) : - CmdLineParserBase(name, version, description, contributor, category), _virtuosSupport(virtuosSupport) + const std::string& description, const std::string& contributor, const std::string& category) : + CmdLineParserBase(name, version, description, contributor, category) { //REQUIRED addOption(OPTION_DOSE1_FILENAME, OPTION_GROUP_REQUIRED, "File path to the first dose.", 'd', true); addInformationForXML(OPTION_DOSE1_FILENAME, cmdlineparsing::XMLGenerator::paramType::INPUT, { "*" }); addOption(OPTION_DOSE2_FILENAME, OPTION_GROUP_REQUIRED, "File path to the second dose.", 'e', true); addInformationForXML(OPTION_DOSE2_FILENAME, cmdlineparsing::XMLGenerator::paramType::INPUT, { "*" }); addOption(OPTION_OUTPUT_FILENAME, OPTION_GROUP_REQUIRED, "File path where the output should be stored.", 'o', true); addInformationForXML(OPTION_OUTPUT_FILENAME, cmdlineparsing::XMLGenerator::paramType::OUTPUT, { "*" }); addOptionWithDefaultValue(OPTION_INTERPOLATOR, OPTION_GROUP_REQUIRED, "Specifies the interpolator that should be used for mapping. Available options are: " "\"nn\": nearest neighbour, \"linear\": linear interpolation, \"rosu\" interpolation based on the concept of Rosu et al..", "linear", "linear", 'i', true); addInformationForXML(OPTION_INTERPOLATOR, cmdlineparsing::XMLGenerator::paramType::STRINGENUMERATION, { "linear", "nn", "rosu" }); addOptionWithDefaultValue(OPTION_WEIGHT1, OPTION_GROUP_REQUIRED, "Specifies the weight for dose 1.", 1.0, "1.0", 'w', true); addInformationForXML(OPTION_WEIGHT1, cmdlineparsing::XMLGenerator::paramType::DOUBLE); addOptionWithDefaultValue(OPTION_WEIGHT2, OPTION_GROUP_REQUIRED, "Specifies the weight for dose 2.", 1.0, "1.0", 'z', true); addInformationForXML(OPTION_WEIGHT2, cmdlineparsing::XMLGenerator::paramType::DOUBLE); addOptionWithDefaultValue(OPTION_REGISTRATION_FILENAME, OPTION_GROUP_REQUIRED, "Specifies name and location of the registration file that should be used to map dose 2 before accumulating it with dose 1." "The registration should be stored as MatchPoint registration.", "", "no mapping", 'r', true); addInformationForXML(OPTION_REGISTRATION_FILENAME, cmdlineparsing::XMLGenerator::paramType::INPUT, { "mapr" }); std::vector defaultLoadingStyle; defaultLoadingStyle.push_back("dicom"); std::string doseLoadStyleDescription = "Options are:\n \"dicom\": normal dicom dose\n" "\"itk\": use itk image loading\n\"helax\": load a helax dose (choosing this style, the dose path should only be a directory)."; - - if (_virtuosSupport) - { - doseLoadStyleDescription += "\n" - "\"virtuos\": load of a virtuos dose (This style is a multi argument. The second argument specifies the virtuos plan file, e.g. : \"--" - + OPTION_LOAD_STYLE_DOSE1 + " or " + OPTION_LOAD_STYLE_DOSE2 + " virtuos myFavorite.pln\")"; - } - addOptionWithDefaultValue >(OPTION_LOAD_STYLE_DOSE1, OPTION_GROUP_REQUIRED, "Load style for dose 1. " + doseLoadStyleDescription, defaultLoadingStyle, defaultLoadingStyle.at(0), 't', true, true); addInformationForXML(OPTION_LOAD_STYLE_DOSE1, cmdlineparsing::XMLGenerator::paramType::STRINGENUMERATION, { "dicom","itk","helax" }); addOptionWithDefaultValue >(OPTION_LOAD_STYLE_DOSE2, OPTION_GROUP_REQUIRED, "Load style for dose 2. See " + OPTION_LOAD_STYLE_DOSE1, defaultLoadingStyle, defaultLoadingStyle.at(0), 'u', true, true); addInformationForXML(OPTION_LOAD_STYLE_DOSE2, cmdlineparsing::XMLGenerator::paramType::STRINGENUMERATION, { "dicom","itk","helax" }); addOptionWithDefaultValue(OPTION_OPERATOR, OPTION_GROUP_REQUIRED, "Specifies the operator used. Available operators are '+' and '*'. Operator '*' has implemented no weight option.", "+", "+", 'p', true); addInformationForXML(OPTION_OPERATOR, cmdlineparsing::XMLGenerator::paramType::STRINGENUMERATION, { "+","*"}); addPositionalOption(OPTION_DOSE1_FILENAME, 1); addPositionalOption(OPTION_DOSE2_FILENAME, 1); addPositionalOption(OPTION_OUTPUT_FILENAME, 1); parse(argc, argv); } void DoseAccCmdLineParser::validateInput() const { std::vector doseLoadStyle1 = get >(OPTION_LOAD_STYLE_DOSE1); std::string doseLoadStyleAbbreviation1 = doseLoadStyle1.at(0); - if (doseLoadStyleAbbreviation1 != "dicom" && (!_virtuosSupport || doseLoadStyleAbbreviation1 != "virtuos") + if (doseLoadStyleAbbreviation1 != "dicom" && doseLoadStyleAbbreviation1 != "itk" && doseLoadStyleAbbreviation1 != "helax") { throw cmdlineparsing::InvalidConstraintException("Unknown load style for dose1 file: " + doseLoadStyleAbbreviation1 + ".\nPlease refer to the help for valid loading style settings."); } - if (_virtuosSupport && doseLoadStyleAbbreviation1 == "virtuos") - { - if (doseLoadStyle1.size() < 2) - { - throw cmdlineparsing::InvalidConstraintException("Cannot load virtuos dose. Plan file is missing. Specify plan file as 2nd io style argument."); - } - } - std::vector doseLoadStyle2 = get >(OPTION_LOAD_STYLE_DOSE2); std::string doseLoadStyleAbbreviation2 = doseLoadStyle2.at(0); - if (doseLoadStyleAbbreviation2 != "dicom" && (!_virtuosSupport || doseLoadStyleAbbreviation2 != "virtuos") + if (doseLoadStyleAbbreviation2 != "dicom" && doseLoadStyleAbbreviation2 != "itk" && doseLoadStyleAbbreviation2 != "helax") { throw cmdlineparsing::InvalidConstraintException("Unknown load style for dose2 file: " + doseLoadStyleAbbreviation2 + ".\nPlease refer to the help for valid loading style settings."); } - if (_virtuosSupport && doseLoadStyleAbbreviation2 == "virtuos") - { - if (doseLoadStyle2.size() < 2) - { - throw cmdlineparsing::InvalidConstraintException("Cannot load virtuos dose. Plan file is missing. Specify plan file as 2nd io style argument."); - } - } - std::string interpolator = get(OPTION_INTERPOLATOR); if (interpolator != "nn" && interpolator != "linear" && interpolator != "rosu") { throw cmdlineparsing::InvalidConstraintException("Unknown interpolator: " + interpolator + ".\nPlease refer to the help for valid interpolator settings."); } std::string operatorString = get(OPTION_OPERATOR); if (operatorString != "+" && operatorString != "*") { throw cmdlineparsing::InvalidConstraintException("Unknown operator: " + operatorString + ".\nPlease refer to the help for valid operator settings."); } if (operatorString == "*"){ double weight1 = get(OPTION_WEIGHT1); double weight2 = get(OPTION_WEIGHT2); if (weight1 != 1.0 || weight2 != 1.0){ throw cmdlineparsing::InvalidConstraintException("Operator \"*\" has no weight option implemented. Options --" + OPTION_WEIGHT1 + " and --" + OPTION_WEIGHT2 + " are invalid."); } } } void DoseAccCmdLineParser::printHelp() const { cmdlineparsing::CmdLineParserBase::printHelp(); std::cout << " Example:" << std::endl << std::endl; std::cout << " DoseAcc dose1.mhd dose2.mhd result.mhd --" + OPTION_LOAD_STYLE_DOSE1 + " itk --" + OPTION_LOAD_STYLE_DOSE2 + " itk --" + OPTION_WEIGHT1 + " 2 -r reg.mapr" << std::endl << std::endl; std::cout << " This will accumulate \"dose1.mhd\" and \"dose2.mhd\" by using \"reg.mapr\" to map dose 2."; std::cout << " For the accumulation, dose 1 will be multiplied by 2. The resulting dose will be stored in \"result.mhd\"." << std::endl << std::endl; - if (_virtuosSupport){ - std::cout << " DoseAcc dose1.dcm dose2.dos.gz result.mhd --" + OPTION_LOAD_STYLE_DOSE2 + " virtuos dose2.pln -r reg.mapr" << std::endl << std::endl; - std::cout << " This will accumulate \"dose1.dcm\" (using default dicom io) and \"dose2.dos.gz\" (using virtuos io and plan file dose2.pln)"; - std::cout << " by using \"reg.mapr\" to map dose 2. The resulting dose will be stored in \"result.mhd\"." << std::endl; - } } } } } diff --git a/apps/DoseAcc/DoseAccCmdLineParser.h b/apps/DoseAcc/DoseAccCmdLineParser.h index bab05e8..237e204 100644 --- a/apps/DoseAcc/DoseAccCmdLineParser.h +++ b/apps/DoseAcc/DoseAccCmdLineParser.h @@ -1,67 +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: 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 __DOSEACC_CMD_LINE_PARSER #define __DOSEACC_CMD_LINE_PARSER #include "CmdLineParserBase.h" namespace rttb { namespace apps { namespace doseAcc { /*! @class DoseAccCmdLineParser @brief Argument parsing is parametrized here based on ArgParserLib @see cmdlineparsing::CmdLineParserBase */ class DoseAccCmdLineParser : public cmdlineparsing::CmdLineParserBase { public: DoseAccCmdLineParser(int argc, const char** argv, const std::string& name, const std::string& version, - const std::string& description, const std::string& contributor, const std::string& category, bool virtuosSupport = false); + const std::string& description, const std::string& contributor, const std::string& category); void validateInput() const override; void printHelp() const override; // Option groups const std::string OPTION_GROUP_REQUIRED = "Required Arguments"; const std::string OPTION_GROUP_OPTIONAL = "Optional Arguments"; // Parameters const std::string OPTION_DOSE1_FILENAME = "dose1"; const std::string OPTION_DOSE2_FILENAME = "dose2"; const std::string OPTION_OUTPUT_FILENAME = "output"; const std::string OPTION_INTERPOLATOR = "interpolator"; const std::string OPTION_WEIGHT1 = "weight1"; const std::string OPTION_WEIGHT2 = "weight2"; const std::string OPTION_REGISTRATION_FILENAME = "registration"; const std::string OPTION_LOAD_STYLE_DOSE1 = "loadStyle1"; const std::string OPTION_LOAD_STYLE_DOSE2 = "loadStyle2"; const std::string OPTION_OPERATOR = "operator"; - - bool _virtuosSupport; }; } } } #endif \ No newline at end of file diff --git a/apps/DoseTool/DoseToolApplicationData.h b/apps/DoseTool/DoseToolApplicationData.h index 7d7beb1..6e241c3 100644 --- a/apps/DoseTool/DoseToolApplicationData.h +++ b/apps/DoseTool/DoseToolApplicationData.h @@ -1,79 +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: 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 __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: /**Vector of arguments used to specify the loading style (always the first argument) - * and, if needed, additional arguments for the specified loading style (e.g. location of the - * Virtuos plan file for the Virtuos IO style). + * and, if needed, additional arguments for the specified loading style. */ typedef std::vector LoadingStyleArgType; core::DoseAccessorInterface::DoseAccessorPointer _dose; core::StructureSetGeneratorInterface::StructureSetPointer _struct; std::string _structNameRegex; std::vector _structIndices; std::vector _structNames; std::string _doseFileName; std::string _structFileName; LoadingStyleArgType _doseLoadStyle; LoadingStyleArgType _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/DoseToolCmdLineParser.cpp b/apps/DoseTool/DoseToolCmdLineParser.cpp index 3a6ec9e..75a6026 100644 --- a/apps/DoseTool/DoseToolCmdLineParser.cpp +++ b/apps/DoseTool/DoseToolCmdLineParser.cpp @@ -1,216 +1,185 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed 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 "DoseToolCmdLineParser.h" namespace rttb { namespace apps { namespace doseTool { DoseToolCmdLineParser::DoseToolCmdLineParser(int argc, const char** argv, const std::string& name, const std::string& version, - const std::string& description, const std::string& contributor, const std::string& category, bool virtuosSupport) : - CmdLineParserBase(name, version, description, contributor, category), _virtuosSupport(virtuosSupport) + const std::string& description, const std::string& contributor, const std::string& category) : + CmdLineParserBase(name, version, description, contributor, category) { //REQUIRED typedef double DoseTypeGy; addOption(OPTION_DOSE_FILE, OPTION_GROUP_REQUIRED, "The name of the dose file. Can be omitted if used as " "positional argument (see above).", 'd', true); addInformationForXML(OPTION_DOSE_FILE, cmdlineparsing::XMLGenerator::paramType::INPUT, { "*" }); addOption(OPTION_STRUCT_FILE, OPTION_GROUP_REQUIRED, "The name of the struct file. Can be omitted if used as " "positional argument (see above).", 's', true); addInformationForXML(OPTION_STRUCT_FILE, cmdlineparsing::XMLGenerator::paramType::INPUT, { "*" }); addOptionWithDefaultValue(OPTION_STRUCT_NAME, OPTION_GROUP_REQUIRED, "The name of the struct as regular expression. Can be omitted if used as " "positional argument or with itk struct loadingStyle (see above).", "", "", 'n', true); addInformationForXML(OPTION_STRUCT_NAME, cmdlineparsing::XMLGenerator::paramType::STRING); addPositionalOption(OPTION_DOSE_FILE, 1); addPositionalOption(OPTION_STRUCT_FILE, 1); addPositionalOption(OPTION_STRUCT_NAME, 1); addPositionalOption(OPTION_DOSE_STATISTICS, 1); std::vector defaultLoadingStyle; defaultLoadingStyle.push_back("dicom"); std::string doseLoadStyleDescription = "\"dicom\": normal dicom dose\n" "\"itk\": use itk image loading\n\"helax\": load a helax dose (choosing this style, the dose path should only be a directory)."; - - if (_virtuosSupport) - { - doseLoadStyleDescription += "\n" - "\"virtuos\": load of a virtuos dose (This style is a multi argument. The second argument specifies the virtuos plan file, e.g. : \"--" - + OPTION_DOSE_LOAD_STYLE + " virtuos myFavorite.pln\")"; - } - addOptionWithDefaultValue >(OPTION_DOSE_LOAD_STYLE, OPTION_GROUP_REQUIRED, doseLoadStyleDescription, defaultLoadingStyle, defaultLoadingStyle.at(0), 't', true, true); addInformationForXML(OPTION_DOSE_LOAD_STYLE, cmdlineparsing::XMLGenerator::paramType::STRINGENUMERATION, { "dicom", "itk", "helax" }); std::string structLoadStyleDescription = "\"dicom\": normal dicom dose\n" "\"itk\": use itk image loading\""; - if (_virtuosSupport) - { - structLoadStyleDescription += "\n" - "\"virtuos\": load of a virtuos struct file (This style is a multi argument. The second argument specifies the ctx file, e.g. : \"--" - + OPTION_STRUCT_LOAD_STYLE + " virtuos myImage.ctx\")"; - } - addOptionWithDefaultValue >(OPTION_STRUCT_LOAD_STYLE, OPTION_GROUP_REQUIRED, structLoadStyleDescription, defaultLoadingStyle, defaultLoadingStyle.at(0), 'u', true, true); addInformationForXML(OPTION_STRUCT_LOAD_STYLE, cmdlineparsing::XMLGenerator::paramType::STRINGENUMERATION, { "dicom", "itk"}); //OPTIONAL addOption(OPTION_DOSE_STATISTICS, OPTION_GROUP_OPTIONAL, "If dose statistics should be computed. The argument is the output file. Can be omitted if used as " "positional argument (see above).", 'y'); addInformationForXML(OPTION_DOSE_STATISTICS, cmdlineparsing::XMLGenerator::paramType::OUTPUT, { "*" }); addOption(OPTION_DVH, OPTION_GROUP_OPTIONAL, "If the DVH should be computed. The argument is the output file", 'z'); addInformationForXML(OPTION_DVH, cmdlineparsing::XMLGenerator::paramType::OUTPUT, { "*" }); addOption(OPTION_COMPLEX_STATISTICS, OPTION_GROUP_OPTIONAL, "If the complex dose statistics (Dx, Vx, MOHx, MOCx, MaxOHx, MinOCx) should be computed.", 'f'); addInformationForXML(OPTION_COMPLEX_STATISTICS, cmdlineparsing::XMLGenerator::paramType::BOOLEAN); addOption(OPTION_PRESCRIBED_DOSE, OPTION_GROUP_OPTIONAL, "The prescribed dose in Gy.", 'p'); addInformationForXML(OPTION_PRESCRIBED_DOSE, cmdlineparsing::XMLGenerator::paramType::DOUBLE); addOption(OPTION_ALLOW_SELF_INTERSECTION_STRUCT, OPTION_GROUP_OPTIONAL, "If a struct file contains self intersecting contours: Allow the processing of these structures and ignore potential problems." "WARNING: only use this parameter if you know what you are doing.", 'a'); addInformationForXML(OPTION_ALLOW_SELF_INTERSECTION_STRUCT, cmdlineparsing::XMLGenerator::paramType::BOOLEAN); addOption(OPTION_MULTIPLE_STRUCTS_MODE, OPTION_GROUP_OPTIONAL, "If the regex agrees with multiple structs: write a dose statistic for every struct file." "The struct name will be appended to the chosen output filename.", 'm'); addInformationForXML(OPTION_MULTIPLE_STRUCTS_MODE, cmdlineparsing::XMLGenerator::paramType::BOOLEAN); parse(argc, argv); } void DoseToolCmdLineParser::validateInput() const { std::vector doseLoadStyle = get >(OPTION_DOSE_LOAD_STYLE); std::string doseLoadStyleAbbreviation = doseLoadStyle.at(0); - if (doseLoadStyleAbbreviation != "dicom" && (!_virtuosSupport || doseLoadStyleAbbreviation != "virtuos") + if (doseLoadStyleAbbreviation != "dicom" && doseLoadStyleAbbreviation != "itk" && doseLoadStyleAbbreviation != "helax") { throw cmdlineparsing::InvalidConstraintException("Unknown load style for dose file:" + doseLoadStyleAbbreviation + ".\nPlease refer to the help for valid loading style settings."); } - if (_virtuosSupport && doseLoadStyleAbbreviation == "virtuos") - { - if (doseLoadStyle.size() < 2) - { - throw cmdlineparsing::InvalidConstraintException("Cannot load virtuos dose. Plan file is missing. Specify plan file as 2nd io style argument."); - } - } - std::vector structLoadStyle = get >(OPTION_STRUCT_LOAD_STYLE); std::string structLoadStyleAbbreviation = structLoadStyle.at(0); - if (structLoadStyleAbbreviation != "dicom" && (!_virtuosSupport || structLoadStyleAbbreviation != "virtuos") + if (structLoadStyleAbbreviation != "dicom" && structLoadStyleAbbreviation != "itk") { throw cmdlineparsing::InvalidConstraintException("Unknown load style for struct file:" + structLoadStyleAbbreviation + ".\nPlease refer to the help for valid loading style settings."); } - if (structLoadStyleAbbreviation == "dicom" || (_virtuosSupport && structLoadStyleAbbreviation == "virtuos") + if (structLoadStyleAbbreviation == "dicom" || structLoadStyleAbbreviation == "helax") { if (get(OPTION_STRUCT_NAME) == "") { throw cmdlineparsing::InvalidConstraintException("The struct name (--" + OPTION_STRUCT_NAME + - ") has to be defined for dicom, virtuos or helax struct files."); - } - } - - if (_virtuosSupport && structLoadStyleAbbreviation == "virtuos") - { - if (structLoadStyle.size() < 2) - { - throw cmdlineparsing::InvalidConstraintException("Cannot load virtuos struct file. CTX file is missing. Specify CTX file as 2nd io style argument."); + ") has to be defined for dicom or helax struct files."); } } if (!isSet(OPTION_DVH) && !isSet(OPTION_DOSE_STATISTICS)) { throw cmdlineparsing::InvalidConstraintException("Neither the Dose statistics (--" + OPTION_DOSE_STATISTICS + "), nor the DVH (--" + OPTION_DVH + ") option was used."); } if (isSet(OPTION_DOSE_STATISTICS) && isSet(OPTION_COMPLEX_STATISTICS)) { if (!isSet(OPTION_PRESCRIBED_DOSE)) { throw cmdlineparsing::InvalidConstraintException("The prescribed dose (--" + OPTION_PRESCRIBED_DOSE + ") has to be set for computation of complex dose statistics."); } else { if (get(OPTION_PRESCRIBED_DOSE) <= 0) { throw cmdlineparsing::InvalidConstraintException("The prescribed dose (--" + OPTION_PRESCRIBED_DOSE + ") has to be >0!"); } } } } void DoseToolCmdLineParser::printHelp() const { cmdlineparsing::CmdLineParserBase::printHelp(); std::cout << "Example:" << std::endl << std::endl; std::cout << m_programName << " dose.dcm struct.dcm Liver result.xml --" + OPTION_DVH + " dvh.xml" << std::endl << std::endl; std::cout << "This will calculate the Dose statistic for liver using \"dose.dcm\" and the struct file \"struct.dcm\" and will write the dose statistics to \"result.xml\". " " The DVH is computed as well, its values are written to \"dvh.xml\". " << std::endl; } } } } diff --git a/apps/DoseTool/DoseToolCmdLineParser.h b/apps/DoseTool/DoseToolCmdLineParser.h index 5b0fce0..685c955 100644 --- a/apps/DoseTool/DoseToolCmdLineParser.h +++ b/apps/DoseTool/DoseToolCmdLineParser.h @@ -1,68 +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: 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_CMD_LINE_PARSER #define __DOSETOOL_CMD_LINE_PARSER #include "CmdLineParserBase.h" namespace rttb { namespace apps { namespace doseTool { /*! @class DoseToolCmdLineParser @brief Argument parsing is parametrized here based on ArgParserLib @see cmdlineparsing::CmdLineParserBase */ class DoseToolCmdLineParser : public cmdlineparsing::CmdLineParserBase { public: DoseToolCmdLineParser(int argc, const char** argv, const std::string& name, const std::string& version, - const std::string& description, const std::string& contributor, const std::string& category, bool virtuosSupport = false); + const std::string& description, const std::string& contributor, const std::string& category); void validateInput() const; void printHelp() const; // Option groups const std::string OPTION_GROUP_REQUIRED = "Required Arguments"; const std::string OPTION_GROUP_OPTIONAL = "Optional Arguments"; // Parameters const std::string OPTION_DOSE_FILE = "doseFile"; const std::string OPTION_STRUCT_FILE = "structFile"; const std::string OPTION_STRUCT_NAME = "structName"; const std::string OPTION_DOSE_STATISTICS = "doseStatistics"; const std::string OPTION_DVH = "DVH"; const std::string OPTION_DOSE_LOAD_STYLE = "doseLoadStyle"; const std::string OPTION_STRUCT_LOAD_STYLE = "structLoadStyle"; const std::string OPTION_COMPLEX_STATISTICS = "complexStatistics"; const std::string OPTION_PRESCRIBED_DOSE = "prescribedDose"; const std::string OPTION_ALLOW_SELF_INTERSECTION_STRUCT = "allowSelfIntersection"; const std::string OPTION_MULTIPLE_STRUCTS_MODE = "multipleStructsMode"; - - bool _virtuosSupport; }; } } } #endif \ No newline at end of file diff --git a/code/core/rttbBaseType.h b/code/core/rttbBaseType.h index 57835bf..8bc5699 100644 --- a/code/core/rttbBaseType.h +++ b/code/core/rttbBaseType.h @@ -1,743 +1,743 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __BASE_TYPE_NEW_H #define __BASE_TYPE_NEW_H #include #include #include #include #include #include #include #include namespace rttb { const double errorConstant = 1e-5; const double reducedErrorConstant = 0.0001; typedef unsigned short UnsignedIndex1D; /*! @class UnsignedIndex2D @brief 2D index. */ class UnsignedIndex2D: public boost::numeric::ublas::vector { public: UnsignedIndex2D() : boost::numeric::ublas::vector(2) {} UnsignedIndex2D(const UnsignedIndex1D value) : boost::numeric::ublas::vector(2, value) {} const UnsignedIndex1D x() const { return (*this)(0); } const UnsignedIndex1D y() const { return (*this)(1); } }; /*! @class UnsignedIndex3D @brief 3D index. */ class UnsignedIndex3D: public boost::numeric::ublas::vector { public: UnsignedIndex3D() : boost::numeric::ublas::vector(3) {} UnsignedIndex3D(const UnsignedIndex1D value) : boost::numeric::ublas::vector(3, value) {} UnsignedIndex3D(const UnsignedIndex1D xValue, const UnsignedIndex1D yValue, const UnsignedIndex1D zValue) : boost::numeric::ublas::vector(3, xValue) { (*this)(1) = yValue; (*this)(2) = zValue; } const UnsignedIndex1D x() const { return (*this)(0); } const UnsignedIndex1D y() const { return (*this)(1); } const UnsignedIndex1D z() const { return (*this)(2); } friend bool operator==(const UnsignedIndex3D& gi1, const UnsignedIndex3D& gi2) { if (gi1.size() != gi2.size()) { return false; } for (size_t i = 0; i < gi1.size(); i++) { if (gi1(i) != gi2(i)) { return false; } } return true; } friend std::ostream& operator<<(std::ostream& s, const UnsignedIndex3D& aVector) { s << "[ " << aVector(0) << ", " << aVector(1) << ", " << aVector(2) << " ]"; return s; } }; typedef std::list UnsignedIndexList; typedef std::string FileNameString; typedef std::string ContourGeometricTypeString; typedef double WorldCoordinate; /*! @class WorldCoordinate2D @brief 2D coordinate in real world coordinates. */ class WorldCoordinate2D: public boost::numeric::ublas::vector { public: WorldCoordinate2D() : boost::numeric::ublas::vector (2) {} WorldCoordinate2D(const WorldCoordinate value) : boost::numeric::ublas::vector(2, value) {} WorldCoordinate2D(const WorldCoordinate xValue, const WorldCoordinate yValue) : boost::numeric::ublas::vector(2, xValue) { (*this)(1) = yValue; } const WorldCoordinate x() const { return (*this)(0); } const WorldCoordinate y() const { return (*this)(1); } const std::string toString() const { std::stringstream ss; ss << x() << ' ' << y(); return ss.str(); } friend bool operator==(const WorldCoordinate2D& wc1, const WorldCoordinate2D& wc2) { if (wc1.size() != wc2.size()) { return false; } for (size_t i = 0; i < wc1.size(); i++) { if (wc1(i) != wc2(i)) { return false; } } return true; } }; /*! @class WorldCoordinate3D @brief 3D coordinate in real world coordinates like in DICOM to define ImagePositionPatient. */ class WorldCoordinate3D: public boost::numeric::ublas::vector { public: WorldCoordinate3D() : boost::numeric::ublas::vector(3) {} WorldCoordinate3D(const WorldCoordinate value) : boost::numeric::ublas::vector(3, value) {} WorldCoordinate3D(const WorldCoordinate xValue, const WorldCoordinate yValue, const WorldCoordinate zValue) : boost::numeric::ublas::vector(3, xValue) { (*this)(1) = yValue; (*this)(2) = zValue; } WorldCoordinate3D(const WorldCoordinate3D& w): boost::numeric::ublas::vector(3) { (*this)(0) = w.x(); (*this)(1) = w.y(); (*this)(2) = w.z(); } const WorldCoordinate x() const { return (*this)(0); } const WorldCoordinate y() const { return (*this)(1); } const WorldCoordinate z() const { return (*this)(2); } //vector cross product (not included in boost.ublas) WorldCoordinate3D cross(WorldCoordinate3D aVector) const { WorldCoordinate3D result; WorldCoordinate x = (*this)(0); WorldCoordinate y = (*this)(1); WorldCoordinate z = (*this)(2); result(0) = y * aVector(2) - z * aVector(1); result(1) = z * aVector(0) - x * aVector(2); result(2) = x * aVector(1) - y * aVector(0); return result; } WorldCoordinate2D getXY() const { WorldCoordinate2D result; result(0) = (*this)(0); result(1) = (*this)(1); return result; } const std::string toString() const { std::stringstream ss; ss << x() << ' ' << y() << ' ' << z(); return ss.str(); } WorldCoordinate3D& operator=(const WorldCoordinate3D& wc) { (*this)(0) = wc.x(); (*this)(1) = wc.y(); (*this)(2) = wc.z(); return (*this); } WorldCoordinate3D& operator=(const boost::numeric::ublas::vector wc) { (*this)(0) = wc(0); (*this)(1) = wc(1); (*this)(2) = wc(2); return (*this); } WorldCoordinate3D operator-(const boost::numeric::ublas::vector wc) { return WorldCoordinate3D((*this)(0) - wc(0), (*this)(1) - wc(1), (*this)(2) - wc(2)); } WorldCoordinate3D operator+(const boost::numeric::ublas::vector wc) { return WorldCoordinate3D((*this)(0) + wc(0), (*this)(1) + wc(1), (*this)(2) + wc(2)); } friend bool operator==(const WorldCoordinate3D& wc1, const WorldCoordinate3D& wc2) { if (wc1.size() != wc2.size()) { return false; } for (size_t i = 0; i < wc1.size(); i++) { if (wc1(i) != wc2(i)) { return false; } } return true; } bool equalsAlmost(const WorldCoordinate3D& another, double errorConstantWC = 1e-5) const { if (size() != another.size()) { return false; } double dist = norm_2(*this - another); return dist < errorConstantWC; } friend std::ostream& operator<<(std::ostream& s, const WorldCoordinate3D& aVector) { s << "[ " << aVector(0) << ", " << aVector(1) << ", " << aVector(2) << " ]"; return s; } }; /* ! @brief continuous index */ typedef WorldCoordinate3D DoubleVoxelGridIndex3D; typedef UnsignedIndex3D ImageSize; /*! @deprecated Use OrientationMatrix instead. */ typedef WorldCoordinate3D ImageOrientation; typedef double GridVolumeType; /*! @class SpacingVectorType3D @brief 3D spacing vector. @pre values of this vector may not be negative. */ class SpacingVectorType3D: public boost::numeric::ublas::vector { public: SpacingVectorType3D() : boost::numeric::ublas::vector(3) {} SpacingVectorType3D(const GridVolumeType value) : boost::numeric::ublas::vector(3, value) {} SpacingVectorType3D(const GridVolumeType xValue, const GridVolumeType yValue, const GridVolumeType zValue) : boost::numeric::ublas::vector(3, xValue) { (*this)(1) = yValue; (*this)(2) = zValue; } SpacingVectorType3D(const SpacingVectorType3D& w): boost::numeric::ublas::vector(3) { (*this)(0) = w.x(); (*this)(1) = w.y(); (*this)(2) = w.z(); } const GridVolumeType x() const { return (*this)(0); } const GridVolumeType y() const { return (*this)(1); } const GridVolumeType z() const { return (*this)(2); } const std::string toString() const { std::stringstream ss; ss << x() << ' ' << y() << ' ' << z(); return ss.str(); } SpacingVectorType3D& operator=(const SpacingVectorType3D& wc) { (*this)(0) = wc.x(); (*this)(1) = wc.y(); (*this)(2) = wc.z(); return (*this); } SpacingVectorType3D& operator=(const WorldCoordinate3D& wc) { (*this)(0) = GridVolumeType(wc.x()); (*this)(1) = GridVolumeType(wc.y()); (*this)(2) = GridVolumeType(wc.z()); return (*this); } SpacingVectorType3D& operator=(const boost::numeric::ublas::vector wc) { (*this)(0) = wc(0); (*this)(1) = wc(1); (*this)(2) = wc(2); return (*this); } friend bool operator==(const SpacingVectorType3D& wc1, const SpacingVectorType3D& wc2) { if (wc1.size() != wc2.size()) { return false; } for (size_t i = 0; i < wc1.size(); i++) { if (wc1(i) != wc2(i)) { return false; } } return true; } bool equalsAlmost(const SpacingVectorType3D& another, double errorConstantSV) const { if ((*this).size() != another.size()) { return false; } double dist = norm_2(*this - another); return dist < errorConstantSV; } friend std::ostream& operator<<(std::ostream& s, const SpacingVectorType3D& aVector) { s << "[ " << aVector(0) << ", " << aVector(1) << ", " << aVector(2) << " ]"; return s; } }; /*! @class OrientationMatrix @brief Used to store image orientation information */ class OrientationMatrix : public boost::numeric::ublas::matrix { public: /*! The default constructor generates a 3x3 unit matrix */ OrientationMatrix() : boost::numeric::ublas::matrix(3, 3, 0) { for (std::size_t m = 0; m < (*this).size1(); m++) { (*this)(m, m) = 1; } } OrientationMatrix(const WorldCoordinate value) : boost::numeric::ublas::matrix(3, 3, value) {} bool equalsAlmost(const OrientationMatrix& anOrientationMatrix, double errorConstantOM) const { if (anOrientationMatrix.size1() == (*this).size1()) { if (anOrientationMatrix.size2() == (*this).size2()) { for (std::size_t m = 0; m < anOrientationMatrix.size1(); m++) { for (std::size_t n = 0; n < anOrientationMatrix.size2(); n++) { if ((std::abs((*this)(m, n) - anOrientationMatrix(m, n)) > errorConstantOM)) { return false; } } }// end element comparison } else { return false; } } else { return false; } return true; } friend bool operator==(const OrientationMatrix& om1, const OrientationMatrix& om2) { return om1.equalsAlmost(om2, 0.0); } friend std::ostream& operator<<(std::ostream& s, const OrientationMatrix& anOrientationMatrix) { s << "[ "; for (std::size_t m = 0; m < anOrientationMatrix.size1(); m++) { s << "[ "; for (std::size_t n = 0; n < anOrientationMatrix.size2(); n++) { if (n == 0) { s << anOrientationMatrix(m, n); } else { s << ", " << anOrientationMatrix(m, n); } } s << " ]"; } s << " ]"; return s; } }; /*! base for 2D and 3D VoxelIndex; Therefore required beside VoxelGridID */ typedef unsigned int GridIndexType; /*! @class VoxelGridIndex3D @brief 3D voxel grid index in a discret geometry (matrix/image). @details analogous to DICOM where ImagePositionPatient gives the position of the center of the first coordinate (0/0/0) */ class VoxelGridIndex3D: public boost::numeric::ublas::vector { public: VoxelGridIndex3D() : boost::numeric::ublas::vector(3) {} VoxelGridIndex3D(const GridIndexType value) : boost::numeric::ublas::vector(3, value) {} VoxelGridIndex3D(const GridIndexType xValue, const GridIndexType yValue, const GridIndexType zValue) : boost::numeric::ublas::vector(3, xValue) { (*this)(1) = yValue; (*this)(2) = zValue; } const GridIndexType x() const { return (*this)(0); } const GridIndexType y() const { return (*this)(1); } const GridIndexType z() const { return (*this)(2); } const std::string toString() const { std::stringstream ss; ss << x() << ' ' << y() << ' ' << z(); return ss.str(); } VoxelGridIndex3D& operator=(const UnsignedIndex3D& ui) { (*this)(0) = ui(0); (*this)(1) = ui(1); (*this)(2) = ui(2); return (*this); } friend bool operator==(const VoxelGridIndex3D& gi1, const VoxelGridIndex3D& gi2) { if (gi1.size() != gi2.size()) { return false; } for (size_t i = 0; i < gi1.size(); i++) { if (gi1(i) != gi2(i)) { return false; } } return true; } friend std::ostream& operator<<(std::ostream& s, const VoxelGridIndex3D& aVector) { s << "[ " << aVector(0) << ", " << aVector(1) << ", " << aVector(2) << " ]"; return s; } }; /*! @class VoxelGridIndex3D @brief 2D voxel grid index. */ class VoxelGridIndex2D: public boost::numeric::ublas::vector { public: VoxelGridIndex2D() : boost::numeric::ublas::vector(2) {} VoxelGridIndex2D(const GridIndexType value) : boost::numeric::ublas::vector(2, value) {} VoxelGridIndex2D(const GridIndexType xValue, const GridIndexType yValue) : boost::numeric::ublas::vector(2, xValue) { (*this)(1) = yValue; } const GridIndexType x() const { return (*this)(0); } const GridIndexType y() const { return (*this)(1); } const std::string toString() const { std::stringstream ss; ss << x() << ' ' << y(); return ss.str(); } friend bool operator==(const VoxelGridIndex2D& gi1, const VoxelGridIndex2D& gi2) { if (gi1.size() != gi2.size()) { return false; } for (size_t i = 0; i < gi1.size(); i++) { if (gi1(i) != gi2(i)) { return false; } } return true; } friend std::ostream& operator<<(std::ostream& s, const VoxelGridIndex2D& aVector) { s << "[ " << aVector(0) << ", " << aVector(1) << " ]"; return s; } }; typedef long GridSizeType; typedef int VoxelGridID; //starts from 0 and is continuously counting all positions on the grid typedef unsigned int VoxelGridDimensionType; typedef boost::numeric::ublas::vector VoxelGridDimensionVectorType; typedef double FractionType, VoxelSizeType, DVHVoxelNumber; typedef double DoseCalcType, DoseTypeGy, GenericValueType, DoseVoxelVolumeType, VolumeType, GridVolumeType, VoxelNumberType, BEDType, LQEDType; typedef std::string IDType; typedef std::string StructureLabel; struct DVHRole { enum Type { TargetVolume = 1, HealthyTissue = 2, WholeVolume = 4, UserDefined = 128 } Type; }; struct DVHType { enum Type { Differential = 1, Cumulative = 2 } Type; }; typedef std::string PatientInfoString; typedef std::string TimeString; typedef std::string FileNameType; typedef std::vector PolygonType; typedef std::vector PolygonSequenceType; typedef double IndexValueType; typedef double DoseStatisticType; typedef std::string DBStringType; - typedef std::string VirtuosFileNameString, DICOMRTFileNameString; + typedef std::string DICOMRTFileNameString; typedef unsigned short Uint16; struct Area2D { WorldCoordinate x_begin; WorldCoordinate x_end; WorldCoordinate y_begin; WorldCoordinate y_end; VoxelGridIndex2D index_begin; VoxelGridIndex2D index_end; void Init() { x_begin = -1000000; x_end = -1000000; y_begin = -1000000; y_end = -1000000; index_begin(0) = 0; index_begin(1) = 0; index_end(0) = 0; index_end(1) = 0; } }; struct Segment2D { WorldCoordinate2D begin; WorldCoordinate2D end; }; struct Segment3D { WorldCoordinate3D begin; WorldCoordinate3D end; }; typedef int DistributionType; typedef std::string PathType; typedef std::string XMLString, StatisticsString; }//end: namespace rttb #endif diff --git a/testing/apps/DoseTool/DoseToolInvalidParametersTest.cpp b/testing/apps/DoseTool/DoseToolInvalidParametersTest.cpp index 9b41b96..22d1dba 100644 --- a/testing/apps/DoseTool/DoseToolInvalidParametersTest.cpp +++ b/testing/apps/DoseTool/DoseToolInvalidParametersTest.cpp @@ -1,109 +1,98 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed 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 #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 DoseToolInvalidParametersTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; std::string doseToolExecutable; if (argc > 1) { doseToolExecutable = argv[1]; } boost::filesystem::path callingPath(_callingAppPath); std::string doseToolExeWithPath = callingPath.parent_path().string() + "/" + doseToolExecutable; //call with too few parameters std::string toofewParametersCommand = doseToolExeWithPath; toofewParametersCommand += " -d test"; toofewParametersCommand += " -s test"; std::cout << "Command line call: " + toofewParametersCommand << std::endl; CHECK_EQUAL(system(toofewParametersCommand.c_str()) != 0, true); toofewParametersCommand = doseToolExeWithPath; toofewParametersCommand += " -s test"; toofewParametersCommand += " -n test"; std::cout << "Command line call: " + toofewParametersCommand << std::endl; CHECK_EQUAL(system(toofewParametersCommand.c_str()) != 0, true); toofewParametersCommand = doseToolExeWithPath; toofewParametersCommand += " test"; toofewParametersCommand += " test"; std::cout << "Command line call: " + toofewParametersCommand << std::endl; CHECK_EQUAL(system(toofewParametersCommand.c_str()) != 0, true); toofewParametersCommand = doseToolExeWithPath; toofewParametersCommand += " -d test"; toofewParametersCommand += " -s test"; toofewParametersCommand += " -n test"; std::cout << "Command line call: " + toofewParametersCommand << std::endl; CHECK_EQUAL(system(toofewParametersCommand.c_str()) != 0, true); //call with invalid dose load option std::string minimalCLI = doseToolExeWithPath + " test test test "; std::string invalidDoseLoadOption = minimalCLI; invalidDoseLoadOption += "-t wrongOption"; std::cout << "Command line call: " + invalidDoseLoadOption << std::endl; CHECK_EQUAL(system(invalidDoseLoadOption.c_str()) != 0, true); //call with invalid struct load option std::string invalidStructLoadOption = minimalCLI; invalidStructLoadOption += "-u wrongOption"; std::cout << "Command line call: " + invalidStructLoadOption << std::endl; CHECK_EQUAL(system(invalidStructLoadOption.c_str()) != 0, true); - //call with virtuos dose load option, but without plan/ctx - std::string invalidVirtuosDoseLoadOption = minimalCLI; - invalidVirtuosDoseLoadOption += "-u virtuos"; - std::cout << "Command line call: " + invalidVirtuosDoseLoadOption << std::endl; - CHECK_EQUAL(system(invalidVirtuosDoseLoadOption.c_str()) != 0, true); - - std::string invalidVirtuosStructLoadOption = minimalCLI; - invalidVirtuosStructLoadOption += "-t virtuos"; - std::cout << "Command line call: " + invalidVirtuosStructLoadOption << std::endl; - CHECK_EQUAL(system(invalidVirtuosStructLoadOption.c_str()) != 0, true); - //call with complex dose statistics, but without prescribed dose std::string complexDoseWithoutPrescribedDoseCommand = minimalCLI; complexDoseWithoutPrescribedDoseCommand += "-f"; std::cout << "Command line call: " + complexDoseWithoutPrescribedDoseCommand << std::endl; CHECK_EQUAL(system(complexDoseWithoutPrescribedDoseCommand.c_str()) != 0, true); RETURN_AND_REPORT_TEST_SUCCESS; } } //namespace testing } //namespace rttb