source: ruby/branches/0.5/lib/open_ehr/rm/data_types/quantity.rb@ 246

Last change on this file since 246 was 246, checked in by KOBAYASHI, Shinji, 15 years ago

move DvOrdinal test to rspec

File size: 12.6 KB
Line 
1# This modules are implemented from the UML shown bellow
2# http://www.openehr.org/uml/release-1.0.1/Browsable/_9_0_76d0249_1109599337877_94556_1510Report.html
3# Ticket refs #50
4#require 'assumed_library_types'
5module OpenEHR
6 module RM
7 module DataTypes
8 module Quantity
9 class DvOrdered < OpenEHR::RM::DataTypes::Basic::DataValue
10 include Comparable
11 attr_accessor :normal_range, :other_refference_ranges, :normal_status
12
13 def initialize(args = {})
14 super(args)
15 self.normal_range = args[:normal_range]
16 self.normal_status = args[:normal_status]
17 self.other_reference_ranges = args[:other_reference_ranges]
18 end
19
20 def is_normal?
21 if @normal_range.nil? and @normal_status.nil?
22 return false
23 elsif !@normal_range.nil?
24 return @normal_range.has(@value)
25 elsif !@normal_status.nil?
26 return @normal_status.code_string == 'N'
27 end
28 end
29
30 def is_simple?
31 return @other_reference_ranges.nil?
32 end
33
34 def <=>(other)
35 raise NotImplementedError, 'This method should be implemented'
36 end
37
38 def other_reference_ranges=(other_reference_ranges)
39 if !other_reference_ranges.nil? && other_reference_ranges.empty?
40 raise ArgumentError, "Other reference ranges validity error"
41 end
42 @other_reference_ranges = other_reference_ranges
43 end
44
45 def is_strictly_comparable_to?(other)
46 raise NotImplementedError, 'this method should be implemented'
47 end
48 end
49
50 class DvInterval < OpenEHR::AssumedLibraryTypes::Interval
51
52 end
53
54 class DvQuantified < DvOrdered
55 attr_reader :magnitude, :magnitude_status
56
57 def initialize(magnitude, magnitude_status=nil,
58 normal_range=nil, normal_status = nil,
59 other_reference_ranges=nil)
60 super(normal_range, normal_status, other_reference_ranges)
61 self.magnitude = magnitude
62 self.magnitude_status = magnitude_status
63 end
64
65 def <=>(others)
66 @value <=> others.value
67 end
68
69 def magnitude=(magnitude)
70 raise ArgumentError, 'magnitude should not be nil' if magnitude.nil?
71 @magnitude = magnitude
72 end
73
74 def magnitude_status=(magnitude_status)
75 if magnitude_status.nil?
76 @magnitude_status = '='
77 elsif DvQuantified.valid_magnitude_status?(magnitude_status)
78 @magnitude_status = magnitude_status
79 else
80 raise ArgumentError, 'magnitude_status invalid'
81 end
82 end
83
84 def accuracy_unknown?
85 return @accuracy.nil?
86 end
87
88 def self.valid_magnitude_status?(s)
89 if s == '=' || s == '>' || s == '<' || s == '<=' ||
90 s == '>=' || s == '~'
91 return true
92 else
93 return false
94 end
95 end
96 end
97
98 class DvOrdinal < DvOrdered
99 attr_reader :value, :symbol, :limits
100
101 def initialize(args = {})
102 super(args)
103 self.symbol = args[:symbol]
104 self.limits = args[:limits]
105 end
106
107 def value=(value)
108 raise ArgumentError, 'value should not be nil' if value.nil?
109 @value = value
110 end
111
112 def symbol=(symbol)
113 raise ArgumentError,'symbol should not be nil' if symbol.nil?
114 @symbol = symbol
115 end
116
117 def is_strictly_comparable_to?(others)
118 unless others.instance_of? OpenEHR::RM::DataTypes::Quantity::DvOrdinal
119 return false
120 end
121 unless others.symbol.defining_code.terminology_id.value ==
122 @symbol.defining_code.terminology_id.value
123 return false
124 end
125 return true
126 end
127
128 def <=>(other)
129 @value <=> other.value
130 end
131
132 def limits=(limits)
133 unless limits.nil? or limits.meaning.value == 'limits'
134 raise ArgumentError, 'invalid limits'
135 else
136 @limits = limits
137 end
138 end
139 end
140
141 class DvAbsoluteQuantity < DvQuantified
142 attr_accessor :accuracy
143
144 def initialize(magnitude, magnitude_status=nil, accuracy=nil,
145 normal_range=nil, normal_status = nil,
146 other_reference_ranges=nil)
147 super(magnitude, magnitude_status, normal_range,
148 normal_status, other_reference_ranges)
149 self.accuracy = accuracy
150 end
151
152 def add(a_diff)
153 raise NotImplementedError, 'add must be implemented'
154 end
155
156 def diff(other)
157 raise NotImplementedError, 'diff must be implemented'
158 end
159
160 def subtract(a_diff)
161 raise NotImplementedError, 'subtract must be implemented'
162 end
163 end
164
165 class DvAmount < DvQuantified
166 attr_reader :accuracy, :accuracy_percent
167 def initialize(magnitude, magnitude_status=nil, accuracy=nil,
168 accuracy_percent=nil, normal_range=nil,
169 normal_status = nil, other_reference_ranges=nil)
170 super(magnitude, magnitude_status, normal_range,
171 normal_status, other_reference_ranges)
172 unless accuracy.nil?
173 set_accuracy(accuracy, accuracy_percent)
174 else
175 @accuracy, @accuracy_percent = nil, nil
176 end
177 end
178
179 def +(other)
180 unless self.is_strictly_comparable_to?(other)
181 raise ArgumentError, 'type mismatch'
182 end
183 return DvAmount.new(@magnitude+other.magnitude, @magnitude_status,
184 @accuracy, @accuracy_percent, @normal_range,
185 @normal_status, @other_reference_ranges)
186 end
187
188 def -(other)
189 other.magnitude = - other.magnitude
190 self+(other)
191 end
192
193 def set_accuracy(accuracy, accuracy_percent)
194 if accuracy_percent
195 raise ArgumentError, 'accuracy invalid' if accuracy < 0.0 || accuracy > 100.0
196 else
197 raise ArgumentError, 'accuracy invaild' if accuracy < 0.0 || accuracy > 1.0
198 end
199 @accuracy, @accuracy_percent = accuracy, accuracy_percent
200 end
201
202 def accuracy_is_percent?
203 return @accuracy_percent
204 end
205 end
206
207 class DvQuantity < DvAmount
208 attr_reader :units, :precision
209 def initialize(magnitude, units, magnitude_status=nil, precision=nil,
210 accuracy=nil, accuracy_percent=nil, normal_range=nil,
211 normal_status = nil, other_reference_ranges=nil)
212 super(magnitude, magnitude_status, accuracy, accuracy_percent,
213 normal_range, normal_status, other_reference_ranges)
214 self.units = units
215 self.precision = precision
216 end
217
218 def units=(units)
219 raise ArgumentError, 'units should not be nil' if units.nil?
220 @units = units
221 end
222
223 def precision=(precision)
224 unless precision.nil? || precision >= -1
225 raise ArgumentError, 'precision invalid'
226 end
227 @precision = precision
228 end
229
230 def is_strictly_comparable_to?(others)
231 return false if others.nil?
232 if others.instance_of?(DvQuantity) && others.units == @units
233 return true
234 else
235 return false
236 end
237 end
238
239 def is_integral?
240 if @precision.nil? || precision != 0
241 return false
242 else
243 return true
244 end
245 end
246# accuracy???
247 def +(other)
248 dv_amount = super(other)
249 return DvQuantity.new(dv_amount.magnitude, @units,
250 @magnitude_status, @precision,
251 @accuracy, @accuracy_percent, @normal_range,
252 @normal_status, @other_reference_ranges)
253 end
254 end
255
256 class DvCount < DvAmount
257 def is_strictly_comparable_to?(others)
258 return false if others.nil?
259 if others.instance_of?(DvCount)
260 return true
261 else
262 return false
263 end
264 end
265 end
266
267 class ReferenceRange
268 attr_reader :meaning, :range
269
270 def initialize(args = {})
271 self.meaning = args[:meaning]
272 self.range = args[:range]
273 end
274
275 def meaning=(meaning)
276 if meaning.nil?
277 raise ArgumentError, 'meaning should not be nil'
278 end
279 @meaning = meaning
280 end
281
282 def range=(range)
283 if range.nil?
284 raise ArgumentError, 'range should not be nil'
285 end
286 @range = range
287 end
288
289 def is_in_range?(val)
290 return @range.has?(val)
291 end
292 end
293
294 module ProportionKind
295 PK_RATIO = 0
296 PK_UNITARY = 1
297 PK_PERCENT = 2
298 PK_FRACTION = 3
299 PK_INTEGER_FRACTION = 4
300
301 def ProportionKind.valid_proportion_kind?(kind)
302 return true if kind >= 0 && kind <= 4
303 return false
304 end
305 end # end of ProportionKind
306
307 class DvProportion < DvAmount
308 include ProportionKind
309 attr_reader :numerator, :denominator, :type, :precision
310
311 def initialize(numerator, denominator, type, precision=nil,
312 magnitude_status=nil, accuracy=nil,
313 accuracy_percent=nil, normal_range=nil,
314 normal_status = nil, other_reference_ranges=nil)
315 self.type = type
316 self.numerator = numerator
317 self.denominator = denominator
318 self.precision = precision
319 self.magnitude_status = magnitude_status
320 unless accuracy.nil?
321 set_accuracy(accuracy, accuracy_percent)
322 else
323 @accuracy, @accuracy_percent = nil, nil
324 end
325 self.normal_range = normal_range
326 self.normal_status = normal_status
327 self.other_reference_ranges = other_reference_ranges
328 end
329
330 def numerator=(numerator)
331 raise ArgumentError, 'numerator should not be nil' if numerator.nil?
332 if (@type == PK_FRACTION || @type == PK_INTEGER_FRACTION) &&
333 !numerator.integer?
334 raise ArgumentError, 'numerator invalid for type'
335 end
336 @numerator = numerator
337 end
338
339 def denominator=(denominator)
340 if denominator.nil? or denominator == PK_RATIO
341 raise ArgumentError, 'denominator invalid'
342 end
343 if (@type == PK_FRACTION || @type == PK_INTEGER_FRACTION) &&
344 !denominator.integer?
345 raise ArgumentError, 'denominator invalid for type'
346 end
347 if @type == PK_UNITARY && denominator != 1
348 raise ArgumentError, 'denominator invalid for type'
349 end
350 if @type == PK_PERCENT && denominator != 100
351 raise ArgumentError, 'denominator invaild for type'
352 end
353 @denominator = denominator
354 end
355
356 def type=(type)
357 if ProportionKind.valid_proportion_kind?(type)
358 @type = type
359 else
360 raise ArgumentError, 'type invalid'
361 end
362 end
363
364 def magnitude
365 return numerator.to_f/denominator.to_f
366 end
367
368 def precision=(precision)
369 unless precision.nil?
370 unless precision == 0 || self.is_integral?
371 @precision = precision
372 else
373 raise ArgumentError, 'precision invalid'
374 end
375 end
376 end
377
378 def is_integral?
379 return denominator.integer? && numerator.integer?
380 end
381
382 def is_strictly_comparable_to?(other)
383 unless other.instance_of?(DvProportion)
384 return false
385 end
386 if other.type == @type
387 return true
388 else
389 return false
390 end
391 end
392 end # end of DvProportion
393 end # of Quantity
394 end # of Data_Types
395 end # of RM
396end # of OpenEHR
Note: See TracBrowser for help on using the repository browser.