diff --git a/demoapps/VoxelizerTool/CMakeLists.txt b/demoapps/VoxelizerTool/CMakeLists.txt index 921bec6..5e4b54c 100644 --- a/demoapps/VoxelizerTool/CMakeLists.txt +++ b/demoapps/VoxelizerTool/CMakeLists.txt @@ -1,3 +1,3 @@ MESSAGE (STATUS "generating demo app: VoxelizerTool - writing files of voxelized structures") -RTTB_CREATE_APPLICATION(VoxelizerTool DEPENDS RTTBITKIO RTTBOTBMask RTTBBoostMask RTTBDicomIO RTTBMasks RTTBCore PACKAGE_DEPENDS MatchPoint ITK) \ No newline at end of file +RTTB_CREATE_APPLICATION(VoxelizerTool DEPENDS RTTBITKIO RTTBOTBMask RTTBBoostMask RTTBDicomIO RTTBMasks RTTBCore PACKAGE_DEPENDS MatchPoint ITK BoostBinaries) \ No newline at end of file diff --git a/demoapps/VoxelizerTool/rttbCommandOptions.cpp b/demoapps/VoxelizerTool/rttbCommandOptions.cpp index 544ae84..3671d49 100644 --- a/demoapps/VoxelizerTool/rttbCommandOptions.cpp +++ b/demoapps/VoxelizerTool/rttbCommandOptions.cpp @@ -1,144 +1,150 @@ // ----------------------------------------------------------------------- // 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: 5603 $ (last changed revision) // @date $Date: 2015-08-24 15:17:30 +0200 (Mo, 24 Aug 2015) $ (last change date) // @author $Author: strubel $ (last changed by) */ #include #include "rttbCommandOptions.h" #include "rttbVoxelizerHelper.h" namespace rttb { namespace apps { namespace voxelizer { CommandOptions::CommandOptions(): PARAM_HELP("help"), PARAM_STRUCT_FILE("structFile"), PARAM_REFERENCE_FILE("referenceFile"), PARAM_OUT_FILE("output"), PARAM_REGEX("struct"), PARAM_MULTISTRUCT("multipleStructs"), PARAM_LEGACY_VOXELIZATION("legacyVoxelization"), PARAM_BOOST_VOXELIZATION("boostVoxelization"), PARAM_BOOLEAN_VOXELIZATION("booleanVoxelization"), - PARAM_ADDSTRUCTURES("addStructures") + PARAM_ADDSTRUCTURES("addStructures"), _returnAfterHelp(false) { _params.multipleStructs = false; _params.legacyVoxelization = false; _params.booleanVoxelization = false; _params.addStructures = false; - _returnAfterHelp = false; po::options_description required("Required arguments"); addOption(required, PARAM_STRUCT_FILE, "s", po::value(&_params.structFile)->required(), "Filename of the structfile (*.dcm)"); addOption(required, PARAM_REFERENCE_FILE, "r", po::value(&_params.referenceFile)->required(), "Filename of the reference image (*.dcm)"); addOption(required, PARAM_REGEX, "e", po::value>(&_params.regEx)->multitoken()->required(), "set a regular expression describing the structs of interest"); addOption(required, PARAM_OUT_FILE, "o", - po::value(&_params.outputFilename)->default_value("out.hdr")->required(), "set output file name "); + po::value(&_params.outputFilename)->default_value("out.hdr"), "set output file name "); addOption(required, PARAM_BOOST_VOXELIZATION, "b", po::bool_switch()->default_value(true), "to use boost voxelization"); po::options_description optional("Optional arguments"); addOption(optional, PARAM_HELP, "h", nullptr, "Display help message"); addOption(optional, PARAM_MULTISTRUCT, "m", po::bool_switch(&_params.multipleStructs)->default_value(false), "if multiple structs match the regular expression (--struct), save all in files"); addOption(optional, PARAM_LEGACY_VOXELIZATION, "l", po::bool_switch(&_params.legacyVoxelization)->default_value(false), "to use legacy voxelization"); addOption(optional, PARAM_BOOLEAN_VOXELIZATION, "v", po::bool_switch(&_params.booleanVoxelization)->default_value(false), "Determines if the voxelization should be binarized (only values 0 or 1)"); - addOption(optional, PARAM_ADDSTRUCTURES, "a", nullptr, ""); + addOption(optional, PARAM_ADDSTRUCTURES, "a", nullptr, "Voxelizes multiple structs in one result file."); _description.add(required).add(optional); } void CommandOptions::addOption(po::options_description& o, const std::string& name, const std::string& shortcut, const po::value_semantic* valueSemantic, const std::string& description) { if (valueSemantic) { o.add_options()((name + std::string(",") + shortcut).c_str(), valueSemantic, description.c_str()); } else { o.add_options()((name + std::string(",") + shortcut).c_str(), description.c_str()); } } void CommandOptions::showHelp() const { std::cout << "Usage: VoxelizerTool [options] \n"; std::cout << _description << std::endl; std::cout << "Example: VoxelizerTool -s structFile.dcm -r referenceFile.dcm -e Kidney -o outputFile.mhd -m" << std::endl; std::cout << "Computes a voxelization file outputFile.mhd based on the DICOMRT-STRUCT structFile.dcm in the geometry of referenceFile.dcm where"; std::cout << "the name of the struct matches the regular expression 'Kidney'." << std::endl; std::cout << "If structures 'Kidney_left' and 'Kidney_right' are defined, "; std::cout << "both are written under the names outputFile_Kidney_left.mhd and outputFile_Kidney_right.mhd (parameter -m)." << std::endl; } bool CommandOptions::command(int argc, char* argv[]) { try { po::variables_map var; po::store(po::command_line_parser(argc, argv).options(_description).run(), var); if (var.count(PARAM_HELP)) { showHelp(); _returnAfterHelp = true; return true; } po::notify(var); if (var.count(PARAM_BOOST_VOXELIZATION)) { _params.legacyVoxelization = false; } + if (_params.outputFilename.find('.') == std::string::npos) + { + std::cout << "--output has to specify a file format (e.g. output.hdr). None is given: " << _params.outputFilename << + std::endl; + return false; + } + if (var.count(PARAM_ADDSTRUCTURES)) { _params.addStructures = true; _params.multipleStructs = false; } } catch (const std::exception& e) { std::cout << "Error: " << e.what() << std::endl; return false; } return true; } } } } \ No newline at end of file diff --git a/demoapps/VoxelizerTool/rttbMaskWriter.cpp b/demoapps/VoxelizerTool/rttbMaskWriter.cpp index 64e3af5..0520a3e 100644 --- a/demoapps/VoxelizerTool/rttbMaskWriter.cpp +++ b/demoapps/VoxelizerTool/rttbMaskWriter.cpp @@ -1,158 +1,132 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision: 5603 $ (last changed revision) // @date $Date: 2015-08-24 15:17:30 +0200 (Mo, 24 Aug 2015) $ (last change date) // @author $Author: strubel $ (last changed by) */ #include "rttbMaskWriter.h" #include "itkImage.h" #include "itkImageFileWriter.h" #include "itkBinaryThresholdImageFilter.h" #include "itkAddImageFilter.h" namespace rttb { namespace apps { namespace voxelizer { MaskWriter::MaskWriter(std::vector maskPointer, bool voxelization) : _maskPointerVector(maskPointer), _booleanvoxelization(voxelization) { } void MaskWriter::writeMaskToFile(const std::string& outputFileName) const { if (!_maskPointerVector.empty()) { ITKImageTypeConstPointer itkImage; if (_maskPointerVector.size() > 1) { itkImage = addMultipleStructsToImage(); } else { io::itk::ITKImageMaskAccessorConverter maskAccessorConverter(_maskPointerVector.at(0)); maskAccessorConverter.process(); itkImage = maskAccessorConverter.getITKImage(); } if (_booleanvoxelization) { itkImage = applyThresholdFilter(itkImage); } writeITKImageToFile(itkImage, outputFileName); } } MaskWriter::ITKImageTypeConstPointer MaskWriter::addMultipleStructsToImage() const { std::vector listOfITKImages; for (int i = 0; i < _maskPointerVector.size(); i++) { io::itk::ITKImageMaskAccessorConverter maskAccessorConverter(_maskPointerVector.at(i)); maskAccessorConverter.process(); listOfITKImages.push_back(maskAccessorConverter.getITKImage()); } typedef itk::AddImageFilter AddImageFilterType; AddImageFilterType::Pointer addFilter = AddImageFilterType::New(); ITKImageTypePointer filterResult; for (int k = 1; k < listOfITKImages.size(); k++) { if (k == 1) { addFilter->SetInput1(listOfITKImages.at(0)); } else { addFilter->SetInput1(filterResult); } addFilter->SetInput2(listOfITKImages.at(k)); - try - { - addFilter->Update(); - } - catch (itk::ExceptionObject& err) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return NULL; - } + addFilter->Update(); filterResult = addFilter->GetOutput(); } return filterResult; } MaskWriter::ITKImageTypeConstPointer MaskWriter::applyThresholdFilter( ITKImageTypeConstPointer itkImage) const { typedef itk::BinaryThresholdImageFilter< ITKMaskImageType, ITKMaskImageType > FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetInput(itkImage); filter->SetLowerThreshold(0.5); filter->SetUpperThreshold(1.0); filter->SetInsideValue(1.0); - try - { - filter->Update(); - } - catch (itk::ExceptionObject& err) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return NULL; - } + filter->Update(); return filter->GetOutput(); } void MaskWriter::writeITKImageToFile(ITKImageTypeConstPointer itkImage, const std::string& outputfilename) const { typedef itk::ImageFileWriter< ITKMaskImageType > WriterType; WriterType::Pointer writer = WriterType::New(); writer->SetFileName(outputfilename); writer->SetInput(itkImage); - try - { - writer->Update(); - } - catch (itk::ExceptionObject& err) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - } + writer->Update(); } } } } \ No newline at end of file diff --git a/demoapps/VoxelizerTool/rttbVoxelizerTool.cpp b/demoapps/VoxelizerTool/rttbVoxelizerTool.cpp index 2def25d..188d4c0 100644 --- a/demoapps/VoxelizerTool/rttbVoxelizerTool.cpp +++ b/demoapps/VoxelizerTool/rttbVoxelizerTool.cpp @@ -1,148 +1,171 @@ // ----------------------------------------------------------------------- // 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: 5603 $ (last changed revision) // @date $Date: 2015-08-24 15:17:30 +0200 (Mo, 24 Aug 2015) $ (last change date) // @author $Author: strubel $ (last changed by) */ #include +#include "itkMacro.h" + #include "rttbVoxelizerHelper.h" #include "rttbMaskProcess.h" #include "rttbMaskWriter.h" #include "rttbStructDataReader.h" #include "rttbCommandOptions.h" int main(int argc, char* argv[]) { typedef rttb::core::MaskAccessorInterface::MaskAccessorPointer MaskAccessorPointer; boost::shared_ptr co = boost::make_shared(); if (!co->command(argc, argv)) { - return EXIT_FAILURE; + return 1; } if (co->isReturnAfterHelp()) { - return EXIT_SUCCESS; + return 0; } rttb::apps::voxelizer::Parameters params = co->getParameters(); - boost::shared_ptr SDR; + boost::shared_ptr reader; try { - SDR = boost::make_shared(params.structFile, - params.referenceFile); + reader = boost::make_shared(params.structFile, + params.referenceFile); } catch (rttb::core::Exception& e) { std::cerr << "RTTB Error!!!" << std::endl; std::cerr << e.what() << std::endl; - return 1; + return 2; } catch (const std::exception& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e.what() << std::endl; - return 1; + return 2; } catch (...) { std::cerr << "Error!!! unknown error while reading input image." << std::endl; - return 1; + return 2; } std::vector listOfCorrectElements; for (int i = 0; i < params.regEx.size(); i++) { std::vector indexOfCorrectElements; - indexOfCorrectElements = rttb::apps::voxelizer::filterForExpression(SDR->getAllLabels(), + indexOfCorrectElements = rttb::apps::voxelizer::filterForExpression(reader->getAllLabels(), params.regEx.at(i)); std::copy(indexOfCorrectElements.begin(), indexOfCorrectElements.end(), std::back_inserter(listOfCorrectElements)); } - boost::shared_ptr MP = - boost::make_shared(SDR->getStructureSetPointer(), - SDR->getDoseAccessorPointer(), + boost::shared_ptr maskProcessor = + boost::make_shared(reader->getStructureSetPointer(), + reader->getDoseAccessorPointer(), params.legacyVoxelization); if (!listOfCorrectElements.empty()) { std::string fileName = rttb::apps::voxelizer::getFilenameWithoutEnding( params.outputFilename); std::string fileEnding = rttb::apps::voxelizer::getFileEnding(params.outputFilename); std::vector maskVector; if (params.addStructures) { std::string labelName; for (int i = 0; i < listOfCorrectElements.size(); i++) { - maskVector.push_back(MP->createMask(listOfCorrectElements.at(i))); int labelIndex = listOfCorrectElements.at(i); - std::vector labelVector = SDR->getAllLabels(); + maskVector.push_back(maskProcessor->createMask(labelIndex)); + std::vector labelVector = reader->getAllLabels(); std::string labelOfInterest = labelVector.at(labelIndex); rttb::apps::voxelizer::removeSpecialCharacters(labelOfInterest); labelName += "_" + labelOfInterest; } - boost::shared_ptr MW = + boost::shared_ptr writer = boost::make_shared(maskVector, params.booleanVoxelization); - MW->writeMaskToFile(fileName + labelName + fileEnding); + writer->writeMaskToFile(fileName + labelName + fileEnding); } else { unsigned int maxIterationCount = 1; if (params.multipleStructs) { maxIterationCount = listOfCorrectElements.size(); } for (unsigned int i = 0; i < maxIterationCount; i++) { - maskVector.push_back(MP->createMask(listOfCorrectElements.at(i))); + maskVector.push_back(maskProcessor->createMask(listOfCorrectElements.at(i))); int labelIndex = listOfCorrectElements.at(i); - std::vector labelVector = SDR->getAllLabels(); + std::vector labelVector = reader->getAllLabels(); std::string labelOfInterest = labelVector.at(labelIndex); rttb::apps::voxelizer::removeSpecialCharacters(labelOfInterest); boost::shared_ptr MW = boost::make_shared(maskVector, params.booleanVoxelization); - MW->writeMaskToFile(fileName + "_" + labelOfInterest + fileEnding); + + try + { + MW->writeMaskToFile(fileName + "_" + labelOfInterest + fileEnding); + } + catch (itk::ExceptionObject& err) + { + std::cerr << "ExceptionObject caught !" << std::endl; + std::cerr << err << std::endl; + return 3; + } + catch (const std::exception& e) + { + std::cerr << "Error!!!" << std::endl; + std::cerr << e.what() << std::endl; + return 3; + } + catch (...) + { + std::cerr << "Error!!! unknown error while reading input image." << std::endl; + return 3; + } } } } else { std::cout << "No struct found" << std::endl; } - return EXIT_SUCCESS; + return 0; } diff --git a/testing/demoapps/VoxelizerTool/rttbVoxelizerToolIncorrectCommandsTest.cpp b/testing/demoapps/VoxelizerTool/rttbVoxelizerToolIncorrectCommandsTest.cpp index 806fb02..04683d9 100644 --- a/testing/demoapps/VoxelizerTool/rttbVoxelizerToolIncorrectCommandsTest.cpp +++ b/testing/demoapps/VoxelizerTool/rttbVoxelizerToolIncorrectCommandsTest.cpp @@ -1,88 +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: 5603 $ (last changed revision) // @date $Date: 2015-08-24 15:17:30 +0200 (Mo, 24 Aug 2015) $ (last change date) // @author $Author: strubel $ (last changed by) */ #include #include "litCheckMacros.h" #include /*! @brief VoxelizerToolTest4. Test incorrect commands with a wrong structfile, referencefile and a wrong struct. if the command return one, the program could not run to the end. return zero the command is correct */ namespace rttb { namespace testing { //path to the current running directory. VoxelizerTool is in the same directory (Debug/Release) extern const char* _callingAppPath; int VoxelizerToolIncorrectCommandsTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; std::string voxelizerToolExe; std::string structFile; std::string invalidStructFile; std::string invalidReferenceFile; std::string referenceFile; std::string structureName; std::string invalidStructureName; if (argc > 7) { voxelizerToolExe = argv[1]; structFile = argv[2]; invalidStructFile = argv[3]; referenceFile = argv[4]; invalidReferenceFile = argv[5]; structureName = argv[6]; invalidStructureName = argv[7]; } boost::filesystem::path callingPath(_callingAppPath); std::string voxelizerToolExeWithPath = callingPath.parent_path().string() + "/" + voxelizerToolExe; - std::string StructCommand = voxelizerToolExeWithPath; - StructCommand += " -s " + invalidStructFile; - StructCommand += " -r " + referenceFile; - StructCommand += " -e " + structureName; - std::cout << "Command line call: " + StructCommand << std::endl; - CHECK_EQUAL(system(StructCommand.c_str()), 1); + std::string tooFewArgumentsCommand = voxelizerToolExeWithPath; + tooFewArgumentsCommand += " -s " + invalidStructFile; + tooFewArgumentsCommand += " -r " + referenceFile; + std::cout << "Command line call: " + tooFewArgumentsCommand << std::endl; + CHECK_EQUAL(system(tooFewArgumentsCommand.c_str()), 1); - std::string ReferenceCommand = voxelizerToolExeWithPath; - ReferenceCommand += " -s " + structFile; - ReferenceCommand += " -r " + invalidReferenceFile; - ReferenceCommand += " -e " + structureName; - std::cout << "Command line call: " + ReferenceCommand << std::endl; - CHECK_EQUAL(system(ReferenceCommand.c_str()), 1); + tooFewArgumentsCommand = voxelizerToolExeWithPath; + tooFewArgumentsCommand += " -s " + invalidStructFile; + tooFewArgumentsCommand += " -e " + structureName; + std::cout << "Command line call: " + tooFewArgumentsCommand << std::endl; + CHECK_EQUAL(system(tooFewArgumentsCommand.c_str()), 1); - std::string Structure = voxelizerToolExeWithPath; - Structure += " -s " + structFile; - Structure += " -r " + referenceFile; - Structure += +" -e " + invalidStructureName; - std::cout << "Command line call: " + Structure << std::endl; - CHECK_EQUAL(system(Structure.c_str()), 0); + tooFewArgumentsCommand = voxelizerToolExeWithPath; + std::cout << "Command line call: " + tooFewArgumentsCommand << std::endl; + CHECK_EQUAL(system(tooFewArgumentsCommand.c_str()), 1); + + std::string noOutputEndingCommand = voxelizerToolExeWithPath; + noOutputEndingCommand += " -s " + invalidStructFile; + noOutputEndingCommand += " -r " + referenceFile; + noOutputEndingCommand += " -e " + structureName; + noOutputEndingCommand += " -o bla"; + std::cout << "Command line call: " + noOutputEndingCommand << std::endl; + CHECK_EQUAL(system(noOutputEndingCommand.c_str()), 1); + + std::string structCommand = voxelizerToolExeWithPath; + structCommand += " -s " + invalidStructFile; + structCommand += " -r " + referenceFile; + structCommand += " -e " + structureName; + std::cout << "Command line call: " + structCommand << std::endl; + CHECK_EQUAL(system(structCommand.c_str()), 2); + + std::string referenceCommand = voxelizerToolExeWithPath; + referenceCommand += " -s " + structFile; + referenceCommand += " -r " + invalidReferenceFile; + referenceCommand += " -e " + structureName; + std::cout << "Command line call: " + referenceCommand << std::endl; + CHECK_EQUAL(system(referenceCommand.c_str()), 2); + + std::string structureNameCommand = voxelizerToolExeWithPath; + structureNameCommand += " -s " + structFile; + structureNameCommand += " -r " + referenceFile; + structureNameCommand += +" -e " + invalidStructureName; + std::cout << "Command line call: " + structureNameCommand << std::endl; + CHECK_EQUAL(system(structureNameCommand.c_str()), 0); RETURN_AND_REPORT_TEST_SUCCESS; } } }