UNPKG

cql-execution

Version:

An execution framework for the Clinical Quality Language (CQL)

439 lines (392 loc) 11.5 kB
// Generated by CoffeeScript 1.12.7 (function() { var Code, Exception, Expression, FunctionRef, Quantity, ValueSet, build, clean_unit, coalesceToOne, convert_value, createQuantity, decimalAdjust, doScaledAddition, isValidDecimal, is_valid_ucum_unit, ref, ref1, ucum, ucum_multiply, ucum_time_units, ucum_to_cql_units, ucum_unit, unitValidityCache, units_to_string, extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty; Expression = require('./expression').Expression; FunctionRef = require('./reusable').FunctionRef; ref = require('../util/math'), decimalAdjust = ref.decimalAdjust, isValidDecimal = ref.isValidDecimal; ref1 = require('../datatypes/datatypes'), ValueSet = ref1.ValueSet, Code = ref1.Code; Exception = require('../datatypes/exception').Exception; build = require('./builder').build; ucum = require('ucum'); module.exports.Quantity = Quantity = (function(superClass) { extend(Quantity, superClass); function Quantity(json) { Quantity.__super__.constructor.apply(this, arguments); this.unit = json.unit; if (json.value == null) { throw new Error("Cannot create a quantity with an undefined value"); } else { this.value = parseFloat(json.value); if (!isValidDecimal(this.value)) { throw new Error("Cannot create a quantity with an invalid decimal value"); } } if ((this.unit != null) && !is_valid_ucum_unit(this.unit)) { throw new Error("\'" + this.unit + "\' is not a valid UCUM unit."); } } Object.defineProperties(Quantity.prototype, { isQuantity: { get: function() { return true; } } }); Quantity.prototype.clone = function() { return new Quantity({ value: this.value, unit: this.unit }); }; Quantity.prototype.exec = function(ctx) { return this; }; Quantity.prototype.toString = function() { return this.value + " '" + this.unit + "'"; }; Quantity.prototype.sameOrBefore = function(other) { var other_v; if (other instanceof Quantity) { other_v = convert_value(other.value, ucum_unit(other.unit), ucum_unit(this.unit)); if (other_v == null) { return null; } else { return this.value <= other_v; } } }; Quantity.prototype.sameOrAfter = function(other) { var other_v; if (other instanceof Quantity) { other_v = convert_value(other.value, ucum_unit(other.unit), ucum_unit(this.unit)); if (other_v == null) { return null; } else { return this.value >= other_v; } } }; Quantity.prototype.after = function(other) { var other_v; if (other instanceof Quantity) { other_v = convert_value(other.value, ucum_unit(other.unit), ucum_unit(this.unit)); if (other_v == null) { return null; } else { return this.value > other_v; } } }; Quantity.prototype.before = function(other) { var other_v; if (other instanceof Quantity) { other_v = convert_value(other.value, ucum_unit(other.unit), ucum_unit(this.unit)); if (other_v == null) { return null; } else { return this.value < other_v; } } }; Quantity.prototype.equals = function(other) { var other_v; if (other instanceof Quantity) { if ((!this.unit && other.unit) || (this.unit && !other.unit)) { return false; } else if (!this.unit && !other.unit) { return this.value === other.value; } else { other_v = convert_value(other.value, ucum_unit(other.unit), ucum_unit(this.unit)); if (other_v == null) { return null; } else { return decimalAdjust("round", this.value, -8) === decimalAdjust("round", other_v, -8); } } } }; Quantity.prototype.convertUnits = function(to_units) { return convert_value(this.value, this.unit, to_units); }; Quantity.prototype.dividedBy = function(other) { return this.multiplyDivide(other, "/"); }; Quantity.prototype.multiplyBy = function(other) { return this.multiplyDivide(other, "."); }; Quantity.prototype.multiplyDivide = function(other, operator) { var a, b, can_val, other_can_value, ucum_value, value; if (other instanceof Quantity) { a = this.unit != null ? this : new Quantity({ value: this.value, unit: "1" }); b = other.unit != null ? other : new Quantity({ value: other.value, unit: "1" }); can_val = a.to_ucum(); other_can_value = b.to_ucum(); ucum_value = ucum_multiply(can_val, [[operator, other_can_value]]); try { return createQuantity(ucum_value.value, units_to_string(ucum_value.units)); } catch (error) { return null; } } else { value = operator === "/" ? this.value / other : this.value * other; try { return createQuantity(decimalAdjust("round", value, -8), coalesceToOne(this.unit)); } catch (error) { return null; } } }; Quantity.prototype.to_ucum = function() { var u; u = ucum.parse(ucum_unit(this.unit)); u.value *= this.value; return u; }; return Quantity; })(Expression); clean_unit = function(units) { if (ucum_time_units[units]) { return ucum_to_cql_units[ucum_time_units[units]]; } else { return units; } }; ucum_time_units = { 'years': 'a_g', 'year': 'a_g', 'YEARS': 'a_g', 'YEAR': 'a_g', 'a_g': 'a_g', 'a': 'a_j', 'ANN': 'a_j', 'ann': 'a_j', 'A': 'a_j', 'a_j': 'a_j', 'months': 'mo_g', 'month': 'mo_g', 'mo_g': 'mo_g', 'mo': 'mo_j', 'MO': 'mo_j', 'mo_j': 'mo_j', 'weeks': 'wk', 'week': 'wk', 'wk': 'wk', 'WK': 'wk', 'days': 'd', 'day': 'd', 'd': 'd', 'D': 'd', 'hours': 'h', 'hour': 'h', 'h': 'h', 'H': 'h', 'minutes': 'min', 'minute': 'min', 'min': 'min', 'MIN': 'min', 'seconds': 's', 'second': 's', 's': 's', 'S': 's', 'milliseconds': 'ms', 'millisecond': 'ms', 'ms': 'ms', 'MS': 'ms' }; ucum_to_cql_units = { 'a_j': 'year', 'a_g': 'year', 'mo_j': 'month', 'mo_g': 'month', 'wk': 'week', 'd': 'day', 'h': 'hour', 'min': 'minute', 's': 'second', 'ms': 'millisecond' }; ucum_unit = function(unit) { return ucum_time_units[unit] || unit || ''; }; convert_value = function(value, from, to) { var e; try { if (from === to) { return value; } else { return decimalAdjust("round", ucum.convert(value, ucum_unit(from), ucum_unit(to)), -8); } } catch (error) { e = error; return null; } }; unitValidityCache = {}; is_valid_ucum_unit = function(unit) { if (unitValidityCache.hasOwnProperty(unit)) { return unitValidityCache[unit]; } else { try { ucum.parse(ucum_unit(unit)); unitValidityCache[unit] = true; return true; } catch (error) { unitValidityCache[unit] = false; return false; } } }; module.exports.convert_value = convert_value; units_to_string = function(units) { var denom, i, key, len, numer, pow, ref2, str, unit_string, v; if (units == null) { units = {}; } numer = []; denom = []; ref2 = Object.keys(units); for (i = 0, len = ref2.length; i < len; i++) { key = ref2[i]; v = units[key]; pow = Math.abs(v); str = pow === 1 ? key : key + pow; if (v < 0) { denom.push(str); } else { numer.push(str); } } unit_string = ""; unit_string += numer.join("."); if (denom.length > 0) { unit_string += "/" + denom.join("/"); } if (unit_string === "") { return "1"; } else { return unit_string; } }; ucum_multiply = function(t, ms) { var b, i, k, len, mterm, ref2, ret, sign, v; if (ms == null) { ms = []; } if (ms.length === 0) { return t; } ret = t; for (i = 0, len = ms.length; i < len; i++) { mterm = ms[i]; sign = mterm[0] === '.' ? 1 : -1; b = mterm[1]; ret.value *= Math.pow(b.value, sign); ref2 = b.units; for (k in ref2) { v = ref2[k]; ret.units[k] = ret.units[k] || 0; ret.units[k] = ret.units[k] + sign * v; if (ret.units[k] === 0) { delete ret.units[k]; } } } return ret; }; module.exports.createQuantity = createQuantity = function(value, unit) { return new Quantity({ value: value, unit: unit }); }; module.exports.parseQuantity = function(str) { var components, unit, value; components = /([+|-]?\d+\.?\d*)\s*('(.+)')?/.exec(str); if ((components != null) && (components[1] != null)) { value = parseFloat(components[1]); if (!isValidDecimal(value)) { return null; } if (components[3] != null) { unit = components[3].trim(); } else { unit = ""; } return new Quantity({ value: value, unit: unit }); } else { return null; } }; doScaledAddition = function(a, b, scaleForB) { var a_unit, b_unit, ref2, val; if (a instanceof Quantity && b instanceof Quantity) { ref2 = [coalesceToOne(a.unit), coalesceToOne(b.unit)], a_unit = ref2[0], b_unit = ref2[1]; val = convert_value(b.value * scaleForB, b_unit, a_unit); if (val == null) { return null; } return new Quantity({ unit: a_unit, value: a.value + val }); } else if (a.copy && a.add) { b_unit = b instanceof Quantity ? coalesceToOne(b.unit) : b.unit; return a.copy().add(b.value * scaleForB, clean_unit(b_unit)); } else { throw new Error("Unsupported argument types."); } }; module.exports.doAddition = function(a, b) { return doScaledAddition(a, b, 1); }; module.exports.doSubtraction = function(a, b) { return doScaledAddition(a, b, -1); }; module.exports.doDivision = function(a, b) { if (a instanceof Quantity) { return a.dividedBy(b); } }; module.exports.doMultiplication = function(a, b) { if (a instanceof Quantity) { return a.multiplyBy(b); } else { return b.multiplyBy(a); } }; coalesceToOne = function(o) { if ((o == null) || ((o.trim != null) && !o.trim())) { return '1'; } else { return o; } }; module.exports.compare_units = function(unit_a, unit_b) { var c, e; try { c = ucum.convert(1, ucum_unit(unit_a), ucum_unit(unit_b)); if (c > 1) { return 1; } if (c < 1) { return -1; } return 0; } catch (error) { e = error; return null; } }; }).call(this); //# sourceMappingURL=quantity.js.map