diff --git a/code/core/rttbStrVectorStructureSetGenerator.cpp b/code/core/rttbStrVectorStructureSetGenerator.cpp index 8966d61..25c62ba 100644 --- a/code/core/rttbStrVectorStructureSetGenerator.cpp +++ b/code/core/rttbStrVectorStructureSetGenerator.cpp @@ -1,47 +1,65 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ /*! // @file // @version $Revision$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ - #include "rttbStrVectorStructureSetGenerator.h" +#include namespace rttb { namespace core { StrVectorStructureSetGenerator::StrVectorStructureSetGenerator(std::vector& aStructureVector, IDType aPatientUID) { _patientUID = aPatientUID; _strVector = aStructureVector; } StrVectorStructureSetGenerator::StructureSetPointer StrVectorStructureSetGenerator::generateStructureSet() { - return boost::make_shared(_strVector, _patientUID); + std::vector _filteredStructs = _strVector; + + if (this->getStructureLabelFilterActive()) + { + _filteredStructs.clear(); + + ::boost::regex e(this->getFilterRegEx()); + + for(auto aStruct : _strVector) + { + if (::boost::regex_match(aStruct->getLabel(), e)) + { + _filteredStructs.push_back(aStruct); + } + } + + } + + return boost::make_shared(_filteredStructs, _patientUID); } } }//end namespace rttb diff --git a/code/core/rttbStructureSetGeneratorInterface.h b/code/core/rttbStructureSetGeneratorInterface.h index 6092c01..90e9813 100644 --- a/code/core/rttbStructureSetGeneratorInterface.h +++ b/code/core/rttbStructureSetGeneratorInterface.h @@ -1,64 +1,87 @@ // ----------------------------------------------------------------------- // 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 __STRUCTURE_SET_GENERATOR_INTERFACE_H #define __STRUCTURE_SET_GENERATOR_INTERFACE_H #include #include "rttbStructureSet.h" namespace rttb { namespace core { /*! @class StructureSetGeneratorInterface @brief Interface for all structure set generating classes */ class StructureSetGeneratorInterface { public: typedef boost::shared_ptr StructureSetPointer; private: StructureSetGeneratorInterface(const StructureSetGeneratorInterface&); //not implemented on purpose -> non-copyable StructureSetGeneratorInterface& operator=(const StructureSetGeneratorInterface&);//not implemented on purpose -> non-copyable protected: - StructureSetGeneratorInterface() {}; + StructureSetGeneratorInterface(): _activeFilter(false) { }; virtual ~StructureSetGeneratorInterface() {}; + private: + bool _activeFilter; + std::string _filterRegEx; + public: + void setStructureLableFilterActive(bool active) + { + _activeFilter = active; + }; + + bool getStructureLabelFilterActive() const + { + return _activeFilter; + }; + + void setFilterRegEx(const std::string& filter) + { + _filterRegEx = filter; + }; + + std::string getFilterRegEx() const + { + return _filterRegEx; + }; /*! @brief Generate StructureSet @return Return shared pointer of StructureSet. */ virtual StructureSetPointer generateStructureSet() = 0; }; } } #endif diff --git a/code/io/dicom/rttbDicomFileStructureSetGenerator.cpp b/code/io/dicom/rttbDicomFileStructureSetGenerator.cpp index 7ef6906..3a64b1c 100644 --- a/code/io/dicom/rttbDicomFileStructureSetGenerator.cpp +++ b/code/io/dicom/rttbDicomFileStructureSetGenerator.cpp @@ -1,110 +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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include #include #include "rttbInvalidParameterException.h" #include "rttbStructure.h" #include "rttbDicomFileStructureSetGenerator.h" #include "rttbDicomIODStructureSetGenerator.h" #include "rttbDcmrtException.h" #include "rttbDicomFileReaderHelper.h" namespace rttb { namespace io { namespace dicom { DicomFileStructureSetGenerator::DicomFileStructureSetGenerator(DICOMRTFileNameString aDICOMRTStrSetFileName) { _fileName = aDICOMRTStrSetFileName; } DicomFileStructureSetGenerator::~DicomFileStructureSetGenerator() { } DicomFileStructureSetGenerator::StructureSetPointer DicomFileStructureSetGenerator::generateStructureSet() { std::vector fileVector; //if a file if (isFile(_fileName)) { fileVector.push_back(_fileName); } //if a directory else if (isDirectory(_fileName)) { rttb::io::dicom::Modality strModality = {rttb::io::dicom::Modality::RTSTRUCT}; fileVector = getFileNamesWithSameUID(_fileName, strModality); } else { throw rttb::core::InvalidParameterException("Invalid file/directory name!"); } if (fileVector.size() < 1) { throw rttb::core::InvalidParameterException("There is no structure set files in the directory!"); } OFCondition status; DcmFileFormat fileformat; DRTStrSetIODPtr drtStrSetIODPtr = boost::make_shared(); //get the first structure set file status = fileformat.loadFile(fileVector.at(0).c_str()); if (!status.good()) { throw DcmrtException("Load rt structure set loadFile() failed!"); } status = drtStrSetIODPtr->read(*fileformat.getDataset()); if (!status.good()) { throw DcmrtException("Read DRTStructureSetIOD DRTStructureSetIOD.read() failed!"); } - return (boost::make_shared - (drtStrSetIODPtr))->generateStructureSet(); + io::dicom::DicomIODStructureSetGenerator iodGenerator(drtStrSetIODPtr); + iodGenerator.setStructureLableFilterActive(this->getStructureLabelFilterActive()); + iodGenerator.setFilterRegEx(this->getFilterRegEx()); + return iodGenerator.generateStructureSet(); } }//end namespace dicom }//end namespace io }//end namespace rttb diff --git a/code/io/dicom/rttbDicomIODStructureSetGenerator.cpp b/code/io/dicom/rttbDicomIODStructureSetGenerator.cpp index 76410d6..a1c028c 100644 --- a/code/io/dicom/rttbDicomIODStructureSetGenerator.cpp +++ b/code/io/dicom/rttbDicomIODStructureSetGenerator.cpp @@ -1,185 +1,198 @@ // ----------------------------------------------------------------------- // 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 #include +#include #include +#include #include "rttbNullPointerException.h" #include "rttbInvalidParameterException.h" #include "rttbStructure.h" #include "rttbDicomIODStructureSetGenerator.h" #include "rttbDcmrtException.h" namespace rttb { - namespace io - { - namespace dicom - { - DicomIODStructureSetGenerator::DicomIODStructureSetGenerator(DRTStrSetIODPtr aDRTStructureSetIOD) - { - _drtStrSetIOD = aDRTStructureSetIOD; - } - - - void DicomIODStructureSetGenerator::readStrSet() - { - OFString uid; - _drtStrSetIOD->getSeriesInstanceUID(uid); - _UID = uid.c_str(); - - OFString uid2; - _drtStrSetIOD->getPatientID(uid2); - _patientUID = uid2.c_str(); - - DRTStructureSetROISequence* rois = &_drtStrSetIOD->getStructureSetROISequence(); - - /*A structure is a DRTROIContourSequence::Item. Each Item defines a roi. Each ROI contains a sequence - of one or more contours, where a contour is either a single point (for a point ROI) or more than - one point (representing an open or closed polygon). - */ - DRTROIContourSequence* rcs; - rcs = &_drtStrSetIOD->getROIContourSequence(); - DRTROIContourSequence::Item* rcsItem; - - long numberOfStructures = rcs->getNumberOfItems(); - bool isEmpty = rcs->isEmpty(); - - if (numberOfStructures == 0 || isEmpty) - { - throw core::InvalidParameterException("Empty Structure Set!") ; - } - - int structureNo = 0; - - for (rcs->gotoFirstItem(); (rcs->getCurrentItem(rcsItem)).good(); rcs->gotoNextItem()) - { - OFString refROINumber; - rcsItem->getReferencedROINumber(refROINumber); - DRTContourSequence* cs; - cs = &rcsItem->getContourSequence(); - long no2 = cs->getNumberOfItems(); - - PolygonSequenceType structureVector; - - for (int j = 0; j < no2; j++) - { - /*DRTContourSequence::Item represents a contour (either a single point (for a point ROI) or more than - one point (representing an open or closed polygon))*/ - DRTContourSequence::Item* csItem; - csItem = &cs->getItem(j); - OFString contourData; - OFString numberOfContourPoints; - csItem->getNumberOfContourPoints(numberOfContourPoints); - - int numberOfContourPointsInt; - std::stringstream is(numberOfContourPoints.c_str()); - is >> numberOfContourPointsInt; - OFString countourNumber; - csItem->getContourNumber(countourNumber); - - PolygonType contourVector; - char* pEnd; - - for (int k = 0; k < numberOfContourPointsInt; k++) - { - WorldCoordinate3D point; - - for (int i = 0; i < 3; i++) - { - csItem->getContourData(contourData, k * 3 + i); - - WorldCoordinate value = strtod(contourData.c_str(), &pEnd); - - if (*pEnd != '\0') - { - throw core::InvalidParameterException("Contour data not readable!") ; - } - - if (i == 0) - { - point(0) = value; - } - else if (i == 1) - { - point(1) = value; - } - else - { - point(2) = value; - } - } - - contourVector.push_back(point); - } - - structureVector.push_back(contourVector); - } - - boost::shared_ptr spStruct = boost::make_shared(structureVector); - StructTypePointer str(spStruct); - - for (unsigned long i = 0; i < rois->getNumberOfItems(); i++) - { - DRTStructureSetROISequence::Item* roisItem; - roisItem = &rois->getItem(i); - - OFString roiNumber; - roisItem->getROINumber(roiNumber); - - if (roiNumber == refROINumber) - { - OFString roiName; - roisItem->getROIName(roiName); - str->setLabel(roiName.c_str()); - std::cout << roiName.c_str() << std::endl; - break; - } - } - - std::stringstream sstr; - sstr << structureNo; - str->setUID(sstr.str()); - - _strVector.push_back(str); - structureNo++; - } - } - - DicomIODStructureSetGenerator::~DicomIODStructureSetGenerator() - { - } - - DicomIODStructureSetGenerator::StructureSetPointer - DicomIODStructureSetGenerator::generateStructureSet() - { - this->readStrSet(); - return boost::make_shared(_strVector, _patientUID, _UID); - } - }//end namespace dicom - }//end namespace io + namespace io + { + namespace dicom + { + DicomIODStructureSetGenerator::DicomIODStructureSetGenerator(DRTStrSetIODPtr aDRTStructureSetIOD) + { + _drtStrSetIOD = aDRTStructureSetIOD; + } + + + void DicomIODStructureSetGenerator::readStrSet() + { + OFString uid; + _drtStrSetIOD->getSeriesInstanceUID(uid); + _UID = uid.c_str(); + + OFString uid2; + _drtStrSetIOD->getPatientID(uid2); + _patientUID = uid2.c_str(); + + DRTStructureSetROISequence* rois = &_drtStrSetIOD->getStructureSetROISequence(); + + //generate map of relevant ROIs + std::map filteredROIs; + ::boost::regex e(this->getFilterRegEx()); + + for (unsigned long i = 0; i < rois->getNumberOfItems(); i++) + { + DRTStructureSetROISequence::Item* roisItem = &rois->getItem(i); + + OFString roiNumber; + roisItem->getROINumber(roiNumber); + OFString ofRoiName; + roisItem->getROIName(ofRoiName); + std::string roiName(ofRoiName.c_str()); + + if (!this->getStructureLabelFilterActive() || boost::regex_match(roiName, e)) + { + filteredROIs.insert(std::make_pair(roiNumber, roiName)); + } + } + + /*A structure is a DRTROIContourSequence::Item. Each Item defines a roi. Each ROI contains a sequence + of one or more contours, where a contour is either a single point (for a point ROI) or more than + one point (representing an open or closed polygon). + */ + DRTROIContourSequence* rcs; + rcs = &_drtStrSetIOD->getROIContourSequence(); + DRTROIContourSequence::Item* rcsItem; + + long numberOfStructures = rcs->getNumberOfItems(); + bool isEmpty = rcs->isEmpty(); + + if (numberOfStructures == 0 || isEmpty) + { + throw core::InvalidParameterException("Empty Structure Set!") ; + } + + int structureNo = 0; + + for (rcs->gotoFirstItem(); (rcs->getCurrentItem(rcsItem)).good(); rcs->gotoNextItem()) + { + OFString refROINumber; + rcsItem->getReferencedROINumber(refROINumber); + + //check if ROI number is in the filtered ROIS + if (filteredROIs.find(refROINumber) != filteredROIs.end()) + { + DRTContourSequence* cs; + cs = &rcsItem->getContourSequence(); + long no2 = cs->getNumberOfItems(); + + PolygonSequenceType structureVector; + + for (int j = 0; j < no2; j++) + { + /*DRTContourSequence::Item represents a contour (either a single point (for a point ROI) or more than + one point (representing an open or closed polygon))*/ + DRTContourSequence::Item* csItem; + csItem = &cs->getItem(j); + OFString contourData; + OFString numberOfContourPoints; + csItem->getNumberOfContourPoints(numberOfContourPoints); + + int numberOfContourPointsInt; + std::stringstream is(numberOfContourPoints.c_str()); + is >> numberOfContourPointsInt; + OFString countourNumber; + csItem->getContourNumber(countourNumber); + + PolygonType contourVector; + char* pEnd; + + for (int k = 0; k < numberOfContourPointsInt; k++) + { + WorldCoordinate3D point; + + for (int i = 0; i < 3; i++) + { + csItem->getContourData(contourData, k * 3 + i); + + WorldCoordinate value = strtod(contourData.c_str(), &pEnd); + + if (*pEnd != '\0') + { + throw core::InvalidParameterException("Contour data not readable!") ; + } + + if (i == 0) + { + point(0) = value; + } + else if (i == 1) + { + point(1) = value; + } + else + { + point(2) = value; + } + } + + contourVector.push_back(point); + } + + structureVector.push_back(contourVector); + } + + boost::shared_ptr spStruct = boost::make_shared(structureVector); + StructTypePointer str(spStruct); + + str->setLabel(filteredROIs[refROINumber]); + std::cout << filteredROIs[refROINumber].c_str() << std::endl; + + std::stringstream sstr; + sstr << structureNo; + str->setUID(sstr.str()); + + _strVector.push_back(str); + } + + ++structureNo; + } + } + + DicomIODStructureSetGenerator::~DicomIODStructureSetGenerator() + { + } + + DicomIODStructureSetGenerator::StructureSetPointer + DicomIODStructureSetGenerator::generateStructureSet() + { + this->readStrSet(); + return boost::make_shared(_strVector, _patientUID, _UID); + } + }//end namespace dicom + }//end namespace io }//end namespace rttb