Class: RTKIT::Beam

Inherits:
Object
  • Object
show all
Defined in:
lib/rtkit/beam.rb

Overview

Contains DICOM data and methods related to a Beam, defined in a Plan.

Relations

  • A Plan has many Beams.

  • A Beam has many ControlPoints.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, number, machine, meterset, plan, options = {}) ⇒ Beam

Creates a new Beam instance.

Parameters

  • name – String. The Beam name.

  • number – Integer. The Beam number.

  • machine – The name of the treatment machine.

  • meterset – The Beam’s meterset (e.g. monitor units) value.

  • plan – The Plan instance that this Beam belongs to.

  • options – A hash of parameters.

Options

  • :type – String. Beam type. Defaults to ‘STATIC’.

  • :delivery_type – String. Treatment delivery type. Defaults to ‘TREATMENT’.

  • :description – String. Beam description. Defaults to the ‘name’ attribute.

  • :rad_type – String. Radiation type. Defaults to ‘PHOTON’.

  • :sad – Float. Source-axis distance. Defaults to 1000.0.

  • :unit – String. The primary dosimeter unit. Defaults to ‘MU’.

Raises:

  • (ArgumentError)


98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/rtkit/beam.rb', line 98

def initialize(name, number, machine, meterset, plan, options={})
  raise ArgumentError, "Invalid argument 'plan'. Expected Plan, got #{plan.class}." unless plan.is_a?(Plan)
  @control_points = Array.new
  @collimators = Array.new
  @associated_control_points = Hash.new
  @associated_collimators = Hash.new
  # Set values:
  self.name = name
  self.number = number
  self.machine = machine
  self.meterset = meterset
  # Set options/defaults:
  self.type = options[:type] || 'STATIC'
  self.delivery_type = options[:delivery_type] || 'TREATMENT'
  self.description = options[:description] || @name
  self.rad_type = options[:rad_type] || 'PHOTON'
  self.sad = options[:sad] ? options[:sad] : 1000.0
  self.unit = options[:unit] || 'MU'
  # Set references:
  @plan = plan
  # Register ourselves with the Plan:
  @plan.add_beam(self)
end

Instance Attribute Details

#control_pointsObject (readonly)

An array containing the beam’s ControlPoints.



13
14
15
# File 'lib/rtkit/beam.rb', line 13

def control_points
  @control_points
end

#delivery_typeObject

Treatment delivery type.



15
16
17
# File 'lib/rtkit/beam.rb', line 15

def delivery_type
  @delivery_type
end

#descriptionObject

Beam description.



17
18
19
# File 'lib/rtkit/beam.rb', line 17

def description
  @description
end

#machineObject

Treatment machine name.



19
20
21
# File 'lib/rtkit/beam.rb', line 19

def machine
  @machine
end

#metersetObject

Beam meterset.



21
22
23
# File 'lib/rtkit/beam.rb', line 21

def meterset
  @meterset
end

#nameObject

Beam Name.



23
24
25
# File 'lib/rtkit/beam.rb', line 23

def name
  @name
end

#numberObject

Beam Number (Integer).



25
26
27
# File 'lib/rtkit/beam.rb', line 25

def number
  @number
end

#planObject (readonly)

The Plan that the Beam is defined in.



27
28
29
# File 'lib/rtkit/beam.rb', line 27

def plan
  @plan
end

#rad_typeObject

Radiation type.



29
30
31
# File 'lib/rtkit/beam.rb', line 29

def rad_type
  @rad_type
end

#sadObject

Source-axis distance.



31
32
33
# File 'lib/rtkit/beam.rb', line 31

def sad
  @sad
end

#typeObject

Beam type.



33
34
35
# File 'lib/rtkit/beam.rb', line 33

def type
  @type
end

#unitObject

Primary dosimeter unit.



35
36
37
# File 'lib/rtkit/beam.rb', line 35

def unit
  @unit
end

Class Method Details

.create_from_item(beam_item, meterset, plan) ⇒ Object

Creates a new beam instance from the beam item of the RTPlan file which contains the information related to a particular beam. This method also creates and connects any child structures as indicated in the items (e.g. ControlPoints). Returns the Beam instance.

Parameters

  • beam_item – The Beam’s Item from the Beam Sequence in the DObject of a RTPlan file.

  • meterset – The Beam’s meterset (e.g. monitor units) value.

  • plan – The Plan instance that this Beam belongs to.

Raises:

  • (ArgumentError)


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
75
76
# File 'lib/rtkit/beam.rb', line 48

def self.create_from_item(beam_item, meterset, plan)
  raise ArgumentError, "Invalid argument 'beam_item'. Expected DICOM::Item, got #{beam_item.class}." unless beam_item.is_a?(DICOM::Item)
  raise ArgumentError, "Invalid argument 'meterset'. Expected Float, got #{meterset.class}." unless meterset.is_a?(Float)
  raise ArgumentError, "Invalid argument 'plan'. Expected Plan, got #{plan.class}." unless plan.is_a?(Plan)
  options = Hash.new
  # Values from the Structure Set ROI Sequence Item:
  name = beam_item.value(BEAM_NAME) || ''
  number = beam_item.value(BEAM_NUMBER).to_i
  machine = beam_item.value(MACHINE_NAME) || ''
  options[:type] = beam_item.value(BEAM_TYPE)
  options[:delivery_type] = beam_item.value(DELIVERY_TYPE)
  options[:description] = beam_item.value(BEAM_DESCR)
  options[:rad_type] = beam_item.value(RAD_TYPE)
  options[:sad] = beam_item.value(SAD).to_f
  options[:unit] = beam_item.value(DOSIMETER_UNIT)
  # Create the Beam instance:
  beam = self.new(name, number, machine, meterset, plan, options)
  # Iterate the RT Beam Limiting Device items and create Collimator instances:
  if beam_item.exists?(COLL_SQ)
    beam_item[COLL_SQ].each do |coll_item|
      Collimator.create_from_item(coll_item, beam)
    end
  end
  # Iterate the control point items and create ControlPoint instances:
  beam_item[CONTROL_POINT_SQ].each do |cp_item|
    ControlPoint.create_from_item(cp_item, beam)
  end
  return beam
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?

Returns true if the argument is an instance with attributes equal to self.



124
125
126
127
128
# File 'lib/rtkit/beam.rb', line 124

def ==(other)
  if other.respond_to?(:to_beam)
    other.send(:state) == state
  end
end

#add_collimator(coll) ⇒ Object

Adds a Collimator instance to this Beam.

Raises:

  • (ArgumentError)


134
135
136
137
138
# File 'lib/rtkit/beam.rb', line 134

def add_collimator(coll)
  raise ArgumentError, "Invalid argument 'coll'. Expected Collimator, got #{coll.class}." unless coll.is_a?(Collimator)
  @collimators << coll unless @associated_collimators[coll.type]
  @associated_collimators[coll.type] = coll
end

#add_control_point(cp) ⇒ Object

Adds a ControlPoint instance to this Beam.

Raises:

  • (ArgumentError)


142
143
144
145
146
# File 'lib/rtkit/beam.rb', line 142

def add_control_point(cp)
  raise ArgumentError, "Invalid argument 'cp'. Expected ControlPoint, got #{cp.class}." unless cp.is_a?(ControlPoint)
  @control_points << cp unless @associated_control_points[cp]
  @associated_control_points[cp] = true
end

#beam_itemObject

Creates and returns a Beam Sequence Item from the attributes of the Beam.



150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/rtkit/beam.rb', line 150

def beam_item
  item = DICOM::Item.new
  item.add(DICOM::Element.new(ROI_COLOR, @color))
  s = DICOM::Sequence.new(CONTOUR_SQ)
  item.add(s)
  item.add(DICOM::Element.new(REF_ROI_NUMBER, @number.to_s))
  # Add Contour items to the Contour Sequence (one or several items per Slice):
  @slices.each do |slice|
    slice.contours.each do |contour|
      s.add_item(contour.to_item)
    end
  end
  return item
end

#collimator(*args) ⇒ Object

Returns the Collimator instance mathcing the specified type (if an argument is used). If a specified type doesn’t match, nil is returned. If no argument is passed, the first Collimator instance associated with the Beam is returned.

Parameters

  • type – Integer. The Collimator’s type.

Raises:

  • (ArgumentError)


173
174
175
176
177
178
179
180
181
# File 'lib/rtkit/beam.rb', line 173

def collimator(*args)
  raise ArgumentError, "Expected one or none arguments, got #{args.length}." unless [0, 1].include?(args.length)
  if args.length == 1
    return @associated_collimators[args.first && args.first.to_s]
  else
    # No argument used, therefore we return the first instance:
    return @collimators.first
  end
end

#control_point(*args) ⇒ Object

Returns the ControlPoint instance mathcing the specified index (if an argument is used). If a specified index doesn’t match, nil is returned. If no argument is passed, the first ControlPoint instance associated with the Beam is returned.

Parameters

  • index – Integer. The ControlPoint’s index.

Raises:

  • (ArgumentError)


191
192
193
194
195
196
197
198
199
200
# File 'lib/rtkit/beam.rb', line 191

def control_point(*args)
  raise ArgumentError, "Expected one or none arguments, got #{args.length}." unless [0, 1].include?(args.length)
  if args.length == 1
    raise ArgumentError, "Invalid argument 'index'. Expected Integer (or nil), got #{args.first.class}." unless [Integer, NilClass].include?(args.first.class)
    return @associated_control_points[args.first]
  else
    # No argument used, therefore we return the first instance:
    return @control_points.first
  end
end

#hashObject

Generates a Fixnum hash value for this instance.



226
227
228
# File 'lib/rtkit/beam.rb', line 226

def hash
  state.hash
end

#ref_beam_itemObject

Creates and returns a Referenced Beam Sequence Item from the attributes of the Beam.



287
288
289
290
291
292
293
294
# File 'lib/rtkit/beam.rb', line 287

def ref_beam_item
  item = DICOM::Item.new
  item.add(DICOM::Element.new(OBS_NUMBER, @number.to_s))
  item.add(DICOM::Element.new(REF_ROI_NUMBER, @number.to_s))
  item.add(DICOM::Element.new(ROI_TYPE, @type))
  item.add(DICOM::Element.new(ROI_INTERPRETER, @interpreter))
  return item
end

#to_beamObject

Returns self.



309
310
311
# File 'lib/rtkit/beam.rb', line 309

def to_beam
  self
end