X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=common%2FclitkDicomRT_StructureSet.cxx;h=a845ef55b97cc6a789a7c63b72bb9ce2a805a091;hb=d786b4f836c0f12ba4a6dd06803cbe771ac371e3;hp=4ac4705ef73a673b0487980e569aac56ba3f01ef;hpb=eddba34cfd972c817bdfba337a9c866b3ae5c410;p=clitk.git diff --git a/common/clitkDicomRT_StructureSet.cxx b/common/clitkDicomRT_StructureSet.cxx index 4ac4705..a845ef5 100644 --- a/common/clitkDicomRT_StructureSet.cxx +++ b/common/clitkDicomRT_StructureSet.cxx @@ -91,6 +91,14 @@ const std::string & clitk::DicomRT_StructureSet::GetDate() const //-------------------------------------------------------------------- +//-------------------------------------------------------------------- +void clitk::DicomRT_StructureSet::SetTransformMatrix(vtkMatrix4x4* matrix) +{ + mTransformMatrix = matrix; +} +//-------------------------------------------------------------------- + + //-------------------------------------------------------------------- const std::string & clitk::DicomRT_StructureSet::GetTime() const { @@ -118,6 +126,101 @@ clitk::DicomRT_ROI* clitk::DicomRT_StructureSet::GetROIFromROINumber(int n) } //-------------------------------------------------------------------- +//-------------------------------------------------------------------- +clitk::DicomRT_ROI* clitk::DicomRT_StructureSet::GetROIFromROIName(const std::string& name) +{ + std::map::iterator it = mMapOfROIName.begin(); + int number = -1; + while (it != mMapOfROIName.end() && number == -1) { + if (it->second == name) + number = it->first; + else + it++; + } + + if (number == -1) { + std::cerr << "No ROI name " << name << std::endl; + return NULL; + } + + return mROIs[number]; +} +//-------------------------------------------------------------------- +/* +// RP: 08/02/2013 +// RegEx version shall be available when C++x11 supports it propely +// +//-------------------------------------------------------------------- +clitk::DicomRT_ROI* clitk::DicomRT_StructureSet::GetROIFromROINameRegEx(const std::string& regEx) +{ + std::map::iterator it = mMapOfROIName.begin(); + int number = -1; + + while (it != mMapOfROIName.end() && number == -1) { + if (std::tr1::regex_match (it->second, std::tr1::regex(regEx))) + number = it->first; + else + it++; + } + + if (number == -1) { + std::cerr << "No ROI name " << number << std::endl; + return NULL; + } + + return mROIs[number]; +} +//-------------------------------------------------------------------- +*/ +//-------------------------------------------------------------------- +clitk::DicomRT_ROI* clitk::DicomRT_StructureSet::GetROIFromROINameSubstr(const std::string& s) +{ + std::map::iterator it = mMapOfROIName.begin(); + int number = -1; + + while (it != mMapOfROIName.end() && number == -1) { + if (it->second.find(s) != std::string::npos) + number = it->first; + else + it++; + } + + if (number == -1) { + std::cerr << "No ROI name " << s << std::endl; + return NULL; + } + + return mROIs[number]; +} +//-------------------------------------------------------------------- + +//-------------------------------------------------------------------- +clitk::DicomRT_StructureSet::ROIMapContainer * +clitk::DicomRT_StructureSet::GetROIsFromROINameSubstr(const std::string& s) +{ + static ROIMapContainer rois; + rois.clear(); + + ROIMapContainer::iterator it = mROIs.begin(); + int number = -1; + + while (it != mROIs.end()) { + if (it->second->GetName().find(s) != std::string::npos) { + number = it->first; + rois[number] = it->second; + } + it++; + } + + if (number == -1) { + std::cerr << "No ROI name " << s << std::endl; + return NULL; + } + + return &rois; + +} +//-------------------------------------------------------------------- //-------------------------------------------------------------------- void clitk::DicomRT_StructureSet::Print(std::ostream & os) const @@ -136,7 +239,7 @@ void clitk::DicomRT_StructureSet::Print(std::ostream & os) const //-------------------------------------------------------------------- -#if GDCM_MAJOR_VERSION == 2 +#if GDCM_MAJOR_VERSION >= 2 //-------------------------------------------------------------------- int clitk::DicomRT_StructureSet::ReadROINumber(const gdcm::Item & item) { @@ -152,8 +255,7 @@ int clitk::DicomRT_StructureSet::ReadROINumber(const gdcm::Item & item) //-------------------------------------------------------------------- void clitk::DicomRT_StructureSet::Write(const std::string & filename) { -#if GDCM_MAJOR_VERSION == 2 - DD("DCM RT Writer"); +#if GDCM_MAJOR_VERSION >= 2 // Assert that the gdcm file is still open (we can write only if it was readed) if (mFile == NULL) { @@ -162,8 +264,10 @@ void clitk::DicomRT_StructureSet::Write(const std::string & filename) } // Loop and update each ROI + int i=0; for(ROIIteratorType iter = mROIs.begin(); iter != mROIs.end(); iter++) { iter->second->UpdateDicomItem(); + i++; } // Write [ Structure Set ROI Sequence ] = 0x3006,0x0020 @@ -215,37 +319,51 @@ void clitk::DicomRT_StructureSet::Write(const std::string & filename) //-------------------------------------------------------------------- void clitk::DicomRT_StructureSet::Read(const std::string & filename) { - // Open DICOM -#if GDCM_MAJOR_VERSION == 2 - // Read gdcm file - mReader = new gdcm::Reader; - mReader->SetFileName(filename.c_str()); - mReader->Read(); - mFile = &(mReader->GetFile()); - const gdcm::DataSet & ds = mFile->GetDataSet(); + +//Try to avoid to use extern GDCM library + + //check the RS file is available before conversion + gdcm::Reader RTreader; + RTreader.SetFileName( filename.c_str() ); + if( !RTreader.Read() ) + { + std::cout << "Problem reading file: " << filename << std::endl; + return; + } + + const gdcm::DataSet& ds = RTreader.GetFile().GetDataSet(); - // Check file type - //Verify if the file is a RT-Structure-Set dicom file gdcm::MediaStorage ms; - ms.SetFromFile(*mFile); - if( ms != gdcm::MediaStorage::RTStructureSetStorage ) - { - std::cerr << "Error. the file " << filename - << " is not a Dicom Struct ? (must have a SOP Class UID [0008|0016] = 1.2.840.10008.5.1.4.1.1.481.3 ==> [RT Structure Set Storage])" - << std::endl; - exit(0); - } + ms.SetFromFile( RTreader.GetFile() ); + + // (3006,0020) SQ (Sequence with explicit length #=4) # 370, 1 StructureSetROISequence + gdcm::Tag tssroisq(0x3006,0x0020); + if( !ds.FindDataElement( tssroisq ) ) + { + std::cout << "Problem locating 0x3006,0x0020 - Is this a valid RT Struct file?" << std::endl; + return; + } + gdcm::Tag troicsq(0x3006,0x0039); + if( !ds.FindDataElement( troicsq ) ) + { + std::cout << "Problem locating 0x3006,0x0039 - Is this a valid RT Struct file?" << std::endl; + return; + } - gdcm::Attribute<0x8,0x60> modality; - modality.SetFromDataSet( ds ); - if( modality.GetValue() != "RTSTRUCT" ) - { - std::cerr << "Error. the file " << filename - << " is not a Dicom Struct ? (must have 0x0008,0x0060 = RTSTRUCT [RT Structure Set Storage])" - << std::endl; - exit(0); - } + const gdcm::DataElement &roicsq = ds.GetDataElement( troicsq ); + gdcm::SmartPointer sqi = roicsq.GetValueAsSQ(); + if( !sqi || !sqi->GetNumberOfItems() ) + { + return; + } + const gdcm::DataElement &ssroisq = ds.GetDataElement( tssroisq ); + gdcm::SmartPointer ssqi = ssroisq.GetValueAsSQ(); + if( !ssqi || !ssqi->GetNumberOfItems() ) + { + return; + } + // Read global info gdcm::Attribute<0x20,0x10> studyid; studyid.SetFromDataSet( ds ); @@ -270,12 +388,13 @@ void clitk::DicomRT_StructureSet::Read(const std::string & filename) // Temporary store the list of items std::map mMapOfROIInfo; std::map mMapOfROIContours; + //---------------------------------- // Read all ROI Names and number // 0x3006,0x0020 = [ Structure Set ROI Sequence ] - gdcm::Tag tssroisq(0x3006,0x0020); - const gdcm::DataElement &ssroisq = ds.GetDataElement( tssroisq ); + //gdcm::Tag tssroisq(0x3006,0x0020); + //const gdcm::DataElement &ssroisq = ds.GetDataElement( tssroisq ); mROIInfoSequenceOfItems = ssroisq.GetValueAsSQ(); gdcm::SmartPointer & roi_seq = mROIInfoSequenceOfItems; assert(roi_seq); // TODO error message @@ -306,8 +425,8 @@ void clitk::DicomRT_StructureSet::Read(const std::string & filename) //---------------------------------- // Read all ROI item // 0x3006,0x0039 = [ ROI Contour Sequence ] - gdcm::Tag troicsq(0x3006,0x0039); - const gdcm::DataElement &roicsq = ds.GetDataElement( troicsq ); + //gdcm::Tag troicsq(0x3006,0x0039); + //const gdcm::DataElement &roicsq = ds.GetDataElement( troicsq ); gdcm::SmartPointer roi_contour_seq = roicsq.GetValueAsSQ(); mROIContoursSequenceOfItems = roi_contour_seq; assert(roi_contour_seq); // TODO error message @@ -327,15 +446,41 @@ void clitk::DicomRT_StructureSet::Read(const std::string & filename) for(std::map::iterator i = mMapOfROIInfo.begin(); i != mMapOfROIInfo.end(); i++) { int nb = i->first;//ReadROINumber(i);//mROIIndex[i]; // Create the roi - DicomRT_ROI::Pointer roi = DicomRT_ROI::New(); - roi->Read(mMapOfROIInfo[nb], mMapOfROIContours[nb]); - // mListOfROI.push_back(roi); - // mMapOfROIIndex[nb] = i; - mROIs[nb] = roi; + mROIs[nb] = DicomRT_ROI::New(); + mROIs[nb]->SetTransformMatrix(mTransformMatrix); + mROIs[nb]->Read(mMapOfROIInfo[nb], mMapOfROIContours[nb]); } + + return; + +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +bool clitk::DicomRT_StructureSet::IsDicomRTStruct(const std::string & filename) +{ + // Open DICOM +#if GDCM_MAJOR_VERSION >= 2 + // Read gdcm file + mReader = new gdcm::Reader; + mReader->SetFileName(filename.c_str()); + mReader->Read(); + mFile = &(mReader->GetFile()); + const gdcm::DataSet & ds = mFile->GetDataSet(); + + // Check file type + //Verify if the file is a RT-Structure-Set dicom file + gdcm::MediaStorage ms; + ms.SetFromFile(*mFile); + if( ms != gdcm::MediaStorage::RTStructureSetStorage ) return false; + + gdcm::Attribute<0x8,0x60> modality; + modality.SetFromDataSet( ds ); + if( modality.GetValue() != "RTSTRUCT" ) return false; + + return true; - //---------------------------------------------------------------------------------------- - //---------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------- #else mFile = new gdcm::File; @@ -346,61 +491,12 @@ void clitk::DicomRT_StructureSet::Read(const std::string & filename) // Check file type //Verify if the file is a RT-Structure-Set dicom file - if (!gdcm::Util::DicomStringEqual(mFile->GetEntryValue(0x0008,0x0016),"1.2.840.10008.5.1.4.1.1.481.3")) { //SOP clas UID - std::cerr << "Error. the file " << filename - << " is not a Dicom Struct ? (must have a SOP Class UID [0008|0016] = 1.2.840.10008.5.1.4.1.1.481.3 ==> [RT Structure Set Storage])" - << std::endl; - exit(0); - } - if (!gdcm::Util::DicomStringEqual(mFile->GetEntryValue(0x0008,0x0060),"RTSTRUCT")) { //SOP clas UID - std::cerr << "Error. the file " << filename - << " is not a Dicom Struct ? (must have 0x0008,0x0060 = RTSTRUCT [RT Structure Set Storage])" - << std::endl; - exit(0); - } - - // Read global info - mStudyID = mFile->GetValEntry(0x0020,0x0010)->GetValue(); - mStudyTime = mFile->GetValEntry(0x008,0x0020)->GetValue(); - mStudyDate = mFile->GetValEntry(0x008,0x0030)->GetValue(); - mLabel = mFile->GetValEntry(0x3006,0x002)->GetValue(); - if (!mFile->GetValEntry(0x3006,0x004)) { - mName = "Anonymous"; - } - else { - mName = mFile->GetValEntry(0x3006,0x004)->GetValue(); - } - mTime = mFile->GetValEntry(0x3006,0x009)->GetValue(); + if (!gdcm::Util::DicomStringEqual(mFile->GetEntryValue(0x0008,0x0016),"1.2.840.10008.5.1.4.1.1.481.3")) + return false; + if (!gdcm::Util::DicomStringEqual(mFile->GetEntryValue(0x0008,0x0060),"RTSTRUCT")) + return false; - //---------------------------------- - // Read all ROI Names and number - // 0x3006,0x0020 = [ Structure Set ROI Sequence ] - gdcm::SeqEntry * roi_seq=mFile->GetSeqEntry(0x3006,0x0020); - assert(roi_seq); // TODO error message - for (gdcm::SQItem* r=roi_seq->GetFirstSQItem(); r!=0; r=roi_seq->GetNextSQItem()) { - std::string name = r->GetEntryValue(0x3006,0x0026); // 0x3006,0x0026 = [ROI Name] - int nb = atoi(r->GetEntryValue(0x3006,0x0022).c_str()); // 0x3006,0x0022 = [ROI Number] - // Check if such a number already exist - if (mMapOfROIName.find(nb) != mMapOfROIName.end()) { - std::cerr << "WARNING. A Roi already exist with the number " - << nb << ". I replace." << std::endl; - } - // Add in map - mMapOfROIName[nb] = name; - } - - //---------------------------------- - // Read all ROI - // 0x3006,0x0039 = [ ROI Contour Sequence ] - gdcm::SeqEntry * roi_contour_seq=mFile->GetSeqEntry(0x3006,0x0039); - assert(roi_contour_seq); // TODO error message - int n=0; - for (gdcm::SQItem* r=roi_contour_seq->GetFirstSQItem(); r!=0; r=roi_contour_seq->GetNextSQItem()) { - DicomRT_ROI::Pointer roi = DicomRT_ROI::New(); - roi->Read(mMapOfROIName, r); - mROIs[roi->GetROINumber()] = roi; - n++; - } + return true; #endif }