rtp-connect 1.2 → 1.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,12 @@
1
+ = 1.3
2
+
3
+ === 12th October, 2012
4
+
5
+ * Added support for the updated ExtendedField record values introduced in Mosaiq 2.4.
6
+ * Simply log a warning instead of raising an exception when reading a record with more values than excpected.
7
+ * Allow reading (incomplete) records that contain the required values but not all the optional ones (instead of raising an exception).
8
+
9
+
1
10
  = 1.2
2
11
 
3
12
  === 13th July, 2012
@@ -58,7 +58,10 @@ module RTP
58
58
  def self.load(string, parent)
59
59
  # Get the quote-less values:
60
60
  values = string.to_s.values
61
- raise ArgumentError, "Invalid argument 'string': Expected exactly 233 elements, got #{values.length}." unless values.length == 233
61
+ low_limit = 233
62
+ high_limit = 233
63
+ raise ArgumentError, "Invalid argument 'string': Expected at least #{low_limit} elements, got #{values.length}." if values.length < low_limit
64
+ RTP.logger.warn "The number of elements (#{values.length}) for this ControlPoint record exceeds the known number of data items for this record (#{high_limit}). This may indicate an invalid record or that the RTP format has recently been expanded with new items." if values.length > high_limit
62
65
  cp = self.new(parent)
63
66
  # Assign the values to attributes:
64
67
  cp.keyword = values[0]
@@ -95,7 +98,7 @@ module RTP
95
98
  cp.couch_ped_dir = values[31]
96
99
  cp.mlc_lp_a = [*values[32..131]]
97
100
  cp.mlc_lp_b = [*values[132..231]]
98
- cp.crc = values[232]
101
+ cp.crc = values[-1]
99
102
  return cp
100
103
  end
101
104
 
@@ -31,7 +31,10 @@ module RTP
31
31
  def self.load(string, parent)
32
32
  # Get the quote-less values:
33
33
  values = string.to_s.values
34
- raise ArgumentError, "Invalid argument 'string': Expected exactly 26 elements, got #{values.length}." unless values.length == 26
34
+ low_limit = 24
35
+ high_limit = 26
36
+ raise ArgumentError, "Invalid argument 'string': Expected at least #{low_limit} elements, got #{values.length}." if values.length < low_limit
37
+ RTP.logger.warn "The number of elements (#{values.length}) for this DoseTracking record exceeds the known number of data items for this record (#{high_limit}). This may indicate an invalid record or that the RTP format has recently been expanded with new items." if values.length > high_limit
35
38
  d = self.new(parent)
36
39
  # Assign the values to attributes:
37
40
  d.keyword = values[0]
@@ -41,7 +44,7 @@ module RTP
41
44
  d.region_coeffs = values.values_at(4, 6, 8, 10, 12, 14, 16, 18, 20, 22)
42
45
  d.actual_dose = values[23]
43
46
  d.actual_fractions = values[24]
44
- d.crc = values[25]
47
+ d.crc = values[-1]
45
48
  return d
46
49
  end
47
50
 
@@ -14,6 +14,10 @@ module RTP
14
14
  attr_reader :original_plan_uid
15
15
  attr_reader :original_beam_number
16
16
  attr_reader :original_beam_name
17
+ attr_reader :is_fff
18
+ attr_reader :accessory_code
19
+ attr_reader :accessory_type
20
+ attr_reader :high_dose_authorization
17
21
 
18
22
  # Creates a new (treatment) ExtendedField by parsing a RTPConnect string line.
19
23
  #
@@ -25,15 +29,23 @@ module RTP
25
29
  def self.load(string, parent)
26
30
  # Get the quote-less values:
27
31
  values = string.to_s.values
28
- raise ArgumentError, "Invalid argument 'string': Expected exactly 6 elements, got #{values.length}." unless values.length == 6
32
+ low_limit = 4
33
+ high_limit = 10
34
+ raise ArgumentError, "Invalid argument 'string': Expected at least #{low_limit} elements, got #{values.length}." if values.length < low_limit
35
+ RTP.logger.warn "The number of elements (#{values.length}) for this ExtendedField record exceeds the known number of data items for this record (#{high_limit}). This may indicate an invalid record or that the RTP format has recently been expanded with new items." if values.length > high_limit
29
36
  ef = self.new(parent)
30
- # Assign the values to attributes:
37
+ # Mandatory attributes:
31
38
  ef.keyword = values[0]
32
39
  ef.field_id = values[1]
33
40
  ef.original_plan_uid = values[2]
41
+ # Optional attributes:
34
42
  ef.original_beam_number = values[3]
35
43
  ef.original_beam_name = values[4]
36
- ef.crc = values[5]
44
+ ef.is_fff = values[5] if values[5]
45
+ ef.accessory_code = values[6]
46
+ ef.accessory_type = values[7]
47
+ ef.high_dose_authorization = values[8]
48
+ ef.crc = values[-1]
37
49
  return ef
38
50
  end
39
51
 
@@ -93,7 +105,11 @@ module RTP
93
105
  @field_id,
94
106
  @original_plan_uid,
95
107
  @original_beam_number,
96
- @original_beam_name
108
+ @original_beam_name,
109
+ @is_fff,
110
+ @accessory_code,
111
+ @accessory_type,
112
+ @high_dose_authorization
97
113
  ]
98
114
  end
99
115
 
@@ -166,6 +182,38 @@ module RTP
166
182
  @original_beam_name = value && value.to_s
167
183
  end
168
184
 
185
+ # Sets the is_fff attribute.
186
+ #
187
+ # @param [nil, #to_s] value the new attribute value
188
+ #
189
+ def is_fff=(value)
190
+ @is_fff = value && value.to_s
191
+ end
192
+
193
+ # Sets the accessory_code attribute.
194
+ #
195
+ # @param [nil, #to_s] value the new attribute value
196
+ #
197
+ def accessory_code=(value)
198
+ @accessory_code = value && value.to_s
199
+ end
200
+
201
+ # Sets the accessory_type attribute.
202
+ #
203
+ # @param [nil, #to_s] value the new attribute value
204
+ #
205
+ def accessory_type=(value)
206
+ @accessory_type = value && value.to_s
207
+ end
208
+
209
+ # Sets the high_dose_authorization attribute.
210
+ #
211
+ # @param [nil, #to_s] value the new attribute value
212
+ #
213
+ def high_dose_authorization=(value)
214
+ @high_dose_authorization = value && value.to_s
215
+ end
216
+
169
217
 
170
218
  private
171
219
 
@@ -72,7 +72,10 @@ module RTP
72
72
  def self.load(string, parent)
73
73
  # Get the quote-less values:
74
74
  values = string.to_s.values
75
- raise ArgumentError, "Invalid argument 'string': Expected exactly 49 elements, got #{values.length}." unless values.length == 49
75
+ low_limit = 27
76
+ high_limit = 49
77
+ raise ArgumentError, "Invalid argument 'string': Expected at least #{low_limit} elements, got #{values.length}." if values.length < low_limit
78
+ RTP.logger.warn "The number of elements (#{values.length}) for this Field record exceeds the known number of data items for this record (#{high_limit}). This may indicate an invalid record or that the RTP format has recently been expanded with new items." if values.length > high_limit
76
79
  f = self.new(parent)
77
80
  # Assign the values to attributes:
78
81
  f.keyword = values[0]
@@ -123,7 +126,7 @@ module RTP
123
126
  f.portfilm_delta_open = values[45]
124
127
  f.portfilm_mu_treat = values[46]
125
128
  f.portfilm_coeff_treat = values[47]
126
- f.crc = values[48]
129
+ f.crc = values[-1]
127
130
  return f
128
131
  end
129
132
 
@@ -69,7 +69,10 @@ module RTP
69
69
  def self.load(string)
70
70
  # Get the quote-less values:
71
71
  values = string.to_s.values
72
- raise ArgumentError, "Invalid argument 'string': Expected exactly 28 elements, got #{values.length}." unless values.length == 28
72
+ low_limit = 10
73
+ high_limit = 28
74
+ raise ArgumentError, "Invalid argument 'string': Expected at least #{low_limit} elements, got #{values.length}." if values.length < low_limit
75
+ RTP.logger.warn "The number of elements (#{values.length}) for this Plan record exceeds the known number of data items for this record (#{high_limit}). This may indicate an invalid record or that the RTP format has recently been expanded with new items." if values.length > high_limit
73
76
  rtp = self.new
74
77
  # Assign the values to attributes:
75
78
  rtp.keyword = values[0]
@@ -99,7 +102,7 @@ module RTP
99
102
  rtp.rtp_version = values[24]
100
103
  rtp.rtp_if_protocol = values[25]
101
104
  rtp.rtp_if_version = values[26]
102
- rtp.crc = values[27]
105
+ rtp.crc = values[-1]
103
106
  return rtp
104
107
  end
105
108
 
@@ -151,6 +154,7 @@ module RTP
151
154
  logger.error("This file is too small to contain valid RTP information: #{file}.")
152
155
  else
153
156
  str = File.open(file, "rb") { |f| f.read }
157
+ #str = File.open(file, "r:UTF-8") { |f| f.read }
154
158
  end
155
159
  end
156
160
  end
@@ -5,6 +5,12 @@ module RTP
5
5
  # Converts the Plan (and child) records to a
6
6
  # DICOM::DObject of modality RTPLAN.
7
7
  #
8
+ # @note Only static photon plans have been tested.
9
+ # Electron beams or dynamic photon beams may give an invalid DICOM file.
10
+ # Also note that, due to limitations in the RTP file format, some original
11
+ # values can not be recreated, like e.g. Study UID or Series UID.
12
+ # @return [DICOM::DObject] the converted DICOM object
13
+ #
8
14
  def to_dcm
9
15
  #
10
16
  # FIXME: This method is rather big, with a few sections of somewhat similar, repeating code.
@@ -36,7 +36,10 @@ module RTP
36
36
  def self.load(string, parent)
37
37
  # Get the quote-less values:
38
38
  values = string.to_s.values
39
- raise ArgumentError, "Invalid argument 'string': Expected exactly 13 elements, got #{values.length}." unless values.length == 13
39
+ low_limit = 4
40
+ high_limit = 13
41
+ raise ArgumentError, "Invalid argument 'string': Expected at least #{low_limit} elements, got #{values.length}." if values.length < low_limit
42
+ RTP.logger.warn "The number of elements (#{values.length}) for this Prescription record exceeds the known number of data items for this record (#{high_limit}). This may indicate an invalid record or that the RTP format has recently been expanded with new items." if values.length > high_limit
40
43
  p = self.new(parent)
41
44
  # Assign the values to attributes:
42
45
  p.keyword = values[0]
@@ -51,7 +54,7 @@ module RTP
51
54
  p.pattern = values[9]
52
55
  p.rx_note = values[10]
53
56
  p.number_of_fields = values[11]
54
- p.crc = values[12]
57
+ p.crc = values[-1]
55
58
  return p
56
59
  end
57
60
 
@@ -35,7 +35,10 @@ module RTP
35
35
  def self.load(string, parent)
36
36
  # Get the quote-less values:
37
37
  values = string.to_s.values
38
- raise ArgumentError, "Invalid argument 'string': Expected exactly 16 elements, got #{values.length}." unless values.length == 16
38
+ low_limit = 5
39
+ high_limit = 16
40
+ raise ArgumentError, "Invalid argument 'string': Expected at least #{low_limit} elements, got #{values.length}." if values.length < low_limit
41
+ RTP.logger.warn "The number of elements (#{values.length}) for this SiteSetup record exceeds the known number of data items for this record (#{high_limit}). This may indicate an invalid record or that the RTP format has recently been expanded with new items." if values.length > high_limit
39
42
  s = self.new(parent)
40
43
  # Assign the values to attributes:
41
44
  s.keyword = values[0]
@@ -53,7 +56,7 @@ module RTP
53
56
  s.couch_longitudinal = values[12]
54
57
  s.couch_angle = values[13]
55
58
  s.couch_pedestal = values[14]
56
- s.crc = values[15]
59
+ s.crc = values[-1]
57
60
  return s
58
61
  end
59
62
 
@@ -1,6 +1,6 @@
1
1
  module RTP
2
2
 
3
3
  # The RTPConnect library version string.
4
- VERSION = "1.2"
4
+ VERSION = "1.3"
5
5
 
6
6
  end
data/rakefile.rb CHANGED
@@ -1,8 +1,10 @@
1
1
  # Available commands:
2
2
  # Testing the specification:
3
3
  # bundle exec rake spec
4
- # Building a gem package from source:
4
+ # Building a gem from source with rake:
5
5
  # bundle exec rake package
6
+ # Building a gem from source with rubygems:
7
+ # bundle exec gem build rtp-connect.gemspec
6
8
  # Create html documentation files:
7
9
  # bundle exec rake yard
8
10
 
data/rtp-connect.gemspec CHANGED
@@ -18,12 +18,11 @@ Gem::Specification.new do |s|
18
18
  s.rubyforge_project = 'rtp-connect'
19
19
 
20
20
  s.required_ruby_version = '>= 1.9.2'
21
- s.required_rubygems_version = '>= 1.8.6'
22
21
 
23
- s.add_development_dependency('bundler', '>= 1.0.0')
24
- s.add_development_dependency('dicom', '>= 0.9.3')
25
- s.add_development_dependency('rake', '>= 0.9.2.2')
26
- s.add_development_dependency('rspec', '>= 2.9.0')
27
- s.add_development_dependency('mocha', '>= 0.10.5')
28
- s.add_development_dependency('yard', '>= 0.8.2')
22
+ s.add_development_dependency('bundler', '~> 1.2')
23
+ s.add_development_dependency('dicom', '0.9.3')
24
+ s.add_development_dependency('mocha', '~> 0.12')
25
+ s.add_development_dependency('rake', '~> 0.9.2')
26
+ s.add_development_dependency('rspec', '~> 2.11')
27
+ s.add_development_dependency('yard', '~> 0.8.2')
29
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rtp-connect
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.2'
4
+ version: '1.3'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,30 +9,30 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-13 00:00:00.000000000 Z
12
+ date: 2012-10-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ! '>='
19
+ - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 1.0.0
21
+ version: '1.2'
22
22
  type: :development
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ! '>='
27
+ - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: 1.0.0
29
+ version: '1.2'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: dicom
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
35
- - - ! '>='
35
+ - - '='
36
36
  - !ruby/object:Gem::Version
37
37
  version: 0.9.3
38
38
  type: :development
@@ -40,63 +40,63 @@ dependencies:
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
- - - ! '>='
43
+ - - '='
44
44
  - !ruby/object:Gem::Version
45
45
  version: 0.9.3
46
46
  - !ruby/object:Gem::Dependency
47
- name: rake
47
+ name: mocha
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
51
- - - ! '>='
51
+ - - ~>
52
52
  - !ruby/object:Gem::Version
53
- version: 0.9.2.2
53
+ version: '0.12'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  none: false
58
58
  requirements:
59
- - - ! '>='
59
+ - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: 0.9.2.2
61
+ version: '0.12'
62
62
  - !ruby/object:Gem::Dependency
63
- name: rspec
63
+ name: rake
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  none: false
66
66
  requirements:
67
- - - ! '>='
67
+ - - ~>
68
68
  - !ruby/object:Gem::Version
69
- version: 2.9.0
69
+ version: 0.9.2
70
70
  type: :development
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
- - - ! '>='
75
+ - - ~>
76
76
  - !ruby/object:Gem::Version
77
- version: 2.9.0
77
+ version: 0.9.2
78
78
  - !ruby/object:Gem::Dependency
79
- name: mocha
79
+ name: rspec
80
80
  requirement: !ruby/object:Gem::Requirement
81
81
  none: false
82
82
  requirements:
83
- - - ! '>='
83
+ - - ~>
84
84
  - !ruby/object:Gem::Version
85
- version: 0.10.5
85
+ version: '2.11'
86
86
  type: :development
87
87
  prerelease: false
88
88
  version_requirements: !ruby/object:Gem::Requirement
89
89
  none: false
90
90
  requirements:
91
- - - ! '>='
91
+ - - ~>
92
92
  - !ruby/object:Gem::Version
93
- version: 0.10.5
93
+ version: '2.11'
94
94
  - !ruby/object:Gem::Dependency
95
95
  name: yard
96
96
  requirement: !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
99
- - - ! '>='
99
+ - - ~>
100
100
  - !ruby/object:Gem::Version
101
101
  version: 0.8.2
102
102
  type: :development
@@ -104,7 +104,7 @@ dependencies:
104
104
  version_requirements: !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
- - - ! '>='
107
+ - - ~>
108
108
  - !ruby/object:Gem::Version
109
109
  version: 0.8.2
110
110
  description: RTPConnect is a file format used in radiotherapy for export & import
@@ -133,7 +133,6 @@ files:
133
133
  - CHANGELOG.rdoc
134
134
  - COPYING
135
135
  - Gemfile
136
- - Gemfile.lock
137
136
  - rakefile.rb
138
137
  - README.rdoc
139
138
  - rtp-connect.gemspec
@@ -155,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
155
154
  requirements:
156
155
  - - ! '>='
157
156
  - !ruby/object:Gem::Version
158
- version: 1.8.6
157
+ version: '0'
159
158
  requirements: []
160
159
  rubyforge_project: rtp-connect
161
160
  rubygems_version: 1.8.24
@@ -163,3 +162,4 @@ signing_key:
163
162
  specification_version: 3
164
163
  summary: Library for handling RTPConnect files.
165
164
  test_files: []
165
+ has_rdoc:
data/Gemfile.lock DELETED
@@ -1,35 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- rtp-connect (1.1)
5
-
6
- GEM
7
- remote: http://www.rubygems.org/
8
- specs:
9
- dicom (0.9.3)
10
- diff-lcs (1.1.3)
11
- metaclass (0.0.1)
12
- mocha (0.12.0)
13
- metaclass (~> 0.0.1)
14
- rake (0.9.2.2)
15
- rspec (2.11.0)
16
- rspec-core (~> 2.11.0)
17
- rspec-expectations (~> 2.11.0)
18
- rspec-mocks (~> 2.11.0)
19
- rspec-core (2.11.0)
20
- rspec-expectations (2.11.1)
21
- diff-lcs (~> 1.1.3)
22
- rspec-mocks (2.11.1)
23
- yard (0.8.2.1)
24
-
25
- PLATFORMS
26
- x86-mingw32
27
-
28
- DEPENDENCIES
29
- bundler (>= 1.0.0)
30
- dicom (>= 0.9.3)
31
- mocha (>= 0.10.5)
32
- rake (>= 0.9.2.2)
33
- rspec (>= 2.9.0)
34
- rtp-connect!
35
- yard (>= 0.8.2)