rtp-connect 1.0

Sign up to get free protection for your applications and to get access to all the features.
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