rtp-connect 1.0

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.
data/README.rdoc ADDED
@@ -0,0 +1,128 @@
1
+ = RTPConnect
2
+
3
+ The RTPConnect library allows you to read, edit and write RTPConnect files in Ruby.
4
+ RTPConnect is a file format used in radiotherapy (e.g. Mosaiq) for export & import
5
+ of treatment planning data. The library is written entirely in Ruby and has no
6
+ external dependencies.
7
+
8
+
9
+ == INSTALLATION
10
+
11
+ gem install rtp-connect
12
+
13
+
14
+ == REQUIREMENTS
15
+
16
+ * Ruby 1.9.2
17
+
18
+
19
+ == BASIC USAGE
20
+
21
+ === Load & Include
22
+
23
+ require 'rtp-connect'
24
+ include RTP
25
+
26
+ === Read, modify and write
27
+
28
+ # Read file:
29
+ rtp = Plan.read("some_file.rtp")
30
+ # Extract the Patient's Name:
31
+ name = rtp.patient_last_name
32
+ # Modify the Patient's Name:
33
+ rtp.patient_last_name = "Anonymous"
34
+ # Write to file:
35
+ rtp.write("new_file.rtp")
36
+
37
+ === Create a new Plan Definition Record from scratch
38
+
39
+ # Create the instance:
40
+ rtp = Plan.new
41
+ # Set the Patient's ID attribute:
42
+ rtp.patient_id = "12345"
43
+ # Export the instance to an RTP string (with CRC):
44
+ output = rtp.to_str
45
+
46
+ === Log settings
47
+
48
+ # Change the log level so that only error messages are displayed:
49
+ RTP.logger.level = Logger::ERROR
50
+ # Setting up a simple file log:
51
+ l = Logger.new('my_logfile.log')
52
+ RTP.logger = l
53
+ # Create a logger which ages logfile daily/monthly:
54
+ RTP.logger = Logger.new('foo.log', 'daily')
55
+ RTP.logger = Logger.new('foo.log', 'monthly')
56
+
57
+ === Scripts
58
+
59
+ For more thorough examples, check out the scripts folder which contains
60
+ numerous ruby scripts that shows of real world usage scenarios of the
61
+ RTPConnect library.
62
+
63
+ === IRB Tip
64
+
65
+ When working with the RTPConnect library in irb, you may be annoyed with all
66
+ the information that is printed to screen, regardless of your log level.
67
+ This is because in irb every variable loaded in the program is
68
+ automatically printed to the screen. A useful hack to avoid this effect is
69
+ to append ";0" after a command.
70
+
71
+ Example:
72
+ rtp = Plan.read("some_file.rtp") ;0
73
+
74
+
75
+ == RESOURCES
76
+
77
+ * {Rubygems download}[https://rubygems.org/gems/rtp-connect]
78
+ * {Source code repository}[https://github.com/dicom/rtp-connect]
79
+
80
+
81
+ == RESTRICTIONS
82
+
83
+ === Supported records
84
+
85
+ * Plan definition [PLAN_DEF]
86
+ * Prescription site [RX_DEF]
87
+ * Site setup [SITE_SETUP_DEF]
88
+ * Treatment field [FIELD_DEF]
89
+ * Extended treatment field [EXTENDED_FIELD_DEF]
90
+ * Control point record [CONTROL_PT_DEF]
91
+
92
+ === Unsupported records
93
+
94
+ * Simulation field [SIM_DEF]
95
+ * Document based treatment field [PDF_FIELD_DEF]
96
+ * Multileaf collimator [MLC_DEF]
97
+ * MLC shape [MLC_SHAPE_DEF]
98
+ * Dose tracking record [DOSE_DEF]
99
+ * Dose action points [DOSE_ACTION]
100
+
101
+ If you encounter an RTP file with an unsupported record type, please contact me.
102
+
103
+
104
+ == COPYRIGHT
105
+
106
+ Copyright 2011 Christoffer Lervag
107
+
108
+ This program is free software: you can redistribute it and/or modify
109
+ it under the terms of the GNU General Public License as published by
110
+ the Free Software Foundation, either version 3 of the License, or
111
+ (at your option) any later version.
112
+
113
+ This program is distributed in the hope that it will be useful,
114
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
115
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
116
+ GNU General Public License for more details.
117
+
118
+ You should have received a copy of the GNU General Public License
119
+ along with this program. If not, see http://www.gnu.org/licenses/ .
120
+
121
+
122
+ == ABOUT THE AUTHOR
123
+
124
+ * Name: Christoffer Lervag
125
+ * Location: Norway
126
+ * Email: chris.lervag [@nospam.com] @gmail.com
127
+
128
+ Please don't hesitate to email me if you have any feedback related to this project!
@@ -0,0 +1,20 @@
1
+ # Loads the files that are used by the RTPConnect library.
2
+
3
+ # Logging:
4
+ require_relative 'rtp-connect/logging'
5
+ # Super classes:
6
+ require_relative 'rtp-connect/record'
7
+ # Core library:
8
+ require_relative 'rtp-connect/plan'
9
+ require_relative 'rtp-connect/prescription'
10
+ require_relative 'rtp-connect/site_setup'
11
+ require_relative 'rtp-connect/field'
12
+ require_relative 'rtp-connect/extended_field'
13
+ require_relative 'rtp-connect/control_point'
14
+ # Extensions to the Ruby library:
15
+ require_relative 'rtp-connect/ruby_extensions'
16
+ # Module settings:
17
+ require_relative 'rtp-connect/version'
18
+ require_relative 'rtp-connect/constants'
19
+ require_relative 'rtp-connect/methods'
20
+ require_relative 'rtp-connect/variables'
@@ -0,0 +1,58 @@
1
+ module RTP
2
+
3
+ # The seed value used in the RTPConnect implementation of the CCITT algorithm.
4
+ CRC_SEED = 0x0521
5
+
6
+ # The table & values used in the RTPConnect implementation of the CCITT algorithm.
7
+ CRC_TABLE = [
8
+ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
9
+ 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
10
+ 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
11
+ 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
12
+ 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
13
+ 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
14
+ 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
15
+ 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
16
+ 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
17
+ 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
18
+ 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
19
+ 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
20
+ 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
21
+ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
22
+ 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
23
+ 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
24
+ 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
25
+ 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
26
+ 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
27
+ 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
28
+ 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
29
+ 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
30
+ 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
31
+ 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
32
+ 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
33
+ 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
34
+ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
35
+ 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
36
+ 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
37
+ 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
38
+ 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
39
+ 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
40
+ ]
41
+
42
+ # Pairs of RTPConnect keywords and parse method names.
43
+ PARSE_METHOD = {
44
+ "PLAN_DEF" => :plan_definition,
45
+ "RX_DEF" => :prescription_site,
46
+ "SITE_SETUP_DEF" => :site_setup,
47
+ "SIM_DEF" => :simulation_field,
48
+ "FIELD_DEF" => :treatment_field,
49
+ "EXTENDED_FIELD_DEF" => :extended_treatment_field,
50
+ "PDF_FIELD_DEF" => :document_based_treatment_field,
51
+ "MLC_DEF" => :multileaf_collimator,
52
+ "CONTROL_PT_DEF" => :control_point,
53
+ "MLC_SHAPE_DEF" => :mlc_shape,
54
+ "DOSE_DEF" => :dose_tracking,
55
+ "DOSE_ACTION" => :dose_action,
56
+ }
57
+
58
+ end
@@ -0,0 +1,444 @@
1
+ module RTP
2
+
3
+ # The ControlPoint class.
4
+ #
5
+ # === Relations
6
+ #
7
+ # * Parent: Field
8
+ # * Children: MLCShape
9
+ #
10
+ class ControlPoint < Record
11
+
12
+ # The Record which this instance belongs to.
13
+ attr_reader :parent
14
+ # The MLC shape record (if any) that belongs to this ControlPoint.
15
+ attr_reader :mlc_shape
16
+ attr_reader :field_id
17
+ attr_reader :mlc_type
18
+ attr_reader :mlc_leaves
19
+ attr_reader :total_control_points
20
+ attr_reader :control_pt_number
21
+ attr_reader :mu_convention
22
+ attr_reader :monitor_units
23
+ attr_reader :wedge_position
24
+ attr_reader :energy
25
+ attr_reader :doserate
26
+ attr_reader :ssd
27
+ attr_reader :scale_convention
28
+ attr_reader :gantry_angle
29
+ attr_reader :gantry_dir
30
+ attr_reader :collimator_angle
31
+ attr_reader :collimator_dir
32
+ attr_reader :field_x_mode
33
+ attr_reader :field_x
34
+ attr_reader :collimator_x1
35
+ attr_reader :collimator_x2
36
+ attr_reader :field_y_mode
37
+ attr_reader :field_y
38
+ attr_reader :collimator_y1
39
+ attr_reader :collimator_y2
40
+ attr_reader :couch_vertical
41
+ attr_reader :couch_lateral
42
+ attr_reader :couch_longitudinal
43
+ attr_reader :couch_angle
44
+ attr_reader :couch_dir
45
+ attr_reader :couch_pedestal
46
+ attr_reader :couch_ped_dir
47
+ # Note: This attribute contains an array of all MLC LP A values (leaves 1..100).
48
+ attr_reader :mlc_lp_a
49
+ # Note: This attribute contains an array of all MLC LP B values (leaves 1..100).
50
+ attr_reader :mlc_lp_b
51
+
52
+ # Creates a new ControlPoint by parsing a RTPConnect string line.
53
+ #
54
+ # === Parameters
55
+ #
56
+ # * <tt>string</tt> -- A string containing a control point record.
57
+ # * <tt>parent</tt> -- A Record which is used to determine the proper parent of this instance.
58
+ #
59
+ def self.load(string, parent)
60
+ raise ArgumentError, "Invalid argument 'string'. Expected String, got #{string.class}." unless string.is_a?(String)
61
+ raise ArgumentError, "Invalid argument 'parent'. Expected RTP::Record, got #{parent.class}." unless parent.is_a?(RTP::Record)
62
+ # Get the quote-less values:
63
+ values = string.values
64
+ raise ArgumentError, "Invalid argument 'string': Expected exactly 233 elements, got #{values.length}." unless values.length == 233
65
+ f = self.new(parent)
66
+ # Assign the values to attributes:
67
+ f.keyword = values[0]
68
+ f.field_id = values[1]
69
+ f.mlc_type = values[2]
70
+ f.mlc_leaves = values[3]
71
+ f.total_control_points = values[4]
72
+ f.control_pt_number = values[5]
73
+ f.mu_convention = values[6]
74
+ f.monitor_units = values[7]
75
+ f.wedge_position = values[8]
76
+ f.energy = values[9]
77
+ f.doserate = values[10]
78
+ f.ssd = values[11]
79
+ f.scale_convention = values[12]
80
+ f.gantry_angle = values[13]
81
+ f.gantry_dir = values[14]
82
+ f.collimator_angle = values[15]
83
+ f.collimator_dir = values[16]
84
+ f.field_x_mode = values[17]
85
+ f.field_x = values[18]
86
+ f.collimator_x1 = values[19]
87
+ f.collimator_x2 = values[20]
88
+ f.field_y_mode = values[21]
89
+ f.field_y = values[22]
90
+ f.collimator_y1 = values[23]
91
+ f.collimator_y2 = values[24]
92
+ f.couch_vertical = values[25]
93
+ f.couch_lateral = values[26]
94
+ f.couch_longitudinal = values[27]
95
+ f.couch_angle = values[28]
96
+ f.couch_dir = values[29]
97
+ f.couch_pedestal = values[30]
98
+ f.couch_ped_dir = values[31]
99
+ f.mlc_lp_a = [*values[32..131]]
100
+ f.mlc_lp_b = [*values[132..231]]
101
+ f.crc = values[232]
102
+ return f
103
+ end
104
+
105
+ # Creates a new ControlPoint.
106
+ #
107
+ # === Parameters
108
+ #
109
+ # * <tt>parent</tt> -- A Record which is used to determine the proper parent of this instance.
110
+ #
111
+ def initialize(parent)
112
+ raise ArgumentError, "Invalid argument 'parent'. Expected RTP::Record, got #{parent.class}." unless parent.is_a?(RTP::Record)
113
+ # Child:
114
+ @mlc_shape = nil
115
+ # Parent relation:
116
+ @parent = get_parent(parent, Field)
117
+ @parent.add_control_point(self)
118
+ @keyword = 'CONTROL_PT_DEF'
119
+ @mlc_lp_a = Array.new(100)
120
+ @mlc_lp_b = Array.new(100)
121
+ end
122
+
123
+ # As of now, returns an empty array.
124
+ # However, by definition, this record may have an mlc shape record as child,
125
+ # but this is not implemented yet.
126
+ #
127
+ def children
128
+ #return [@mlc_shape]
129
+ return Array.new
130
+ end
131
+
132
+ # Returns the values of this instance in an array.
133
+ # The values does not include the CRC.
134
+ #
135
+ def values
136
+ return [
137
+ @keyword,
138
+ @field_id,
139
+ @mlc_type,
140
+ @mlc_leaves,
141
+ @total_control_points,
142
+ @control_pt_number,
143
+ @mu_convention,
144
+ @monitor_units,
145
+ @wedge_position,
146
+ @energy,
147
+ @doserate,
148
+ @ssd,
149
+ @scale_convention,
150
+ @gantry_angle,
151
+ @gantry_dir,
152
+ @collimator_angle,
153
+ @collimator_dir,
154
+ @field_x_mode,
155
+ @field_x,
156
+ @collimator_x1,
157
+ @collimator_x2,
158
+ @field_y_mode,
159
+ @field_y,
160
+ @collimator_y1,
161
+ @collimator_y2,
162
+ @couch_vertical,
163
+ @couch_lateral,
164
+ @couch_longitudinal,
165
+ @couch_angle,
166
+ @couch_dir,
167
+ @couch_pedestal,
168
+ @couch_ped_dir,
169
+ *@mlc_lp_a,
170
+ *@mlc_lp_b
171
+ ]
172
+ end
173
+
174
+ # Writes the ControlPoint object + any hiearchy of child objects,
175
+ # to a properly formatted RTPConnect ascii string.
176
+ #
177
+ def to_str
178
+ str = encode
179
+ if children
180
+ children.each do |child|
181
+ str += child.to_str
182
+ end
183
+ end
184
+ return str
185
+ end
186
+
187
+ # Sets the mlc_a attribute.
188
+ #
189
+ # === Notes
190
+ #
191
+ # As opposed to the ordinary (string) attributes, this attribute
192
+ # contains an array holding all 100 MLC leaf 'A' string values.
193
+ #
194
+ def mlc_lp_a=(array)
195
+ raise ArgumentError, "Invalid argument 'array'. Expected Array, got #{array.class}." unless array.is_a?(Array)
196
+ raise ArgumentError, "Invalid argument 'array'. Expected array with length 100, got #{array.length}." unless array.length == 100
197
+ unexpected_types = array.collect{|i| i.class}.uniq - [String, NilClass]
198
+ raise ArgumentError, "Invalid argument 'array'. Array must contain only string or nil values, got unexpected class #{unexpected_types}." if unexpected_types.length > 0
199
+ @mlc_lp_a = array
200
+ end
201
+
202
+ # Sets the mlc_b attribute.
203
+ #
204
+ # === Notes
205
+ #
206
+ # As opposed to the ordinary (string) attributes, this attribute
207
+ # contains an array holding all 100 MLC leaf 'A' string values.
208
+ #
209
+ def mlc_lp_b=(array)
210
+ raise ArgumentError, "Invalid argument 'array'. Expected Array, got #{array.class}." unless array.is_a?(Array)
211
+ raise ArgumentError, "Invalid argument 'array'. Expected array with length 100, got #{array.length}." unless array.length == 100
212
+ unexpected_types = array.collect{|i| i.class}.uniq - [String, NilClass]
213
+ raise ArgumentError, "Invalid argument 'array'. Array must contain only string or nil values, got unexpected class #{unexpected_types}." if unexpected_types.length > 0
214
+ @mlc_lp_b = array
215
+ end
216
+
217
+ # Sets the keyword attribute.
218
+ #
219
+ def keyword=(value)
220
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
221
+ raise ArgumentError, "Invalid keyword. Expected 'CONTROL_PT_DEF', got #{value}." unless value.upcase == "CONTROL_PT_DEF"
222
+ @keyword = value
223
+ end
224
+
225
+ # Sets the field_id attribute.
226
+ #
227
+ def field_id=(value)
228
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
229
+ @field_id = value
230
+ end
231
+
232
+ # Sets the mlc_type attribute.
233
+ #
234
+ def mlc_type=(value)
235
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
236
+ @mlc_type = value
237
+ end
238
+
239
+ # Sets the mlc_leaves attribute.
240
+ #
241
+ def mlc_leaves=(value)
242
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
243
+ @mlc_leaves = value
244
+ end
245
+
246
+ # Sets the total_control_points attribute.
247
+ #
248
+ def total_control_points=(value)
249
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
250
+ @total_control_points = value
251
+ end
252
+
253
+ # Sets the control_pt_number attribute.
254
+ #
255
+ def control_pt_number=(value)
256
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
257
+ @control_pt_number = value
258
+ end
259
+
260
+ # Sets the mu_convention attribute.
261
+ #
262
+ def mu_convention=(value)
263
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
264
+ @mu_convention = value
265
+ end
266
+
267
+ # Sets the monitor_units attribute.
268
+ #
269
+ def monitor_units=(value)
270
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
271
+ @monitor_units = value
272
+ end
273
+
274
+ # Sets the wedge_position attribute.
275
+ #
276
+ def wedge_position=(value)
277
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
278
+ @wedge_position = value
279
+ end
280
+
281
+ # Sets the energy attribute.
282
+ #
283
+ def energy=(value)
284
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
285
+ @energy = value
286
+ end
287
+
288
+ # Sets the doserate attribute.
289
+ #
290
+ def doserate=(value)
291
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
292
+ @doserate = value
293
+ end
294
+
295
+ # Sets the ssd attribute.
296
+ #
297
+ def ssd=(value)
298
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
299
+ @ssd = value
300
+ end
301
+
302
+ # Sets the scale_convention attribute.
303
+ #
304
+ def scale_convention=(value)
305
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
306
+ @scale_convention = value
307
+ end
308
+
309
+ # Sets the gantry_angle attribute.
310
+ #
311
+ def gantry_angle=(value)
312
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
313
+ @gantry_angle = value
314
+ end
315
+
316
+ # Sets the gantry_dir attribute.
317
+ #
318
+ def gantry_dir=(value)
319
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
320
+ @gantry_dir = value
321
+ end
322
+
323
+ # Sets the collimator_angle attribute.
324
+ #
325
+ def collimator_angle=(value)
326
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
327
+ @collimator_angle = value
328
+ end
329
+
330
+ # Sets the collimator_dir attribute.
331
+ #
332
+ def collimator_dir=(value)
333
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
334
+ @collimator_dir = value
335
+ end
336
+
337
+ # Sets the field_x_mode attribute.
338
+ #
339
+ def field_x_mode=(value)
340
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
341
+ @field_x_mode = value
342
+ end
343
+
344
+ # Sets the field_x attribute.
345
+ #
346
+ def field_x=(value)
347
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
348
+ @field_x = value
349
+ end
350
+
351
+ # Sets the collimator_x1 attribute.
352
+ #
353
+ def collimator_x1=(value)
354
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
355
+ @collimator_x1 = value
356
+ end
357
+
358
+ # Sets the collimator_x2 attribute.
359
+ #
360
+ def collimator_x2=(value)
361
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
362
+ @collimator_x2 = value
363
+ end
364
+
365
+ # Sets the field_y_mode attribute.
366
+ #
367
+ def field_y_mode=(value)
368
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
369
+ @field_y_mode = value
370
+ end
371
+
372
+ # Sets the field_y attribute.
373
+ #
374
+ def field_y=(value)
375
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
376
+ @field_y = value
377
+ end
378
+
379
+ # Sets the collimator_y1 attribute.
380
+ #
381
+ def collimator_y1=(value)
382
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
383
+ @collimator_y1 = value
384
+ end
385
+
386
+ # Sets the collimator_y2 attribute.
387
+ #
388
+ def collimator_y2=(value)
389
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
390
+ @collimator_y2 = value
391
+ end
392
+
393
+ # Sets the couch_vertical attribute.
394
+ #
395
+ def couch_vertical=(value)
396
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
397
+ @couch_vertical = value
398
+ end
399
+
400
+ # Sets the couch_lateral attribute.
401
+ #
402
+ def couch_lateral=(value)
403
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
404
+ @couch_lateral = value
405
+ end
406
+
407
+ # Sets the couch_longitudinal attribute.
408
+ #
409
+ def couch_longitudinal=(value)
410
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
411
+ @couch_longitudinal = value
412
+ end
413
+
414
+ # Sets the couch_angle attribute.
415
+ #
416
+ def couch_angle=(value)
417
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
418
+ @couch_angle = value
419
+ end
420
+
421
+ # Sets the couch_dir attribute.
422
+ #
423
+ def couch_dir=(value)
424
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
425
+ @couch_dir = value
426
+ end
427
+
428
+ # Sets the couch_pedestal attribute.
429
+ #
430
+ def couch_pedestal=(value)
431
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
432
+ @couch_pedestal = value
433
+ end
434
+
435
+ # Sets the couch_ped_dir attribute.
436
+ #
437
+ def couch_ped_dir=(value)
438
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
439
+ @couch_ped_dir = value
440
+ end
441
+
442
+ end
443
+
444
+ end