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
RevLine 
[88]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
[141]4require 'assumed_library_types'
[167]5module OpenEhr
[4]6 module RM
[167]7 module DataTypes
[4]8 module Quantity
[137]9
10 autoload :Date_Time, "rm/data_types/quantity/date_time.rb"
11
[167]12 class DvOrdered < OpenEhr::RM::DataTypes::Basic::DataValue
[4]13 include Comparable
[138]14 attr_accessor :normal_range, :other_refference_ranges, :normal_status
[122]15
[124]16 def initialize(normal_range=nil, normal_status = nil,
17 other_reference_ranges=nil)
[123]18 self.normal_range = normal_range
[124]19 self.normal_status = normal_status
[123]20 self.other_reference_ranges = other_reference_ranges
[4]21 end
[122]22
[4]23 def is_normal?
[124]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
[4]31 end
[122]32
[4]33 def is_simple?
[88]34 normal_status.nil? and other_refference_ranges.nil?
[4]35 end
[122]36
37 def <=>(other)
[124]38 raise NotImplementedError, 'This method should be implemented'
[122]39 end
40
41 def other_reference_ranges=(other_reference_ranges)
[123]42 unless other_reference_ranges.nil? or !other_reference_ranges.is_empty?
[4]43 raise ArgumentError, "Other reference ranges validity error"
44 end
[123]45 @other_reference_ranges = other_reference_ranges
[4]46 end
[123]47
[142]48 def is_strictly_comparable_to?(other)
[137]49 raise NotImplementedError, 'this method should be implemented'
50 end
[4]51 end
[88]52
[167]53 class DvInterval < OpenEhr::AssumedLibraryTypes::Interval
[141]54
55 end
[142]56
[167]57 class DvQuantified < DvOrdered
[146]58 attr_reader :magnitude, :magnitude_status
[137]59
[144]60 def initialize(magnitude, magnitude_status=nil,
61 normal_range=nil, normal_status = nil,
[138]62 other_reference_ranges=nil)
[139]63 super(normal_range, normal_status, other_reference_ranges)
[144]64 self.magnitude = magnitude
65 self.magnitude_status = magnitude_status
[137]66 end
67
68 def <=>(others)
[140]69 @value <=> others.value
[137]70 end
71
[144]72 def magnitude=(magnitude)
73 raise ArgumentError, 'magnitude should not be nil' if magnitude.nil?
74 @magnitude = magnitude
75 end
[140]76
[144]77 def magnitude_status=(magnitude_status)
78 if magnitude_status.nil?
79 @magnitude_status = '='
[167]80 elsif DvQuantified.valid_magnitude_status?(magnitude_status)
[144]81 @magnitude_status = magnitude_status
82 else
83 raise ArgumentError, 'magnitude_status invalid'
84 end
[4]85 end
[144]86
87 def accuracy_unknown?
[148]88 return @accuracy.nil?
[144]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
[4]99 end
[88]100
[167]101 class DvOrdinal < DvOrdered
[142]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)
[140]110 end
[137]111
[142]112 def value=(value)
113 raise ArgumentError, 'value should not be nil' if value.nil?
114 @value = value
115 end
[140]116
[142]117 def symbol=(symbol)
118 raise ArgumentError,'symbol should not be nil' if symbol.nil?
119 @symbol = symbol
[88]120 end
[137]121
[142]122 def is_strictly_comparable_to?(others)
[167]123 unless others.instance_of? OpenEhr::RM::DataTypes::Quantity::DvOrdinal
[142]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
[139]133 def <=>(other)
[142]134 @value <=> other.value
[139]135 end
[140]136
[142]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
[88]143 end
144 end
145
[167]146 class DvAbsoluteQuantity < DvQuantified
[148]147 attr_accessor :accuracy
[88]148
[148]149 def initialize(magnitude, magnitude_status=nil, accuracy=nil,
150 normal_range=nil, normal_status = nil,
151 other_reference_ranges=nil)
[149]152 super(magnitude, magnitude_status, normal_range,
[148]153 normal_status, other_reference_ranges)
154 self.accuracy = accuracy
155 end
156
[88]157 def add(a_diff)
[149]158 raise NotImplementedError, 'add must be implemented'
[88]159 end
160
161 def diff(other)
[149]162 raise NotImplementedError, 'diff must be implemented'
[88]163 end
164
165 def subtract(a_diff)
[149]166 raise NotImplementedError, 'subtract must be implemented'
[88]167 end
168 end
[120]169
[167]170 class DvAmount < DvQuantified
[146]171 attr_reader :accuracy, :accuracy_percent
[145]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)
[146]177 unless accuracy.nil?
178 set_accuracy(accuracy, accuracy_percent)
179 else
180 @accuracy, @accuracy_percent = nil, nil
181 end
[145]182 end
[147]183
[145]184 def +(other)
[147]185 unless self.is_strictly_comparable_to?(other)
186 raise ArgumentError, 'type mismatch'
187 end
[167]188 return DvAmount.new(@magnitude+other.magnitude, @magnitude_status,
[147]189 @accuracy, @accuracy_percent, @normal_range,
190 @normal_status, @other_reference_ranges)
[145]191 end
[140]192
[145]193 def -(other)
[147]194 other.magnitude = - other.magnitude
195 self+(other)
[122]196 end
[145]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
[122]205 end
[145]206
207 def accuracy_is_percent?
208 return @accuracy_percent
209 end
[122]210 end
211
[167]212 class DvQuantity < DvAmount
[146]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
[140]222
[146]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?
[167]237 if others.instance_of?(DvQuantity) && others.units == @units
[146]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)
[147]253 dv_amount = super(other)
[167]254 return DvQuantity.new(dv_amount.magnitude, @units,
[146]255 @magnitude_status, @precision,
256 @accuracy, @accuracy_percent, @normal_range,
257 @normal_status, @other_reference_ranges)
258 end
[147]259 end
260
[167]261 class DvCount < DvAmount
[147]262 def is_strictly_comparable_to?(others)
263 return false if others.nil?
[167]264 if others.instance_of?(DvCount)
[147]265 return true
266 else
267 return false
268 end
[146]269 end
[140]270 end
271
[167]272 class ReferenceRange
[144]273 attr_reader :meaning, :range
[141]274
[144]275 def initialize(meaning, range)
[141]276 self.meaning = meaning
[144]277 self.range = range
[141]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
[144]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
[124]297 end
[139]298
[167]299 module ProportionKind
[139]300 PK_RATIO = 0
301 PK_UNITARY = 1
302 PK_PERCENT = 2
303 PK_FRACTION = 3
304 PK_INTEGER_FRACTION = 4
305
[167]306 def ProportionKind.valid_proportion_kind?(kind)
[139]307 return true if kind >= 0 && kind <= 4
308 return false
309 end
[167]310 end # end of ProportionKind
[147]311
[167]312 class DvProportion < DvAmount
313 include ProportionKind
[147]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
[148]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
[147]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)
[167]362 if ProportionKind.valid_proportion_kind?(type)
[147]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)
[167]388 unless other.instance_of?(DvProportion)
[147]389 return false
390 end
391 if other.type == @type
392 return true
393 else
394 return false
395 end
396 end
[167]397 end # end of DvProportion
[4]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.