rtp-connect 1.0

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.
@@ -0,0 +1,218 @@
1
+ module RTP
2
+
3
+ # The Prescription site class.
4
+ #
5
+ # === Relations
6
+ #
7
+ # * Parent: Plan
8
+ # * Children: SiteSetup, (SimulationField), Field
9
+ #
10
+ class Prescription < Record
11
+
12
+ # The Record which this instance belongs to.
13
+ attr_reader :parent
14
+ # The SiteSetup record (if any) that belongs to this Prescription.
15
+ attr_reader :site_setup
16
+ # An array of Field records (if any) that belongs to this Prescription.
17
+ attr_reader :fields
18
+ attr_reader :course_id
19
+ attr_reader :rx_site_name
20
+ attr_reader :technique
21
+ attr_reader :modality
22
+ attr_reader :dose_spec
23
+ attr_reader :rx_depth
24
+ attr_reader :dose_ttl
25
+ attr_reader :dose_tx
26
+ attr_reader :pattern
27
+ attr_reader :rx_note
28
+ attr_reader :number_of_fields
29
+
30
+ # Creates a new Prescription site by parsing a RTPConnect string line.
31
+ #
32
+ # === Parameters
33
+ #
34
+ # * <tt>string</tt> -- A string containing a prescription site record.
35
+ # * <tt>parent</tt> -- A Record which is used to determine the proper parent of this instance.
36
+ #
37
+ def self.load(string, parent)
38
+ raise ArgumentError, "Invalid argument 'string'. Expected String, got #{string.class}." unless string.is_a?(String)
39
+ raise ArgumentError, "Invalid argument 'parent'. Expected RTP::Record, got #{parent.class}." unless parent.is_a?(RTP::Record)
40
+ # Get the quote-less values:
41
+ values = string.values
42
+ raise ArgumentError, "Invalid argument 'string': Expected exactly 13 elements, got #{values.length}." unless values.length == 13
43
+ p = self.new(parent)
44
+ # Assign the values to attributes:
45
+ p.keyword = values[0]
46
+ p.course_id = values[1]
47
+ p.rx_site_name = values[2]
48
+ p.technique = values[3]
49
+ p.modality = values[4]
50
+ p.dose_spec = values[5]
51
+ p.rx_depth = values[6]
52
+ p.dose_ttl = values[7]
53
+ p.dose_tx = values[8]
54
+ p.pattern = values[9]
55
+ p.rx_note = values[10]
56
+ p.number_of_fields = values[11]
57
+ p.crc = values[12]
58
+ return p
59
+ end
60
+
61
+ # Creates a new Prescription site.
62
+ #
63
+ # === Parameters
64
+ #
65
+ # * <tt>parent</tt> -- A Record which is used to determine the proper parent of this instance.
66
+ #
67
+ def initialize(parent)
68
+ raise ArgumentError, "Invalid argument 'parent'. Expected RTP::Record, got #{parent.class}." unless parent.is_a?(RTP::Record)
69
+ # Child objects:
70
+ @site_setup = nil
71
+ @fields = Array.new
72
+ # Parent relation:
73
+ @parent = get_parent(parent, Plan)
74
+ @parent.add_prescription(self)
75
+ @keyword = 'RX_DEF'
76
+ end
77
+
78
+ # Adds a treatment Field record to this instance.
79
+ #
80
+ def add_field(child)
81
+ raise ArgumentError, "Invalid argument 'child'. Expected RTP::Field, got #{child.class}." unless child.is_a?(RTP::Field)
82
+ @fields << child
83
+ end
84
+
85
+ # Connects a Site setup record to this instance.
86
+ #
87
+ def add_site_setup(child)
88
+ raise ArgumentError, "Invalid argument 'child'. Expected RTP::SiteSetup, got #{child.class}." unless child.is_a?(RTP::SiteSetup)
89
+ @site_setup = child
90
+ end
91
+
92
+ # Returns the a properly sorted array of the child records of this instance.
93
+ #
94
+ def children
95
+ return [@site_setup, @fields].flatten.compact
96
+ end
97
+
98
+ # Returns the values of this instance in an array.
99
+ # The values does not include the CRC.
100
+ #
101
+ def values
102
+ return [
103
+ @keyword,
104
+ @course_id,
105
+ @rx_site_name,
106
+ @technique,
107
+ @modality,
108
+ @dose_spec,
109
+ @rx_depth,
110
+ @dose_ttl,
111
+ @dose_tx,
112
+ @pattern,
113
+ @rx_note,
114
+ @number_of_fields
115
+ ]
116
+ end
117
+
118
+ # Writes the Prescription object + any hiearchy of child objects,
119
+ # to a properly formatted RTPConnect ascii string.
120
+ #
121
+ def to_str
122
+ str = encode
123
+ if children
124
+ children.each do |child|
125
+ str += child.to_str
126
+ end
127
+ end
128
+ return str
129
+ end
130
+
131
+ # Sets the keyword attribute.
132
+ #
133
+ def keyword=(value)
134
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
135
+ raise ArgumentError, "Invalid keyword. Expected 'RX_DEF', got #{value}." unless value.upcase == "RX_DEF"
136
+ @keyword = value
137
+ end
138
+
139
+ # Sets the course_id attribute.
140
+ #
141
+ def course_id=(value)
142
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
143
+ @course_id = value
144
+ end
145
+
146
+ # Sets the rx_site_name attribute.
147
+ #
148
+ def rx_site_name=(value)
149
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
150
+ @rx_site_name = value
151
+ end
152
+
153
+ # Sets the technique attribute.
154
+ #
155
+ def technique=(value)
156
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
157
+ @technique = value
158
+ end
159
+
160
+ # Sets the modality attribute.
161
+ #
162
+ def modality=(value)
163
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
164
+ @modality = value
165
+ end
166
+
167
+ # Sets the dose_spec attribute.
168
+ #
169
+ def dose_spec=(value)
170
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
171
+ @dose_spec = value
172
+ end
173
+
174
+ # Sets the rx_depth attribute.
175
+ #
176
+ def rx_depth=(value)
177
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
178
+ @rx_depth = value
179
+ end
180
+
181
+ # Sets the dose_ttl attribute.
182
+ #
183
+ def dose_ttl=(value)
184
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
185
+ @dose_ttl = value
186
+ end
187
+
188
+ # Sets the dose_tx attribute.
189
+ #
190
+ def dose_tx=(value)
191
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
192
+ @dose_tx = value
193
+ end
194
+
195
+ # Sets the pattern attribute.
196
+ #
197
+ def pattern=(value)
198
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
199
+ @pattern = value
200
+ end
201
+
202
+ # Sets the rx_note attribute.
203
+ #
204
+ def rx_note=(value)
205
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
206
+ @rx_note = value
207
+ end
208
+
209
+ # Sets the number_of_fields attribute.
210
+ #
211
+ def number_of_fields=(value)
212
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
213
+ @number_of_fields = value
214
+ end
215
+
216
+ end
217
+
218
+ end
@@ -0,0 +1,37 @@
1
+ module RTP
2
+
3
+ class Record
4
+
5
+ attr_reader :keyword
6
+ attr_reader :crc
7
+
8
+ # Encodes a string from the contents of this instance.
9
+ # This produces the full line, including a computed CRC checksum.
10
+ #
11
+ def encode
12
+ content = values.encode + ","
13
+ checksum = content.checksum
14
+ # Complete string is content + checksum (in double quotes) + carriage return + line feed
15
+ return content + checksum.to_s.wrap + "\r\n"
16
+ end
17
+
18
+ # Follows the tree of parents until the appropriate parent of the requesting record is found.
19
+ #
20
+ def get_parent(last_parent, klass)
21
+ if last_parent.is_a?(klass)
22
+ return last_parent
23
+ else
24
+ return last_parent.get_parent(last_parent.parent, klass)
25
+ end
26
+ end
27
+
28
+ # Setting the keyword attribute.
29
+ #
30
+ def crc=(value)
31
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
32
+ @crc = value
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,82 @@
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 extensions are focused on analyzing RTPConnect strings.
6
+ #
7
+ class String
8
+
9
+ # Returns the CRC checksum (16 bit unsigned integer) for a given string.
10
+ #
11
+ def checksum
12
+ crc = RTP::CRC_SEED
13
+ self.each_codepoint do |byte|
14
+ crc = RTP::CRC_TABLE[(crc ^ byte) & 0xff] ^ (crc >> 8)
15
+ end
16
+ return crc
17
+ end
18
+
19
+ # Returns the elements of a line from the RTPConnect ascii string.
20
+ # The line consists of elements (surrounded by double quotes), separated by comma.
21
+ # This method performs a split based on comma and returns the element strings in an array.
22
+ #
23
+ def elements
24
+ return self.split(',')
25
+ end
26
+
27
+ # Removes double quotes from a string.
28
+ # Returns the quote-less string.
29
+ #
30
+ def value
31
+ return self.gsub('"', '')
32
+ end
33
+
34
+ # Returns the element values of a line from the RTPConnect ascii string.
35
+ # The line consists of values (surrounded by double quotes), separated by comma.
36
+ # This method performs a split based on comma and removes the quotes from each value,
37
+ # and the resulting quote-less value strings are returned in an array.
38
+ #
39
+ def values
40
+ original = self.split(',')
41
+ processed = Array.new
42
+ original.collect {|element| processed << element.gsub('"', '')}
43
+ return processed
44
+ end
45
+
46
+ # Wraps double quotes around the string.
47
+ #
48
+ def wrap
49
+ return '"' + self + '"'
50
+ end
51
+
52
+ end
53
+
54
+
55
+ # Extension to the Array class. These extensions are focused on creating RTPConnect
56
+ # strings from an array of values.
57
+ #
58
+ class Array
59
+
60
+ # Encodes an RTPConnect string from an array of values.
61
+ # Each value in the array is wrapped with double quotes,
62
+ # before the values are joined with a comma separator.
63
+ #
64
+ def encode
65
+ wrapped = self.collect{|value| value.wrap}
66
+ return wrapped.join(',')
67
+ end
68
+
69
+ end
70
+
71
+ # An extension to the NilClass, facilitating a transformation from nil to
72
+ # an empty (double quoted) string in the case of undefined attributes.
73
+ #
74
+ class NilClass
75
+
76
+ # Returns a double quoted, but otherwise empty string.
77
+ #
78
+ def wrap
79
+ return '""'
80
+ end
81
+
82
+ end
@@ -0,0 +1,227 @@
1
+ module RTP
2
+
3
+ # The SiteSetup class.
4
+ #
5
+ # === Relations
6
+ #
7
+ # * Parent: Prescription
8
+ # * Children: none
9
+ #
10
+ class SiteSetup < Record
11
+
12
+ # The Record which this instance belongs to.
13
+ attr_reader :parent
14
+ attr_reader :rx_site_name
15
+ attr_reader :patient_orientation
16
+ attr_reader :treatment_machine
17
+ attr_reader :tolerance_table
18
+ attr_reader :iso_pos_x
19
+ attr_reader :iso_pos_y
20
+ attr_reader :iso_pos_z
21
+ attr_reader :structure_set_uid
22
+ attr_reader :frame_of_ref_uid
23
+ attr_reader :couch_vertical
24
+ attr_reader :couch_lateral
25
+ attr_reader :couch_longitudinal
26
+ attr_reader :couch_angle
27
+ attr_reader :couch_pedestal
28
+
29
+ # Creates a new SiteSetup setup by parsing a RTPConnect string line.
30
+ #
31
+ # === Parameters
32
+ #
33
+ # * <tt>string</tt> -- A string containing a site setup record.
34
+ # * <tt>parent</tt> -- A Record which is used to determine the proper parent of this instance.
35
+ #
36
+ def self.load(string, parent)
37
+ raise ArgumentError, "Invalid argument 'string'. Expected String, got #{string.class}." unless string.is_a?(String)
38
+ raise ArgumentError, "Invalid argument 'parent'. Expected RTP::Prescription, got #{parent.class}." unless parent.is_a?(RTP::Prescription)
39
+ # Get the quote-less values:
40
+ values = string.values
41
+ raise ArgumentError, "Invalid argument 'string': Expected exactly 16 elements, got #{values.length}." unless values.length == 16
42
+ s = self.new(parent)
43
+ # Assign the values to attributes:
44
+ s.keyword = values[0]
45
+ s.rx_site_name = values[1]
46
+ s.patient_orientation = values[2]
47
+ s.treatment_machine = values[3]
48
+ s.tolerance_table = values[4]
49
+ s.iso_pos_x = values[5]
50
+ s.iso_pos_y = values[6]
51
+ s.iso_pos_z = values[7]
52
+ s.structure_set_uid = values[8]
53
+ s.frame_of_ref_uid = values[9]
54
+ s.couch_vertical = values[10]
55
+ s.couch_lateral = values[11]
56
+ s.couch_longitudinal = values[12]
57
+ s.couch_angle = values[13]
58
+ s.couch_pedestal = values[14]
59
+ s.crc = values[15]
60
+ return s
61
+ end
62
+
63
+ # Creates a new SiteSetup.
64
+ #
65
+ # === Parameters
66
+ #
67
+ # * <tt>parent</tt> -- A Record which is used to determine the proper parent of this instance.
68
+ #
69
+ def initialize(parent)
70
+ raise ArgumentError, "Invalid argument 'parent'. Expected RTP::Prescription, got #{parent.class}." unless parent.is_a?(RTP::Prescription)
71
+ # Parent relation:
72
+ @parent = get_parent(parent, Prescription)
73
+ @parent.add_site_setup(self)
74
+ @keyword = 'SITE_SETUP_DEF'
75
+ end
76
+
77
+ # Returns an empty array, as these instances are child-less by definition.
78
+ #
79
+ def children
80
+ return Array.new
81
+ end
82
+
83
+ # Returns the values of this instance in an array.
84
+ # The values does not include the CRC.
85
+ #
86
+ def values
87
+ return [
88
+ @keyword,
89
+ @rx_site_name,
90
+ @patient_orientation,
91
+ @treatment_machine,
92
+ @tolerance_table,
93
+ @iso_pos_x,
94
+ @iso_pos_y,
95
+ @iso_pos_z,
96
+ @structure_set_uid,
97
+ @frame_of_ref_uid,
98
+ @couch_vertical,
99
+ @couch_lateral,
100
+ @couch_longitudinal,
101
+ @couch_angle,
102
+ @couch_pedestal
103
+ ]
104
+ end
105
+
106
+ # Writes the SiteSetup object + any hiearchy of child objects,
107
+ # to a properly formatted RTPConnect ascii string.
108
+ #
109
+ def to_str
110
+ str = encode
111
+ if children
112
+ children.each do |child|
113
+ str += child.to_str
114
+ end
115
+ end
116
+ return str
117
+ end
118
+
119
+ # Sets the keyword attribute.
120
+ #
121
+ def keyword=(value)
122
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
123
+ raise ArgumentError, "Invalid keyword. Expected 'SITE_SETUP_DEF', got #{value}." unless value.upcase == "SITE_SETUP_DEF"
124
+ @keyword = value
125
+ end
126
+
127
+ # Sets the rx_site_name attribute.
128
+ #
129
+ def rx_site_name=(value)
130
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
131
+ @rx_site_name = value
132
+ end
133
+
134
+ # Sets the patient_orientation attribute.
135
+ #
136
+ def patient_orientation=(value)
137
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
138
+ @patient_orientation = value
139
+ end
140
+
141
+ # Sets the treatment_machine attribute.
142
+ #
143
+ def treatment_machine=(value)
144
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
145
+ @treatment_machine = value
146
+ end
147
+
148
+ # Sets the tolerance_table attribute.
149
+ #
150
+ def tolerance_table=(value)
151
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
152
+ @tolerance_table = value
153
+ end
154
+
155
+ # Sets the iso_pos_x attribute.
156
+ #
157
+ def iso_pos_x=(value)
158
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
159
+ @iso_pos_x = value
160
+ end
161
+
162
+ # Sets the iso_pos_y attribute.
163
+ #
164
+ def iso_pos_y=(value)
165
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
166
+ @iso_pos_y = value
167
+ end
168
+
169
+ # Sets the iso_pos_z attribute.
170
+ #
171
+ def iso_pos_z=(value)
172
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
173
+ @iso_pos_z = value
174
+ end
175
+
176
+ # Sets the structure_set_uid attribute.
177
+ #
178
+ def structure_set_uid=(value)
179
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
180
+ @structure_set_uid = value
181
+ end
182
+
183
+ # Sets the frame_of_ref_uid attribute.
184
+ #
185
+ def frame_of_ref_uid=(value)
186
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
187
+ @frame_of_ref_uid = value
188
+ end
189
+
190
+ # Sets the couch_vertical attribute.
191
+ #
192
+ def couch_vertical=(value)
193
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
194
+ @couch_vertical = value
195
+ end
196
+
197
+ # Sets the couch_lateral attribute.
198
+ #
199
+ def couch_lateral=(value)
200
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
201
+ @couch_lateral = value
202
+ end
203
+
204
+ # Sets the couch_longitudinal attribute.
205
+ #
206
+ def couch_longitudinal=(value)
207
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
208
+ @couch_longitudinal = value
209
+ end
210
+
211
+ # Sets the couch_angle attribute.
212
+ #
213
+ def couch_angle=(value)
214
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
215
+ @couch_angle = value
216
+ end
217
+
218
+ # Sets the couch_pedestal attribute.
219
+ #
220
+ def couch_pedestal=(value)
221
+ raise ArgumentError, "Invalid argument 'value'. Expected String, got #{value.class}." unless value.is_a?(String)
222
+ @couch_pedestal = value
223
+ end
224
+
225
+ end
226
+
227
+ end