diff --git a/code/core/rttbMaskVoxel.cpp b/code/core/rttbMaskVoxel.cpp index 95b21f3..4081533 100644 --- a/code/core/rttbMaskVoxel.cpp +++ b/code/core/rttbMaskVoxel.cpp @@ -1,85 +1,95 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbMaskVoxel.h" #include "rttbInvalidParameterException.h" -namespace rttb{ - namespace core{ +namespace rttb +{ + namespace core + { - MaskVoxel::MaskVoxel(const rttb::VoxelGridID &aVoxelGridID){ - if(aVoxelGridID<0) - { - std::cout << aVoxelGridID<1) - { - std::cout << aVolumeFraction< 1) + { + std::cout << aVolumeFraction << std::endl; throw InvalidParameterException("Volume fraction needs to be between 0 and 1!"); - } + } else - { - _voxelGridID=aVoxelGridID; - _volumeFraction=aVolumeFraction; - } + { + _voxelGridID = aVoxelGridID; + _volumeFraction = aVolumeFraction; } + } - bool MaskVoxel::operator==(const MaskVoxel& voxel) const{ - return ( (_voxelGridID==voxel.getVoxelGridID()) && (_volumeFraction==voxel.getRelevantVolumeFraction()) ); - } + bool MaskVoxel::operator==(const MaskVoxel& voxel) const + { + return ((_voxelGridID == voxel.getVoxelGridID()) && (_volumeFraction == voxel.getRelevantVolumeFraction())); + } - bool MaskVoxel::operator<(const MaskVoxel& maskVoxel) const{ + bool MaskVoxel::operator<(const MaskVoxel& maskVoxel) const + { return (_voxelGridID < maskVoxel.getVoxelGridID()); } - const VoxelGridID& MaskVoxel::getVoxelGridID() const{ + const VoxelGridID& MaskVoxel::getVoxelGridID() const + { return _voxelGridID; - } + } - void MaskVoxel::setRelevantVolumeFraction(FractionType aVolumeFraction){ - if(aVolumeFraction<0 || aVolumeFraction>1) - { - std::cout << aVolumeFraction< 1) + { + std::cout << aVolumeFraction << std::endl; throw InvalidParameterException("Volume fraction needs to be between 0 and 1!"); - } - _volumeFraction=aVolumeFraction; } - FractionType MaskVoxel::getRelevantVolumeFraction() const{ + _volumeFraction = aVolumeFraction; + } + + FractionType MaskVoxel::getRelevantVolumeFraction() const + { return _volumeFraction; - } + } - }//end namespace core + }//end namespace core }//end namespace rttb diff --git a/demoapps/VoxelizerTool/rttbCommandOptions.cpp b/demoapps/VoxelizerTool/rttbCommandOptions.cpp index 8931764..b80ddb3 100644 --- a/demoapps/VoxelizerTool/rttbCommandOptions.cpp +++ b/demoapps/VoxelizerTool/rttbCommandOptions.cpp @@ -1,150 +1,173 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include "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"), _returnAfterHelp(false) + PARAM_ADDSTRUCTURES("addStructures"), + PARAM_ALLOW_SELF_INTERSECTIONS("selfIntersections"), + _returnAfterHelp(false) { _params.multipleStructs = false; _params.legacyVoxelization = false; _params.booleanVoxelization = false; _params.addStructures = false; + std::vector defaultRefLoadingStyle; + defaultRefLoadingStyle.push_back("dicom"); + + 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_REFERENCE_FILE_LOAD_STYLE, "y", + po::value >(&_params.referenceFileLoadStyle)->required()->default_value( + defaultRefLoadingStyle, "dicom"), + "set the load style for the reference file. Available styles are:\n" + "\"dicom\": normal dicom dose\n" + "\"itk\": use itk image loading."); 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"), "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, "Voxelizes multiple structs in one result file."); + addOption(optional, PARAM_ALLOW_SELF_INTERSECTIONS, "i", + po::bool_switch(&_params.allowSelfIntersections)->default_value(false), + "If self intersections of polygons should be tolerated."); _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 (_params.referenceFileLoadStyle.empty() || (_params.referenceFileLoadStyle.at(0) != "dicom" + && _params.referenceFileLoadStyle.at(0) != "itk")) + { + std::cout << "Unknown load style:" + _params.referenceFileLoadStyle.at(0) + + ".\nPlease refer to the help for valid loading style settings." << 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/rttbCommandOptions.h b/demoapps/VoxelizerTool/rttbCommandOptions.h index 64b4c09..d70a14a 100644 --- a/demoapps/VoxelizerTool/rttbCommandOptions.h +++ b/demoapps/VoxelizerTool/rttbCommandOptions.h @@ -1,123 +1,129 @@ // ----------------------------------------------------------------------- // 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 __CommandOptions_h #define __CommandOptions_h #include namespace rttb { namespace apps { namespace voxelizer { namespace po = boost::program_options; /** @brief Simple struct holding all variables. */ struct Parameters { /** @brief Filename of the StructFile*/ std::string structFile; /** @brief Filename of the ReferenceFile*/ std::string referenceFile; + std::vector referenceFileLoadStyle; /** @brief Output Filename*/ std::string outputFilename; /** @brief Expressions from User*/ std::vector regEx; /** @brief for more than one struct*/ bool multipleStructs; /** @brief add: legacyVoxelization=false means boostVoxelization is turned on*/ bool legacyVoxelization; /** @brief voxelization should be binarized to value 0 or 1 */ bool booleanVoxelization ; /** @brief multiple structures voxelization should be combined in one file*/ bool addStructures; + /** @brief requests a strict voxelization (non-strict: polygon intersections are tolerated)*/ + bool allowSelfIntersections; + }; /*! @class CommandOptions @brief CommandOptions Class, everything about the command line */ class CommandOptions { public: /** @details add the description for command line options * add parameter --h or --help for help informations, * --Structfile= to set a struct file, * --Reference= to set the reference file, * --Output= to set an output file name and * --struct= to add an expression like(SPINE). */ CommandOptions(); /** @brief Validates the given input parameters and fills the corresponding variables. @param argc Number of arguments. @param argv Array of individual arguments. @return true if all arguments were valid (i.e. none were missing or incorrect), otherwise false. */ bool command(int argc, char* argv[]); const Parameters& getParameters() const { return _params; } bool isReturnAfterHelp() const { return _returnAfterHelp; } private: /** *@brief Adds an option to the given option container. *@param o Option container the new option should be added to. *@param name Name of the new option (i.e. the actual parameter, e.g. "test" adds the option with the parameter "--test"). *@param shortcut A single letter that is used as a shortcut for this option (e.g. if the name is "test, the shortcut might be "t", so you can call the parameter with "-t" instead of "--test"). *@param valueSemantic The desired value semantic object, i.e. the object that binds this option's value to a variable. *@param description The description text for this option. */ void addOption(po::options_description& o, const std::string& name, const std::string& shortcut, const po::value_semantic* valueSemantic, const std::string& description); /*! @brief print out the dicription.*/ void showHelp()const; const std::string PARAM_STRUCT_FILE; const std::string PARAM_REFERENCE_FILE; + const std::string PARAM_REFERENCE_FILE_LOAD_STYLE; const std::string PARAM_OUT_FILE; const std::string PARAM_REGEX; const std::string PARAM_MULTISTRUCT; const std::string PARAM_HELP; const std::string PARAM_LEGACY_VOXELIZATION; const std::string PARAM_BOOST_VOXELIZATION; const std::string PARAM_BOOLEAN_VOXELIZATION; const std::string PARAM_ADDSTRUCTURES; + const std::string PARAM_ALLOW_SELF_INTERSECTIONS; /*! create description object */ po::options_description _description; Parameters _params; bool _returnAfterHelp; }; } } } #endif \ No newline at end of file diff --git a/demoapps/VoxelizerTool/rttbMaskProcess.cpp b/demoapps/VoxelizerTool/rttbMaskProcess.cpp index 0ac86f7..d616879 100644 --- a/demoapps/VoxelizerTool/rttbMaskProcess.cpp +++ b/demoapps/VoxelizerTool/rttbMaskProcess.cpp @@ -1,64 +1,64 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbMaskProcess.h" #include #include "rttbBoostMaskAccessor.h" namespace rttb { namespace apps { namespace voxelizer { MaskProcess::MaskProcess(StructureSetPointer rtStructureSet, DoseAccessorPointer doseAccessor, - bool legacy) : _rtStructureSet(rtStructureSet), _doseAccessor(doseAccessor), - _legacyVoxelization(legacy) + bool legacy, bool allowSelfIntersection) : _rtStructureSet(rtStructureSet), _doseAccessor(doseAccessor), + _legacyVoxelization(legacy), _allowSelfIntersection(allowSelfIntersection) { } MaskProcess::MaskAccessorPointer MaskProcess::createMask(unsigned int indexOfStructure) const { MaskAccessorPointer maskAccessorPtr; if (_doseAccessor != NULL && _rtStructureSet != NULL) { if (_legacyVoxelization) { maskAccessorPtr = boost::make_shared (_rtStructureSet->getStructure(indexOfStructure), _doseAccessor->getGeometricInfo()); } else { maskAccessorPtr = boost::make_shared - (_rtStructureSet->getStructure(indexOfStructure), _doseAccessor->getGeometricInfo()); + (_rtStructureSet->getStructure(indexOfStructure), _doseAccessor->getGeometricInfo(), !_allowSelfIntersection); } maskAccessorPtr->updateMask(); } return maskAccessorPtr; } } } } \ No newline at end of file diff --git a/demoapps/VoxelizerTool/rttbMaskProcess.h b/demoapps/VoxelizerTool/rttbMaskProcess.h index f7a4a30..d28fb22 100644 --- a/demoapps/VoxelizerTool/rttbMaskProcess.h +++ b/demoapps/VoxelizerTool/rttbMaskProcess.h @@ -1,62 +1,63 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __MaskProcess_h #define __MaskProcess_h #include "rttbDicomFileStructureSetGenerator.h" #include "rttbOTBMaskAccessor.h" namespace rttb { namespace apps { namespace voxelizer { /*! @class MaskProcess @brief MaskProcess create a Mask with the struct and reference object */ class MaskProcess { public: typedef core::MaskAccessorInterface::MaskAccessorPointer MaskAccessorPointer; typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; typedef core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; /*!@brief Constructor @details save the rtStructureSet (structfile) object into _rtStructureSet and * doseAccessor (referencefile) object into _doseAccessor */ MaskProcess(StructureSetPointer rtStructureSet, DoseAccessorPointer doseAccessor, - bool legacyVoxelization); + bool legacyVoxelization, bool allowSelfIntersection); /**@brief create a mask with _rtStructureSet and _doseAccessor object. @return a mask object */ MaskAccessorPointer createMask(unsigned int numberOfStructure) const; private: StructureSetPointer _rtStructureSet; DoseAccessorPointer _doseAccessor; bool _legacyVoxelization; + bool _allowSelfIntersection; }; } } } #endif \ No newline at end of file diff --git a/demoapps/VoxelizerTool/rttbMaskWriter.cpp b/demoapps/VoxelizerTool/rttbMaskWriter.cpp index ac4b36b..2868b4e 100644 --- a/demoapps/VoxelizerTool/rttbMaskWriter.cpp +++ b/demoapps/VoxelizerTool/rttbMaskWriter.cpp @@ -1,132 +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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (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)); 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); filter->Update(); return filter->GetOutput(); } void MaskWriter::writeITKImageToFile(ITKImageTypeConstPointer itkImage, - const std::string& outputfilename) const + const std::string& outputfilename, bool useCompression) const { typedef itk::ImageFileWriter< ITKMaskImageType > WriterType; WriterType::Pointer writer = WriterType::New(); writer->SetFileName(outputfilename); - + writer->SetUseCompression(useCompression); writer->SetInput(itkImage); writer->Update(); } } } } \ No newline at end of file diff --git a/demoapps/VoxelizerTool/rttbMaskWriter.h b/demoapps/VoxelizerTool/rttbMaskWriter.h index 3e097dd..28cfdad 100644 --- a/demoapps/VoxelizerTool/rttbMaskWriter.h +++ b/demoapps/VoxelizerTool/rttbMaskWriter.h @@ -1,70 +1,71 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __MaskWriter_h #define __MaskWriter_h #include "rttbITKImageMaskAccessorConverter.h" #include "rttbITKImageFileMaskAccessorGenerator.h" namespace rttb { namespace apps { namespace voxelizer { /*! @class MaskWriter @brief MaskWriter write a mask into a file */ class MaskWriter { public: typedef core::MaskAccessorInterface::MaskAccessorPointer MaskAccessorPointer; typedef io::itk::ITKImageMaskAccessor::ITKMaskImageType::Pointer ITKImageTypePointer; typedef io::itk::ITKImageMaskAccessor::ITKMaskImageType::ConstPointer ITKImageTypeConstPointer; typedef itk::Image ITKMaskImageType; /*!@brief Constructor @details save the object parameter into _maskAccessorPtr objekt @param vector with MaskAccessorPointer object/s */ MaskWriter(std::vector maskPointer, bool voxelization); /**@brief write the mask into the outputfile @param Outputfilename */ void writeMaskToFile(const std::string& outputFileName) const; private: ITKImageTypeConstPointer addMultipleStructsToImage() const; ITKImageTypeConstPointer applyThresholdFilter(ITKImageTypeConstPointer itkImage) const; - void writeITKImageToFile(ITKImageTypeConstPointer itkImage, const std::string& outputfilename) const; + void writeITKImageToFile(ITKImageTypeConstPointer itkImage, const std::string& outputfilename, + bool useCompression = true) const; //MaskAccessorPointer _maskAccessorPtr; bool _booleanvoxelization; std::vector _maskPointerVector; }; } } } #endif \ No newline at end of file diff --git a/demoapps/VoxelizerTool/rttbStructDataReader.cpp b/demoapps/VoxelizerTool/rttbStructDataReader.cpp index 3cc22ee..b7252af 100644 --- a/demoapps/VoxelizerTool/rttbStructDataReader.cpp +++ b/demoapps/VoxelizerTool/rttbStructDataReader.cpp @@ -1,81 +1,114 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include "rttbStructDataReader.h" #include "rttbDicomFileDoseAccessorGenerator.h" +#include "rttbITKImageFileAccessorGenerator.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace apps { namespace voxelizer { - StructDataReader::StructDataReader(const std::string& structfile, const std::string& reference) + StructDataReader::StructDataReader(const std::string& structFileName, const std::string& referenceFileName, + const std::vector& referenceFileLoadingStyle) : _referenceFilename(referenceFileName), + _structFilename(structFileName), _referenceFileLoadingStyle(referenceFileLoadingStyle) { - _doseAccessor = readReferenceFile(reference); - _rtStructureSet = readStructFile(structfile); + } + + void StructDataReader::read() + { + _doseAccessor = readReferenceFile(_referenceFilename, _referenceFileLoadingStyle); + _rtStructureSet = readStructFile(_structFilename); } std::vector StructDataReader::getAllLabels() const { std::vector allLabels; if (_rtStructureSet != NULL) { for (int j = 0; j < _rtStructureSet->getNumberOfStructures(); j++) { allLabels.push_back(_rtStructureSet->getStructure(j)->getLabel()); } } return allLabels; } StructDataReader::StructureSetPointer StructDataReader::getStructureSetPointer() const { return _rtStructureSet; } StructDataReader::DoseAccessorPointer StructDataReader::getDoseAccessorPointer() const { return _doseAccessor; } StructDataReader::DoseAccessorPointer StructDataReader::readReferenceFile( - const std::string& referencefile) const + const std::string& filename, const std::vector& fileLoadingStyle) const + { + if (fileLoadingStyle.at(0) == "dicom") + { + return readDicomFile(filename); + } + else if (fileLoadingStyle.at(0) == "itk") + { + return readITKFile(filename); + } + else + { + return NULL; + } + + } + + StructDataReader::DoseAccessorPointer StructDataReader::readDicomFile(const std::string& filename) const + { + rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator(filename.c_str()); + return doseAccessorGenerator.generateDoseAccessor(); + } + + StructDataReader::DoseAccessorPointer StructDataReader::readITKFile(const std::string& filename) const { - rttb::io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1(referencefile.c_str()); - DoseAccessorPointer doseAccessor(doseAccessorGenerator1.generateDoseAccessor()); - return doseAccessor; + rttb::io::itk::ITKImageFileAccessorGenerator generator(filename); + return generator.generateDoseAccessor(); } StructDataReader::StructureSetPointer StructDataReader::readStructFile( - const std::string& structfile) const + const std::string& filename) const { StructureSetPointer rtStructureSet = rttb::io::dicom::DicomFileStructureSetGenerator( - structfile.c_str()).generateStructureSet(); + filename.c_str()).generateStructureSet(); return rtStructureSet; } + + + + } } } \ No newline at end of file diff --git a/demoapps/VoxelizerTool/rttbStructDataReader.h b/demoapps/VoxelizerTool/rttbStructDataReader.h index a983c7e..bf43ff2 100644 --- a/demoapps/VoxelizerTool/rttbStructDataReader.h +++ b/demoapps/VoxelizerTool/rttbStructDataReader.h @@ -1,79 +1,88 @@ // ----------------------------------------------------------------------- // 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 __StructDataReader_h #define __StructDataReader_h #include "rttbDicomFileStructureSetGenerator.h" #include "rttbOTBMaskAccessor.h" namespace rttb { namespace apps { namespace voxelizer { /*! @class StructDataReader @brief StructDataReader read struct and reference file */ class StructDataReader { public: typedef rttb::core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; typedef rttb::core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; - /*!@brief Constructor - @details calls readStructFile and readReferenceFile method and save the result in _rtStructureSet and _doseAccessor - @param structfile - @param referencefile - */ - StructDataReader(const std::string& structfile, const std::string& referencefile); + StructDataReader(const std::string& structFileName, const std::string& referenceFileName, + const std::vector& referenceFileLoadingStyle); + + /*!@brief Reads structure and reference file and saves the result in variables */ + void read(); + /**@brief read all labels an save it in a vector. @return a vector of all labels */ std::vector getAllLabels() const; /**@brief - @return the objekt _rtStructureSet + @return the object _rtStructureSet */ StructureSetPointer getStructureSetPointer() const; /**@brief - @return the objekt _doseAccessor + @return the object _doseAccessor */ DoseAccessorPointer getDoseAccessorPointer() const; private: - /**@brief read a referencefile + /**@brief read a reference file @return the result as object */ - DoseAccessorPointer readReferenceFile(const std::string& referencefile) const; - /**@brief read a structfile + DoseAccessorPointer readReferenceFile(const std::string& filename, + const std::vector& fileLoadingStyle) const; + + DoseAccessorPointer readDicomFile(const std::string& filename) const; + DoseAccessorPointer readITKFile(const std::string& filename) const; + + /**@brief read a struct file @return the result as object */ - StructureSetPointer readStructFile(const std::string& structfile) const; + StructureSetPointer readStructFile(const std::string& filename) const; StructureSetPointer _rtStructureSet; DoseAccessorPointer _doseAccessor; + + std::string _structFilename; + std::string _referenceFilename; + std::vector _referenceFileLoadingStyle; }; } } } #endif \ No newline at end of file diff --git a/demoapps/VoxelizerTool/rttbVoxelizerTool.cpp b/demoapps/VoxelizerTool/rttbVoxelizerTool.cpp index 7b5bc7c..b7166b1 100644 --- a/demoapps/VoxelizerTool/rttbVoxelizerTool.cpp +++ b/demoapps/VoxelizerTool/rttbVoxelizerTool.cpp @@ -1,171 +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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (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 1; } if (co->isReturnAfterHelp()) { return 0; } rttb::apps::voxelizer::Parameters params = co->getParameters(); - boost::shared_ptr reader; + boost::shared_ptr reader = + boost::make_shared(params.structFile, + params.referenceFile, params.referenceFileLoadStyle); + std::cout << "reading reference and structure file..."; try { - reader = boost::make_shared(params.structFile, - params.referenceFile); + reader->read(); } 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 input image." << std::endl; return 2; } + std::cout << "done." << std::endl; + + std::cout << "searching for structs..."; std::vector listOfCorrectElements; for (int i = 0; i < params.regEx.size(); i++) { std::vector indexOfCorrectElements; indexOfCorrectElements = rttb::apps::voxelizer::filterForExpression(reader->getAllLabels(), params.regEx.at(i)); std::copy(indexOfCorrectElements.begin(), indexOfCorrectElements.end(), std::back_inserter(listOfCorrectElements)); } + std::cout << "done." << std::endl; + boost::shared_ptr maskProcessor = boost::make_shared(reader->getStructureSetPointer(), reader->getDoseAccessorPointer(), - params.legacyVoxelization); + params.legacyVoxelization, params.allowSelfIntersections); 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++) { int labelIndex = listOfCorrectElements.at(i); 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 writer = boost::make_shared(maskVector, params.booleanVoxelization); writer->writeMaskToFile(fileName + labelName + fileEnding); } else { unsigned int maxIterationCount = 1; if (params.multipleStructs) { maxIterationCount = listOfCorrectElements.size(); } for (unsigned int i = 0; i < maxIterationCount; i++) { + std::cout << "creating mask..."; maskVector.push_back(maskProcessor->createMask(listOfCorrectElements.at(i))); + std::cout << "done" << std::endl; int labelIndex = listOfCorrectElements.at(i); 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); 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 0; } diff --git a/testing/demoapps/VoxelizerTool/rttbVoxelizerToolIncorrectCommandsTest.cpp b/testing/demoapps/VoxelizerTool/rttbVoxelizerToolIncorrectCommandsTest.cpp index 5cc9697..a7c9536 100644 --- a/testing/demoapps/VoxelizerTool/rttbVoxelizerToolIncorrectCommandsTest.cpp +++ b/testing/demoapps/VoxelizerTool/rttbVoxelizerToolIncorrectCommandsTest.cpp @@ -1,112 +1,120 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (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 tooFewArgumentsCommand = voxelizerToolExeWithPath; tooFewArgumentsCommand += " -s " + invalidStructFile; tooFewArgumentsCommand += " -r " + referenceFile; std::cout << "Command line call: " + tooFewArgumentsCommand << std::endl; CHECK_EQUAL(system(tooFewArgumentsCommand.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); 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); + std::string referenceLoadingStyleCommand = voxelizerToolExeWithPath; + referenceLoadingStyleCommand += " -s " + structFile; + referenceLoadingStyleCommand += " -r " + referenceFile; + referenceLoadingStyleCommand += +" -e " + invalidStructureName; + referenceLoadingStyleCommand += +" -y nonsense"; + std::cout << "Command line call: " + referenceLoadingStyleCommand << std::endl; + CHECK_EQUAL(system(referenceLoadingStyleCommand.c_str()), 1); + RETURN_AND_REPORT_TEST_SUCCESS; } } }