rtp-connect 1.0 → 1.1

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/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.to_str
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 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.
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 Lervag
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 Lervag
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 to_str
196
+ def to_s
178
197
  str = encode
179
198
  if children
180
199
  children.each do |child|
181
- str += child.to_str
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
- 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
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
- 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
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
- 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"
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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
- raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
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