Accessing nested sequences in DICOM RT IODs¶
What is the best way to access sequence items using dcmrt objects?
Example excerpt from a DICOM RT structure set. Printout created using dcmdump
(3006,0010) SQ (Sequence with explicit length #=1) # 11924, 1 ReferencedFrameOfReferenceSequence (fffe,e000) na (Item with explicit length #=2) # 11916, 1 Item (0020,0052) UI [1.2.276.0.20.1.30.4.964244505725.4620.1253284397.625000] # 56, 1 FrameOfReferenceUID (3006,0012) SQ (Sequence with explicit length #=1) # 11840, 1 RTReferencedStudySequence (fffe,e000) na (Item with explicit length #=3) # 11832, 1 Item (0008,1150) UI =DetachedStudyManagementSOPClass # 24, 1 ReferencedSOPClassUID (0008,1155) UI [1.2.276.0.20.1.2.4.964244505725.4620.1253284397.593750] # 54, 1 ReferencedSOPInstanceUID (3006,0014) SQ (Sequence with explicit length #=1) # 11726, 1 RTReferencedSeriesSequence (fffe,e000) na (Item with explicit length #=2) # 11718, 1 Item (0020,000e) UI [1.2.276.0.20.1.3.4.964244505725.4620.1253284397.609375] # 54, 1 SeriesInstanceUID (3006,0016) SQ (Sequence with explicit length #=112) # 11644, 1 ContourImageSequence (fffe,e000) na (Item with explicit length #=2) # 96, 1 Item (0008,1150) UI =CTImageStorage # 26, 1 ReferencedSOPClassUID (0008,1155) UI [1.2.276.0.20.1.4.4.964244505725.4620.1253284397.640625] # 54, 1 ReferencedSOPInstanceUID (fffe,e00d) na (ItemDelimitationItem for re-encoding) # 0, 0 ItemDelimitationItem ...... snip ...... (fffe,e00d) na (ItemDelimitationItem for re-encoding) # 0, 0 ItemDelimitationItem (fffe,e0dd) na (SequenceDelimitationItem for re-encod.) # 0, 0 SequenceDelimitationItem (fffe,e00d) na (ItemDelimitationItem for re-encoding) # 0, 0 ItemDelimitationItem (fffe,e0dd) na (SequenceDelimitationItem for re-encod.) # 0, 0 SequenceDelimitationItem (fffe,e00d) na (ItemDelimitationItem for re-encoding) # 0, 0 ItemDelimitationItem (fffe,e0dd) na (SequenceDelimitationItem for re-encod.) # 0, 0 SequenceDelimitationItem (fffe,e00d) na (ItemDelimitationItem for re-encoding) # 0, 0 ItemDelimitationItem (fffe,e0dd) na (SequenceDelimitationItem for re-encod.) # 0, 0 SequenceDelimitationItem
How to access this data preserving and reflecting the data structure hierachy in your code.
Is this the preferred way to read items from nested sequences???
DRTReferencedFrameOfReferenceSequence &seq = this->getReferencedFrameOfReferenceSequence(); Uint16 num_items = seq.getNumberOfItems(); for(int i = 0; i < num_items; i++) { DRTReferencedFrameOfReferenceSequence::Item &item = seq.getItem(i); OFString uid; item.getFrameOfReferenceUID(uid); DRTRTReferencedStudySequence &rss_ref = item.getRTReferencedStudySequence(); for (int j = 0; j < rss_ref.getNumberOfItems(); j++) { DRTRTReferencedStudySequence::Item &rss_item = rss_ref.getItem(i); DRTRTReferencedSeriesSequence &ref_series_seq = rss_item.getRTReferencedSeriesSequence(); Uint16 nssitem = ref_series_seq.getNumberOfItems(); for (int k = 0; k < nssitem; k++) { DRTRTReferencedSeriesSequence::Item &ref_series_seq_item = ref_series_seq.getItem(i); DRTContourImageSequence &image_sequence = ref_series_seq_item.getContourImageSequence(); Uint16 num_images_in_sequence = image_sequence.getNumberOfItems(); for (int l = 0; l < num_images_in_sequence; l++) { DRTContourImageSequence::Item &image_contour_item = image_sequence.getItem(l); OFString refframenum; image_contour_item.getReferencedFrameNumber(refframenum); std::cout << refframenum << std::endl; } } } }
No, iterating over all items of a sequence is better done like this:
DRTReferencedFrameOfReferenceSequence &seq = this->getReferencedFrameOfReferenceSequence(); if (seq.gotoFirstItem().good()) { do { DRTReferencedFrameOfReferenceSequence::Item &item = seq.getCurrentItem(); OFString uid; item.getFrameOfReferenceUID(uid); DRTRTReferencedStudySequence &reference_study_sequence_ref = item.getRTReferencedStudySequence(); if (reference_study_sequence_ref.gotoFirstItem().good()) { do { DRTRTReferencedStudySequence::Item &rss_item = reference_study_sequence_ref.getCurrentItem(); DRTRTReferencedSeriesSequence &series_seq_ref = rss_item.getRTReferencedSeriesSequence(); if (series_seq_ref.gotoFirstItem().good()) { do { DRTRTReferencedSeriesSequence::Item &ref_series_seq_item = series_seq_ref.getCurrentItem(); DRTContourImageSequence &image_sequence_seq_ref = ref_series_seq_item.getContourImageSequence(); if (image_sequence_seq_ref.gotoFirstItem().good()) { do { DRTContourImageSequence::Item &image_contour_item = image_sequence_seq_ref.getCurrentItem(); OFString refSOPInstUID; image_contour_item.getReferencedSOPInstanceUID(refSOPInstUID); std::cout << refSOPInstUID << std::endl; } while (image_sequence_seq_ref.gotoNextItem().good()); } // end if image_sequence_seq_ref } while (series_seq_ref.gotoNextItem().good()); } // end if series_seq_ref good } while (reference_study_sequence_ref.gotoNextItem().good()); } // end if reference_study_sequence_ref good } while (seq.gotoNextItem().good()); } // end if seq.first item
Notes¶
Also see the following discussion in the DCMRT forum.