Project

General

Profile

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.