//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+void clitk::DicomRT_StructureSet::SetTransformMatrix(vtkMatrix4x4* matrix)
+{
+ mTransformMatrix = matrix;
+}
+//--------------------------------------------------------------------
+
+
//--------------------------------------------------------------------
const std::string & clitk::DicomRT_StructureSet::GetTime() const
{
}
//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+clitk::DicomRT_ROI* clitk::DicomRT_StructureSet::GetROIFromROIName(const std::string& name)
+{
+ std::map<int, std::string>::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<int, std::string>::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<int, std::string>::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
//--------------------------------------------------------------------
-#if GDCM_MAJOR_VERSION == 2
+#if GDCM_MAJOR_VERSION >= 2
//--------------------------------------------------------------------
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) {
}
// 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
//--------------------------------------------------------------------
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<gdcm::SequenceOfItems> sqi = roicsq.GetValueAsSQ();
+ if( !sqi || !sqi->GetNumberOfItems() )
+ {
+ return;
+ }
+ const gdcm::DataElement &ssroisq = ds.GetDataElement( tssroisq );
+ gdcm::SmartPointer<gdcm::SequenceOfItems> ssqi = ssroisq.GetValueAsSQ();
+ if( !ssqi || !ssqi->GetNumberOfItems() )
+ {
+ return;
+ }
+
// Read global info
gdcm::Attribute<0x20,0x10> studyid;
studyid.SetFromDataSet( ds );
// Temporary store the list of items
std::map<int, gdcm::Item*> mMapOfROIInfo;
std::map<int, gdcm::Item*> 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<gdcm::SequenceOfItems> & roi_seq = mROIInfoSequenceOfItems;
assert(roi_seq); // TODO error message
//----------------------------------
// 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<gdcm::SequenceOfItems> roi_contour_seq = roicsq.GetValueAsSQ();
mROIContoursSequenceOfItems = roi_contour_seq;
assert(roi_contour_seq); // TODO error message
for(std::map<int, gdcm::Item*>::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;
// 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
}