Class: RTKIT::BinVolume
Overview
Contains the DICOM data and methods related to a binary volume.
Inheritance
-
As the BinVolume class inherits from the PixelData class, all PixelData methods are available to instances of BinVolume.
Instance Attribute Summary collapse
-
#bin_images ⇒ Object
readonly
An array of BinImage references.
-
#dice ⇒ Object
Dice’s Coeffecient.
-
#narr ⇒ Object
A NArray associated with this BinVolume (NB! This is a cached copy. If you want to ensure to extract an narray which corresponds to the BinVolume’s Images, use the narray method instead..
-
#sensitivity ⇒ Object
A score (fraction) of the segmented volume compared to a master volume, ranging from 0 (worst) to 1 (all true voxels segmented in this volume).
-
#series ⇒ Object
readonly
The BinVolume’s series reference (e.g. ImageSeries or DoseVolume).
-
#source ⇒ Object
readonly
A reference to the source of this BinaryVolume (ROI or Dose instance).
-
#specificity ⇒ Object
A score (fraction) of the segmented volume compared to a master volume, ranging from 0 (worst) to 1 (none of the true remaining voxels are segmented in this volume).
Class Method Summary collapse
-
.from_dose(dose_volume, min = nil, max = nil, image_volume) ⇒ Object
Creates a new BinVolume instance from a DoseVolume.
-
.from_roi(roi, image_volume) ⇒ Object
Creates a new BinVolume instance from a ROI.
-
.from_volume(image_volume) ⇒ Object
Creates a new BinVolume instance from an image series (i.e. ImageSeries or DoseVolume).
Instance Method Summary collapse
-
#==(other) ⇒ Object
(also: #eql?)
Returns true if the argument is an instance with attributes equal to self.
-
#add(bin_image) ⇒ Object
Adds a BinImage instance to the volume.
-
#columns ⇒ Object
Returns the number of columns in the images of the volume.
-
#frames ⇒ Object
Returns the number of frames (slices) in the set of images that makes up this volume.
-
#hash ⇒ Object
Generates a Fixnum hash value for this instance.
-
#initialize(series, options = {}) ⇒ BinVolume
constructor
Creates a new BinVolume instance.
-
#narray(sort_slices = true) ⇒ Object
Returns 3d volume array consisting of the 2d Narray images from the BinImage instances that makes up this volume.
- #reorder_images(order) ⇒ Object
-
#rows ⇒ Object
Returns the number of rows in the images of the volume.
-
#to_bin_volume ⇒ Object
Returns self.
-
#to_roi(struct, options = {}) ⇒ Object
Creates a ROI instance from the segmentation of this BinVolume.
Methods inherited from PixelData
#coordinates_from_indices, #coordinates_to_indices, #draw_lines, #flood_fill, #indices_general_to_specific, #indices_specific_to_general, #print_img
Constructor Details
#initialize(series, options = {}) ⇒ BinVolume
Creates a new BinVolume instance.
Parameters
-
series
– The image series (e.g. ImageSeries or DoseVolume) which forms the reference data of the BinVolume. -
options
– A hash of parameters.
Options
-
:images
– An array of BinImage instances that is assigned to this BinVolume. -
:source
– The object which is the source of the binary (segmented) data (i.e. ROI or Dose/Hounsfield threshold).
136 137 138 139 140 141 142 143 144 |
# File 'lib/rtkit/bin_volume.rb', line 136 def initialize(series, ={}) raise ArgumentError, "Invalid argument 'series'. Expected ImageSeries or DoseVolume, got #{series.class}." unless [ImageSeries, DoseVolume].include?(series.class) raise ArgumentError, "Invalid option 'images'. Expected Array, got #{[:images].class}." if [:images] && [:images].class != Array raise ArgumentError, "Invalid option 'source'. Expected ROI or RTDose, got #{[:source].class}." if [:source] && ![ROI, RTDose].include?([:source].class) raise ArgumentError, "Invalid option 'images'. Expected only BinImage instances in the array, got #{[:images].collect{|i| i.class}.uniq}." if [:images] && [:images].collect{|i| i.class}.uniq.length > 1 @series = series @bin_images = [:images] || Array.new @source = [:source] end |
Instance Attribute Details
#bin_images ⇒ Object (readonly)
An array of BinImage references.
12 13 14 |
# File 'lib/rtkit/bin_volume.rb', line 12 def bin_images @bin_images end |
#dice ⇒ Object
Dice’s Coeffecient.
14 15 16 |
# File 'lib/rtkit/bin_volume.rb', line 14 def dice @dice end |
#narr ⇒ Object
A NArray associated with this BinVolume (NB! This is a cached copy. If you want to ensure to extract an narray which corresponds to the BinVolume’s Images, use the narray method instead.
17 18 19 |
# File 'lib/rtkit/bin_volume.rb', line 17 def narr @narr end |
#sensitivity ⇒ Object
A score (fraction) of the segmented volume compared to a master volume, ranging from 0 (worst) to 1 (all true voxels segmented in this volume).
19 20 21 |
# File 'lib/rtkit/bin_volume.rb', line 19 def sensitivity @sensitivity end |
#series ⇒ Object (readonly)
The BinVolume’s series reference (e.g. ImageSeries or DoseVolume).
21 22 23 |
# File 'lib/rtkit/bin_volume.rb', line 21 def series @series end |
#source ⇒ Object (readonly)
A reference to the source of this BinaryVolume (ROI or Dose instance).
23 24 25 |
# File 'lib/rtkit/bin_volume.rb', line 23 def source @source end |
#specificity ⇒ Object
A score (fraction) of the segmented volume compared to a master volume, ranging from 0 (worst) to 1 (none of the true remaining voxels are segmented in this volume).
25 26 27 |
# File 'lib/rtkit/bin_volume.rb', line 25 def specificity @specificity end |
Class Method Details
.from_dose(dose_volume, min = nil, max = nil, image_volume) ⇒ Object
Creates a new BinVolume instance from a DoseVolume. The BinVolume is typically defined from a ROI delineation against an image series, but it may also be applied to an rtdose ‘image’ series. Returns the BinVolume instance.
Notes
-
Even though listed as optional parameters, at least one of the min and max options must be specified in order to construct a valid binary volume.
Parameters
-
image_volume
– The image volume which the binary volume will be based on (a DoseVolume or an ImageSeries). -
min
– Float. An optional lower dose limit from which to define the the binary volume. -
max
– Float. An optional upper dose limit from which to define the the binary volume.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/rtkit/bin_volume.rb', line 43 def self.from_dose(dose_volume, min=nil, max=nil, image_volume) raise ArgumentError, "Invalid argument 'dose_volume'. Expected DoseVolume, got #{dose_volume.class}." unless dose_volume.class == DoseVolume raise ArgumentError, "Invalid argument 'image_volume'. Expected ImageSeries or DoseVolume, got #{image_volume.class}." unless [ImageSeries, DoseVolume].include?(image_volume.class) raise ArgumentError "Need at least one dose limit parameter. Neither min nor max was specified." unless min or max # Create the BinVolume instance: bv = self.new(dose_volume) # FIXME: Specify dose limit somehow here?! # Add BinImages for each of the DoseVolume's images: dose_narr = dose_volume.dose_arr dose_volume.images.each_index do |i| #ref_image = image_volume.image(dose_img.pos_slice) ref_image = image_volume.images[i] dose_image = dose_narr[i, true, true] # Create the bin narray: narr = NArray.byte(ref_image.columns, ref_image.rows) if !min # Only the max limit is specified: marked_indices = (dose_image.le max.to_f) elsif !max # Only the min limit is specified: marked_indices = (dose_image.ge min.to_f) else # Both min and max limits are specified: smaller = (dose_image.le max.to_f) bigger = (dose_image.ge min.to_f) marked_indices = smaller.and bigger end narr[marked_indices] = 1 bin_img = BinImage.new(narr, ref_image) bv.add(bin_img) end return bv end |
.from_roi(roi, image_volume) ⇒ Object
Creates a new BinVolume instance from a ROI. The BinVolume is typically defined from a ROI delineation against an image series, but it may also be applied to an rtdose ‘image’ series. Returns the BinVolume instance.
Parameters
-
roi
– A ROI from which to define the binary volume. -
image_volume
– The image volume which the binary volume will be based on (an ImageSeries or a DoseVolume).
86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/rtkit/bin_volume.rb', line 86 def self.from_roi(roi, image_volume) raise ArgumentError, "Invalid argument 'roi'. Expected ROI, got #{roi.class}." unless roi.is_a?(ROI) raise ArgumentError, "Invalid argument 'image_volume'. Expected ImageSeries or DoseVolume, got #{image_volume.class}." unless [ImageSeries, DoseVolume].include?(image_volume.class) # Create the BinVolume instance: bv = self.new(roi.image_series, :source => roi) # Add BinImages for each of the ROIs slices: roi.slices.each do |slice| image = image_volume.image(slice.pos) BinImage.from_contours(slice.contours, image, bv) #bv.add(slice.bin_image) end return bv end |
.from_volume(image_volume) ⇒ Object
Creates a new BinVolume instance from an image series (i.e. ImageSeries or DoseVolume). A BinVolume created this way specified the entire volume: i.e. the Binvolume has the same dimensions as the image series, and all pixels are 1. Returns the BinVolume instance.
Parameters
-
image_volume
– The image volume which the binary volume will be based on (an ImageSeries or a DoseVolume).
109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/rtkit/bin_volume.rb', line 109 def self.from_volume(image_volume) raise ArgumentError, "Invalid argument 'image_volume'. Expected ImageSeries or DoseVolume, got #{image_volume.class}." unless [ImageSeries, DoseVolume].include?(image_volume.class) # Create the BinVolume instance: bv = self.new(image_volume) # Add BinImages for each of the ROIs slices: image_volume.images.each do |image| # Make an NArray of proper size filled with ones: narr = NArray.byte(image.columns, image.rows).fill(1) # Create the BinImage instance and add it to the BinVolume: bin_img = BinImage.new(narr, image) bv.add(bin_img) end return bv end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
Returns true if the argument is an instance with attributes equal to self.
148 149 150 151 152 |
# File 'lib/rtkit/bin_volume.rb', line 148 def ==(other) if other.respond_to?(:to_bin_volume) other.send(:state) == state end end |
#add(bin_image) ⇒ Object
Adds a BinImage instance to the volume.
158 159 160 161 |
# File 'lib/rtkit/bin_volume.rb', line 158 def add(bin_image) raise ArgumentError, "Invalid argument 'bin_image'. Expected BinImage, got #{bin_image.class}." unless bin_image.is_a?(BinImage) @bin_images << bin_image end |
#columns ⇒ Object
Returns the number of columns in the images of the volume.
165 166 167 |
# File 'lib/rtkit/bin_volume.rb', line 165 def columns return @bin_images.first.columns if @bin_images.first end |
#frames ⇒ Object
Returns the number of frames (slices) in the set of images that makes up this volume.
171 172 173 |
# File 'lib/rtkit/bin_volume.rb', line 171 def frames return @bin_images.length end |
#hash ⇒ Object
Generates a Fixnum hash value for this instance.
177 178 179 |
# File 'lib/rtkit/bin_volume.rb', line 177 def hash state.hash end |
#narray(sort_slices = true) ⇒ Object
Returns 3d volume array consisting of the 2d Narray images from the BinImage instances that makes up this volume. Returns nil if no BinImage instances are connected to this BinVolume.
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/rtkit/bin_volume.rb', line 184 def narray(sort_slices=true) if @bin_images.length > 0 # Determine the slice position of each BinImage: locations = Array.new if sort_slices @bin_images.collect {|image| locations << image.pos_slice} images = @bin_images.sort_by_order(locations.sort_order) else images = @bin_images end # Create volume array and fill in the images: volume = NArray.byte(frames, columns, rows) images.each_with_index do |sorted_image, i| volume[i, true, true] = sorted_image.narray end @narr = volume end end |
#reorder_images(order) ⇒ Object
203 204 205 |
# File 'lib/rtkit/bin_volume.rb', line 203 def reorder_images(order) @bin_images = @bin_images.sort_by_order(order) end |
#rows ⇒ Object
Returns the number of rows in the images of the volume.
209 210 211 |
# File 'lib/rtkit/bin_volume.rb', line 209 def rows return @bin_images.first.rows if @bin_images.first end |
#to_bin_volume ⇒ Object
Returns self.
215 216 217 |
# File 'lib/rtkit/bin_volume.rb', line 215 def to_bin_volume self end |
#to_roi(struct, options = {}) ⇒ Object
Creates a ROI instance from the segmentation of this BinVolume. Returns the ROI instance.
Parameters
-
struct
– A StructureSet instance which the ROI will be connected to. -
options
– A hash of parameters.
Options
-
:algorithm
– String. The ROI Generation Algorithm. Defaults to ‘Automatic’. -
:name
– String. The ROI Name. Defaults to ‘BinVolume’. -
: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’.
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/rtkit/bin_volume.rb', line 235 def to_roi(struct, ={}) raise ArgumentError, "Invalid argument 'struct'. Expected StructureSet, got #{struct.class}." unless struct.is_a?(StructureSet) # Set values: algorithm = [:algorithm] name = [:name] || 'BinVolume' number = [:number] interpreter = [:interpreter] type = [:type] # Create the ROI: roi = struct.create_roi(@series.frame, :algorithm => algorithm, :name => name, :number => number, :interpreter => interpreter, :type => type) # Create Slices: @bin_images.each do |bin_image| bin_image.to_slice(roi) end return roi end |