diff --git a/code/io/dicom/rttbDicomFileDoseAccessorGenerator.cpp b/code/io/dicom/rttbDicomFileDoseAccessorGenerator.cpp index c7e1da2..8acb537 100644 --- a/code/io/dicom/rttbDicomFileDoseAccessorGenerator.cpp +++ b/code/io/dicom/rttbDicomFileDoseAccessorGenerator.cpp @@ -1,100 +1,97 @@ // ----------------------------------------------------------------------- // 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 "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomDoseAccessor.h" #include "rttbNullPointerException.h" #include "rttbInvalidDoseException.h" #include "rttbDcmrtException.h" #include "rttbIndexOutOfBoundsException.h" #include "rttbDicomFileReaderHelper.h" #include "rttbInvalidParameterException.h" namespace rttb{ namespace io{ namespace dicom{ DicomFileDoseAccessorGenerator::~DicomFileDoseAccessorGenerator(){} DicomFileDoseAccessorGenerator::DicomFileDoseAccessorGenerator(FileNameType aDICOMRTDoseFileName){ _dicomDoseFileName=aDICOMRTDoseFileName; } core::DoseAccessorGeneratorInterface::DoseAccessorPointer DicomFileDoseAccessorGenerator::generateDoseAccessor() { std::vector fileVector; //if a file if(isFile(_dicomDoseFileName)){ fileVector.push_back(_dicomDoseFileName); } //if a directory else if(isDirectory(_dicomDoseFileName)){ rttb::io::dicom::Modality doseModality= {rttb::io::dicom::Modality::RTDOSE}; fileVector = getFileNamesWithSameUID(_dicomDoseFileName, doseModality); } 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; - std::cout << _dicomDoseFileName << std::endl; - std::cout << fileVector.at(0) << std::endl; - DRTDoseIODPtr dose= boost::make_shared(); status = fileformat.loadFile(fileVector.at(0).c_str()); if (!status.good()) { std::cerr << "Error: load rtdose loadFile("<(*fileformat.getDataset()); status = dose->read(*dataSet); if(!status.good()) { std::cerr << "Error: read DRTDoseIOD failed!"<(dose, dataSet); return _doseAccessor; } } } } diff --git a/code/io/dicom/rttbDicomFileReaderHelper.cpp b/code/io/dicom/rttbDicomFileReaderHelper.cpp index 20fdfaf..8113bf5 100644 --- a/code/io/dicom/rttbDicomFileReaderHelper.cpp +++ b/code/io/dicom/rttbDicomFileReaderHelper.cpp @@ -1,224 +1,216 @@ // ----------------------------------------------------------------------- // 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: 707 $ (last changed revision) // @date $Date: 2014-09-04 16:37:24 +0200 (Do, 04 Sep 2014) $ (last change date) // @author $Author: floca $ (last changed by) */ #include "rttbDicomFileReaderHelper.h" #include #include #include #include "boost/filesystem/operations.hpp" #include "boost/filesystem/path.hpp" #include "boost/progress.hpp" #include "rttbInvalidDoseException.h" #include "rttbDcmrtException.h" #include "rttbIndexOutOfBoundsException.h" #include "rttbInvalidParameterException.h" namespace rttb{ namespace io{ namespace dicom{ bool isFile(FileNameType aName){ boost::filesystem::path path=boost::filesystem::path(aName); if(boost::filesystem::exists(path) && boost::filesystem::is_regular_file(path)) return true; else return false; } bool isDirectory(FileNameType aName){ boost::filesystem::path path=boost::filesystem::path(aName); if(boost::filesystem::exists(path) && boost::filesystem::is_directory(path)) return true; else return false; } + OFString getModality(DcmDataSetPtr aDcmDataSet){ + OFString modality; + OFCondition status; + status = aDcmDataSet->findAndGetOFString(DcmTagKey(0x0008, 0x0060), modality); + if (!status.good()) + { + throw DcmrtException("Error: get modality failed!"); + } + return modality; + } + + + OFString getUID(DcmDataSetPtr aDcmDataSet){ + OFString uid; + OFCondition status; + status = aDcmDataSet->findAndGetOFString(DcmTagKey(0x0020, 0x000e), uid); + if (!status.good()) + { + throw DcmrtException("Error: get uid failed!"); + } + return uid; + } + std::vector getFileNamesWithSameUID(FileNameType aDirName, Modality aModality){ std::vector fileNameVector; std::string modalityStrArray[] = {"RTDOSE", "RTSTRUCT", "RTPLAN"}; boost::filesystem::path path=boost::filesystem::path(aDirName); OFCondition status; DcmFileFormat fileformat; - IDType uid; + IDType uid = ""; DcmDataSetPtr datasetPtr; - int file_count=0; - if(!boost::filesystem::exists(path)){ - throw core::InvalidParameterException("Error: file/directory does not exist!"); - } if(aModality.Type != 1 && aModality.Type != 2 && aModality.Type != 3){ throw core::InvalidParameterException("Error: invalid modality! The modality should be RTDOSE(1)/RTSTRUCT(2)/RTPLAN(3)."); } //if a directory - if(boost::filesystem::is_directory(path)){ + if(isDirectory(aDirName)){ boost::filesystem::directory_iterator end_iter; - bool isFirst=true; + bool isFirst=false; for(boost::filesystem::directory_iterator dir_itr(path);dir_itr!=end_iter;++dir_itr) { if(boost::filesystem::is_regular_file(dir_itr->status())) { boost::filesystem::path filePath(dir_itr->path().filename().string()); filePath=boost::filesystem::system_complete(dir_itr->path()); status = fileformat.loadFile(filePath.string().c_str()); if (!status.good()) { - throw DcmrtException("Error: load dose fileformat.loadFile failed!"); + throw DcmrtException("Error: load dose file "+ filePath.string() +" failed!"); } datasetPtr = boost::make_shared(*fileformat.getDataset()); - OFString modalityOFS; - status = datasetPtr->findAndGetOFString(DcmTagKey(0x0008, 0x0060), modalityOFS); - if (!status.good()) - { - throw DcmrtException("Error: get modality failed!"); - } - + OFString modalityOFS = getModality(datasetPtr); for(unsigned int i=0; i<3; i++){ if (aModality.Type == (i+1) && modalityOFS == modalityStrArray[i].c_str()) { - ++file_count; - OFString currentUID; - status = datasetPtr->findAndGetOFString(DcmTagKey(0x0020, 0x000e), currentUID); - if (!status.good()) - { - throw DcmrtException("Error: get uid failed!"); + if(uid == ""){ + isFirst = true; } - + OFString currentUID = getUID(datasetPtr); + //get the first uid of the given modality - if(file_count==1) + if(isFirst) { uid = currentUID.c_str(); + isFirst = false; } - - if(uid == currentUID.c_str()) { fileNameVector.push_back(filePath.string().c_str()); } - + break; } } } } } - else if(boost::filesystem::is_regular_file(path)){ - std::cout << "Important: the given name is a file name, not a directory name. Given modality will be ignored, use the modality of the file." << std::endl; + else if(isFile(aDirName)){ + std::cout << "Important: the given name "+ aDirName +" is a file name, not a directory name. Given modality will be ignored, use the modality of the file." << std::endl; fileNameVector = getFileNames(aDirName); } else{ throw core::InvalidParameterException("Error: file/directory does not exist!"); } return fileNameVector; } std::vector getFileNames(FileNameType aFileName){ + + if(!isFile(aFileName)){ + throw core::InvalidParameterException("Error: file does not exist!"); + } + std::vector fileNameVector; boost::filesystem::path path=boost::filesystem::path(aFileName); OFCondition status; DcmFileFormat fileformat; DcmDataSetPtr datasetPtr; OFString modality;//modality of the given file OFString uid;//uid of the given file - if(!boost::filesystem::exists(path) || !boost::filesystem::is_regular_file(path)){ - throw core::InvalidParameterException("Error: file does not exist!"); - } - status = fileformat.loadFile(aFileName.c_str()); if (!status.good()) { throw DcmrtException("Error: fileformat.loadFile failed!"); } datasetPtr = boost::make_shared(*fileformat.getDataset()); - status = datasetPtr->findAndGetOFString(DcmTagKey(0x0008, 0x0060), modality); - if (!status.good()) - { - throw DcmrtException("Error: get modality failed!"); - } - status = datasetPtr->findAndGetOFString(DcmTagKey(0x0020, 0x000e), uid); - if (!status.good()) - { - throw DcmrtException("Error: get uid failed!"); - } + modality = getModality(datasetPtr); + uid = getUID(datasetPtr); //get parent directory boost::filesystem::path parentDir = path.parent_path(); if(boost::filesystem::is_directory(parentDir)){ boost::filesystem::directory_iterator end_iter; for(boost::filesystem::directory_iterator dir_itr(parentDir);dir_itr!=end_iter;++dir_itr) { if(boost::filesystem::is_regular_file(dir_itr->status())) { boost::filesystem::path currentFilePath(dir_itr->path().filename().string()); currentFilePath = boost::filesystem::system_complete(dir_itr->path()); status = fileformat.loadFile(currentFilePath.string().c_str()); if (!status.good()) { throw DcmrtException("Error: load dose fileformat.loadFile failed!"); } datasetPtr = boost::make_shared(*fileformat.getDataset()); - OFString currentModality; - status = datasetPtr->findAndGetOFString(DcmTagKey(0x0008, 0x0060), currentModality); - if (!status.good()) - { - throw DcmrtException("Error: get modality failed!"); - } - OFString currentUID; - status = datasetPtr->findAndGetOFString(DcmTagKey(0x0020, 0x000e), currentUID); - if (!status.good()) - { - throw DcmrtException("Error: get modality failed!"); - } + OFString currentModality = getModality(datasetPtr); + OFString currentUID = getUID(datasetPtr); //if the same modality if (modality == currentModality && uid == currentUID){ fileNameVector.push_back(currentFilePath.string().c_str()); } } } } return fileNameVector; } } } } diff --git a/code/io/dicom/rttbDicomFileReaderHelper.h b/code/io/dicom/rttbDicomFileReaderHelper.h index d778fe2..dad301a 100644 --- a/code/io/dicom/rttbDicomFileReaderHelper.h +++ b/code/io/dicom/rttbDicomFileReaderHelper.h @@ -1,79 +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: 707 $ (last changed revision) // @date $Date: 2014-09-04 16:37:24 +0200 (Do, 04 Sep 2014) $ (last change date) // @author $Author: floca $ (last changed by) */ #ifndef __DICOM_FILE_READER_HELPER_H #define __DICOM_FILE_READER_HELPER_H #include #include #include #include "osconfig.h" /* make sure OS specific configuration is included first */ #include "drtdose.h" #include "rttbBaseType.h" namespace rttb{ namespace io{ namespace dicom{ struct Modality { enum Type { RTDOSE = 1, RTSTRUCT = 2, RTPLAN = 3, UserDefined = 128 } Type; }; typedef boost::shared_ptr DRTDoseIODPtr; typedef boost::shared_ptr DcmDataSetPtr; /*! Return the vector of all files with the same UID in the given directory, the UID is defined by the first file with the modality. @exception InvalidParameterException thrown if the file/directory does not exist or the modality is invalid @exception DcmrtException thrown if load/read file failed */ std::vector getFileNamesWithSameUID(FileNameType aDirName, Modality aModality); /*! Return the vector of all files with the same UID in the directory of the given file @exception InvalidParameterException thrown if the file does not exist @exception DcmrtException thrown if load/read file failed */ std::vector getFileNames(FileNameType aFileName); /*! Return if the given name is a file */ bool isFile(FileNameType aName); /*! Return if the given name is a directory */ bool isDirectory(FileNameType aName); + /*! Return modality DcmTagKey(0x0008, 0x0060) + @exception DcmrtException thrown if reading modality failed*/ + OFString getModality(DcmDataSetPtr aDcmDataSet); + + /*! Return uid DcmTagKey(0x0020, 0x000e) + @exception DcmrtException thrown if reading uid failed*/ + OFString getUID(DcmDataSetPtr aDcmDataSet); + }; } } #endif diff --git a/testing/io/dicom/DicomFileReaderHelperTest.cpp b/testing/io/dicom/DicomFileReaderHelperTest.cpp index ba3c4db..9be7184 100644 --- a/testing/io/dicom/DicomFileReaderHelperTest.cpp +++ b/testing/io/dicom/DicomFileReaderHelperTest.cpp @@ -1,94 +1,94 @@ // ----------------------------------------------------------------------- // 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: 841 $ (last changed revision) // @date $Date: 2014-11-07 14:39:21 +0100 (Fr, 07 Nov 2014) $ (last change date) // @author $Author: zhangl $ (last changed by) */ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbDicomFileReaderHelper.h" namespace rttb { namespace testing { /*!@brief DicomDoseAccessorGeneratorTest - test the generators for dicom data 1) test getFileNamesWithSameUID() with a directory name 2) test getFileNames() with a RTDOSE file name and check equal with getFileNamesWithSameUID() 3) test getFileNames() with a RTSTRUCT file name */ int DicomFileReaderHelperTest(int argc, char* argv[]) { typedef boost::shared_ptr DRTDoseIODPtr; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: // 1: helax directory name // 2: dose file name // 3: structure file name std::string RT_DIRNAME; std::string RTDOSE_FILENAME; std::string RTStr_FILENAME; if (argc > 3) { RT_DIRNAME = argv[1]; RTDOSE_FILENAME = argv[2]; RTStr_FILENAME = argv[3]; } rttb::io::dicom::Modality doseModality= {rttb::io::dicom::Modality::RTDOSE}; rttb::io::dicom::Modality strModality= {rttb::io::dicom::Modality::RTSTRUCT}; //1) test getFileNamesWithSameUID() with a directory name std::vector fileVector = rttb::io::dicom::getFileNamesWithSameUID(RT_DIRNAME, doseModality); CHECK_EQUAL(fileVector.size(), 52); //2) test getFileNames() with a RTDOSE file name and check equal with getFileNamesWithSameUID() std::vector fileVector2 = rttb::io::dicom::getFileNames(RTDOSE_FILENAME); for(int i=0; i