source: ruby/branches/0.5.0/lib/open_ehr/rm/data_types/quantity.rb@ 167

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

adjust for rails

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