rtp-connect 1.1 → 1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +30 -19
- data/COPYING +674 -674
- data/Gemfile +3 -0
- data/Gemfile.lock +35 -0
- data/README.rdoc +12 -6
- data/lib/rtp-connect.rb +24 -22
- data/lib/rtp-connect/constants.rb +57 -57
- data/lib/rtp-connect/control_point.rb +176 -86
- data/lib/rtp-connect/dose_tracking.rb +222 -0
- data/lib/rtp-connect/extended_field.rb +56 -26
- data/lib/rtp-connect/field.rb +163 -43
- data/lib/rtp-connect/logging.rb +155 -158
- data/lib/rtp-connect/methods.rb +3 -4
- data/lib/rtp-connect/plan.rb +136 -52
- data/lib/rtp-connect/plan_to_dcm.rb +503 -0
- data/lib/rtp-connect/prescription.rb +71 -23
- data/lib/rtp-connect/record.rb +18 -2
- data/lib/rtp-connect/ruby_extensions.rb +90 -81
- data/lib/rtp-connect/site_setup.rb +78 -28
- data/lib/rtp-connect/version.rb +5 -5
- data/rakefile.rb +29 -0
- data/rtp-connect.gemspec +29 -0
- metadata +105 -53
@@ -2,10 +2,9 @@ module RTP
|
|
2
2
|
|
3
3
|
# The Prescription site class.
|
4
4
|
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# * Children: SiteSetup, (SimulationField), Field
|
5
|
+
# @note Relations:
|
6
|
+
# * Parent: Plan
|
7
|
+
# * Children: SiteSetup, Field
|
9
8
|
#
|
10
9
|
class Prescription < Record
|
11
10
|
|
@@ -29,10 +28,10 @@ module RTP
|
|
29
28
|
|
30
29
|
# Creates a new Prescription site by parsing a RTPConnect string line.
|
31
30
|
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
31
|
+
# @param [#to_s] string the prescription site definition record string line
|
32
|
+
# @param [Record] parent a record which is used to determine the proper parent of this instance
|
33
|
+
# @return [Prescription] the created Precription instance
|
34
|
+
# @raise [ArgumentError] if given a string containing an invalid number of elements
|
36
35
|
#
|
37
36
|
def self.load(string, parent)
|
38
37
|
# Get the quote-less values:
|
@@ -58,9 +57,7 @@ module RTP
|
|
58
57
|
|
59
58
|
# Creates a new Prescription site.
|
60
59
|
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
# * <tt>parent</tt> -- A Record which is used to determine the proper parent of this instance.
|
60
|
+
# @param [Record] parent a record which is used to determine the proper parent of this instance
|
64
61
|
#
|
65
62
|
def initialize(parent)
|
66
63
|
# Child objects:
|
@@ -72,7 +69,13 @@ module RTP
|
|
72
69
|
@keyword = 'RX_DEF'
|
73
70
|
end
|
74
71
|
|
75
|
-
#
|
72
|
+
# Checks for equality.
|
73
|
+
#
|
74
|
+
# Other and self are considered equivalent if they are
|
75
|
+
# of compatible types and their attributes are equivalent.
|
76
|
+
#
|
77
|
+
# @param other an object to be compared with self.
|
78
|
+
# @return [Boolean] true if self and other are considered equivalent
|
76
79
|
#
|
77
80
|
def ==(other)
|
78
81
|
if other.respond_to?(:to_prescription)
|
@@ -82,32 +85,44 @@ module RTP
|
|
82
85
|
|
83
86
|
alias_method :eql?, :==
|
84
87
|
|
85
|
-
# Adds a treatment
|
88
|
+
# Adds a treatment field record to this instance.
|
89
|
+
#
|
90
|
+
# @param [Field] child a Field instance which is to be associated with self
|
86
91
|
#
|
87
92
|
def add_field(child)
|
88
93
|
@fields << child.to_field
|
89
94
|
end
|
90
95
|
|
91
|
-
#
|
96
|
+
# Adds a site setup record to this instance.
|
97
|
+
#
|
98
|
+
# @param [SiteSetup] child a SiteSetup instance which is to be associated with self
|
92
99
|
#
|
93
100
|
def add_site_setup(child)
|
94
101
|
@site_setup = child.to_site_setup
|
95
102
|
end
|
96
103
|
|
97
|
-
#
|
104
|
+
# Collects the child records of this instance in a properly sorted array.
|
105
|
+
#
|
106
|
+
# @return [Array<SiteSetup, Field>] a sorted array of self's child records
|
98
107
|
#
|
99
108
|
def children
|
100
109
|
return [@site_setup, @fields].flatten.compact
|
101
110
|
end
|
102
111
|
|
103
|
-
#
|
112
|
+
# Computes a hash code for this object.
|
113
|
+
#
|
114
|
+
# @note Two objects with the same attributes will have the same hash code.
|
115
|
+
#
|
116
|
+
# @return [Fixnum] the object's hash code
|
104
117
|
#
|
105
118
|
def hash
|
106
119
|
state.hash
|
107
120
|
end
|
108
121
|
|
109
|
-
#
|
110
|
-
#
|
122
|
+
# Collects the values (attributes) of this instance.
|
123
|
+
#
|
124
|
+
# @note The CRC is not considered part of the actual values and is excluded.
|
125
|
+
# @return [Array<String>] an array of attributes (in the same order as they appear in the RTP string)
|
111
126
|
#
|
112
127
|
def values
|
113
128
|
return [
|
@@ -128,13 +143,17 @@ module RTP
|
|
128
143
|
|
129
144
|
# Returns self.
|
130
145
|
#
|
146
|
+
# @return [Prescription] self
|
147
|
+
#
|
131
148
|
def to_prescription
|
132
149
|
self
|
133
150
|
end
|
134
151
|
|
135
|
-
#
|
152
|
+
# Encodes the Prescription object + any hiearchy of child objects,
|
136
153
|
# to a properly formatted RTPConnect ascii string.
|
137
154
|
#
|
155
|
+
# @return [String] an RTP string with a single or multiple lines/records
|
156
|
+
#
|
138
157
|
def to_s
|
139
158
|
str = encode
|
140
159
|
if children
|
@@ -149,6 +168,10 @@ module RTP
|
|
149
168
|
|
150
169
|
# Sets the keyword attribute.
|
151
170
|
#
|
171
|
+
# @note Since only a specific string is accepted, this is more of an argument check than a traditional setter method
|
172
|
+
# @param [#to_s] value the new attribute value
|
173
|
+
# @raise [ArgumentError] if given an unexpected keyword
|
174
|
+
#
|
152
175
|
def keyword=(value)
|
153
176
|
value = value.to_s.upcase
|
154
177
|
raise ArgumentError, "Invalid keyword. Expected 'RX_DEF', got #{value}." unless value == "RX_DEF"
|
@@ -157,75 +180,100 @@ module RTP
|
|
157
180
|
|
158
181
|
# Sets the course_id attribute.
|
159
182
|
#
|
183
|
+
# @param [nil, #to_s] value the new attribute value
|
184
|
+
#
|
160
185
|
def course_id=(value)
|
161
186
|
@course_id = value && value.to_s
|
162
187
|
end
|
163
188
|
|
164
189
|
# Sets the rx_site_name attribute.
|
165
190
|
#
|
191
|
+
# @param [nil, #to_s] value the new attribute value
|
192
|
+
#
|
166
193
|
def rx_site_name=(value)
|
167
194
|
@rx_site_name = value && value.to_s
|
168
195
|
end
|
169
196
|
|
170
197
|
# Sets the technique attribute.
|
171
198
|
#
|
199
|
+
# @param [nil, #to_s] value the new attribute value
|
200
|
+
#
|
172
201
|
def technique=(value)
|
173
202
|
@technique = value && value.to_s
|
174
203
|
end
|
175
204
|
|
176
205
|
# Sets the modality attribute.
|
177
206
|
#
|
207
|
+
# @param [nil, #to_s] value the new attribute value
|
208
|
+
#
|
178
209
|
def modality=(value)
|
179
210
|
@modality = value && value.to_s
|
180
211
|
end
|
181
212
|
|
182
213
|
# Sets the dose_spec attribute.
|
183
214
|
#
|
215
|
+
# @param [nil, #to_s] value the new attribute value
|
216
|
+
#
|
184
217
|
def dose_spec=(value)
|
185
218
|
@dose_spec = value && value.to_s
|
186
219
|
end
|
187
220
|
|
188
221
|
# Sets the rx_depth attribute.
|
189
222
|
#
|
223
|
+
# @param [nil, #to_s] value the new attribute value
|
224
|
+
#
|
190
225
|
def rx_depth=(value)
|
191
226
|
@rx_depth = value && value.to_s
|
192
227
|
end
|
193
228
|
|
194
229
|
# Sets the dose_ttl attribute.
|
195
230
|
#
|
231
|
+
# @param [nil, #to_s] value the new attribute value
|
232
|
+
#
|
196
233
|
def dose_ttl=(value)
|
197
|
-
@dose_ttl = value && value.to_s
|
234
|
+
@dose_ttl = value && value.to_s.strip
|
198
235
|
end
|
199
236
|
|
200
237
|
# Sets the dose_tx attribute.
|
201
238
|
#
|
239
|
+
# @param [nil, #to_s] value the new attribute value
|
240
|
+
#
|
202
241
|
def dose_tx=(value)
|
203
|
-
@dose_tx = value && value.to_s
|
242
|
+
@dose_tx = value && value.to_s.strip
|
204
243
|
end
|
205
244
|
|
206
245
|
# Sets the pattern attribute.
|
207
246
|
#
|
247
|
+
# @param [nil, #to_s] value the new attribute value
|
248
|
+
#
|
208
249
|
def pattern=(value)
|
209
250
|
@pattern = value && value.to_s
|
210
251
|
end
|
211
252
|
|
212
253
|
# Sets the rx_note attribute.
|
213
254
|
#
|
255
|
+
# @param [nil, #to_s] value the new attribute value
|
256
|
+
#
|
214
257
|
def rx_note=(value)
|
215
258
|
@rx_note = value && value.to_s
|
216
259
|
end
|
217
260
|
|
218
261
|
# Sets the number_of_fields attribute.
|
219
262
|
#
|
263
|
+
# @param [nil, #to_s] value the new attribute value
|
264
|
+
#
|
220
265
|
def number_of_fields=(value)
|
221
|
-
@number_of_fields = value && value.to_s
|
266
|
+
@number_of_fields = value && value.to_s.strip
|
222
267
|
end
|
223
268
|
|
224
269
|
|
225
270
|
private
|
226
271
|
|
227
272
|
|
228
|
-
#
|
273
|
+
# Collects the attributes of this instance.
|
274
|
+
#
|
275
|
+
# @note The CRC is not considered part of the attributes of interest and is excluded
|
276
|
+
# @return [Array<String>] an array of attributes
|
229
277
|
#
|
230
278
|
alias_method :state, :values
|
231
279
|
|
data/lib/rtp-connect/record.rb
CHANGED
@@ -1,18 +1,29 @@
|
|
1
1
|
module RTP
|
2
2
|
|
3
|
+
# The Record class contains attributes and methods that are common
|
4
|
+
# for the various record types defined in the RTPConnect standard.
|
5
|
+
#
|
3
6
|
class Record
|
4
7
|
|
8
|
+
# The keyword defines the record type of a particular RTP string line.
|
5
9
|
attr_reader :keyword
|
10
|
+
# The CRC is used to validate the integrity of the content of the RTP string line.
|
6
11
|
attr_reader :crc
|
7
12
|
|
8
|
-
#
|
13
|
+
# Sets the crc (checksum) attribute.
|
14
|
+
#
|
15
|
+
# @note This value is not used when creating an RTP string from a record (a new crc is calculated)
|
16
|
+
# @param [#to_s] value the new attribute value
|
9
17
|
#
|
10
18
|
def crc=(value)
|
11
19
|
@crc = value.to_s
|
12
20
|
end
|
13
21
|
|
14
22
|
# Encodes a string from the contents of this instance.
|
15
|
-
#
|
23
|
+
#
|
24
|
+
# This produces the full record string line, including a computed CRC checksum.
|
25
|
+
#
|
26
|
+
# @return [String] a proper RTPConnect type CSV string
|
16
27
|
#
|
17
28
|
def encode
|
18
29
|
content = values.encode + ","
|
@@ -23,6 +34,9 @@ module RTP
|
|
23
34
|
|
24
35
|
# Follows the tree of parents until the appropriate parent of the requesting record is found.
|
25
36
|
#
|
37
|
+
# @param [Record] last_parent the previous parent (the record from the previous line in the RTP file)
|
38
|
+
# @param [Record] klass the expected parent record class of this record (e.g. Plan, Field)
|
39
|
+
#
|
26
40
|
def get_parent(last_parent, klass)
|
27
41
|
if last_parent.is_a?(klass)
|
28
42
|
return last_parent
|
@@ -33,6 +47,8 @@ module RTP
|
|
33
47
|
|
34
48
|
# Returns self.
|
35
49
|
#
|
50
|
+
# @return [Record] self
|
51
|
+
#
|
36
52
|
def to_record
|
37
53
|
self
|
38
54
|
end
|
@@ -1,82 +1,91 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
# This file contains extensions to the Ruby library which are used by the RTPConnect library.
|
4
|
-
|
5
|
-
# Extension to the String class. These
|
6
|
-
#
|
7
|
-
class String
|
8
|
-
|
9
|
-
#
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
#
|
22
|
-
#
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
#
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
#
|
38
|
-
#
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# This file contains extensions to the Ruby library which are used by the RTPConnect library.
|
4
|
+
|
5
|
+
# Extension to the String class. These facilitate processing and analysis of RTPConnect strings.
|
6
|
+
#
|
7
|
+
class String
|
8
|
+
|
9
|
+
# Determines the checksum (CRC) for a given string.
|
10
|
+
#
|
11
|
+
# @return [Fixnum] the checksum (a 16 bit unsigned integer)
|
12
|
+
#
|
13
|
+
def checksum
|
14
|
+
crc = RTP::CRC_SEED
|
15
|
+
self.each_codepoint do |byte|
|
16
|
+
crc = RTP::CRC_TABLE[(crc ^ byte) & 0xff] ^ (crc >> 8)
|
17
|
+
end
|
18
|
+
return crc
|
19
|
+
end
|
20
|
+
|
21
|
+
# Splits the elements of a string separated by comma.
|
22
|
+
#
|
23
|
+
# @return [Array<String>] an array of the string values originally separated by a comma
|
24
|
+
#
|
25
|
+
def elements
|
26
|
+
self.split(',')
|
27
|
+
end
|
28
|
+
|
29
|
+
# Removes double quotes from a string.
|
30
|
+
#
|
31
|
+
# @return [String] the string stripped of double-quotes
|
32
|
+
#
|
33
|
+
def value
|
34
|
+
self.gsub('"', '')
|
35
|
+
end
|
36
|
+
|
37
|
+
# Splits the elements of a CSV string (comma separated values),
|
38
|
+
# and removes double-quotes from the resulting string elements.
|
39
|
+
#
|
40
|
+
# @return [Array<String>] an array of the comma separated values
|
41
|
+
#
|
42
|
+
def values
|
43
|
+
original = CSV.parse(self).first
|
44
|
+
processed = Array.new
|
45
|
+
original.collect {|element| processed << element.gsub('"', '')}
|
46
|
+
return processed
|
47
|
+
end
|
48
|
+
|
49
|
+
# Wraps double quotes around the string.
|
50
|
+
#
|
51
|
+
# @return [String] the string padded with double-quotes
|
52
|
+
#
|
53
|
+
def wrap
|
54
|
+
'"' + self + '"'
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
# Extension to the Array class. These facilitate the creation
|
61
|
+
# of RTPConnect strings from an array of values.
|
62
|
+
#
|
63
|
+
class Array
|
64
|
+
|
65
|
+
# Encodes an RTPConnect string from an array of values.
|
66
|
+
# Each value in the array is wrapped with double quotes,
|
67
|
+
# before the values are joined with a comma separator.
|
68
|
+
#
|
69
|
+
# @return [String] a proper RTPConnect type CSV string
|
70
|
+
#
|
71
|
+
def encode
|
72
|
+
wrapped = self.collect{|value| value.wrap}
|
73
|
+
return wrapped.join(',')
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
# An extension to the NilClass, facilitating a transformation from nil to
|
79
|
+
# an empty (double quoted) string in the case of undefined attributes.
|
80
|
+
#
|
81
|
+
class NilClass
|
82
|
+
|
83
|
+
# Gives a double quoted, but otherwise empty string.
|
84
|
+
#
|
85
|
+
# @return [String] a string containing two double-quotes
|
86
|
+
#
|
87
|
+
def wrap
|
88
|
+
'""'
|
89
|
+
end
|
90
|
+
|
82
91
|
end
|