Class: RTKIT::StructureSet
Overview
The StructureSet class contains methods that are specific for this modality (RTSTRUCT).
Inheritance
-
StructureSet inherits all methods and attributes from the Series class.
Instance Attribute Summary collapse
-
#dcm ⇒ Object
readonly
The original DObject instance of the StructureSet.
-
#image_series ⇒ Object
readonly
An array of ImageSeries that this Structure Set Series references has ROIs defined for.
-
#plans ⇒ Object
readonly
An array of RTPlans associated with this Structure Set Series.
-
#rois ⇒ Object
readonly
An array of ROIs belonging to this structure set.
-
#sop_uid ⇒ Object
readonly
The SOP Instance UID.
Attributes inherited from Series
#class_uid, #date, #description, #modality, #series_uid, #study, #time
Class Method Summary collapse
-
.image_series(dcm, study) ⇒ Object
Identifies the ImageSeries that the StructureSet object belongs to.
-
.load(dcm, study) ⇒ Object
Creates a new StructureSet instance by loading the relevant information from the specified DICOM object.
Instance Method Summary collapse
-
#==(other) ⇒ Object
(also: #eql?)
Returns true if the argument is an instance with attributes equal to self.
-
#add(dcm) ⇒ Object
Registers a DICOM Object to the StructureSet, and processes it to create (and reference) the ROIs contained in the object.
-
#add_plan(plan) ⇒ Object
Adds a Plan Series to this StructureSet.
-
#add_roi(roi) ⇒ Object
Adds a ROI instance to this StructureSet.
-
#create_roi(frame, options = {}) ⇒ Object
Creates a ROI belonging to this StructureSet.
-
#hash ⇒ Object
Generates a Fixnum hash value for this instance.
-
#initialize(sop_uid, image_series, options = {}) ⇒ StructureSet
constructor
Creates a new StructureSet instance.
-
#plan(*args) ⇒ Object
Returns the Plan instance mathcing the specified SOP Instance UID (if an argument is used).
-
#remove_roi(instance_or_number) ⇒ Object
Removes the ROI (specified by a ROI Number) from the Structure Set.
-
#remove_rois ⇒ Object
Removes all ROIs from the Structure Set.
-
#roi(name_or_number) ⇒ Object
Returns a ROI that matches the specified number or name.
-
#roi_names ⇒ Object
Returns the ROI Names assigned to the various structures present in the structure set.
-
#roi_numbers ⇒ Object
Returns the ROI Numbers assigned to the various structures present in the structure set.
-
#rois_in_frame(uid) ⇒ Object
Returns all ROIs defined in this structure set that belongs to the specified Frame of Reference UID.
-
#set_colors ⇒ Object
Sets new color values for all ROIs belonging to the StructureSet.
-
#set_numbers ⇒ Object
Sets new ROI Numbers to all ROIs belonging to the StructureSet.
-
#to_dcm ⇒ Object
Dumps the StructureSet instance to a DObject.
-
#to_structure_set ⇒ Object
Returns self.
-
#write(path) ⇒ Object
Writes the StructureSet to a DICOM file given by the specified file string.
Methods inherited from Series
Constructor Details
#initialize(sop_uid, image_series, options = {}) ⇒ StructureSet
Creates a new StructureSet instance.
Parameters
-
sop_uid
– The SOP Instance UID string. -
image_series
– An Image Series that this StructureSet belongs to. -
options
– A hash of parameters.
Options
-
:date
– String. The Series Date (DICOM tag ‘0008,0021’). -
:time
– String. The Series Time (DICOM tag ‘0008,0031’). -
:description
– String. The Series Description (DICOM tag ‘0008,103E’). -
:series_uid
– String. The Series Instance UID (DICOM tag ‘0020,000E’).
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/rtkit/structure_set.rb', line 94 def initialize(sop_uid, image_series, ={}) raise ArgumentError, "Invalid argument 'sop_uid'. Expected String, got #{sop_uid.class}." unless sop_uid.is_a?(String) raise ArgumentError, "Invalid argument 'image_series'. Expected ImageSeries, got #{image_series.class}." unless image_series.is_a?(ImageSeries) # Pass attributes to Series initialization: [:class_uid] = '1.2.840.10008.5.1.4.1.1.481.3' # RT Structure Set Storage # Get a randomized Series UID unless it has been defined in the options hash: series_uid = [:series_uid] || RTKIT.series_uid super(series_uid, 'RTSTRUCT', image_series.study, ) @sop_uid = sop_uid # Default attributes: @image_series = Array.new @rois = Array.new @plans = Array.new @associated_plans = Hash.new # Register ourselves with the ImageSeries: image_series.add_struct(self) @image_series << image_series end |
Instance Attribute Details
#dcm ⇒ Object (readonly)
The original DObject instance of the StructureSet.
12 13 14 |
# File 'lib/rtkit/structure_set.rb', line 12 def dcm @dcm end |
#image_series ⇒ Object (readonly)
An array of ImageSeries that this Structure Set Series references has ROIs defined for.
14 15 16 |
# File 'lib/rtkit/structure_set.rb', line 14 def image_series @image_series end |
#plans ⇒ Object (readonly)
An array of RTPlans associated with this Structure Set Series.
16 17 18 |
# File 'lib/rtkit/structure_set.rb', line 16 def plans @plans end |
#rois ⇒ Object (readonly)
An array of ROIs belonging to this structure set.
18 19 20 |
# File 'lib/rtkit/structure_set.rb', line 18 def rois @rois end |
#sop_uid ⇒ Object (readonly)
The SOP Instance UID.
20 21 22 |
# File 'lib/rtkit/structure_set.rb', line 20 def sop_uid @sop_uid end |
Class Method Details
.image_series(dcm, study) ⇒ Object
Identifies the ImageSeries that the StructureSet object belongs to. If the referenced instances (ImageSeries & Frame) does not exist, they are created by this method.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/rtkit/structure_set.rb', line 53 def self.image_series(dcm, study) raise ArgumentError, "Invalid argument 'dcm'. Expected DObject, got #{dcm.class}." unless dcm.is_a?(DICOM::DObject) raise ArgumentError, "Invalid argument 'study'. Expected Study, got #{study.class}." unless study.is_a?(Study) raise ArgumentError, "Invalid argument 'dcm'. Expected DObject with modality 'RTSTUCT', got #{dcm.value(MODALITY)}." unless dcm.value(MODALITY) == 'RTSTRUCT' # Extract the Referenced Frame UID: begin ref_frame_of_ref = dcm[REF_FRAME_OF_REF_SQ][0].value(FRAME_OF_REF) rescue ref_frame_of_ref = nil end # Extract referenced Image Series UID: begin ref_series_uid = dcm[REF_FRAME_OF_REF_SQ][0][RT_REF_STUDY_SQ][0][RT_REF_SERIES_SQ][0].value(SERIES_UID) rescue ref_series_uid = nil end # Create the Frame if it doesn't exist: f = study.patient.dataset.frame(ref_frame_of_ref) f = Frame.new(ref_frame_of_ref, study.patient) unless f # Create the ImageSeries if it doesnt exist: is = f.series(ref_series_uid) is = ImageSeries.new(ref_series_uid, 'CT', f, study) unless is study.add_series(is) return is end |
.load(dcm, study) ⇒ Object
Creates a new StructureSet instance by loading the relevant information from the specified DICOM object. The SOP Instance UID string value is used to uniquely identify a StructureSet instance.
Parameters
-
dcm
– An instance of a DICOM object (DICOM::DObject) with modality ‘RTSTRUCT’. -
study
– The Study instance that this StructureSet belongs to.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/rtkit/structure_set.rb', line 30 def self.load(dcm, study) raise ArgumentError, "Invalid argument 'dcm'. Expected DObject, got #{dcm.class}." unless dcm.is_a?(DICOM::DObject) raise ArgumentError, "Invalid argument 'study'. Expected Study, got #{study.class}." unless study.is_a?(Study) raise ArgumentError, "Invalid argument 'dcm'. Expected DObject with modality 'RTSTUCT', got #{dcm.value(MODALITY)}." unless dcm.value(MODALITY) == 'RTSTRUCT' # Required attributes: sop_uid = dcm.value(SOP_UID) # Optional attributes: class_uid = dcm.value(SOP_CLASS) date = dcm.value(SERIES_DATE) time = dcm.value(SERIES_TIME) description = dcm.value(SERIES_DESCR) series_uid = dcm.value(SERIES_UID) # Get the corresponding image series: image_series = self.image_series(dcm, study) # Create the StructureSet instance: ss = self.new(sop_uid, image_series, :class_uid => class_uid, :date => date, :time => time, :description => description, :series_uid => series_uid) ss.add(dcm) return ss end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
Returns true if the argument is an instance with attributes equal to self.
115 116 117 118 119 |
# File 'lib/rtkit/structure_set.rb', line 115 def ==(other) if other.respond_to?(:to_structure_set) other.send(:state) == state end end |
#add(dcm) ⇒ Object
Registers a DICOM Object to the StructureSet, and processes it to create (and reference) the ROIs contained in the object.
126 127 128 129 130 |
# File 'lib/rtkit/structure_set.rb', line 126 def add(dcm) raise ArgumentError, "Invalid argument 'dcm'. Expected DObject, got #{dcm.class}." unless dcm.is_a?(DICOM::DObject) @dcm = dcm load_rois end |
#add_plan(plan) ⇒ Object
Adds a Plan Series to this StructureSet. Note: Intended for internal use in the library only.
135 136 137 138 139 |
# File 'lib/rtkit/structure_set.rb', line 135 def add_plan(plan) raise ArgumentError, "Invalid argument 'plan'. Expected Plan, got #{plan.class}." unless plan.is_a?(Plan) @plans << plan unless @associated_plans[plan.uid] @associated_plans[plan.uid] = plan end |
#add_roi(roi) ⇒ Object
Adds a ROI instance to this StructureSet.
143 144 145 146 |
# File 'lib/rtkit/structure_set.rb', line 143 def add_roi(roi) raise ArgumentError, "Invalid argument 'roi'. Expected ROI, got #{roi.class}." unless roi.is_a?(ROI) @rois << roi unless @rois.include?(roi) end |
#create_roi(frame, options = {}) ⇒ Object
Creates a ROI belonging to this StructureSet. Returns the created ROI.
Notes
-
The ROI is created without Slices, and these must be added after the ROI creation.
Parameters
-
frame
– The Frame instance which the ROI will belong to. -
options
– A hash of parameters.
Options
-
:algorithm
– String. The ROI Generation Algorithm. Defaults to ‘Automatic’. -
:name
– String. The ROI Name. Defaults to ‘RTKIT-VOLUME’. -
:number
– Integer. The ROI Number. Defaults to the first available ROI Number in the StructureSet. -
:interpreter
– String. The ROI Interpreter. Defaults to ‘RTKIT’. -
:type
– String. The ROI Interpreted Type. Defaults to ‘CONTROL’.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/rtkit/structure_set.rb', line 168 def create_roi(frame, ={}) raise ArgumentError, "Expected Frame, got #{frame.class}." unless frame.is_a?(Frame) # Set values: algorithm = [:algorithm] || 'Automatic' name = [:name] || 'RTKIT-VOLUME' interpreter = [:interpreter] || 'RTKIT' type = [:type] || 'CONTROL' if [:number] raise ArgumentError, "Expected Integer, got #{[:number].class} for the option :number." unless [:number].is_a?(Integer) raise ArgumentError, "The specified ROI Number (#{[:roi_number]}) is already used by one of the existing ROIs (#{roi_numbers})." if roi_numbers.include?([:number]) number = [:number] else number = (roi_numbers.max ? roi_numbers.max + 1 : 1) end # Create ROI: roi = ROI.new(name, number, frame, self, :algorithm => algorithm, :name => name, :number => number, :interpreter => interpreter, :type => type) return roi end |
#hash ⇒ Object
Generates a Fixnum hash value for this instance.
189 190 191 |
# File 'lib/rtkit/structure_set.rb', line 189 def hash state.hash end |
#plan(*args) ⇒ Object
Returns the Plan instance mathcing the specified SOP Instance UID (if an argument is used). If a specified UID doesn’t match, nil is returned. If no argument is passed, the first Plan instance associated with the StructureSet is returned.
Parameters
-
uid
– String. The value of the SOP Instance UID element.
201 202 203 204 205 206 207 208 209 210 |
# File 'lib/rtkit/structure_set.rb', line 201 def plan(*args) raise ArgumentError, "Expected one or none arguments, got #{args.length}." unless [0, 1].include?(args.length) if args.length == 1 raise ArgumentError, "Expected String (or nil), got #{args.first.class}." unless [String, NilClass].include?(args.first.class) return @associated_plans[args.first] else # No argument used, therefore we return the first Plan instance: return @plans.first end end |
#remove_roi(instance_or_number) ⇒ Object
Removes the ROI (specified by a ROI Number) from the Structure Set.
Parameters
-
instance_or_number
– The ROI Instance (or ROI Number of the instance) to be removed.
218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/rtkit/structure_set.rb', line 218 def remove_roi(instance_or_number) raise ArgumentError, "Invalid argument 'instance_or_number'. Expected a ROI Instance or an Integer (ROI Number). Got #{instance_or_number.class}." unless [ROI, Integer].include?(instance_or_number.class) roi_instance = instance_or_number if instance_or_number.is_a?(Integer) roi_instance = roi(instance_or_number) end index = @rois.index(roi_instance) if index @rois.delete_at(index) roi_instance.remove_references end end |
#remove_rois ⇒ Object
Removes all ROIs from the Structure Set.
233 234 235 236 237 238 |
# File 'lib/rtkit/structure_set.rb', line 233 def remove_rois @rois.each do |roi| roi.remove_references end @rois = Array.new end |
#roi(name_or_number) ⇒ Object
Returns a ROI that matches the specified number or name. Returns nil if no match is found.
243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/rtkit/structure_set.rb', line 243 def roi(name_or_number) raise ArgumentError, "Invalid argument 'name_or_number'. Expected String or Integer, got #{name_or_number.class}." unless [String, Integer, Fixnum].include?(name_or_number.class) if name_or_number.is_a?(String) @rois.each do |r| return r if r.name == name_or_number end else @rois.each do |r| return r if r.number == name_or_number end end return nil end |
#roi_names ⇒ Object
Returns the ROI Names assigned to the various structures present in the structure set. The names are returned in an array.
260 261 262 263 264 265 266 |
# File 'lib/rtkit/structure_set.rb', line 260 def roi_names names = Array.new @rois.each do |roi| names << roi.name end return names end |
#roi_numbers ⇒ Object
Returns the ROI Numbers assigned to the various structures present in the structure set. The numbers are returned in an array.
271 272 273 274 275 276 277 |
# File 'lib/rtkit/structure_set.rb', line 271 def roi_numbers numbers = Array.new @rois.each do |roi| numbers << roi.number end return numbers end |
#rois_in_frame(uid) ⇒ Object
Returns all ROIs defined in this structure set that belongs to the specified Frame of Reference UID. Returns an empty array if no matching ROIs are found.
282 283 284 285 286 287 288 289 |
# File 'lib/rtkit/structure_set.rb', line 282 def rois_in_frame(uid) raise ArgumentError, "Expected String, got #{uid.class}." unless uid.is_a?(String) frame_rois = Array.new @rois.each do |roi| frame_rois << roi if roi.frame.uid == uid end return frame_rois end |
#set_colors ⇒ Object
Sets new color values for all ROIs belonging to the StructureSet. Color values will be selected in a way which attempts to make the ROI colors maximally different. The method uses a predefined list containing 54 colors, which means for the rare case of more than 24 ROIs, some will not be assigned a color. Obviously, the more ROIs to assign colors to, the more similar the color values will be.
297 298 299 300 301 302 303 304 305 306 |
# File 'lib/rtkit/structure_set.rb', line 297 def set_colors if @rois.length > 0 # Determine colors: initialize_colors # Set colors: @rois.each_index do |i| @rois[i].color = @colors[i] if i < 24 end end end |
#set_numbers ⇒ Object
Sets new ROI Numbers to all ROIs belonging to the StructureSet. Numbers increase sequentially, starting at 1 for the first ROI.
311 312 313 314 315 |
# File 'lib/rtkit/structure_set.rb', line 311 def set_numbers @rois.each_with_index do |roi, i| roi.number = i + 1 end end |
#to_dcm ⇒ Object
Dumps the StructureSet instance to a DObject. This overwrites the dcm instance attribute. Returns the DObject instance.
321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/rtkit/structure_set.rb', line 321 def to_dcm # Use the original DICOM object as a starting point (keeping all non-sequence elements): #@dcm[REF_FRAME_OF_REF_SQ].delete_children @dcm[STRUCTURE_SET_ROI_SQ].delete_children @dcm[ROI_CONTOUR_SQ].delete_children @dcm[RT_ROI_OBS_SQ].delete_children # Create DICOM @rois.each do |roi| @dcm[STRUCTURE_SET_ROI_SQ].add_item(roi.ss_item) @dcm[ROI_CONTOUR_SQ].add_item(roi.contour_item) @dcm[RT_ROI_OBS_SQ].add_item(roi.obs_item) end return @dcm end |
#to_structure_set ⇒ Object
Returns self.
338 339 340 |
# File 'lib/rtkit/structure_set.rb', line 338 def to_structure_set self end |
#write(path) ⇒ Object
Writes the StructureSet to a DICOM file given by the specified file string.
344 345 346 347 |
# File 'lib/rtkit/structure_set.rb', line 344 def write(path) to_dcm @dcm.write(path) end |