rtp-connect 1.6 → 1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/{CHANGELOG.rdoc → CHANGELOG.md} +29 -14
- data/Gemfile.lock +27 -21
- data/{README.rdoc → README.md} +62 -50
- data/lib/rtp-connect.rb +1 -0
- data/lib/rtp-connect/constants.rb +1 -0
- data/lib/rtp-connect/control_point.rb +142 -100
- data/lib/rtp-connect/dose_tracking.rb +31 -36
- data/lib/rtp-connect/extended_field.rb +15 -51
- data/lib/rtp-connect/extended_plan.rb +133 -0
- data/lib/rtp-connect/field.rb +101 -128
- data/lib/rtp-connect/methods.rb +31 -16
- data/lib/rtp-connect/plan.rb +80 -98
- data/lib/rtp-connect/plan_to_dcm.rb +68 -106
- data/lib/rtp-connect/prescription.rb +18 -56
- data/lib/rtp-connect/record.rb +62 -1
- data/lib/rtp-connect/ruby_extensions.rb +34 -3
- data/lib/rtp-connect/simulation_field.rb +58 -136
- data/lib/rtp-connect/site_setup.rb +51 -62
- data/lib/rtp-connect/version.rb +1 -1
- data/rakefile.rb +0 -1
- data/rtp-connect.gemspec +7 -7
- metadata +51 -41
@@ -29,23 +29,8 @@ module RTP
|
|
29
29
|
# @raise [ArgumentError] if given a string containing an invalid number of elements
|
30
30
|
#
|
31
31
|
def self.load(string, parent)
|
32
|
-
# Get the quote-less values:
|
33
|
-
values = string.to_s.values
|
34
|
-
low_limit = 24
|
35
|
-
high_limit = 26
|
36
|
-
raise ArgumentError, "Invalid argument 'string': Expected at least #{low_limit} elements, got #{values.length}." if values.length < low_limit
|
37
|
-
RTP.logger.warn "The number of elements (#{values.length}) for this DoseTracking record exceeds the known number of data items for this record (#{high_limit}). This may indicate an invalid record or that the RTP format has recently been expanded with new items." if values.length > high_limit
|
38
32
|
d = self.new(parent)
|
39
|
-
|
40
|
-
d.keyword = values[0]
|
41
|
-
d.region_name = values[1]
|
42
|
-
d.region_prior_dose = values[2]
|
43
|
-
d.field_ids = values.values_at(3, 5, 7, 9, 11, 13, 15, 17, 19, 21)
|
44
|
-
d.region_coeffs = values.values_at(4, 6, 8, 10, 12, 14, 16, 18, 20, 22)
|
45
|
-
d.actual_dose = values[23]
|
46
|
-
d.actual_fractions = values[24]
|
47
|
-
d.crc = values[-1]
|
48
|
-
return d
|
33
|
+
d.load(string)
|
49
34
|
end
|
50
35
|
|
51
36
|
# Creates a new DoseTracking.
|
@@ -53,14 +38,25 @@ module RTP
|
|
53
38
|
# @param [Record] parent a record which is used to determine the proper parent of this instance
|
54
39
|
#
|
55
40
|
def initialize(parent)
|
41
|
+
super('DOSE_DEF', 24, 26)
|
56
42
|
# Child records:
|
57
43
|
@dose_actions = Array.new
|
58
44
|
# Parent relation (may get more than one type of record here):
|
59
45
|
@parent = get_parent(parent.to_record, Plan)
|
60
46
|
@parent.add_dose_tracking(self)
|
61
|
-
@keyword = 'DOSE_DEF'
|
62
47
|
@field_ids = Array.new(10)
|
63
48
|
@region_coeffs = Array.new(10)
|
49
|
+
@attributes = [
|
50
|
+
# Required:
|
51
|
+
:keyword,
|
52
|
+
:region_name,
|
53
|
+
:region_prior_dose,
|
54
|
+
:field_ids,
|
55
|
+
:region_coeffs,
|
56
|
+
# Optional:
|
57
|
+
:actual_dose,
|
58
|
+
:actual_fractions
|
59
|
+
]
|
64
60
|
end
|
65
61
|
|
66
62
|
# Checks for equality.
|
@@ -105,7 +101,7 @@ module RTP
|
|
105
101
|
# @return [Array<String>] an array of attributes (in the same order as they appear in the RTP string)
|
106
102
|
#
|
107
103
|
def values
|
108
|
-
|
104
|
+
[
|
109
105
|
@keyword,
|
110
106
|
@region_name,
|
111
107
|
@region_prior_dose,
|
@@ -148,9 +144,7 @@ module RTP
|
|
148
144
|
# @param [Array<nil, #to_s>] array the new attribute values
|
149
145
|
#
|
150
146
|
def field_ids=(array)
|
151
|
-
|
152
|
-
raise ArgumentError, "Invalid argument 'array'. Expected length 10, got #{array.length}." unless array.length == 10
|
153
|
-
@field_ids = array.collect! {|e| e && e.to_s}
|
147
|
+
@field_ids = array.to_a.validate_and_process(10)
|
154
148
|
end
|
155
149
|
|
156
150
|
# Sets the region_coeffs attribute.
|
@@ -160,21 +154,7 @@ module RTP
|
|
160
154
|
# @param [Array<nil, #to_s>] array the new attribute values
|
161
155
|
#
|
162
156
|
def region_coeffs=(array)
|
163
|
-
|
164
|
-
raise ArgumentError, "Invalid argument 'array'. Expected length 10, got #{array.length}." unless array.length == 10
|
165
|
-
@region_coeffs = array.collect! {|e| e && e.to_s}
|
166
|
-
end
|
167
|
-
|
168
|
-
# Sets the keyword attribute.
|
169
|
-
#
|
170
|
-
# @note Since only a specific string is accepted, this is more of an argument check than a traditional setter method
|
171
|
-
# @param [#to_s] value the new attribute value
|
172
|
-
# @raise [ArgumentError] if given an unexpected keyword
|
173
|
-
#
|
174
|
-
def keyword=(value)
|
175
|
-
value = value.to_s.upcase
|
176
|
-
raise ArgumentError, "Invalid keyword. Expected 'DOSE_DEF', got #{value}." unless value == "DOSE_DEF"
|
177
|
-
@keyword = value
|
157
|
+
@region_coeffs = array.to_a.validate_and_process(10)
|
178
158
|
end
|
179
159
|
|
180
160
|
# Sets the region_name attribute.
|
@@ -220,6 +200,21 @@ module RTP
|
|
220
200
|
#
|
221
201
|
alias_method :state, :values
|
222
202
|
|
203
|
+
# Sets the attributes of the record instance.
|
204
|
+
#
|
205
|
+
# @param [Array<String>] values the record attributes (as parsed from a record string)
|
206
|
+
#
|
207
|
+
def set_attributes(values)
|
208
|
+
self.keyword = values[0]
|
209
|
+
@region_name = values[1]
|
210
|
+
@region_prior_dose = values[2]
|
211
|
+
@field_ids = values.values_at(3, 5, 7, 9, 11, 13, 15, 17, 19, 21)
|
212
|
+
@region_coeffs = values.values_at(4, 6, 8, 10, 12, 14, 16, 18, 20, 22)
|
213
|
+
@actual_dose = values[23]
|
214
|
+
@actual_fractions = values[24]
|
215
|
+
@crc = values[-1]
|
216
|
+
end
|
217
|
+
|
223
218
|
end
|
224
219
|
|
225
220
|
end
|
@@ -27,26 +27,8 @@ module RTP
|
|
27
27
|
# @raise [ArgumentError] if given a string containing an invalid number of elements
|
28
28
|
#
|
29
29
|
def self.load(string, parent)
|
30
|
-
# Get the quote-less values:
|
31
|
-
values = string.to_s.values
|
32
|
-
low_limit = 4
|
33
|
-
high_limit = 10
|
34
|
-
raise ArgumentError, "Invalid argument 'string': Expected at least #{low_limit} elements, got #{values.length}." if values.length < low_limit
|
35
|
-
RTP.logger.warn "The number of elements (#{values.length}) for this ExtendedField record exceeds the known number of data items for this record (#{high_limit}). This may indicate an invalid record or that the RTP format has recently been expanded with new items." if values.length > high_limit
|
36
30
|
ef = self.new(parent)
|
37
|
-
|
38
|
-
ef.keyword = values[0]
|
39
|
-
ef.field_id = values[1]
|
40
|
-
ef.original_plan_uid = values[2]
|
41
|
-
# Optional attributes:
|
42
|
-
ef.original_beam_number = values[3]
|
43
|
-
ef.original_beam_name = values[4]
|
44
|
-
ef.is_fff = values[5] if values[5]
|
45
|
-
ef.accessory_code = values[6]
|
46
|
-
ef.accessory_type = values[7]
|
47
|
-
ef.high_dose_authorization = values[8]
|
48
|
-
ef.crc = values[-1]
|
49
|
-
return ef
|
31
|
+
ef.load(string)
|
50
32
|
end
|
51
33
|
|
52
34
|
# Creates a new (treatment) ExtendedField.
|
@@ -54,10 +36,23 @@ module RTP
|
|
54
36
|
# @param [Record] parent a record which is used to determine the proper parent of this instance
|
55
37
|
#
|
56
38
|
def initialize(parent)
|
39
|
+
super('EXTENDED_FIELD_DEF', 4, 10)
|
57
40
|
# Parent relation (may get more than one type of record here):
|
58
41
|
@parent = get_parent(parent.to_record, Field)
|
59
42
|
@parent.add_extended_field(self)
|
60
|
-
@
|
43
|
+
@attributes = [
|
44
|
+
# Required:
|
45
|
+
:keyword,
|
46
|
+
:field_id,
|
47
|
+
:original_plan_uid,
|
48
|
+
# Optional:
|
49
|
+
:original_beam_number,
|
50
|
+
:original_beam_name,
|
51
|
+
:is_fff,
|
52
|
+
:accessory_code,
|
53
|
+
:accessory_type,
|
54
|
+
:high_dose_authorization
|
55
|
+
]
|
61
56
|
end
|
62
57
|
|
63
58
|
# Checks for equality.
|
@@ -94,25 +89,6 @@ module RTP
|
|
94
89
|
state.hash
|
95
90
|
end
|
96
91
|
|
97
|
-
# Collects the values (attributes) of this instance.
|
98
|
-
#
|
99
|
-
# @note The CRC is not considered part of the actual values and is excluded.
|
100
|
-
# @return [Array<String>] an array of attributes (in the same order as they appear in the RTP string)
|
101
|
-
#
|
102
|
-
def values
|
103
|
-
return [
|
104
|
-
@keyword,
|
105
|
-
@field_id,
|
106
|
-
@original_plan_uid,
|
107
|
-
@original_beam_number,
|
108
|
-
@original_beam_name,
|
109
|
-
@is_fff,
|
110
|
-
@accessory_code,
|
111
|
-
@accessory_type,
|
112
|
-
@high_dose_authorization
|
113
|
-
]
|
114
|
-
end
|
115
|
-
|
116
92
|
# Returns self.
|
117
93
|
#
|
118
94
|
# @return [ExtendedField] self
|
@@ -138,18 +114,6 @@ module RTP
|
|
138
114
|
|
139
115
|
alias :to_str :to_s
|
140
116
|
|
141
|
-
# Sets the keyword attribute.
|
142
|
-
#
|
143
|
-
# @note Since only a specific string is accepted, this is more of an argument check than a traditional setter method
|
144
|
-
# @param [#to_s] value the new attribute value
|
145
|
-
# @raise [ArgumentError] if given an unexpected keyword
|
146
|
-
#
|
147
|
-
def keyword=(value)
|
148
|
-
value = value.to_s.upcase
|
149
|
-
raise ArgumentError, "Invalid keyword. Expected 'EXTENDED_FIELD_DEF', got #{value}." unless value == "EXTENDED_FIELD_DEF"
|
150
|
-
@keyword = value
|
151
|
-
end
|
152
|
-
|
153
117
|
# Sets the field_id attribute.
|
154
118
|
#
|
155
119
|
# @param [nil, #to_s] value the new attribute value
|
@@ -0,0 +1,133 @@
|
|
1
|
+
module RTP
|
2
|
+
|
3
|
+
# The Extended plan class.
|
4
|
+
#
|
5
|
+
# @note Relations:
|
6
|
+
# * Parent: Plan
|
7
|
+
# * Children: none
|
8
|
+
#
|
9
|
+
class ExtendedPlan < Record
|
10
|
+
|
11
|
+
# The Record which this instance belongs to.
|
12
|
+
attr_reader :parent
|
13
|
+
attr_reader :encoding
|
14
|
+
attr_reader :fullname
|
15
|
+
|
16
|
+
# Creates a new ExtendedPlan by parsing a RTPConnect string line.
|
17
|
+
#
|
18
|
+
# @param [#to_s] string the extended plan definition record string line
|
19
|
+
# @param [Record] parent a record which is used to determine the proper parent of this instance
|
20
|
+
# @return [ExtendedPlan] the created ExtendedPlan instance
|
21
|
+
# @raise [ArgumentError] if given a string containing an invalid number of elements
|
22
|
+
#
|
23
|
+
def self.load(string, parent)
|
24
|
+
ep = self.new(parent)
|
25
|
+
ep.load(string)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Creates a new ExtendedPlan.
|
29
|
+
#
|
30
|
+
# @param [Record] parent a record which is used to determine the proper parent of this instance
|
31
|
+
#
|
32
|
+
def initialize(parent)
|
33
|
+
super('EXTENDED_PLAN_DEF', 4, 4)
|
34
|
+
# Parent relation (may get more than one type of record here):
|
35
|
+
@parent = get_parent(parent.to_record, Plan)
|
36
|
+
@parent.add_extended_plan(self)
|
37
|
+
@attributes = [
|
38
|
+
# Required:
|
39
|
+
:keyword,
|
40
|
+
:encoding,
|
41
|
+
:fullname
|
42
|
+
]
|
43
|
+
end
|
44
|
+
|
45
|
+
# Checks for equality.
|
46
|
+
#
|
47
|
+
# Other and self are considered equivalent if they are
|
48
|
+
# of compatible types and their attributes are equivalent.
|
49
|
+
#
|
50
|
+
# @param other an object to be compared with self.
|
51
|
+
# @return [Boolean] true if self and other are considered equivalent
|
52
|
+
#
|
53
|
+
def ==(other)
|
54
|
+
if other.respond_to?(:to_extended_plan)
|
55
|
+
other.send(:state) == state
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
alias_method :eql?, :==
|
60
|
+
|
61
|
+
# Gives an empty array, as these instances are child-less by definition.
|
62
|
+
#
|
63
|
+
# @return [Array] an emtpy array
|
64
|
+
#
|
65
|
+
def children
|
66
|
+
return Array.new
|
67
|
+
end
|
68
|
+
|
69
|
+
# Computes a hash code for this object.
|
70
|
+
#
|
71
|
+
# @note Two objects with the same attributes will have the same hash code.
|
72
|
+
#
|
73
|
+
# @return [Fixnum] the object's hash code
|
74
|
+
#
|
75
|
+
def hash
|
76
|
+
state.hash
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns self.
|
80
|
+
#
|
81
|
+
# @return [ExtendedPlan] self
|
82
|
+
#
|
83
|
+
def to_extended_plan
|
84
|
+
self
|
85
|
+
end
|
86
|
+
|
87
|
+
# Encodes the ExtendedPlan object + any hiearchy of child objects,
|
88
|
+
# to a properly formatted RTPConnect ascii string.
|
89
|
+
#
|
90
|
+
# @return [String] an RTP string with a single or multiple lines/records
|
91
|
+
#
|
92
|
+
def to_s
|
93
|
+
str = encode
|
94
|
+
if children
|
95
|
+
children.each do |child|
|
96
|
+
str += child.to_s
|
97
|
+
end
|
98
|
+
end
|
99
|
+
return str
|
100
|
+
end
|
101
|
+
|
102
|
+
alias :to_str :to_s
|
103
|
+
|
104
|
+
# Sets the encoding attribute.
|
105
|
+
#
|
106
|
+
# @param [nil, #to_s] value the new attribute value
|
107
|
+
#
|
108
|
+
def encoding=(value)
|
109
|
+
@encoding = value && value.to_s
|
110
|
+
end
|
111
|
+
|
112
|
+
# Sets the fullname attribute.
|
113
|
+
#
|
114
|
+
# @param [nil, #to_s] value the new attribute value
|
115
|
+
#
|
116
|
+
def fullname=(value)
|
117
|
+
@fullname = value && value.to_s
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
|
124
|
+
# Collects the attributes of this instance.
|
125
|
+
#
|
126
|
+
# @note The CRC is not considered part of the attributes of interest and is excluded
|
127
|
+
# @return [Array<String>] an array of attributes
|
128
|
+
#
|
129
|
+
alias_method :state, :values
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
data/lib/rtp-connect/field.rb
CHANGED
@@ -70,64 +70,8 @@ module RTP
|
|
70
70
|
# @raise [ArgumentError] if given a string containing an invalid number of elements
|
71
71
|
#
|
72
72
|
def self.load(string, parent)
|
73
|
-
# Get the quote-less values:
|
74
|
-
values = string.to_s.values
|
75
|
-
low_limit = 27
|
76
|
-
high_limit = 49
|
77
|
-
raise ArgumentError, "Invalid argument 'string': Expected at least #{low_limit} elements, got #{values.length}." if values.length < low_limit
|
78
|
-
RTP.logger.warn "The number of elements (#{values.length}) for this Field record exceeds the known number of data items for this record (#{high_limit}). This may indicate an invalid record or that the RTP format has recently been expanded with new items." if values.length > high_limit
|
79
73
|
f = self.new(parent)
|
80
|
-
|
81
|
-
f.keyword = values[0]
|
82
|
-
f.rx_site_name = values[1]
|
83
|
-
f.field_name = values[2]
|
84
|
-
f.field_id = values[3]
|
85
|
-
f.field_note = values[4]
|
86
|
-
f.field_dose = values[5]
|
87
|
-
f.field_monitor_units = values[6]
|
88
|
-
f.wedge_monitor_units = values[7]
|
89
|
-
f.treatment_machine = values[8]
|
90
|
-
f.treatment_type = values[9]
|
91
|
-
f.modality = values[10]
|
92
|
-
f.energy = values[11]
|
93
|
-
f.time = values[12]
|
94
|
-
f.doserate = values[13]
|
95
|
-
f.sad = values[14]
|
96
|
-
f.ssd = values[15]
|
97
|
-
f.gantry_angle = values[16]
|
98
|
-
f.collimator_angle = values[17]
|
99
|
-
f.field_x_mode = values[18]
|
100
|
-
f.field_x = values[19]
|
101
|
-
f.collimator_x1 = values[20]
|
102
|
-
f.collimator_x2 = values[21]
|
103
|
-
f.field_y_mode = values[22]
|
104
|
-
f.field_y = values[23]
|
105
|
-
f.collimator_y1 = values[24]
|
106
|
-
f.collimator_y2 = values[25]
|
107
|
-
f.couch_vertical = values[26]
|
108
|
-
f.couch_lateral = values[27]
|
109
|
-
f.couch_longitudinal = values[28]
|
110
|
-
f.couch_angle = values[29]
|
111
|
-
f.couch_pedestal = values[30]
|
112
|
-
f.tolerance_table = values[31]
|
113
|
-
f.arc_direction = values[32]
|
114
|
-
f.arc_start_angle = values[33]
|
115
|
-
f.arc_stop_angle = values[34]
|
116
|
-
f.arc_mu_degree = values[35]
|
117
|
-
f.wedge = values[36]
|
118
|
-
f.dynamic_wedge = values[37]
|
119
|
-
f.block = values[38]
|
120
|
-
f.compensator = values[39]
|
121
|
-
f.e_applicator = values[40]
|
122
|
-
f.e_field_def_aperture = values[41]
|
123
|
-
f.bolus = values[42]
|
124
|
-
f.portfilm_mu_open = values[43]
|
125
|
-
f.portfilm_coeff_open = values[44]
|
126
|
-
f.portfilm_delta_open = values[45]
|
127
|
-
f.portfilm_mu_treat = values[46]
|
128
|
-
f.portfilm_coeff_treat = values[47]
|
129
|
-
f.crc = values[-1]
|
130
|
-
return f
|
74
|
+
f.load(string)
|
131
75
|
end
|
132
76
|
|
133
77
|
# Creates a new (treatment) Field.
|
@@ -135,13 +79,65 @@ module RTP
|
|
135
79
|
# @param [Record] parent a record which is used to determine the proper parent of this instance
|
136
80
|
#
|
137
81
|
def initialize(parent)
|
82
|
+
super('FIELD_DEF', 27, 49)
|
138
83
|
# Child records:
|
139
84
|
@control_points = Array.new
|
140
85
|
@extended_field = nil
|
141
86
|
# Parent relation (may get more than one type of record here):
|
142
87
|
@parent = get_parent(parent.to_record, Prescription)
|
143
88
|
@parent.add_field(self)
|
144
|
-
@
|
89
|
+
@attributes = [
|
90
|
+
# Required:
|
91
|
+
:keyword,
|
92
|
+
:rx_site_name,
|
93
|
+
:field_name,
|
94
|
+
:field_id,
|
95
|
+
:field_note,
|
96
|
+
:field_dose,
|
97
|
+
:field_monitor_units,
|
98
|
+
:wedge_monitor_units,
|
99
|
+
:treatment_machine,
|
100
|
+
:treatment_type,
|
101
|
+
:modality,
|
102
|
+
:energy,
|
103
|
+
:time,
|
104
|
+
:doserate,
|
105
|
+
:sad,
|
106
|
+
:ssd,
|
107
|
+
:gantry_angle,
|
108
|
+
:collimator_angle,
|
109
|
+
:field_x_mode,
|
110
|
+
:field_x,
|
111
|
+
:collimator_x1,
|
112
|
+
:collimator_x2,
|
113
|
+
:field_y_mode,
|
114
|
+
:field_y,
|
115
|
+
:collimator_y1,
|
116
|
+
:collimator_y2,
|
117
|
+
# Optional:
|
118
|
+
:couch_vertical,
|
119
|
+
:couch_lateral,
|
120
|
+
:couch_longitudinal,
|
121
|
+
:couch_angle,
|
122
|
+
:couch_pedestal,
|
123
|
+
:tolerance_table,
|
124
|
+
:arc_direction,
|
125
|
+
:arc_start_angle,
|
126
|
+
:arc_stop_angle,
|
127
|
+
:arc_mu_degree,
|
128
|
+
:wedge,
|
129
|
+
:dynamic_wedge,
|
130
|
+
:block,
|
131
|
+
:compensator,
|
132
|
+
:e_applicator,
|
133
|
+
:e_field_def_aperture,
|
134
|
+
:bolus,
|
135
|
+
:portfilm_mu_open,
|
136
|
+
:portfilm_coeff_open,
|
137
|
+
:portfilm_delta_open,
|
138
|
+
:portfilm_mu_treat,
|
139
|
+
:portfilm_coeff_treat
|
140
|
+
]
|
145
141
|
end
|
146
142
|
|
147
143
|
# Checks for equality.
|
@@ -184,6 +180,38 @@ module RTP
|
|
184
180
|
return [@extended_field, @control_points].flatten.compact
|
185
181
|
end
|
186
182
|
|
183
|
+
# Converts the collimator_x1 attribute to proper DICOM format.
|
184
|
+
#
|
185
|
+
# @return [Float] the DICOM-formatted collimator_x1 attribute
|
186
|
+
#
|
187
|
+
def dcm_collimator_x1
|
188
|
+
dcm_collimator1(:x)
|
189
|
+
end
|
190
|
+
|
191
|
+
# Converts the collimator_x2 attribute to proper DICOM format.
|
192
|
+
#
|
193
|
+
# @return [Float] the DICOM-formatted collimator_x2 attribute
|
194
|
+
#
|
195
|
+
def dcm_collimator_x2
|
196
|
+
value = @collimator_x2.to_f * 10
|
197
|
+
end
|
198
|
+
|
199
|
+
# Converts the collimator_y1 attribute to proper DICOM format.
|
200
|
+
#
|
201
|
+
# @return [Float] the DICOM-formatted collimator_y1 attribute
|
202
|
+
#
|
203
|
+
def dcm_collimator_y1
|
204
|
+
dcm_collimator1(:y)
|
205
|
+
end
|
206
|
+
|
207
|
+
# Converts the collimator_y2 attribute to proper DICOM format.
|
208
|
+
#
|
209
|
+
# @return [Float] the DICOM-formatted collimator_y2 attribute
|
210
|
+
#
|
211
|
+
def dcm_collimator_y2
|
212
|
+
value = @collimator_y2.to_f * 10
|
213
|
+
end
|
214
|
+
|
187
215
|
# Computes a hash code for this object.
|
188
216
|
#
|
189
217
|
# @note Two objects with the same attributes will have the same hash code.
|
@@ -194,64 +222,6 @@ module RTP
|
|
194
222
|
state.hash
|
195
223
|
end
|
196
224
|
|
197
|
-
# Collects the values (attributes) of this instance.
|
198
|
-
#
|
199
|
-
# @note The CRC is not considered part of the actual values and is excluded.
|
200
|
-
# @return [Array<String>] an array of attributes (in the same order as they appear in the RTP string)
|
201
|
-
#
|
202
|
-
def values
|
203
|
-
return [
|
204
|
-
@keyword,
|
205
|
-
@rx_site_name,
|
206
|
-
@field_name,
|
207
|
-
@field_id,
|
208
|
-
@field_note,
|
209
|
-
@field_dose,
|
210
|
-
@field_monitor_units,
|
211
|
-
@wedge_monitor_units,
|
212
|
-
@treatment_machine,
|
213
|
-
@treatment_type,
|
214
|
-
@modality,
|
215
|
-
@energy,
|
216
|
-
@time,
|
217
|
-
@doserate,
|
218
|
-
@sad,
|
219
|
-
@ssd,
|
220
|
-
@gantry_angle,
|
221
|
-
@collimator_angle,
|
222
|
-
@field_x_mode,
|
223
|
-
@field_x,
|
224
|
-
@collimator_x1,
|
225
|
-
@collimator_x2,
|
226
|
-
@field_y_mode,
|
227
|
-
@field_y,
|
228
|
-
@collimator_y1,
|
229
|
-
@collimator_y2,
|
230
|
-
@couch_vertical,
|
231
|
-
@couch_lateral,
|
232
|
-
@couch_longitudinal,
|
233
|
-
@couch_angle,
|
234
|
-
@couch_pedestal,
|
235
|
-
@tolerance_table,
|
236
|
-
@arc_direction,
|
237
|
-
@arc_start_angle,
|
238
|
-
@arc_stop_angle,
|
239
|
-
@arc_mu_degree,
|
240
|
-
@wedge,
|
241
|
-
@dynamic_wedge,
|
242
|
-
@block,
|
243
|
-
@compensator,
|
244
|
-
@e_applicator,
|
245
|
-
@e_field_def_aperture,
|
246
|
-
@bolus,
|
247
|
-
@portfilm_mu_open,
|
248
|
-
@portfilm_coeff_open,
|
249
|
-
@portfilm_delta_open,
|
250
|
-
@portfilm_mu_treat,
|
251
|
-
@portfilm_coeff_treat
|
252
|
-
]
|
253
|
-
end
|
254
|
-
|
255
225
|
# Returns self.
|
256
226
|
#
|
257
227
|
# @return [Field] self
|
@@ -277,18 +247,6 @@ module RTP
|
|
277
247
|
|
278
248
|
alias :to_str :to_s
|
279
249
|
|
280
|
-
# Sets the keyword attribute.
|
281
|
-
#
|
282
|
-
# @note Since only a specific string is accepted, this is more of an argument check than a traditional setter method
|
283
|
-
# @param [#to_s] value the new attribute value
|
284
|
-
# @raise [ArgumentError] if given an unexpected keyword
|
285
|
-
#
|
286
|
-
def keyword=(value)
|
287
|
-
value = value.to_s.upcase
|
288
|
-
raise ArgumentError, "Invalid keyword. Expected 'FIELD_DEF', got #{value}." unless value == "FIELD_DEF"
|
289
|
-
@keyword = value
|
290
|
-
end
|
291
|
-
|
292
250
|
# Sets the rx_site_name attribute.
|
293
251
|
#
|
294
252
|
# @param [nil, #to_s] value the new attribute value
|
@@ -676,6 +634,21 @@ module RTP
|
|
676
634
|
#
|
677
635
|
alias_method :state, :values
|
678
636
|
|
637
|
+
# Converts the collimator attribute to proper DICOM format.
|
638
|
+
#
|
639
|
+
# @param [Symbol] axis a representation for the axis of interest (x or y)
|
640
|
+
# @return [Float] the DICOM-formatted collimator attribute
|
641
|
+
#
|
642
|
+
def dcm_collimator1(axis)
|
643
|
+
value = self.send("collimator_#{axis}1").to_f * 10
|
644
|
+
mode = self.send("field_#{axis}_mode")
|
645
|
+
if mode && mode.upcase == 'SYM' && value > 0
|
646
|
+
-value
|
647
|
+
else
|
648
|
+
value
|
649
|
+
end
|
650
|
+
end
|
651
|
+
|
679
652
|
end
|
680
653
|
|
681
654
|
end
|