diff --git a/apps/VoxelizerTool/VoxelizerToolCmdLineParser.cpp b/apps/VoxelizerTool/VoxelizerToolCmdLineParser.cpp index e0cb7a4..3dae3dd 100644 --- a/apps/VoxelizerTool/VoxelizerToolCmdLineParser.cpp +++ b/apps/VoxelizerTool/VoxelizerToolCmdLineParser.cpp @@ -1,124 +1,115 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ -/*! -// @file -// @version $Revision: 1221 $ (last changed revision) -// @date $Date: 2015-12-01 13:43:31 +0100 (Di, 01 Dez 2015) $ (last change date) -// @author $Author: strubel $ (last changed by) -*/ #include "VoxelizerToolCmdLineParser.h" namespace rttb { namespace apps { namespace voxelizerTool { VoxelizerCmdLineParser::VoxelizerCmdLineParser(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(OPTION_STRUCT_FILE, OPTION_GROUP_REQUIRED, "Filename of the structfile (*.dcm)", 's', true); addInformationForXML(OPTION_STRUCT_FILE, cmdlineparsing::XMLGenerator::paramType::INPUT, {"dcm", "*"}); addOption(OPTION_REFERENCE_FILE, OPTION_GROUP_REQUIRED, "Filename of the reference image (*.dcm)", 'r', true); addInformationForXML(OPTION_REFERENCE_FILE, cmdlineparsing::XMLGenerator::paramType::INPUT, { "dcm", "*" }); addOptionWithDefaultValue(OPTION_OUTPUT_FILE_NAME, OPTION_GROUP_REQUIRED, "Set output file name. Remark: if it used in conjunction with flag -m, it is only regarded as " "hint for the file name pattern. VoxelizerTool will add a suffix indicating the voxelized " "structure to each filename.","out.hdr","out.hdr", 'o', true); addInformationForXML(OPTION_OUTPUT_FILE_NAME, cmdlineparsing::XMLGenerator::paramType::OUTPUT, { "hdr", "nrrd", "*" }); addPositionalOption(OPTION_STRUCT_FILE,1); addPositionalOption(OPTION_REFERENCE_FILE, 1); addPositionalOption(OPTION_OUTPUT_FILE_NAME, 1); - - std::vector defaultLoadingStyle; - defaultLoadingStyle.push_back("dicom"); - addOptionWithDefaultValue(OPTION_REGEX, OPTION_GROUP_REQUIRED, - "set a regular expression describing the structs of interest", "", "",'e', true); + addOption(OPTION_REGEX, OPTION_GROUP_REQUIRED, + "set a regular expression describing the structs of interest",'e', true); addInformationForXML(OPTION_REGEX, cmdlineparsing::XMLGenerator::paramType::STRING); - addOptionWithDefaultValue>(OPTION_REFERENCE_FILE_LOAD_STYLE, OPTION_GROUP_REQUIRED, - "set the load style for the reference file. Available styles are: " - "dicom: normal dicom dose" - "itk: use itk image loading.", defaultLoadingStyle, defaultLoadingStyle.at(0), 'y', true); - addInformationForXML(OPTION_REFERENCE_FILE_LOAD_STYLE, cmdlineparsing::XMLGenerator::paramType::STRINGENUMERATION, { "dicom", "itk" }); + addOptionWithDefaultValue(OPTION_REFERENCE_FILE_LOAD_STYLE, OPTION_GROUP_REQUIRED, + "set the load style for the reference file. Available styles are:" + "\ndicom: normal dicom dose" + "\nitk: use itk image loading" + "\nitkDicom: use itk dicom image loading", "dicom", "dicom", 'y', true); + addInformationForXML(OPTION_REFERENCE_FILE_LOAD_STYLE, cmdlineparsing::XMLGenerator::paramType::STRING); //OPTIONAL addOption(OPTION_MULTIPLE_STRUCTS, OPTION_GROUP_OPTIONAL, "if multiple structs match the regular expression" + OPTION_STRUCT_FILE + ", save all in files\n" "If structures 'Kidney_left' and 'Kidney_right' are defined,\n" "both are written under the names outputFile_Kidney_left.mhd and outputFile_Kidney_right.mhd",'m'); addInformationForXML(OPTION_MULTIPLE_STRUCTS, cmdlineparsing::XMLGenerator::paramType::BOOLEAN); addOption(OPTION_BINARY_VOXELIZATION, OPTION_GROUP_OPTIONAL, "Determines if the voxelization should be binarized (only values 0 or 1), the threshold value is by 0.5",'z'); addInformationForXML(OPTION_BINARY_VOXELIZATION, cmdlineparsing::XMLGenerator::paramType::BOOLEAN); addOption(OPTION_ADDSTRUCTURES, OPTION_GROUP_OPTIONAL, "Voxelizes multiple structs in one result file.",'a'); addInformationForXML(OPTION_ADDSTRUCTURES, cmdlineparsing::XMLGenerator::paramType::BOOLEAN); addOption(OPTION_NO_STRICT_VOXELIZATION, OPTION_GROUP_OPTIONAL, "Deviations of wrong voxel volumes are tolerated and corrected.",'i'); addInformationForXML(OPTION_NO_STRICT_VOXELIZATION, cmdlineparsing::XMLGenerator::paramType::BOOLEAN); parse(argc, argv); } void VoxelizerCmdLineParser::validateInput() const { - std::vector referenceLoadStyle = get >(OPTION_REFERENCE_FILE_LOAD_STYLE); - std::string referenceLoadStyleString = referenceLoadStyle.at(0); + std::string referenceLoadStyle = get(OPTION_REFERENCE_FILE_LOAD_STYLE); - if (referenceLoadStyleString != "dicom" && referenceLoadStyleString != "itk") + if (referenceLoadStyle != "dicom" && referenceLoadStyle != "itk" && referenceLoadStyle != "itkDicom") { throw cmdlineparsing::InvalidConstraintException("Unknown load style for reference file:" + - referenceLoadStyleString+ + referenceLoadStyle + ".\nPlease refer to the help for valid loading style settings."); } if (get(OPTION_OUTPUT_FILE_NAME).find('.') == std::string::npos) { throw cmdlineparsing::InvalidConstraintException(OPTION_OUTPUT_FILE_NAME + " has to specify a file format (e.g. output.hdr). None is given: " + get(OPTION_OUTPUT_FILE_NAME) ); } } void VoxelizerCmdLineParser::printHelp() const { cmdlineparsing::CmdLineParserBase::printHelp(); 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'.\n"; 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; } } } } \ No newline at end of file diff --git a/code/io/itk/rttbITKIOHelper.cpp b/code/io/itk/rttbITKIOHelper.cpp index 74d9fe2..155a7c9 100644 --- a/code/io/itk/rttbITKIOHelper.cpp +++ b/code/io/itk/rttbITKIOHelper.cpp @@ -1,170 +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$ (last changed revision) -// @date $Date$ (last change date) -// @author $Author$ (last changed by) -*/ #include "rttbITKIOHelper.h" #include "rttbException.h" #include "rttbInvalidDoseException.h" #include "rttbInvalidParameterException.h" namespace rttb { namespace io { namespace itk { - ITKImageType::Pointer readITKDoubleImage(FileNameType aITKImageFile) + ITKImageType::Pointer readITKDoubleImage(FileNameType aITKImageFile) { + return readITKDoubleImage(aITKImageFile, false); + } + + ITKImageType::Pointer readITKDoubleImage(FileNameType aITKImageFile, bool isDicom) { ITKImageType::Pointer itkDoubleImage; GenericImageReader::Pointer spReader = GenericImageReader::New(); + if (isDicom) { + spReader->setSeriesReadStyle(ImageSeriesReadStyle::Type::Dicom); + } spReader->setFileName(aITKImageFile); GenericImageReader::GenericOutputImageType::Pointer itkGenericImage; ITKImageType::ConstPointer itkDoubleImageConst; try { unsigned int loadedDimensions; GenericImageReader::LoadedPixelType loadedPixelType; GenericImageReader::LoadedComponentType loadedComponentType; itkGenericImage = spReader->GetOutput(loadedDimensions, loadedPixelType, loadedComponentType); if (loadedDimensions != 3) { throw core::InvalidParameterException("image dimensions != 3. Only dim = 3 supported."); } if (loadedPixelType != ::itk::ImageIOBase::SCALAR) { throw core::InvalidParameterException("image component type != SCALAR. Only SCALAR supported."); } if (loadedComponentType == ::itk::ImageIOBase::DOUBLE) { itkDoubleImage = dynamic_cast(itkGenericImage.GetPointer()); } else { itkDoubleImage = handleGenericImage(itkGenericImage, loadedComponentType); } if (itkDoubleImage.IsNull()) { throw core::InvalidDoseException("Error!!! unable to load input image. File is not existing or has an unsupported format."); } } catch (::itk::ExceptionObject& e) { std::cerr << "Error!!!" << std::endl; std::cerr << e << std::endl; throw rttb::core::InvalidDoseException(e.GetDescription()); } return itkDoubleImage; } ITKImageType::Pointer handleGenericImage( GenericImageReader::GenericOutputImageType* itkGenericImage, ::itk::ImageIOBase::IOComponentType& loadedComponentType) { ITKImageType::Pointer itkDoubleImage; switch (loadedComponentType) { case ::itk::ImageIOBase::UCHAR: { itkDoubleImage = doCasting(itkGenericImage); break; } case ::itk::ImageIOBase::CHAR: { itkDoubleImage = doCasting(itkGenericImage); break; } case ::itk::ImageIOBase::USHORT: { itkDoubleImage = doCasting(itkGenericImage); break; } case ::itk::ImageIOBase::SHORT: { itkDoubleImage = doCasting(itkGenericImage); break; } case ::itk::ImageIOBase::UINT: { itkDoubleImage = doCasting(itkGenericImage); break; } case ::itk::ImageIOBase::INT: { itkDoubleImage = doCasting(itkGenericImage); break; } case ::itk::ImageIOBase::ULONG: { itkDoubleImage = doCasting(itkGenericImage); break; } case ::itk::ImageIOBase::LONG: { itkDoubleImage = doCasting(itkGenericImage); break; } case ::itk::ImageIOBase::FLOAT: { itkDoubleImage = doCasting(itkGenericImage); break; } case ::itk::ImageIOBase::DOUBLE: { itkDoubleImage = doCasting(itkGenericImage); break; } default: { throw core::InvalidParameterException("image type unknown"); } } return itkDoubleImage; } }//end namespace itk }//end namespace io }//end namespace rttb diff --git a/code/io/itk/rttbITKIOHelper.h b/code/io/itk/rttbITKIOHelper.h index 94d7fd3..81ccdc1 100644 --- a/code/io/itk/rttbITKIOHelper.h +++ b/code/io/itk/rttbITKIOHelper.h @@ -1,65 +1,62 @@ // ----------------------------------------------------------------------- // 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 __ITK_IO_HELPER_H #define __ITK_IO_HELPER_H #include "rttbBaseType.h" #include "rttbGenericImageReader.h" #include "itkImage.h" namespace rttb { namespace io { namespace itk { typedef ::itk::Image ITKImageType; /*! @brief Read a itk image file into itkImage */ ITKImageType::Pointer readITKDoubleImage(FileNameType aITKImageFile); + ITKImageType::Pointer readITKDoubleImage(FileNameType aITKImageFile, bool isDicom); + /*! @brief Converts a generic image to itkImage @param itkGenericImage the image read by GenericImageReader @param loadedComponentType the component type (used for casting later on) @exception InvalidParameterException if component type is not supported @sa GenericImageReader */ ITKImageType::Pointer handleGenericImage(GenericImageReader::GenericOutputImageType* itkGenericImage, ::itk::ImageIOBase::IOComponentType& loadedComponentType); /*! @brief Casts into itkImage */ template ITKImageType::Pointer doCasting( GenericImageReader::GenericOutputImageType* genericImage); }//end namespace itk }//end namespace io }//end namespace rttb #include "rttbITKIOHelper.tpp" #endif diff --git a/code/io/itk/rttbITKImageFileAccessorGenerator.cpp b/code/io/itk/rttbITKImageFileAccessorGenerator.cpp index a6a1096..aba58d1 100644 --- a/code/io/itk/rttbITKImageFileAccessorGenerator.cpp +++ b/code/io/itk/rttbITKImageFileAccessorGenerator.cpp @@ -1,56 +1,52 @@ // ----------------------------------------------------------------------- // 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 #include "rttbITKImageFileAccessorGenerator.h" #include "rttbITKImageAccessorConverter.h" #include "rttbITKIOHelper.h" namespace rttb { namespace io { namespace itk { ITKImageFileAccessorGenerator::~ITKImageFileAccessorGenerator() = default; ITKImageFileAccessorGenerator::ITKImageFileAccessorGenerator(const FileNameType& fileName) { _fileName = fileName; } - rttb::core::DoseAccessorGeneratorBase::DoseAccessorPointer - ITKImageFileAccessorGenerator::generateDoseAccessor() - { - _itkDoubleImage = readITKDoubleImage(_fileName); + rttb::core::DoseAccessorGeneratorBase::DoseAccessorPointer ITKImageFileAccessorGenerator::generateDoseAccessor() { + return ITKImageFileAccessorGenerator::generateDoseAccessor(false); + } + + rttb::core::DoseAccessorGeneratorBase::DoseAccessorPointer ITKImageFileAccessorGenerator::generateDoseAccessor(bool isDicom) { + _itkDoubleImage = readITKDoubleImage(_fileName, isDicom); _doseAccessor = boost::make_shared(_itkDoubleImage.GetPointer()); return _doseAccessor; } }//end namespace itk }//end namespace io }//end namespace rttb diff --git a/code/io/itk/rttbITKImageFileAccessorGenerator.h b/code/io/itk/rttbITKImageFileAccessorGenerator.h index 1309b33..d408200 100644 --- a/code/io/itk/rttbITKImageFileAccessorGenerator.h +++ b/code/io/itk/rttbITKImageFileAccessorGenerator.h @@ -1,77 +1,73 @@ // ----------------------------------------------------------------------- // 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 __ITK_IMAGE_FILE_ACCESSOR_GENERATOR_H #define __ITK_IMAGE_FILE_ACCESSOR_GENERATOR_H #include "rttbDoseAccessorGeneratorBase.h" #include "rttbBaseType.h" #include "itkImage.h" namespace rttb { namespace io { namespace itk { /*! @class ITKImageFileAccessorGenerator @brief Load image data using the itk loading methods and wraps the resulting itk image in a ITKImageAccessor. * this can be used if dose distributions are stored in formats like meta image, nrrd... * @note it implies that the dose information is stored in absolute Gy values. */ class ITKImageFileAccessorGenerator: public core::DoseAccessorGeneratorBase { public: typedef ::itk::Image ITKImageType; using DoseAccessorPointer = DoseAccessorGeneratorBase::DoseAccessorPointer; private: FileNameType _fileName; /** @brief The dose as itkImage */ ITKImageType::Pointer _itkDoubleImage; ITKImageFileAccessorGenerator() = delete; public: ~ITKImageFileAccessorGenerator() override; ITKImageFileAccessorGenerator(const FileNameType& fileName); /*! @brief Generate DoseAccessor @return Return shared pointer of DoseAccessor. @exception InvalidDoseException Thrown if file could not be read @exception InvalidParameterException Thrown if file has imageDimension !=3 or image component type != SCALAR @details is always converted into a itkImage by using a CastImageFilter @sa doCasting, handleGenericImage */ DoseAccessorPointer generateDoseAccessor() override; + DoseAccessorPointer generateDoseAccessor(bool isDicom); }; }//end namespace itk }//end namespace io }//end namespace rttb #endif diff --git a/code/io/utils/rttbDoseLoader.cpp b/code/io/utils/rttbDoseLoader.cpp index 0596cbe..ab783b9 100644 --- a/code/io/utils/rttbDoseLoader.cpp +++ b/code/io/utils/rttbDoseLoader.cpp @@ -1,105 +1,108 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ -/*! -// @file -// @version $Revision: 1674 $ (last changed revision) -// @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) -// @author $Author: hentsch $ (last changed by) -*/ #ifndef __RTTB_DOSE_LOADER_H #define __RTTB_DOSE_LOADER_H #include "rttbDoseIteratorInterface.h" #include "rttbExceptionMacros.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomHelaxFileDoseAccessorGenerator.h" #include "rttbITKImageFileAccessorGenerator.h" namespace rttb { namespace io { namespace utils { /*! @brief loads a dicom dose from a file. @exception Throws an rttb::Exception if loading fails @sa DicomFileDoseAccessorGenerator */ rttb::core::DoseAccessorInterface::DoseAccessorPointer loadDicomDose(const std::string& fileName) { rttb::io::dicom::DicomFileDoseAccessorGenerator generator(fileName); return generator.generateDoseAccessor(); } /*! @brief loads a helax dose from a file. @exception Throws an rttb::Exception if loading fails @sa DicomHelaxFileDoseAccessorGenerator */ rttb::core::DoseAccessorInterface::DoseAccessorPointer loadHelaxDose(const std::string& path) { rttb::io::helax::DicomHelaxFileDoseAccessorGenerator generator(path); return generator.generateDoseAccessor(); } /*! @brief loads an itk dose from a file. @exception Throws an rttb::Exception if loading fails. @details Might be of all formats that ITK know (*.mhd, *.nrrd, ...). The absolute image values are taken as dose. @sa ITKImageFileAccessorGenerator */ rttb::core::DoseAccessorInterface::DoseAccessorPointer loadITKDose(const std::string& fileName) { rttb::io::itk::ITKImageFileAccessorGenerator generator(fileName); return generator.generateDoseAccessor(); } + rttb::core::DoseAccessorInterface::DoseAccessorPointer loadITKDicomDose(const std::string& fileName) { + rttb::io::itk::ITKImageFileAccessorGenerator generator(fileName); + return generator.generateDoseAccessor(true); + } + /*! @brief loads a dose from a file based on the loadingStyle. @params args[0]: determines the loadingStyle @exception Throws an rttb::Exception if loading fails */ rttb::core::DoseAccessorInterface::DoseAccessorPointer loadDose(const std::string& fileName, const std::vector& args) { rttb::core::DoseAccessorInterface::DoseAccessorPointer result; if (args.empty() || args[0] == "dicom") { result = loadDicomDose(fileName); } else if (args[0] == "helax") { result = loadHelaxDose(fileName); } else if (args[0] == "itk") { result = loadITKDose(fileName); } + else if (args[0] == "itkDicom") + { + result = loadITKDicomDose(fileName); + } else { rttbDefaultExceptionStaticMacro(<< "Unknown io style selected. Cannot load data. Selected style: " << args[0]); } return result; } } } } #endif