rtp-connect 1.0 → 1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +11 -0
- data/README.rdoc +8 -7
- data/lib/rtp-connect.rb +4 -1
- data/lib/rtp-connect/control_point.rb +76 -82
- data/lib/rtp-connect/extended_field.rb +43 -18
- data/lib/rtp-connect/field.rb +88 -108
- data/lib/rtp-connect/methods.rb +1 -1
- data/lib/rtp-connect/plan.rb +62 -65
- data/lib/rtp-connect/prescription.rb +52 -36
- data/lib/rtp-connect/record.rb +9 -4
- data/lib/rtp-connect/ruby_extensions.rb +1 -1
- data/lib/rtp-connect/site_setup.rb +53 -38
- data/lib/rtp-connect/version.rb +1 -1
- metadata +4 -4
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
= 1.1
|
2
|
+
|
3
|
+
=== 18th April, 2012
|
4
|
+
|
5
|
+
* Added to_* methods for all records to complete the implementation of dynamic typing
|
6
|
+
* Added comparison related methods to the record classes: #==, #eql? and #hash
|
7
|
+
* Added the #to_s method to records which may replace the #to_str methods.
|
8
|
+
* Added dynamic string conversion of parameters, e.g. numeric parameters can be passed to records.
|
9
|
+
* Fixed an issue where reading string values containing a comma would lead to a crash.
|
10
|
+
* Fixed an issue where reading a string with a single digit checksum would fail.
|
11
|
+
|
1
12
|
= 1.0
|
2
13
|
|
3
14
|
=== 29th December, 2011
|
data/README.rdoc
CHANGED
@@ -13,7 +13,7 @@ external dependencies.
|
|
13
13
|
|
14
14
|
== REQUIREMENTS
|
15
15
|
|
16
|
-
* Ruby 1.9.2
|
16
|
+
* Ruby 1.9.2 (or higher)
|
17
17
|
|
18
18
|
|
19
19
|
== BASIC USAGE
|
@@ -41,7 +41,7 @@ external dependencies.
|
|
41
41
|
# Set the Patient's ID attribute:
|
42
42
|
rtp.patient_id = "12345"
|
43
43
|
# Export the instance to an RTP string (with CRC):
|
44
|
-
output = rtp.
|
44
|
+
output = rtp.to_s
|
45
45
|
|
46
46
|
=== Log settings
|
47
47
|
|
@@ -56,9 +56,9 @@ external dependencies.
|
|
56
56
|
|
57
57
|
=== Scripts
|
58
58
|
|
59
|
-
For more
|
60
|
-
|
61
|
-
RTPConnect library.
|
59
|
+
For more comprehensive and useful examples, check out the scripts folder
|
60
|
+
which contains various Ruby scripts that intends to show off real world
|
61
|
+
usage scenarios of the RTPConnect library.
|
62
62
|
|
63
63
|
=== IRB Tip
|
64
64
|
|
@@ -75,6 +75,7 @@ Example:
|
|
75
75
|
== RESOURCES
|
76
76
|
|
77
77
|
* {Rubygems download}[https://rubygems.org/gems/rtp-connect]
|
78
|
+
* {Documentation}[http://rubydoc.info/gems/rtp-connect/frames]
|
78
79
|
* {Source code repository}[https://github.com/dicom/rtp-connect]
|
79
80
|
|
80
81
|
|
@@ -103,7 +104,7 @@ If you encounter an RTP file with an unsupported record type, please contact me.
|
|
103
104
|
|
104
105
|
== COPYRIGHT
|
105
106
|
|
106
|
-
Copyright 2011 Christoffer
|
107
|
+
Copyright 2011-2012 Christoffer Lervåg
|
107
108
|
|
108
109
|
This program is free software: you can redistribute it and/or modify
|
109
110
|
it under the terms of the GNU General Public License as published by
|
@@ -121,7 +122,7 @@ along with this program. If not, see http://www.gnu.org/licenses/ .
|
|
121
122
|
|
122
123
|
== ABOUT THE AUTHOR
|
123
124
|
|
124
|
-
* Name: Christoffer
|
125
|
+
* Name: Christoffer Lervåg
|
125
126
|
* Location: Norway
|
126
127
|
* Email: chris.lervag [@nospam.com] @gmail.com
|
127
128
|
|
data/lib/rtp-connect.rb
CHANGED
@@ -17,4 +17,7 @@ require_relative 'rtp-connect/ruby_extensions'
|
|
17
17
|
require_relative 'rtp-connect/version'
|
18
18
|
require_relative 'rtp-connect/constants'
|
19
19
|
require_relative 'rtp-connect/methods'
|
20
|
-
require_relative 'rtp-connect/variables'
|
20
|
+
require_relative 'rtp-connect/variables'
|
21
|
+
|
22
|
+
# Load the CSV library:
|
23
|
+
require 'csv'
|
@@ -57,10 +57,8 @@ module RTP
|
|
57
57
|
# * <tt>parent</tt> -- A Record which is used to determine the proper parent of this instance.
|
58
58
|
#
|
59
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
60
|
# Get the quote-less values:
|
63
|
-
values = string.values
|
61
|
+
values = string.to_s.values
|
64
62
|
raise ArgumentError, "Invalid argument 'string': Expected exactly 233 elements, got #{values.length}." unless values.length == 233
|
65
63
|
f = self.new(parent)
|
66
64
|
# Assign the values to attributes:
|
@@ -109,17 +107,26 @@ module RTP
|
|
109
107
|
# * <tt>parent</tt> -- A Record which is used to determine the proper parent of this instance.
|
110
108
|
#
|
111
109
|
def initialize(parent)
|
112
|
-
raise ArgumentError, "Invalid argument 'parent'. Expected RTP::Record, got #{parent.class}." unless parent.is_a?(RTP::Record)
|
113
110
|
# Child:
|
114
111
|
@mlc_shape = nil
|
115
|
-
# Parent relation:
|
116
|
-
@parent = get_parent(parent, Field)
|
112
|
+
# Parent relation (may get more than one type of record here):
|
113
|
+
@parent = get_parent(parent.to_record, Field)
|
117
114
|
@parent.add_control_point(self)
|
118
115
|
@keyword = 'CONTROL_PT_DEF'
|
119
116
|
@mlc_lp_a = Array.new(100)
|
120
117
|
@mlc_lp_b = Array.new(100)
|
121
118
|
end
|
122
119
|
|
120
|
+
# Returns true if the argument is an instance with attributes equal to self.
|
121
|
+
#
|
122
|
+
def ==(other)
|
123
|
+
if other.respond_to?(:to_control_point)
|
124
|
+
other.send(:state) == state
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
alias_method :eql?, :==
|
129
|
+
|
123
130
|
# As of now, returns an empty array.
|
124
131
|
# However, by definition, this record may have an mlc shape record as child,
|
125
132
|
# but this is not implemented yet.
|
@@ -129,6 +136,12 @@ module RTP
|
|
129
136
|
return Array.new
|
130
137
|
end
|
131
138
|
|
139
|
+
# Generates a Fixnum hash value for this instance.
|
140
|
+
#
|
141
|
+
def hash
|
142
|
+
state.hash
|
143
|
+
end
|
144
|
+
|
132
145
|
# Returns the values of this instance in an array.
|
133
146
|
# The values does not include the CRC.
|
134
147
|
#
|
@@ -171,19 +184,27 @@ module RTP
|
|
171
184
|
]
|
172
185
|
end
|
173
186
|
|
187
|
+
# Returns self.
|
188
|
+
#
|
189
|
+
def to_control_point
|
190
|
+
self
|
191
|
+
end
|
192
|
+
|
174
193
|
# Writes the ControlPoint object + any hiearchy of child objects,
|
175
194
|
# to a properly formatted RTPConnect ascii string.
|
176
195
|
#
|
177
|
-
def
|
196
|
+
def to_s
|
178
197
|
str = encode
|
179
198
|
if children
|
180
199
|
children.each do |child|
|
181
|
-
str += child.
|
200
|
+
str += child.to_s
|
182
201
|
end
|
183
202
|
end
|
184
203
|
return str
|
185
204
|
end
|
186
205
|
|
206
|
+
alias :to_str :to_s
|
207
|
+
|
187
208
|
# Sets the mlc_a attribute.
|
188
209
|
#
|
189
210
|
# === Notes
|
@@ -192,11 +213,9 @@ module RTP
|
|
192
213
|
# contains an array holding all 100 MLC leaf 'A' string values.
|
193
214
|
#
|
194
215
|
def mlc_lp_a=(array)
|
195
|
-
|
196
|
-
raise ArgumentError, "Invalid argument 'array'. Expected
|
197
|
-
|
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
|
216
|
+
array = array.to_a
|
217
|
+
raise ArgumentError, "Invalid argument 'array'. Expected length 100, got #{array.length}." unless array.length == 100
|
218
|
+
@mlc_lp_a = array.collect! {|e| e && e.to_s}
|
200
219
|
end
|
201
220
|
|
202
221
|
# Sets the mlc_b attribute.
|
@@ -207,238 +226,213 @@ module RTP
|
|
207
226
|
# contains an array holding all 100 MLC leaf 'A' string values.
|
208
227
|
#
|
209
228
|
def mlc_lp_b=(array)
|
210
|
-
|
211
|
-
raise ArgumentError, "Invalid argument 'array'. Expected
|
212
|
-
|
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
|
229
|
+
array = array.to_a
|
230
|
+
raise ArgumentError, "Invalid argument 'array'. Expected length 100, got #{array.length}." unless array.length == 100
|
231
|
+
@mlc_lp_b = array.collect! {|e| e && e.to_s}
|
215
232
|
end
|
216
233
|
|
217
234
|
# Sets the keyword attribute.
|
218
235
|
#
|
219
236
|
def keyword=(value)
|
220
|
-
|
221
|
-
raise ArgumentError, "Invalid keyword. Expected 'CONTROL_PT_DEF', got #{value}." unless value
|
237
|
+
value = value.to_s.upcase
|
238
|
+
raise ArgumentError, "Invalid keyword. Expected 'CONTROL_PT_DEF', got #{value}." unless value == "CONTROL_PT_DEF"
|
222
239
|
@keyword = value
|
223
240
|
end
|
224
241
|
|
225
242
|
# Sets the field_id attribute.
|
226
243
|
#
|
227
244
|
def field_id=(value)
|
228
|
-
|
229
|
-
@field_id = value
|
245
|
+
@field_id = value && value.to_s
|
230
246
|
end
|
231
247
|
|
232
248
|
# Sets the mlc_type attribute.
|
233
249
|
#
|
234
250
|
def mlc_type=(value)
|
235
|
-
|
236
|
-
@mlc_type = value
|
251
|
+
@mlc_type = value && value.to_s
|
237
252
|
end
|
238
253
|
|
239
254
|
# Sets the mlc_leaves attribute.
|
240
255
|
#
|
241
256
|
def mlc_leaves=(value)
|
242
|
-
|
243
|
-
@mlc_leaves = value
|
257
|
+
@mlc_leaves = value && value.to_s
|
244
258
|
end
|
245
259
|
|
246
260
|
# Sets the total_control_points attribute.
|
247
261
|
#
|
248
262
|
def total_control_points=(value)
|
249
|
-
|
250
|
-
@total_control_points = value
|
263
|
+
@total_control_points = value && value.to_s
|
251
264
|
end
|
252
265
|
|
253
266
|
# Sets the control_pt_number attribute.
|
254
267
|
#
|
255
268
|
def control_pt_number=(value)
|
256
|
-
|
257
|
-
@control_pt_number = value
|
269
|
+
@control_pt_number = value && value.to_s
|
258
270
|
end
|
259
271
|
|
260
272
|
# Sets the mu_convention attribute.
|
261
273
|
#
|
262
274
|
def mu_convention=(value)
|
263
|
-
|
264
|
-
@mu_convention = value
|
275
|
+
@mu_convention = value && value.to_s
|
265
276
|
end
|
266
277
|
|
267
278
|
# Sets the monitor_units attribute.
|
268
279
|
#
|
269
280
|
def monitor_units=(value)
|
270
|
-
|
271
|
-
@monitor_units = value
|
281
|
+
@monitor_units = value && value.to_s
|
272
282
|
end
|
273
283
|
|
274
284
|
# Sets the wedge_position attribute.
|
275
285
|
#
|
276
286
|
def wedge_position=(value)
|
277
|
-
|
278
|
-
@wedge_position = value
|
287
|
+
@wedge_position = value && value.to_s
|
279
288
|
end
|
280
289
|
|
281
290
|
# Sets the energy attribute.
|
282
291
|
#
|
283
292
|
def energy=(value)
|
284
|
-
|
285
|
-
@energy = value
|
293
|
+
@energy = value && value.to_s
|
286
294
|
end
|
287
295
|
|
288
296
|
# Sets the doserate attribute.
|
289
297
|
#
|
290
298
|
def doserate=(value)
|
291
|
-
|
292
|
-
@doserate = value
|
299
|
+
@doserate = value && value.to_s
|
293
300
|
end
|
294
301
|
|
295
302
|
# Sets the ssd attribute.
|
296
303
|
#
|
297
304
|
def ssd=(value)
|
298
|
-
|
299
|
-
@ssd = value
|
305
|
+
@ssd = value && value.to_s
|
300
306
|
end
|
301
307
|
|
302
308
|
# Sets the scale_convention attribute.
|
303
309
|
#
|
304
310
|
def scale_convention=(value)
|
305
|
-
|
306
|
-
@scale_convention = value
|
311
|
+
@scale_convention = value && value.to_s
|
307
312
|
end
|
308
313
|
|
309
314
|
# Sets the gantry_angle attribute.
|
310
315
|
#
|
311
316
|
def gantry_angle=(value)
|
312
|
-
|
313
|
-
@gantry_angle = value
|
317
|
+
@gantry_angle = value && value.to_s
|
314
318
|
end
|
315
319
|
|
316
320
|
# Sets the gantry_dir attribute.
|
317
321
|
#
|
318
322
|
def gantry_dir=(value)
|
319
|
-
|
320
|
-
@gantry_dir = value
|
323
|
+
@gantry_dir = value && value.to_s
|
321
324
|
end
|
322
325
|
|
323
326
|
# Sets the collimator_angle attribute.
|
324
327
|
#
|
325
328
|
def collimator_angle=(value)
|
326
|
-
|
327
|
-
@collimator_angle = value
|
329
|
+
@collimator_angle = value && value.to_s
|
328
330
|
end
|
329
331
|
|
330
332
|
# Sets the collimator_dir attribute.
|
331
333
|
#
|
332
334
|
def collimator_dir=(value)
|
333
|
-
|
334
|
-
@collimator_dir = value
|
335
|
+
@collimator_dir = value && value.to_s
|
335
336
|
end
|
336
337
|
|
337
338
|
# Sets the field_x_mode attribute.
|
338
339
|
#
|
339
340
|
def field_x_mode=(value)
|
340
|
-
|
341
|
-
@field_x_mode = value
|
341
|
+
@field_x_mode = value && value.to_s
|
342
342
|
end
|
343
343
|
|
344
344
|
# Sets the field_x attribute.
|
345
345
|
#
|
346
346
|
def field_x=(value)
|
347
|
-
|
348
|
-
@field_x = value
|
347
|
+
@field_x = value && value.to_s
|
349
348
|
end
|
350
349
|
|
351
350
|
# Sets the collimator_x1 attribute.
|
352
351
|
#
|
353
352
|
def collimator_x1=(value)
|
354
|
-
|
355
|
-
@collimator_x1 = value
|
353
|
+
@collimator_x1 = value && value.to_s
|
356
354
|
end
|
357
355
|
|
358
356
|
# Sets the collimator_x2 attribute.
|
359
357
|
#
|
360
358
|
def collimator_x2=(value)
|
361
|
-
|
362
|
-
@collimator_x2 = value
|
359
|
+
@collimator_x2 = value && value.to_s
|
363
360
|
end
|
364
361
|
|
365
362
|
# Sets the field_y_mode attribute.
|
366
363
|
#
|
367
364
|
def field_y_mode=(value)
|
368
|
-
|
369
|
-
@field_y_mode = value
|
365
|
+
@field_y_mode = value && value.to_s
|
370
366
|
end
|
371
367
|
|
372
368
|
# Sets the field_y attribute.
|
373
369
|
#
|
374
370
|
def field_y=(value)
|
375
|
-
|
376
|
-
@field_y = value
|
371
|
+
@field_y = value && value.to_s
|
377
372
|
end
|
378
373
|
|
379
374
|
# Sets the collimator_y1 attribute.
|
380
375
|
#
|
381
376
|
def collimator_y1=(value)
|
382
|
-
|
383
|
-
@collimator_y1 = value
|
377
|
+
@collimator_y1 = value && value.to_s
|
384
378
|
end
|
385
379
|
|
386
380
|
# Sets the collimator_y2 attribute.
|
387
381
|
#
|
388
382
|
def collimator_y2=(value)
|
389
|
-
|
390
|
-
@collimator_y2 = value
|
383
|
+
@collimator_y2 = value && value.to_s
|
391
384
|
end
|
392
385
|
|
393
386
|
# Sets the couch_vertical attribute.
|
394
387
|
#
|
395
388
|
def couch_vertical=(value)
|
396
|
-
|
397
|
-
@couch_vertical = value
|
389
|
+
@couch_vertical = value && value.to_s
|
398
390
|
end
|
399
391
|
|
400
392
|
# Sets the couch_lateral attribute.
|
401
393
|
#
|
402
394
|
def couch_lateral=(value)
|
403
|
-
|
404
|
-
@couch_lateral = value
|
395
|
+
@couch_lateral = value && value.to_s
|
405
396
|
end
|
406
397
|
|
407
398
|
# Sets the couch_longitudinal attribute.
|
408
399
|
#
|
409
400
|
def couch_longitudinal=(value)
|
410
|
-
|
411
|
-
@couch_longitudinal = value
|
401
|
+
@couch_longitudinal = value && value.to_s
|
412
402
|
end
|
413
403
|
|
414
404
|
# Sets the couch_angle attribute.
|
415
405
|
#
|
416
406
|
def couch_angle=(value)
|
417
|
-
|
418
|
-
@couch_angle = value
|
407
|
+
@couch_angle = value && value.to_s
|
419
408
|
end
|
420
409
|
|
421
410
|
# Sets the couch_dir attribute.
|
422
411
|
#
|
423
412
|
def couch_dir=(value)
|
424
|
-
|
425
|
-
@couch_dir = value
|
413
|
+
@couch_dir = value && value.to_s
|
426
414
|
end
|
427
415
|
|
428
416
|
# Sets the couch_pedestal attribute.
|
429
417
|
#
|
430
418
|
def couch_pedestal=(value)
|
431
|
-
|
432
|
-
@couch_pedestal = value
|
419
|
+
@couch_pedestal = value && value.to_s
|
433
420
|
end
|
434
421
|
|
435
422
|
# Sets the couch_ped_dir attribute.
|
436
423
|
#
|
437
424
|
def couch_ped_dir=(value)
|
438
|
-
|
439
|
-
@couch_ped_dir = value
|
425
|
+
@couch_ped_dir = value && value.to_s
|
440
426
|
end
|
441
427
|
|
428
|
+
|
429
|
+
private
|
430
|
+
|
431
|
+
|
432
|
+
# Returns the attributes of this instance in an array (for comparison purposes).
|
433
|
+
#
|
434
|
+
alias_method :state, :values
|
435
|
+
|
442
436
|
end
|
443
437
|
|
444
438
|
end
|