Class: RTKIT::Slice
- Inherits:
-
Object
- Object
- RTKIT::Slice
- Defined in:
- lib/rtkit/slice.rb
Overview
Contains DICOM data and methods related to an Image Slice, in which a set of contours are defined.
Relations
-
A Slice is characterized by a SOP Instance UID, which relates it to an Image.
-
A ROI has many Slices, as derived from the Structure Set.
-
A Slice has many Contours.
Instance Attribute Summary collapse
-
#contours ⇒ Object
readonly
An array containing the Contours defined for this Slice.
-
#image ⇒ Object
readonly
The Slice’s Image reference.
-
#roi ⇒ Object
readonly
The ROI that the Slice belongs to.
-
#uid ⇒ Object
readonly
The Referenced SOP Instance UID.
Class Method Summary collapse
-
.create_from_items(sop_uid, contour_items, roi) ⇒ Object
Creates a new Slice instance from an array of contour items belonging to a single slice of a particular ROI.
Instance Method Summary collapse
-
#==(other) ⇒ Object
(also: #eql?)
Returns true if the argument is an instance with attributes equal to self.
-
#add_contour(contour) ⇒ Object
Adds a Contour instance to this Slice.
-
#area ⇒ Object
Calculates the area defined by the contours of this slice.
-
#attach_to(series) ⇒ Object
Attaches a Slice to an Image instance belonging to the specified ImageSeries, by setting the Image reference of the Slice to an Image instance which matches the coordinates of the Slice’s Contour(s).
-
#bin_image(source_image = @image) ⇒ Object
Creates a binary segmented image, from the contours defined for this slice, applied to the referenced Image instance.
-
#hash ⇒ Object
Generates a Fixnum hash value for this instance.
-
#initialize(sop_uid, roi) ⇒ Slice
constructor
Creates a new Slice instance.
-
#plane ⇒ Object
Returns the Plane corresponding to this Slice.
-
#pos ⇒ Object
Returns the position of this slice, which in effect is the pos_slice attribute of the referenced image.
-
#to_slice ⇒ Object
Returns self.
Constructor Details
#initialize(sop_uid, roi) ⇒ Slice
Creates a new Slice instance.
Parameters
-
sop_uid
– The SOP Instance UID reference for this slice. -
contour_item
– An array of contour items from the Contour Sequence in ROI Contour Sequence, belonging to the same slice. -
roi
– The ROI instance that this Slice belongs to.
53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/rtkit/slice.rb', line 53 def initialize(sop_uid, roi) raise ArgumentError, "Invalid argument 'sop_uid'. Expected String, got #{sop_uid.class}." unless sop_uid.is_a?(String) raise ArgumentError, "Invalid argument 'roi'. Expected ROI, got #{roi.class}." unless roi.is_a?(ROI) # Key attributes: @contours = Array.new @uid = sop_uid @roi = roi # Set up the Image reference: @image = roi.frame.image(@uid) # Register ourselves with the ROI: @roi.add_slice(self) end |
Instance Attribute Details
#contours ⇒ Object (readonly)
An array containing the Contours defined for this Slice.
14 15 16 |
# File 'lib/rtkit/slice.rb', line 14 def contours @contours end |
#image ⇒ Object (readonly)
The Slice’s Image reference.
16 17 18 |
# File 'lib/rtkit/slice.rb', line 16 def image @image end |
#roi ⇒ Object (readonly)
The ROI that the Slice belongs to.
18 19 20 |
# File 'lib/rtkit/slice.rb', line 18 def roi @roi end |
#uid ⇒ Object (readonly)
The Referenced SOP Instance UID.
20 21 22 |
# File 'lib/rtkit/slice.rb', line 20 def uid @uid end |
Class Method Details
.create_from_items(sop_uid, contour_items, roi) ⇒ Object
Creates a new Slice instance from an array of contour items belonging to a single slice of a particular ROI. This method also creates and connects any child structures as indicated in the items (e.g. Contours). Returns the Slice.
Parameters
-
sop_uid
– The SOP Instance UID reference for this slice. -
contour_item
– An array of contour items from the Contour Sequence in ROI Contour Sequence, belonging to the same slice. -
roi
– The ROI instance that this Slice belongs to.
32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/rtkit/slice.rb', line 32 def self.create_from_items(sop_uid, contour_items, roi) raise ArgumentError, "Invalid argument 'sop_uid'. Expected String, got #{sop_uid.class}." unless sop_uid.is_a?(String) raise ArgumentError, "Invalid argument 'contour_items'. Expected Array, got #{contour_items.class}." unless contour_items.is_a?(Array) raise ArgumentError, "Invalid argument 'roi'. Expected ROI, got #{roi.class}." unless roi.is_a?(ROI) # Create the Slice instance: slice = self.new(sop_uid, roi) # Create the Contours belonging to the ROI in this Slice: contour_items.each do |contour_item| Contour.create_from_item(contour_item, slice) end return slice end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
Returns true if the argument is an instance with attributes equal to self.
68 69 70 71 72 |
# File 'lib/rtkit/slice.rb', line 68 def ==(other) if other.respond_to?(:to_slice) other.send(:state) == state end end |
#add_contour(contour) ⇒ Object
Adds a Contour instance to this Slice.
78 79 80 81 |
# File 'lib/rtkit/slice.rb', line 78 def add_contour(contour) raise ArgumentError, "Invalid argument 'contour'. Expected Contour, got #{contour.class}." unless contour.is_a?(Contour) @contours << contour unless @contours.include?(contour) end |
#area ⇒ Object
Calculates the area defined by the contours of this slice. Returns a float value, in units of millimeters squared.
86 87 88 |
# File 'lib/rtkit/slice.rb', line 86 def area bin_image.area end |
#attach_to(series) ⇒ Object
Attaches a Slice to an Image instance belonging to the specified ImageSeries, by setting the Image reference of the Slice to an Image instance which matches the coordinates of the Slice’s Contour(s). Raises an exception if a suitable match is not found for the Slice.
Notes
This method can be useful when you have multiple segmentations based on the same image series from multiple raters (perhaps as part of a comparison study), and the rater’s software has modified the UIDs of the original image series, so that the references of the returned Structure Set does not match your original image series. This method uses coordinate information to calculate plane equations, which allows it to identify the corresponding image slice even in the case of slice geometry being non-perpendicular with respect to the patient geometry (direction cosine values != [0,1]).
104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/rtkit/slice.rb', line 104 def attach_to(series) raise ArgumentError, "Invalid argument 'series'. Expected ImageSeries, got #{series.class}." unless series.is_a?(Series) # Do not bother to attempt this change if we have an image reference and this image instance already belongs to the series: if @image && !series.image(@image.uid) or !@image # Query the ImageSeries for an Image instance that matches the Plane of this Slice: matched_image = series.match_image(plane) if matched_image @image = matched_image @uid = matched_image.uid else raise "No matching Image was found for this Slice." end end end |
#bin_image(source_image = @image) ⇒ Object
Creates a binary segmented image, from the contours defined for this slice, applied to the referenced Image instance. Returns an BinImage instance, containing a 2d NArray with dimensions: columns*rows
Parameters
-
source_image
– The image on which the binary volume will be applied (defaults to the referenced image, but may be e.g. a dose ‘image’).
126 127 128 129 130 131 132 133 134 135 |
# File 'lib/rtkit/slice.rb', line 126 def bin_image(source_image=@image) raise "Referenced ROI Slice Image is missing from the dataset. Unable to construct image." unless @image bin_img = BinImage.new(NArray.byte(source_image.columns, source_image.rows), source_image) # Delineate and fill for each contour, then create the final image: @contours.each_with_index do |contour, i| x, y, z = contour.coords bin_img.add(source_image.binary_image(x, y, z)) end return bin_img end |
#hash ⇒ Object
Generates a Fixnum hash value for this instance.
139 140 141 |
# File 'lib/rtkit/slice.rb', line 139 def hash state.hash end |
#plane ⇒ Object
Returns the Plane corresponding to this Slice. The plane is calculated from coordinates belonging to this instance, and an error is raised if not enough Coordinates are present (at least 3 required).
147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/rtkit/slice.rb', line 147 def plane # Such a change is only possible if the Slice instance has a Contour with at least three Coordinates: raise "This Slice does not contain a Contour. Plane determination is not possible." if @contours.length == 0 raise "This Slice does not contain a Contour with at least 3 Coordinates. Plane determination is not possible." if @contours.first.coordinates.length < 3 # Get three coordinates from our Contour: contour = @contours.first num_coords = contour.coordinates.length c1 = contour.coordinates.first c2 = contour.coordinates[num_coords / 3] c3 = contour.coordinates[2 * num_coords / 3] return Plane.calculate(c1, c2, c3) end |
#pos ⇒ Object
Returns the position of this slice, which in effect is the pos_slice attribute of the referenced image.
163 164 165 |
# File 'lib/rtkit/slice.rb', line 163 def pos return @image ? @image.pos_slice : nil end |
#to_slice ⇒ Object
Returns self.
169 170 171 |
# File 'lib/rtkit/slice.rb', line 169 def to_slice self end |