Class: RTKIT::Plan

Inherits:
Series show all
Defined in:
lib/rtkit/plan.rb

Overview

The Plan class contains methods that are specific for this modality (RTPLAN).

Inheritance

  • Plan inherits all methods and attributes from the Series class.

Instance Attribute Summary collapse

Attributes inherited from Series

#class_uid, #date, #description, #modality, #series_uid, #study, #time

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Series

#image_modality?, #uid

Constructor Details

#initialize(sop_uid, struct, options = {}) ⇒ Plan

Creates a new Plan instance.

Parameters

  • sop_uid – The SOP Instance UID string.

  • struct – The StructureSet that this Plan 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’).

Raises:

  • (ArgumentError)


106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/rtkit/plan.rb', line 106

def initialize(sop_uid, struct, options={})
  raise ArgumentError, "Invalid argument 'sop_uid'. Expected String, got #{sop_uid.class}." unless sop_uid.is_a?(String)
  raise ArgumentError, "Invalid argument 'struct'. Expected StructureSet, got #{struct.class}." unless struct.is_a?(StructureSet)
  # Pass attributes to Series initialization:
  options[:class_uid] = '1.2.840.10008.5.1.4.1.1.481.5' # RT Plan Storage
  # Get a randomized Series UID unless it has been defined in the options hash:
  series_uid = options[:series_uid] || RTKIT.series_uid
  super(series_uid, 'RTPLAN', struct.study, options)
  @sop_uid = sop_uid
  @struct = struct
  # Default attributes:
  @beams = Array.new
  @rt_doses = Array.new
  @rt_images = Array.new
  @associated_rt_doses = Hash.new
  # Register ourselves with the StructureSet:
  @struct.add_plan(self)
end

Instance Attribute Details

#beamsObject (readonly)

An array of radiotherapy beams belonging to this Plan.



12
13
14
# File 'lib/rtkit/plan.rb', line 12

def beams
  @beams
end

#dcmObject (readonly)

The DObject instance of this Plan.



14
15
16
# File 'lib/rtkit/plan.rb', line 14

def dcm
  @dcm
end

#patient_positionObject (readonly)

The patient position.



16
17
18
# File 'lib/rtkit/plan.rb', line 16

def patient_position
  @patient_position
end

#rt_dosesObject (readonly)

An array of RTDose instances associated with this Plan.



18
19
20
# File 'lib/rtkit/plan.rb', line 18

def rt_doses
  @rt_doses
end

#rt_imagesObject (readonly)

An array of RTImage (series) instances associated with this Plan.



20
21
22
# File 'lib/rtkit/plan.rb', line 20

def rt_images
  @rt_images
end

#setupObject (readonly)

The referenced patient Setup instance.



22
23
24
# File 'lib/rtkit/plan.rb', line 22

def setup
  @setup
end

#sop_uidObject (readonly)

The SOP Instance UID.



24
25
26
# File 'lib/rtkit/plan.rb', line 24

def sop_uid
  @sop_uid
end

#structObject (readonly)

The StructureSet that this Plan belongs to.



26
27
28
# File 'lib/rtkit/plan.rb', line 26

def struct
  @struct
end

Class Method Details

.load(dcm, study) ⇒ Object

Creates a new Plan instance by loading the relevant information from the specified DICOM object. The SOP Instance UID string value is used to uniquely identify a Plan instance.

Parameters

  • dcm – An instance of a DICOM object (DICOM::DObject) with modality ‘RTPLAN’.

  • study – The Study instance that this RTPlan belongs to.

Raises:

  • (ArgumentError)


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/rtkit/plan.rb', line 36

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 'RTPLAN', got #{dcm.value(MODALITY)}." unless dcm.value(MODALITY) == 'RTPLAN'
  # 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 StructureSet:
  struct = self.structure_set(dcm, study)
  # Create the Plan instance:
  plan = self.new(sop_uid, struct, :class_uid => class_uid, :date => date, :time => time, :description => description, :series_uid => series_uid)
  plan.add(dcm)
  return plan
end

.structure_set(dcm, study) ⇒ Object

Identifies the StructureSet that the Plan object belongs to. If the referenced instances (StructureSet, ImageSeries & Frame) does not exist, they are created by this method.

Raises:

  • (ArgumentError)


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/rtkit/plan.rb', line 59

def self.structure_set(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 'RTPLAN', got #{dcm.value(MODALITY)}." unless dcm.value(MODALITY) == 'RTPLAN'
  # Extract the Frame of Reference UID:
  begin
    frame_of_ref = dcm.value(FRAME_OF_REF)
  rescue
    frame_of_ref = nil
  end
  # Extract referenced Structure Set SOP Instance UID:
  begin
    ref_struct_uid = dcm[REF_STRUCT_SQ][0].value(REF_SOP_UID)
  rescue
    ref_struct_uid = nil
  end
  # Create the Frame if it doesn't exist:
  f = study.patient.dataset.frame(frame_of_ref)
  f = Frame.new(frame_of_ref, study.patient) unless f
  # Create the StructureSet & ImageSeries if the StructureSet doesn't exist:
  struct = study.fseries(ref_struct_uid)
  unless struct
    # Create ImageSeries (assuming modality CT):
    is = ImageSeries.new(RTKIT.series_uid, 'CT', f, study)
    study.add_series(is)
    # Create StructureSet:
    struct = StructureSet.new(ref_struct_uid, is)
    study.add_series(struct)
  end
  return struct
end

Instance Method Details

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

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



127
128
129
130
131
# File 'lib/rtkit/plan.rb', line 127

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

#add(dcm) ⇒ Object

Registers a DICOM Object to the Plan, and processes it to create (and reference) the fields contained in the object.

Raises:

  • (ArgumentError)


138
139
140
141
142
143
# File 'lib/rtkit/plan.rb', line 138

def add(dcm)
  raise ArgumentError, "Invalid argument 'dcm'. Expected DObject, got #{dcm.class}." unless dcm.is_a?(DICOM::DObject)
  @dcm = dcm
  #load_patient_setup
  load_beams
end

#add_beam(beam) ⇒ Object

Adds a Beam to this Plan. Note: Intended for internal use in the library only.

Raises:

  • (ArgumentError)


148
149
150
151
# File 'lib/rtkit/plan.rb', line 148

def add_beam(beam)
  raise ArgumentError, "Invalid argument 'beam'. Expected Beam, got #{beam.class}." unless beam.is_a?(Beam)
  @beams << beam unless @beams.include?(beam)
end

#add_rt_dose(rt_dose) ⇒ Object

Adds a RTDose series to this Plan. Note: Intended for internal use in the library only.

Raises:

  • (ArgumentError)


156
157
158
159
160
# File 'lib/rtkit/plan.rb', line 156

def add_rt_dose(rt_dose)
  raise ArgumentError, "Invalid argument 'rt_dose'. Expected RTDose, got #{rt_dose.class}." unless rt_dose.is_a?(RTDose)
  @rt_doses << rt_dose unless @associated_rt_doses[rt_dose.uid]
  @associated_rt_doses[rt_dose.uid] = rt_dose
end

#add_rt_image(rt_image) ⇒ Object

Adds a RTImage Series to this Plan. Note: Intended for internal use in the library only.

Raises:

  • (ArgumentError)


165
166
167
168
# File 'lib/rtkit/plan.rb', line 165

def add_rt_image(rt_image)
  raise ArgumentError, "Invalid argument 'rt_image'. Expected RTImage, got #{rt_image.class}." unless rt_image.is_a?(RTImage)
  @rt_images << rt_image unless @rt_images.include?(rt_image)
end

#add_setup(setup) ⇒ Object

Sets the Setup reference for this Plan. Note: Intended for internal use in the library only.

Raises:

  • (ArgumentError)


173
174
175
176
# File 'lib/rtkit/plan.rb', line 173

def add_setup(setup)
  raise ArgumentError, "Invalid argument 'setup'. Expected Setup, got #{setup.class}." unless setup.is_a?(Setup)
  @setup = setup
end

#hashObject

Generates a Fixnum hash value for this instance.



180
181
182
# File 'lib/rtkit/plan.rb', line 180

def hash
  state.hash
end

#rt_dose(*args) ⇒ Object

Returns the RTDose instance mathcing the specified Series Instance UID (if an argument is used). If a specified UID doesn’t match, nil is returned. If no argument is passed, the first RTDose instance associated with the Plan is returned.

Parameters

  • uid – String. The value of the Series Instance UID element.

Raises:

  • (ArgumentError)


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

def rt_dose(*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_rt_doses[args.first]
  else
    # No argument used, therefore we return the first RTDose instance:
    return @rt_doses.first
  end
end

#to_planObject

Returns self.



205
206
207
# File 'lib/rtkit/plan.rb', line 205

def to_plan
  self
end