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 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