source: ruby/trunk/lib/models/rm/data_types/quantity.rb@ 147

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

ref #50

Most of the quantity type pacage was finished.
Jobs have been accumulated for more than a year
Rest of the work on the quantity package
Is not so much. Tomorrow, I will finish this
Package, perfectly.

File size: 12.3 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 Data_Types
8 module Quantity
9
10 autoload :Date_Time, "rm/data_types/quantity/date_time.rb"
11
12 class DV_Ordered < OpenEHR::RM::Data_Types::Basic::Data_Value
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 DV_Interval < OpenEHR::Assumed_Library_Types::Interval
54
55 end
56
57 class DV_Quantified < DV_Ordered
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 DV_Quantified.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=(accuracy)
88 raise NotImplementedError, 'subclasses need to implemented'
89 end
90
91 def accuracy_unknown?
92 return accuracy.nil?
93 end
94
95 def self.valid_magnitude_status?(s)
96 if s == '=' || s == '>' || s == '<' || s == '<=' ||
97 s == '>=' || s == '~'
98 return true
99 else
100 return false
101 end
102 end
103 end
104
105 class DV_Ordinal < DV_Ordered
106 attr_reader :value, :symbol, :limits
107
108 def initialize(value, symbol, limits=nil, normal_range=nil,
109 normal_status = nil, other_reference_ranges=nil)
110 self.value = value
111 self.symbol = symbol
112 self.limits = limits
113 super(normal_range, normal_status, other_reference_ranges)
114 end
115
116 def value=(value)
117 raise ArgumentError, 'value should not be nil' if value.nil?
118 @value = value
119 end
120
121 def symbol=(symbol)
122 raise ArgumentError,'symbol should not be nil' if symbol.nil?
123 @symbol = symbol
124 end
125
126 def is_strictly_comparable_to?(others)
127 unless others.instance_of? OpenEHR::RM::Data_Types::Quantity::DV_Ordinal
128 return false
129 end
130 unless others.symbol.defining_code.terminology_id.value ==
131 @symbol.defining_code.terminology_id.value
132 return false
133 end
134 return true
135 end
136
137 def <=>(other)
138 @value <=> other.value
139 end
140
141 def limits=(limits)
142 unless limits.nil? or limits.meaning.value == 'limits'
143 raise ArgumentError, 'invalid limits'
144 else
145 @limits = limits
146 end
147 end
148 end
149
150 class DV_Absolute_Quantity < DV_Quantified
151 attr_reader :accuracy
152
153 def add(a_diff)
154 raise NotImplementError, 'add must be implemented'
155 end
156
157 def diff(other)
158 raise NotImplementError, 'diff must be implemented'
159 end
160
161 def subtract(a_diff)
162 raise NotImplementError, 'subtract must be implemented'
163 end
164 end
165
166 class DV_Amount < DV_Quantified
167 attr_reader :accuracy, :accuracy_percent
168 def initialize(magnitude, magnitude_status=nil, accuracy=nil,
169 accuracy_percent=nil, normal_range=nil,
170 normal_status = nil, other_reference_ranges=nil)
171 super(magnitude, magnitude_status, normal_range,
172 normal_status, other_reference_ranges)
173 unless accuracy.nil?
174 set_accuracy(accuracy, accuracy_percent)
175 else
176 @accuracy, @accuracy_percent = nil, nil
177 end
178 end
179
180 def +(other)
181 unless self.is_strictly_comparable_to?(other)
182 raise ArgumentError, 'type mismatch'
183 end
184 return DV_Amount.new(@magnitude+other.magnitude, @magnitude_status,
185 @accuracy, @accuracy_percent, @normal_range,
186 @normal_status, @other_reference_ranges)
187 end
188
189 def -(other)
190 other.magnitude = - other.magnitude
191 self+(other)
192 end
193
194 def set_accuracy(accuracy, accuracy_percent)
195 if accuracy_percent
196 raise ArgumentError, 'accuracy invalid' if accuracy < 0.0 || accuracy > 100.0
197 else
198 raise ArgumentError, 'accuracy invaild' if accuracy < 0.0 || accuracy > 1.0
199 end
200 @accuracy, @accuracy_percent = accuracy, accuracy_percent
201 end
202
203 def accuracy_is_percent?
204 return @accuracy_percent
205 end
206 end
207
208 class DV_Quantity < DV_Amount
209 attr_reader :units, :precision
210 def initialize(magnitude, units, magnitude_status=nil, precision=nil,
211 accuracy=nil, accuracy_percent=nil, normal_range=nil,
212 normal_status = nil, other_reference_ranges=nil)
213 super(magnitude, magnitude_status, accuracy, accuracy_percent,
214 normal_range, normal_status, other_reference_ranges)
215 self.units = units
216 self.precision = precision
217 end
218
219 def units=(units)
220 raise ArgumentError, 'units should not be nil' if units.nil?
221 @units = units
222 end
223
224 def precision=(precision)
225 unless precision.nil? || precision >= -1
226 raise ArgumentError, 'precision invalid'
227 end
228 @precision = precision
229 end
230
231 def is_strictly_comparable_to?(others)
232 return false if others.nil?
233 if others.instance_of?(DV_Quantity) && others.units == @units
234 return true
235 else
236 return false
237 end
238 end
239
240 def is_integral?
241 if @precision.nil? || precision != 0
242 return false
243 else
244 return true
245 end
246 end
247# accuracy???
248 def +(other)
249 dv_amount = super(other)
250 return DV_Quantity.new(dv_amount.magnitude, @units,
251 @magnitude_status, @precision,
252 @accuracy, @accuracy_percent, @normal_range,
253 @normal_status, @other_reference_ranges)
254 end
255 end
256
257 class DV_Count < DV_Amount
258 def is_strictly_comparable_to?(others)
259 return false if others.nil?
260 if others.instance_of?(DV_Count)
261 return true
262 else
263 return false
264 end
265 end
266 end
267
268 class Reference_Range
269 attr_reader :meaning, :range
270
271 def initialize(meaning, range)
272 self.meaning = meaning
273 self.range = range
274 end
275
276 def meaning=(meaning)
277 if meaning.nil?
278 raise ArgumentError, 'meaning should not be nil'
279 end
280 @meaning = meaning
281 end
282
283 def range=(range)
284 if range.nil?
285 raise ArgumentError, 'range should not be nil'
286 end
287 @range = range
288 end
289
290 def is_in_range?(val)
291 return @range.has?(val)
292 end
293 end
294
295 module Proportion_Kind
296 PK_RATIO = 0
297 PK_UNITARY = 1
298 PK_PERCENT = 2
299 PK_FRACTION = 3
300 PK_INTEGER_FRACTION = 4
301
302 def Proportion_Kind.valid_proportion_kind?(kind)
303 return true if kind >= 0 && kind <= 4
304 return false
305 end
306 end # end of Proportion_Kind
307
308 class DV_Proportion < DV_Amount
309 include Proportion_Kind
310 attr_reader :numerator, :denominator, :type, :precision
311
312 def initialize(numerator, denominator, type, precision=nil,
313 magnitude_status=nil, accuracy=nil,
314 accuracy_percent=nil, normal_range=nil,
315 normal_status = nil, other_reference_ranges=nil)
316 self.type = type
317 self.numerator = numerator
318 self.denominator = denominator
319 self.precision = precision
320 end
321
322 def numerator=(numerator)
323 raise ArgumentError, 'numerator should not be nil' if numerator.nil?
324 if (@type == PK_FRACTION || @type == PK_INTEGER_FRACTION) &&
325 !numerator.integer?
326 raise ArgumentError, 'numerator invalid for type'
327 end
328 @numerator = numerator
329 end
330
331 def denominator=(denominator)
332 if denominator.nil? or denominator == PK_RATIO
333 raise ArgumentError, 'denominator invalid'
334 end
335 if (@type == PK_FRACTION || @type == PK_INTEGER_FRACTION) &&
336 !denominator.integer?
337 raise ArgumentError, 'denominator invalid for type'
338 end
339 if @type == PK_UNITARY && denominator != 1
340 raise ArgumentError, 'denominator invalid for type'
341 end
342 if @type == PK_PERCENT && denominator != 100
343 raise ArgumentError, 'denominator invaild for type'
344 end
345 @denominator = denominator
346 end
347
348 def type=(type)
349 if Proportion_Kind.valid_proportion_kind?(type)
350 @type = type
351 else
352 raise ArgumentError, 'type invalid'
353 end
354 end
355
356 def magnitude
357 return numerator.to_f/denominator.to_f
358 end
359
360 def precision=(precision)
361 unless precision.nil?
362 unless precision == 0 || self.is_integral?
363 @precision = precision
364 else
365 raise ArgumentError, 'precision invalid'
366 end
367 end
368 end
369
370 def is_integral?
371 return denominator.integer? && numerator.integer?
372 end
373
374 def is_strictly_comparable_to?(other)
375 unless other.instance_of?(DV_Proportion)
376 return false
377 end
378 if other.type == @type
379 return true
380 else
381 return false
382 end
383 end
384 end # end of DV_Proportion
385
386 end # of Quantity
387 end # of Data_Types
388 end # of RM
389end # of OpenEHR
Note: See TracBrowser for help on using the repository browser.