diff --git a/apps/DoseAcc/DoseAccApplicationData.cpp b/apps/DoseAcc/DoseAccApplicationData.cpp index 0ce1965..9d74070 100644 --- a/apps/DoseAcc/DoseAccApplicationData.cpp +++ b/apps/DoseAcc/DoseAccApplicationData.cpp @@ -1,76 +1,70 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ -/*! -// @file -// @version $Revision: 1145 $ (last changed revision) -// @date $Date: 2015-10-12 17:06:10 +0200 (Mo, 12 Okt 2015) $ (last change date) -// @author $Author: hentsch $ (last changed by) -*/ #include "DoseAccApplicationData.h" #include "DoseAccCmdLineParser.h" namespace rttb { namespace apps { namespace doseAcc { ApplicationData:: ApplicationData() { this->Reset(); } void ApplicationData:: Reset() { _dose1FileName = ""; _dose2FileName = ""; _outputFileName = ""; _regFileName = ""; _interpolatorName = "linear"; _weightDose1 = 1.0; _weightDose2 = 1.0; _operator = "+"; } void populateAppData(boost::shared_ptr<DoseAccCmdLineParser> argParser, ApplicationData& appData) { appData._dose1FileName = argParser->get<std::string>(argParser->OPTION_DOSE1_FILENAME); - appData._dose1LoadStyle = argParser->get<std::vector<std::string> > + appData._dose1LoadStyle = argParser->get<std::string> (argParser->OPTION_LOAD_STYLE_DOSE1); appData._dose2FileName = argParser->get<std::string>(argParser->OPTION_DOSE2_FILENAME); - appData._dose2LoadStyle = argParser->get<std::vector<std::string> > + appData._dose2LoadStyle = argParser->get<std::string> (argParser->OPTION_LOAD_STYLE_DOSE2); appData._outputFileName = argParser->get<std::string>(argParser->OPTION_OUTPUT_FILENAME); appData._interpolatorName = argParser->get<std::string>(argParser->OPTION_INTERPOLATOR); appData._weightDose1 = argParser->get<double>(argParser->OPTION_WEIGHT1); appData._weightDose2 = argParser->get<double>(argParser->OPTION_WEIGHT2); appData._regFileName = argParser->get<std::string>(argParser->OPTION_REGISTRATION_FILENAME); appData._operator = argParser->get<std::string>(argParser->OPTION_OPERATOR); } } } } diff --git a/apps/DoseAcc/DoseAccApplicationData.h b/apps/DoseAcc/DoseAccApplicationData.h index 2fbed4a..85de2f8 100644 --- a/apps/DoseAcc/DoseAccApplicationData.h +++ b/apps/DoseAcc/DoseAccApplicationData.h @@ -1,78 +1,68 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ -/*! -// @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. - */ - typedef std::vector<std::string> LoadingStyleArgType; + /** Loaded Dose.*/ core::DoseAccessorInterface::DoseAccessorPointer _dose1; std::string _dose1FileName; - LoadingStyleArgType _dose1LoadStyle; + std::string _dose1LoadStyle; core::DoseAccessorInterface::DoseAccessorPointer _dose2; std::string _dose2FileName; - LoadingStyleArgType _dose2LoadStyle; + std::string _dose2LoadStyle; RegistrationType::Pointer _spReg; std::string _regFileName; std::string _operator; std::string _outputFileName; double _weightDose1; double _weightDose2; std::string _interpolatorName; void Reset(); ApplicationData(); }; /*! @brief Reads the necessary arguments from the DoseToolCmdLineParser and writes them in the respective variables of ApplicationData. */ void populateAppData(boost::shared_ptr<DoseAccCmdLineParser> argParser, ApplicationData& appData); } } } #endif diff --git a/apps/DoseAcc/DoseAccCmdLineParser.cpp b/apps/DoseAcc/DoseAccCmdLineParser.cpp index 93e6bcb..659c979 100644 --- a/apps/DoseAcc/DoseAccCmdLineParser.cpp +++ b/apps/DoseAcc/DoseAccCmdLineParser.cpp @@ -1,162 +1,159 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ -/*! -// @file -// @version $Revision: 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) : CmdLineParserBase(name, version, description, contributor, category) { //REQUIRED addOption<std::string>(OPTION_DOSE1_FILENAME, OPTION_GROUP_REQUIRED, "File path to the first dose.", 'd', true); addInformationForXML(OPTION_DOSE1_FILENAME, cmdlineparsing::XMLGenerator::paramType::INPUT, { "*" }); addOption<std::string>(OPTION_DOSE2_FILENAME, OPTION_GROUP_REQUIRED, "File path to the second dose.", 'e', true); addInformationForXML(OPTION_DOSE2_FILENAME, cmdlineparsing::XMLGenerator::paramType::INPUT, { "*" }); addOption<std::string>(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<std::string>(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<double>(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<double>(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<std::string>(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<std::string> 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)."; + std::string defaultLoadingStyle; + defaultLoadingStyle = "dicom"; + std::string doseLoadStyleDescription = "Options are:" + "\ndicom: normal dicom dose" + "\nitk: use itk image loading" + "\nitkDicom: use itk dicom image loading" + "\nhelax: load a helax dose (choosing this style, the dose path should only be a directory)."; - addOptionWithDefaultValue<std::vector<std::string> >(OPTION_LOAD_STYLE_DOSE1, OPTION_GROUP_REQUIRED, + addOptionWithDefaultValue<std::string>(OPTION_LOAD_STYLE_DOSE1, OPTION_GROUP_REQUIRED, "Load style for dose 1. " + doseLoadStyleDescription, - defaultLoadingStyle, defaultLoadingStyle.at(0), + defaultLoadingStyle, defaultLoadingStyle, 't', true, true); - addInformationForXML(OPTION_LOAD_STYLE_DOSE1, cmdlineparsing::XMLGenerator::paramType::STRINGENUMERATION, { "dicom","itk","helax" }); + addInformationForXML(OPTION_LOAD_STYLE_DOSE1, cmdlineparsing::XMLGenerator::paramType::STRING); - addOptionWithDefaultValue<std::vector<std::string> >(OPTION_LOAD_STYLE_DOSE2, OPTION_GROUP_REQUIRED, + addOptionWithDefaultValue<std::string>(OPTION_LOAD_STYLE_DOSE2, OPTION_GROUP_REQUIRED, "Load style for dose 2. See " + OPTION_LOAD_STYLE_DOSE1, - defaultLoadingStyle, defaultLoadingStyle.at(0), + defaultLoadingStyle, defaultLoadingStyle, 'u', true, true); - addInformationForXML(OPTION_LOAD_STYLE_DOSE2, cmdlineparsing::XMLGenerator::paramType::STRINGENUMERATION, { "dicom","itk","helax" }); + addInformationForXML(OPTION_LOAD_STYLE_DOSE2, cmdlineparsing::XMLGenerator::paramType::STRING); addOptionWithDefaultValue<std::string>(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<std::string> doseLoadStyle1 = get<std::vector<std::string> >(OPTION_LOAD_STYLE_DOSE1); - std::string doseLoadStyleAbbreviation1 = doseLoadStyle1.at(0); + std::string doseLoadStyle1 = get<std::string>(OPTION_LOAD_STYLE_DOSE1); - if (doseLoadStyleAbbreviation1 != "dicom" - && doseLoadStyleAbbreviation1 != "itk" - && doseLoadStyleAbbreviation1 != "helax") + if (doseLoadStyle1 != "dicom" + && doseLoadStyle1 != "itk" + && doseLoadStyle1 != "itkDicom" + && doseLoadStyle1 != "helax") { throw cmdlineparsing::InvalidConstraintException("Unknown load style for dose1 file: " + - doseLoadStyleAbbreviation1 + + doseLoadStyle1 + ".\nPlease refer to the help for valid loading style settings."); } - std::vector<std::string> doseLoadStyle2 = get<std::vector<std::string> >(OPTION_LOAD_STYLE_DOSE2); - std::string doseLoadStyleAbbreviation2 = doseLoadStyle2.at(0); + std::string doseLoadStyle2 = get<std::string>(OPTION_LOAD_STYLE_DOSE2); - if (doseLoadStyleAbbreviation2 != "dicom" - && doseLoadStyleAbbreviation2 != "itk" - && doseLoadStyleAbbreviation2 != "helax") + if (doseLoadStyle2 != "dicom" + && doseLoadStyle2 != "itk" + && doseLoadStyle2 != "itkDicom" + && doseLoadStyle2 != "helax") { throw cmdlineparsing::InvalidConstraintException("Unknown load style for dose2 file: " + - doseLoadStyleAbbreviation2 + + doseLoadStyle2 + ".\nPlease refer to the help for valid loading style settings."); } std::string interpolator = get<std::string>(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<std::string>(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<double>(OPTION_WEIGHT1); double weight2 = get<double>(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; } } } } diff --git a/apps/DoseMap/DoseMapApplicationData.cpp b/apps/DoseMap/DoseMapApplicationData.cpp index edae0f0..3af2ef6 100644 --- a/apps/DoseMap/DoseMapApplicationData.cpp +++ b/apps/DoseMap/DoseMapApplicationData.cpp @@ -1,73 +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: 1145 $ (last changed revision) -// @date $Date: 2015-10-12 17:06:10 +0200 (Mo, 12 Okt 2015) $ (last change date) -// @author $Author: hentsch $ (last changed by) -*/ #include "DoseMapApplicationData.h" #include "DoseMapCmdLineParser.h" namespace rttb { namespace apps { namespace doseMap { ApplicationData:: ApplicationData() { this->reset(); } void ApplicationData:: reset() { _inputDoseFileName = ""; _refDoseFileName = ""; _outputFileName = ""; _regFileName = ""; _interpolatorName = "linear"; } void populateAppData(boost::shared_ptr<rttb::apps::doseMap::DoseMapCmdLineParser> argParser, ApplicationData& appData) { appData.reset(); appData._inputDoseFileName = argParser->get<std::string>(argParser->OPTION_INPUT_DOSE_FILE_NAME); appData._outputFileName = argParser->get<std::string>(argParser->OPTION_OUTPUT_FILE_NAME); appData._interpolatorName = argParser->get<std::string>(argParser->OPTION_INTERPOLATOR); appData._regFileName = argParser->get<std::string>(argParser->OPTION_REG_FILE_NAME); - appData._inputDoseLoadStyle = argParser->get<std::vector<std::string> > (argParser->OPTION_INPUT_DOSE_LOAD_STYLE); + appData._inputDoseLoadStyle = argParser->get<std::string>(argParser->OPTION_INPUT_DOSE_LOAD_STYLE); if (!argParser->isSet(argParser->OPTION_REF_DOSE_FILE)){ appData._refDoseFileName = argParser->get<std::string>(argParser->OPTION_INPUT_DOSE_FILE_NAME); - appData._refDoseLoadStyle = argParser->get<std::vector<std::string> >(argParser->OPTION_INPUT_DOSE_LOAD_STYLE); - } - else{ + appData._refDoseLoadStyle = argParser->get<std::string>(argParser->OPTION_INPUT_DOSE_LOAD_STYLE); + } else { appData._refDoseFileName = argParser->get<std::string>(argParser->OPTION_REF_DOSE_FILE); - appData._refDoseLoadStyle = argParser->get<std::vector<std::string> >(argParser->OPTION_REF_DOSE_LOAD_STYLE); + appData._refDoseLoadStyle = argParser->get<std::string>(argParser->OPTION_REF_DOSE_LOAD_STYLE); } } } } } \ No newline at end of file diff --git a/apps/DoseMap/DoseMapApplicationData.h b/apps/DoseMap/DoseMapApplicationData.h index 3cebc22..517d754 100644 --- a/apps/DoseMap/DoseMapApplicationData.h +++ b/apps/DoseMap/DoseMapApplicationData.h @@ -1,77 +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: 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 __DOSEMAP_APPLICATION_DATA_H #define __DOSEMAP_APPLICATION_DATA_H #include "mapRegistration.h" #include "rttbDoseAccessorInterface.h" namespace rttb { namespace apps { namespace doseMap { class DoseMapCmdLineParser; /*! @class ApplicationData @brief Class for storing all relevant variables needed in DoseMap */ class ApplicationData { public: typedef map::core::Registration<3, 3> RegistrationType; - /**Vector of arguments used to specify the loading style (always the first argument) - * and, if needed, additional arguments for the specified loading style. - */ - typedef std::vector<std::string> LoadingStyleArgType; /** Loaded Dose.*/ core::DoseAccessorInterface::DoseAccessorPointer _inputDose; std::string _inputDoseFileName; - LoadingStyleArgType _inputDoseLoadStyle; + std::string _inputDoseLoadStyle; core::DoseAccessorInterface::DoseAccessorPointer _refDose; std::string _refDoseFileName; - LoadingStyleArgType _refDoseLoadStyle; + std::string _refDoseLoadStyle; RegistrationType::Pointer _spReg; std::string _regFileName; std::string _outputFileName; std::string _interpolatorName; void reset(); ApplicationData(); }; /*! @brief Reads the necessary arguments from the DoseToolCmdLineParser and writes them in the respective variables of ApplicationData. */ void populateAppData(boost::shared_ptr<DoseMapCmdLineParser> argParser, ApplicationData& appData); } } } #endif diff --git a/apps/DoseMap/DoseMapCmdLineParser.cpp b/apps/DoseMap/DoseMapCmdLineParser.cpp index 747af67..ac1c12b 100644 --- a/apps/DoseMap/DoseMapCmdLineParser.cpp +++ b/apps/DoseMap/DoseMapCmdLineParser.cpp @@ -1,115 +1,112 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ -/*! -// @file -// @version $Revision: 1145 $ (last changed revision) -// @date $Date: 2015-10-12 17:06:10 +0200 (Mo, 12 Okt 2015) $ (last change date) -// @author $Author: hentsch $ (last changed by) -*/ #include "DoseMapCmdLineParser.h" namespace rttb { namespace apps { namespace doseMap { DoseMapCmdLineParser::DoseMapCmdLineParser(int argc, const char** argv, const std::string& name, const std::string& version) : CmdLineParserBase(name, version) { - std::vector<std::string> defaultLoadingStyle; - defaultLoadingStyle.push_back("dicom"); - std::string doseLoadStyleDescription = "Indicates the load style that should be used for the input dose. Available styles: \"dicom\": normal dicom dose (default);" - "\"itk\": use itk image loading; \"helax\": load a helax dose (choosing this style, the dose path should only be a directory)."; + std::string defaultLoadingStyle; + defaultLoadingStyle = "dicom"; + std::string doseLoadStyleDescription = "Indicates the load style that should be used for the input dose. Available styles:" + "\ndicom: normal dicom dose (default)" + "\nitk: use itk image loading" + "\nitkDicom: use itk dicom image loading" + "\nhelax: load a helax dose (choosing this style, the dose path should only be a directory)."; addOption<std::string>(OPTION_INPUT_DOSE_FILE_NAME, OPTION_GROUP_REQUIRED, "The name of the input dose file. Can be omitted if used as positional argument (see above).", 'd', true); addOption<std::string>(OPTION_OUTPUT_FILE_NAME, OPTION_GROUP_REQUIRED, "The name of the output file. Can be omitted if used as positional argument (see above).", 'o', true); addOptionWithDefaultValue<std::string>(OPTION_INTERPOLATOR, OPTION_GROUP_REQUIRED, "Specifies the interpolator that should be used for mapping." "Available options are: \"nn\": nearest neighbor,\"linear\": linear interpolation, \"rosu\" interpolation based on the concept of Rosu et al..", "linear", "linear", 'i', true); addOptionWithDefaultValue<std::string>(OPTION_REG_FILE_NAME, OPTION_GROUP_REQUIRED, "Specifies name and location of the registration file that should be used to map the input dose. " "Default is no mapping, thus an identity transform is used. The registration should be stored as MatchPoint registration.", "", "no mapping", 'r',true); addOption<std::string>(OPTION_REF_DOSE_FILE, OPTION_GROUP_OPTIONAL, "Specifies name and location of the dose file that should be the reference/template for the grid to map into. " "If flag is not specified, the input dose is the reference.", 't'); - addOptionWithDefaultValue<std::vector<std::string> >(OPTION_INPUT_DOSE_LOAD_STYLE, OPTION_GROUP_REQUIRED, doseLoadStyleDescription, - defaultLoadingStyle, defaultLoadingStyle.at(0),'l',true); + addOptionWithDefaultValue<std::string>(OPTION_INPUT_DOSE_LOAD_STYLE, OPTION_GROUP_REQUIRED, doseLoadStyleDescription, + defaultLoadingStyle, defaultLoadingStyle, 'l', true); - addOptionWithDefaultValue<std::vector<std::string> >(OPTION_REF_DOSE_LOAD_STYLE, OPTION_GROUP_OPTIONAL, doseLoadStyleDescription, - defaultLoadingStyle, defaultLoadingStyle.at(0), 's', true); + addOptionWithDefaultValue<std::string>(OPTION_REF_DOSE_LOAD_STYLE, OPTION_GROUP_OPTIONAL, doseLoadStyleDescription, + defaultLoadingStyle, defaultLoadingStyle, 's', true); addPositionalOption(OPTION_INPUT_DOSE_FILE_NAME, 1); addPositionalOption(OPTION_OUTPUT_FILE_NAME, 1); parse(argc, argv); } void DoseMapCmdLineParser::validateInput() const { auto interpolator = get<std::string>(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::vector<std::string> inputDoseLoadStyle = get<std::vector<std::string> >(OPTION_INPUT_DOSE_LOAD_STYLE); - std::string indoseLoadStyleAbbreviation = inputDoseLoadStyle.at(0); - if (indoseLoadStyleAbbreviation != "dicom" && indoseLoadStyleAbbreviation != "itk" && indoseLoadStyleAbbreviation != "helax") + std::string inputDoseLoadStyle = get<std::string>(OPTION_INPUT_DOSE_LOAD_STYLE); + + if (inputDoseLoadStyle != "dicom" && inputDoseLoadStyle != "itk" && inputDoseLoadStyle != "itkDicom" && inputDoseLoadStyle != "helax") { throw cmdlineparsing::InvalidConstraintException("Unknown load style for input dose file: " + - indoseLoadStyleAbbreviation + + inputDoseLoadStyle + ".\nPlease refer to the help for valid loading style settings."); } if (isSet(OPTION_REF_DOSE_FILE)){ - std::vector<std::string> refDoseLoadStyle = get<std::vector<std::string> >(OPTION_REF_DOSE_LOAD_STYLE); - std::string refDoseLoadStyleAbbreviation = refDoseLoadStyle.at(0); - if (refDoseLoadStyleAbbreviation != "dicom" && refDoseLoadStyleAbbreviation != "itk" && refDoseLoadStyleAbbreviation != "helax") + std::string refDoseLoadStyle = get<std::string>(OPTION_REF_DOSE_LOAD_STYLE); + + if (refDoseLoadStyle != "dicom" && refDoseLoadStyle != "itk" && refDoseLoadStyle != "itkDicom" && refDoseLoadStyle != "helax") { throw cmdlineparsing::InvalidConstraintException("Unknown load style for reference dose file: " + - refDoseLoadStyleAbbreviation + + refDoseLoadStyle + ".\nPlease refer to the help for valid loading style settings."); } } } void DoseMapCmdLineParser::printHelp() const { cmdlineparsing::CmdLineParserBase::printHelp(); std::cout << "Example:" << std::endl << std::endl; std::cout << m_programName << " dose1.mhd result.mhd -r reg.mapr --" << OPTION_INPUT_DOSE_LOAD_STYLE << " itk --" << OPTION_REF_DOSE_LOAD_STYLE+ " itk" << std::endl << std::endl; std::cout << "This will map \"dose1.mhd\" by using \"reg.mapr\" into the grid geometry of the input dose. The resulting dose will be stored in \"result.mhd\"." << std::endl; } } } } diff --git a/apps/DoseTool/DoseTool.cpp b/apps/DoseTool/DoseTool.cpp index a12b793..7ea8b3d 100644 --- a/apps/DoseTool/DoseTool.cpp +++ b/apps/DoseTool/DoseTool.cpp @@ -1,170 +1,164 @@ // ----------------------------------------------------------------------- // 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" #include "rttbStructLoader.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<rttb::apps::doseTool::DoseToolCmdLineParser> 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<rttb::apps::doseTool::DoseToolCmdLineParser>(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::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") + if (appData._structLoadStyle != "itk" && appData._structLoadStyle != "itkDicom") { try { appData._struct = rttb::io::utils::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/DoseToolApplicationData.cpp b/apps/DoseTool/DoseToolApplicationData.cpp index 439ebd0..396f780 100644 --- a/apps/DoseTool/DoseToolApplicationData.cpp +++ b/apps/DoseTool/DoseToolApplicationData.cpp @@ -1,91 +1,75 @@ // ----------------------------------------------------------------------- // 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 "DoseToolApplicationData.h" #include "DoseToolCmdLineParser.h" namespace rttb { namespace apps { namespace doseTool { - ApplicationData:: - ApplicationData() - { + ApplicationData::ApplicationData() { this->reset(); } - void - ApplicationData:: - reset() - { + void ApplicationData::reset() { _doseFileName = ""; _structFileName = ""; _structNameRegex = ""; _doseStatisticOutputFileName = ""; _computeComplexDoseStatistics = false; _allowSelfIntersection = false; _structNames.clear(); _prescribedDose = 1.0; _multipleStructsMode = false; _computeDVH = false; _computeDoseStatistics = false; } - void populateAppData(boost::shared_ptr<DoseToolCmdLineParser> argParser, ApplicationData& appData) - { + void populateAppData(boost::shared_ptr<DoseToolCmdLineParser> argParser, ApplicationData& appData) { appData._doseFileName = argParser->get<std::string>(argParser->OPTION_DOSE_FILE); - appData._doseLoadStyle = argParser->get<std::vector<std::string> > + appData._doseLoadStyle = argParser->get<std::string> (argParser->OPTION_DOSE_LOAD_STYLE); appData._structFileName = argParser->get<std::string>(argParser->OPTION_STRUCT_FILE); - appData._structLoadStyle = argParser->get<std::vector<std::string> > + appData._structLoadStyle = argParser->get<std::string> (argParser->OPTION_STRUCT_LOAD_STYLE); appData._structNameRegex = argParser->get<std::string >(argParser->OPTION_STRUCT_NAME); appData._multipleStructsMode = argParser->isSet(argParser->OPTION_MULTIPLE_STRUCTS_MODE); - if (argParser->isSet(argParser->OPTION_DOSE_STATISTICS)) - { + if (argParser->isSet(argParser->OPTION_DOSE_STATISTICS)) { appData._computeDoseStatistics = true; appData._doseStatisticOutputFileName = argParser->get<std::string > (argParser->OPTION_DOSE_STATISTICS); appData._computeComplexDoseStatistics = argParser->isSet(argParser->OPTION_COMPLEX_STATISTICS); appData._allowSelfIntersection = argParser->isSet(argParser->OPTION_ALLOW_SELF_INTERSECTION_STRUCT); } - if (argParser->isSet(argParser->OPTION_DVH)) - { + if (argParser->isSet(argParser->OPTION_DVH)) { appData._computeDVH = true; appData._dvhOutputFilename = argParser->get<std::string >(argParser->OPTION_DVH); } - if (argParser->isSet(argParser->OPTION_DOSE_STATISTICS) - && argParser->isSet(argParser->OPTION_PRESCRIBED_DOSE)) - { + if (argParser->isSet(argParser->OPTION_DOSE_STATISTICS) && argParser->isSet(argParser->OPTION_PRESCRIBED_DOSE)) { appData._prescribedDose = argParser->get<DoseTypeGy>(argParser->OPTION_PRESCRIBED_DOSE); } } } } } diff --git a/apps/DoseTool/DoseToolApplicationData.h b/apps/DoseTool/DoseToolApplicationData.h index 945c80d..73c0d6a 100644 --- a/apps/DoseTool/DoseToolApplicationData.h +++ b/apps/DoseTool/DoseToolApplicationData.h @@ -1,77 +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: 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 <boost/shared_ptr.hpp> #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. - */ - typedef std::vector<std::string> LoadingStyleArgType; core::DoseAccessorInterface::DoseAccessorPointer _dose; core::StructureSetGeneratorInterface::StructureSetPointer _struct; std::string _structNameRegex; std::vector<std::string> _structNames; - std::string _doseFileName; - std::string _structFileName; - LoadingStyleArgType _doseLoadStyle; - LoadingStyleArgType _structLoadStyle; + std::string _doseFileName; + std::string _structFileName; + std::string _doseLoadStyle; + std::string _structLoadStyle; bool _computeComplexDoseStatistics; DoseTypeGy _prescribedDose; - std::string _doseStatisticOutputFileName; + 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<DoseToolCmdLineParser> argParser, ApplicationData& appData); } } } #endif diff --git a/apps/DoseTool/DoseToolCmdLineParser.cpp b/apps/DoseTool/DoseToolCmdLineParser.cpp index 7dee71c..757b638 100644 --- a/apps/DoseTool/DoseToolCmdLineParser.cpp +++ b/apps/DoseTool/DoseToolCmdLineParser.cpp @@ -1,185 +1,180 @@ // ----------------------------------------------------------------------- // 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) : CmdLineParserBase(name, version, description, contributor, category) { //REQUIRED using DoseTypeGy = double; addOption<std::string>(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<std::string>(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<std::string>(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<std::string> 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)."; + std::string defaultLoadingStyle = "dicom"; + std::string doseLoadStyleDescription = "Available styles:" + "\ndicom: normal dicom dose (default)" + "\nitk: use itk image loading" + "\nitkDicom: use itk dicom image loading" + "\nhelax: load a helax dose (choosing this style, the dose path should only be a directory)."; - addOptionWithDefaultValue<std::vector<std::string> >(OPTION_DOSE_LOAD_STYLE, OPTION_GROUP_REQUIRED, + addOptionWithDefaultValue<std::string>(OPTION_DOSE_LOAD_STYLE, OPTION_GROUP_REQUIRED, doseLoadStyleDescription, - defaultLoadingStyle, defaultLoadingStyle.at(0), + defaultLoadingStyle, defaultLoadingStyle, 't', true, true); - addInformationForXML(OPTION_DOSE_LOAD_STYLE, cmdlineparsing::XMLGenerator::paramType::STRINGENUMERATION, { "dicom", "itk", "helax" }); + addInformationForXML(OPTION_DOSE_LOAD_STYLE, cmdlineparsing::XMLGenerator::paramType::STRING); std::string structLoadStyleDescription = "\"dicom\": normal dicom dose\n" "\"itk\": use itk image loading\""; - addOptionWithDefaultValue<std::vector<std::string> >(OPTION_STRUCT_LOAD_STYLE, + addOptionWithDefaultValue<std::string>(OPTION_STRUCT_LOAD_STYLE, OPTION_GROUP_REQUIRED, structLoadStyleDescription, - defaultLoadingStyle, defaultLoadingStyle.at(0), + defaultLoadingStyle, defaultLoadingStyle, 'u', true, true); - addInformationForXML(OPTION_STRUCT_LOAD_STYLE, cmdlineparsing::XMLGenerator::paramType::STRINGENUMERATION, { "dicom", "itk"}); + addInformationForXML(OPTION_STRUCT_LOAD_STYLE, cmdlineparsing::XMLGenerator::paramType::STRING); //OPTIONAL addOption<std::string>(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<std::string>(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<DoseTypeGy>(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<std::string> doseLoadStyle = get<std::vector<std::string> >(OPTION_DOSE_LOAD_STYLE); - std::string doseLoadStyleAbbreviation = doseLoadStyle.at(0); + std::string doseLoadStyle = get<std::string>(OPTION_DOSE_LOAD_STYLE); - if (doseLoadStyleAbbreviation != "dicom" - && doseLoadStyleAbbreviation != "itk" - && doseLoadStyleAbbreviation != "helax") + if (doseLoadStyle != "dicom" + && doseLoadStyle != "itk" + && doseLoadStyle != "itkDicom" + && doseLoadStyle != "helax") { throw cmdlineparsing::InvalidConstraintException("Unknown load style for dose file:" + - doseLoadStyleAbbreviation + + doseLoadStyle + ".\nPlease refer to the help for valid loading style settings."); } - std::vector<std::string> structLoadStyle = get<std::vector<std::string> >(OPTION_STRUCT_LOAD_STYLE); - std::string structLoadStyleAbbreviation = structLoadStyle.at(0); + std::string structLoadStyle = get<std::string>(OPTION_STRUCT_LOAD_STYLE); - if (structLoadStyleAbbreviation != "dicom" - && structLoadStyleAbbreviation != "itk") + if (structLoadStyle != "dicom" + && structLoadStyle != "itk" + && structLoadStyle != "itkDicom") { throw cmdlineparsing::InvalidConstraintException("Unknown load style for struct file:" + - structLoadStyleAbbreviation + + structLoadStyle + ".\nPlease refer to the help for valid loading style settings."); } - if (structLoadStyleAbbreviation == "dicom" - || structLoadStyleAbbreviation == "helax") + if (structLoadStyle == "dicom" || structLoadStyle == "helax") { if (get<std::string>(OPTION_STRUCT_NAME) == "") { throw cmdlineparsing::InvalidConstraintException("The struct name (--" + OPTION_STRUCT_NAME + ") 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<double>(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/DoseToolHelper.cpp b/apps/DoseTool/DoseToolHelper.cpp index 000f454..484298b 100644 --- a/apps/DoseTool/DoseToolHelper.cpp +++ b/apps/DoseTool/DoseToolHelper.cpp @@ -1,245 +1,199 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ -/*! -// @file -// @version $Revision: 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 "DoseToolApplicationData.h" #include "rttbDicomFileStructureSetGenerator.h" #include "rttbITKImageFileMaskAccessorGenerator.h" #include "rttbDoseStatistics.h" #include "rttbDVH.h" #include "rttbDVHCalculator.h" #include "rttbDVHXMLFileWriter.h" #include "rttbDoseStatisticsCalculator.h" #include "rttbBoostMaskAccessor.h" #include "rttbGenericMaskedDoseIterator.h" #include "rttbDoseStatisticsXMLWriter.h" -std::vector<rttb::core::MaskAccessorInterface::MaskAccessorPointer> -rttb::apps::doseTool::generateMasks( - rttb::apps::doseTool::ApplicationData& appData) -{ +std::vector<rttb::core::MaskAccessorInterface::MaskAccessorPointer> rttb::apps::doseTool::generateMasks(rttb::apps::doseTool::ApplicationData& appData) { + std::vector<core::MaskAccessorInterface::MaskAccessorPointer> maskAccessorPtrVector; - if (appData._structLoadStyle.front() == "itk") - { - maskAccessorPtrVector.push_back(rttb::io::itk::ITKImageFileMaskAccessorGenerator( - appData._structFileName).generateMaskAccessor()); + if (appData._structLoadStyle == "itk" || appData._structLoadStyle == "itkDicom") { + maskAccessorPtrVector.push_back(rttb::io::itk::ITKImageFileMaskAccessorGenerator(appData._structFileName).generateMaskAccessor()); appData._structNames.push_back(appData._structNameRegex); - } - else - { - if (appData._struct->getNumberOfStructures() > 0) { - //default behavior: read only first struct that matches the regex - unsigned int maxIterationCount = 1; - - //only if specified: read all structs that matches the regex - if (appData._multipleStructsMode) - { - maxIterationCount = appData._struct->getNumberOfStructures(); - } - - bool strict = !appData._allowSelfIntersection; - - for (size_t i = 0; i < maxIterationCount; i++) - { - maskAccessorPtrVector.emplace_back(boost::make_shared<rttb::masks::boost::BoostMaskAccessor> - (appData._struct->getStructure(i), appData._dose->getGeometricInfo(), strict)); - maskAccessorPtrVector.at(i)->updateMask(); - appData._structNames.push_back(appData._struct->getStructure(i)->getLabel()); - } - } - else { - std::cout << "no structures in structure set!" << std::endl; - } + } else { + if (appData._struct->getNumberOfStructures() > 0) { + //default behavior: read only first struct that matches the regex + unsigned int maxIterationCount = 1; + + //only if specified: read all structs that matches the regex + if (appData._multipleStructsMode) { + maxIterationCount = appData._struct->getNumberOfStructures(); + } + + bool strict = !appData._allowSelfIntersection; + + for (size_t i = 0; i < maxIterationCount; i++) { + maskAccessorPtrVector.emplace_back(boost::make_shared<rttb::masks::boost::BoostMaskAccessor>(appData._struct->getStructure(i), appData._dose->getGeometricInfo(), strict)); + maskAccessorPtrVector.at(i)->updateMask(); + appData._structNames.push_back(appData._struct->getStructure(i)->getLabel()); + } + } else { + std::cout << "no structures in structure set!" << std::endl; + } } return maskAccessorPtrVector; } -rttb::core::DoseIteratorInterface::DoseIteratorPointer -rttb::apps::doseTool::generateMaskedDoseIterator( - rttb::core::MaskAccessorInterface::MaskAccessorPointer maskAccessorPtr, - rttb::core::DoseAccessorInterface::DoseAccessorPointer doseAccessorPtr) -{ - boost::shared_ptr<core::GenericMaskedDoseIterator> maskedDoseIterator = - boost::make_shared<core::GenericMaskedDoseIterator>(maskAccessorPtr, doseAccessorPtr); +rttb::core::DoseIteratorInterface::DoseIteratorPointer rttb::apps::doseTool::generateMaskedDoseIterator( + rttb::core::MaskAccessorInterface::MaskAccessorPointer maskAccessorPtr, + rttb::core::DoseAccessorInterface::DoseAccessorPointer doseAccessorPtr) { + + boost::shared_ptr<core::GenericMaskedDoseIterator> maskedDoseIterator = boost::make_shared<core::GenericMaskedDoseIterator>(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::DoseStatistics::DoseStatisticsPointer calculateDoseStatistics( + rttb::core::DoseIteratorInterface::DoseIteratorPointer doseIterator, + bool calculateComplexDoseStatistics, + rttb::DoseTypeGy prescribedDose) { + rttb::algorithms::DoseStatisticsCalculator doseStatsCalculator(doseIterator); - if (calculateComplexDoseStatistics) - { + if (calculateComplexDoseStatistics) { return doseStatsCalculator.calculateDoseStatistics(prescribedDose); - } - else - { + } else { return doseStatsCalculator.calculateDoseStatistics(); } } -rttb::core::DVH::DVHPointer calculateDVH( - rttb::core::DoseIteratorInterface::DoseIteratorPointer - doseIterator, rttb::IDType structUID, rttb::IDType doseUID) -{ +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) -{ +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(); + 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 <config>....</config> part to the RTTB generated xml where the used files and struct names are stored. */ -void writeDoseStatisticsFile( - rttb::algorithms::DoseStatistics::DoseStatisticsPointer statistics, - const std::string& filename, const std::string& structName, - rttb::apps::doseTool::ApplicationData& appData) -{ +void writeDoseStatisticsFile(rttb::algorithms::DoseStatistics::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<std::string>('\t', 1)); - + boost::property_tree::write_xml(filename, reorderedTree, std::locale(), boost::property_tree::xml_writer_make_settings<std::string>('\t', 1)); } -void writeDVHFile(rttb::core::DVH::DVHPointer dvh, const std::string& filename) -{ +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) -{ +void rttb::apps::doseTool::processData(rttb::apps::doseTool::ApplicationData& appData) { std::cout << std::endl << "generating masks... "; - std::vector<core::MaskAccessorInterface::MaskAccessorPointer> maskAccessorPtrVector = generateMasks( - appData); + std::vector<core::MaskAccessorInterface::MaskAccessorPointer> maskAccessorPtrVector = generateMasks(appData); std::cout << "done." << std::endl; - for (size_t i = 0; i < maskAccessorPtrVector.size(); i++) - { + for (size_t i = 0; i < maskAccessorPtrVector.size(); i++) { core::DoseIteratorInterface::DoseIteratorPointer spDoseIterator(generateMaskedDoseIterator( maskAccessorPtrVector.at(i), appData._dose)); - if (appData._computeDoseStatistics) - { + 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) - { + if (appData._multipleStructsMode) { outputFilename = assembleFilenameWithStruct(appData._doseStatisticOutputFileName, appData._structNames.at(i)); - } - else - { + } else { outputFilename = appData._doseStatisticOutputFileName; } writeDoseStatisticsFile(statistics, outputFilename, appData._structNames.at(i), appData); std::cout << "done." << std::endl; } - if (appData._computeDVH) - { + if (appData._computeDVH) { std::cout << std::endl << "computing DVH... "; rttb::IDType structUID; rttb::IDType doseUID; + //Generate random UID - if (appData._structLoadStyle.front() == "itk"){ + if (appData._structLoadStyle == "itk") { structUID = "struct42"; doseUID = "dose42"; - } - else { + } else { structUID = appData._struct->getUID(); doseUID = appData._dose->getUID(); } - core::DVH::DVHPointer dvh = calculateDVH(spDoseIterator, structUID, - doseUID); + 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) - { + if (appData._multipleStructsMode) { outputFilename = assembleFilenameWithStruct(appData._dvhOutputFilename, appData._structNames.at(i)); - } - else - { + } else { outputFilename = appData._dvhOutputFilename; } - writeDVHFile(dvh, outputFilename); std::cout << "done." << std::endl; } } - }