@lhncbc/ucum-lhc 4.1.8 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser-dist/ucum-lhc.js +207 -72
- package/package.json +1 -1
- package/source/config.js +3 -2
- package/source/ucumLhcUtils.js +128 -24
- package/source/unit.js +28 -34
- package/source/unitString.js +20 -12
- package/source/unitTables.js +14 -0
- package/source-cjs/config.js +2 -2
- package/source-cjs/config.js.map +1 -1
- package/source-cjs/ucumLhcUtils.js +136 -23
- package/source-cjs/ucumLhcUtils.js.map +1 -1
- package/source-cjs/unit.js +27 -36
- package/source-cjs/unit.js.map +1 -1
- package/source-cjs/unitString.js +23 -14
- package/source-cjs/unitString.js.map +1 -1
- package/source-cjs/unitTables.js +16 -0
- package/source-cjs/unitTables.js.map +1 -1
package/browser-dist/ucum-lhc.js
CHANGED
|
@@ -86,14 +86,14 @@ var Ucum = {
|
|
|
86
86
|
* displaying messages on a web site; should be blank when output is
|
|
87
87
|
* to a file.
|
|
88
88
|
*/
|
|
89
|
-
openEmphHTML_: '<span class="emphSpan">',
|
|
89
|
+
openEmphHTML_: ' <span class="emphSpan">',
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
92
|
* Closing HTML used to emphasize portions of error messages. Used when
|
|
93
93
|
* displaying messages on a web site; should be blank when output is
|
|
94
94
|
* to a file.
|
|
95
95
|
*/
|
|
96
|
-
closeEmphHTML_: '</span>',
|
|
96
|
+
closeEmphHTML_: '</span> ',
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
99
|
* Message that is displayed when annotations are included in a unit
|
|
@@ -1617,24 +1617,17 @@ var UcumLhcUtils = /*#__PURE__*/function () {
|
|
|
1617
1617
|
if (valConv === undefined) valConv = 'validate';
|
|
1618
1618
|
var resp = this.getSpecifiedUnit(uStr, valConv, suggest);
|
|
1619
1619
|
var theUnit = resp['unit'];
|
|
1620
|
-
var retObj = {
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
'
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
'unit': {
|
|
1632
|
-
'code': theUnit.csCode_,
|
|
1633
|
-
'name': theUnit.name_,
|
|
1634
|
-
'guidance': theUnit.guidance_
|
|
1635
|
-
}
|
|
1636
|
-
};
|
|
1637
|
-
}
|
|
1620
|
+
var retObj = !theUnit ? {
|
|
1621
|
+
'ucumCode': null
|
|
1622
|
+
} : {
|
|
1623
|
+
'ucumCode': resp['origString'],
|
|
1624
|
+
'unit': {
|
|
1625
|
+
'code': theUnit.csCode_,
|
|
1626
|
+
'name': theUnit.name_,
|
|
1627
|
+
'guidance': theUnit.guidance_
|
|
1628
|
+
}
|
|
1629
|
+
};
|
|
1630
|
+
retObj.status = resp.status;
|
|
1638
1631
|
|
|
1639
1632
|
if (resp['suggestions']) {
|
|
1640
1633
|
retObj['suggestions'] = resp['suggestions'];
|
|
@@ -1723,10 +1716,7 @@ var UcumLhcUtils = /*#__PURE__*/function () {
|
|
|
1723
1716
|
returnObj['msg'].push('No "from" unit expression specified.');
|
|
1724
1717
|
}
|
|
1725
1718
|
|
|
1726
|
-
|
|
1727
|
-
returnObj['status'] = 'error';
|
|
1728
|
-
returnObj['msg'].push('No "from" value, or an invalid "from" value, ' + 'was specified.');
|
|
1729
|
-
}
|
|
1719
|
+
this._checkFromVal(fromVal, returnObj);
|
|
1730
1720
|
|
|
1731
1721
|
if (toUnitCode) {
|
|
1732
1722
|
toUnitCode = toUnitCode.trim();
|
|
@@ -1817,6 +1807,120 @@ var UcumLhcUtils = /*#__PURE__*/function () {
|
|
|
1817
1807
|
return returnObj;
|
|
1818
1808
|
} // end convertUnitTo
|
|
1819
1809
|
|
|
1810
|
+
/**
|
|
1811
|
+
* Converts the given unit string into its base units, their exponents, and
|
|
1812
|
+
* a magnitude, and returns that data.
|
|
1813
|
+
* @param fromUnit the unit string to be converted to base units information
|
|
1814
|
+
* @param fromVal the number of "from" units to be converted
|
|
1815
|
+
* @returns an object with the properties:
|
|
1816
|
+
* 'status' indicates whether the result succeeded. The value will be one of:
|
|
1817
|
+
* 'succeeded': the conversion was successfully calculated (which can be
|
|
1818
|
+
* true even if it was already in base units);
|
|
1819
|
+
* 'invalid': fromUnit is not a valid UCUM code;
|
|
1820
|
+
* 'failed': the conversion could not be made (e.g., if it is an "arbitrary" unit);
|
|
1821
|
+
* 'error': if an error occurred (an input or programming error)
|
|
1822
|
+
* 'msg': an array of one or more messages, if the string is invalid or
|
|
1823
|
+
* an error occurred, indicating the problem, or a suggestion of a
|
|
1824
|
+
* substitution such as the substitution of 'G' for 'Gauss', or
|
|
1825
|
+
* an empty array if no messages were generated. There can also be a
|
|
1826
|
+
* message that is just informational or warning.
|
|
1827
|
+
* 'magnitude': the new value when fromVal units of fromUnits is expressed in the base units.
|
|
1828
|
+
* 'fromUnitIsSpecial': whether the input unit fromUnit is a "special unit"
|
|
1829
|
+
* as defined in UCUM. This means there is some function applied to convert
|
|
1830
|
+
* between fromUnit and the base units, so the returned magnitude is likely not
|
|
1831
|
+
* useful as a scale factor for other conversions (i.e., it only has validity
|
|
1832
|
+
* and usefulness for the input values that produced it).
|
|
1833
|
+
* 'unitToExp': a map of base units in uStr to their exponent
|
|
1834
|
+
*/
|
|
1835
|
+
|
|
1836
|
+
}, {
|
|
1837
|
+
key: "convertToBaseUnits",
|
|
1838
|
+
value: function convertToBaseUnits(fromUnit, fromVal) {
|
|
1839
|
+
var retObj = {};
|
|
1840
|
+
|
|
1841
|
+
this._checkFromVal(fromVal, retObj);
|
|
1842
|
+
|
|
1843
|
+
if (!retObj.status) {
|
|
1844
|
+
// could be set to 'error' by _checkFromVal
|
|
1845
|
+
var inputUnitLookup = this.getSpecifiedUnit(fromUnit, 'validate');
|
|
1846
|
+
retObj = {
|
|
1847
|
+
status: inputUnitLookup.status == 'valid' ? 'succeeded' : inputUnitLookup.status
|
|
1848
|
+
};
|
|
1849
|
+
var unit = inputUnitLookup.unit;
|
|
1850
|
+
retObj.msg = inputUnitLookup.retMsg || [];
|
|
1851
|
+
|
|
1852
|
+
if (!unit) {
|
|
1853
|
+
var _inputUnitLookup$retM;
|
|
1854
|
+
|
|
1855
|
+
if (((_inputUnitLookup$retM = inputUnitLookup.retMsg) === null || _inputUnitLookup$retM === void 0 ? void 0 : _inputUnitLookup$retM.length) == 0) retObj.msg.push('Could not find unit information for ' + fromUnit);
|
|
1856
|
+
} else if (unit.isArbitrary_) {
|
|
1857
|
+
retObj.msg.push('Arbitrary units cannot be converted to base units or other units.');
|
|
1858
|
+
retObj.status = 'failed';
|
|
1859
|
+
} else if (retObj.status == 'succeeded') {
|
|
1860
|
+
var _unit$dim_;
|
|
1861
|
+
|
|
1862
|
+
var unitToExp = {};
|
|
1863
|
+
var dimVec = (_unit$dim_ = unit.dim_) === null || _unit$dim_ === void 0 ? void 0 : _unit$dim_.dimVec_;
|
|
1864
|
+
var baseUnitString = '1';
|
|
1865
|
+
|
|
1866
|
+
if (dimVec) {
|
|
1867
|
+
var dimVecIndexToBaseUnit = UnitTables.getInstance().dimVecIndexToBaseUnit_;
|
|
1868
|
+
|
|
1869
|
+
for (var i = 0, len = dimVec.length; i < len; ++i) {
|
|
1870
|
+
var exp = dimVec[i];
|
|
1871
|
+
|
|
1872
|
+
if (exp) {
|
|
1873
|
+
unitToExp[dimVecIndexToBaseUnit[i]] = exp;
|
|
1874
|
+
baseUnitString += '.' + dimVecIndexToBaseUnit[i] + exp;
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
} // The unit might have a conversion function, which has to be applied; we
|
|
1878
|
+
// cannot just assume unit_.magnitude_ is the magnitude in base units.
|
|
1879
|
+
|
|
1880
|
+
|
|
1881
|
+
var retUnitLookup = this.getSpecifiedUnit(baseUnitString, 'validate'); // There should not be any error in retUnitLookup, unless there is a bug.
|
|
1882
|
+
|
|
1883
|
+
var retUnit = retUnitLookup.unit;
|
|
1884
|
+
|
|
1885
|
+
if (retUnitLookup.status !== 'valid') {
|
|
1886
|
+
retObj.msg.push('Unable construct base unit string; tried ' + baseUnitString);
|
|
1887
|
+
retObj.status = 'error';
|
|
1888
|
+
} else {
|
|
1889
|
+
try {
|
|
1890
|
+
retObj.magnitude = retUnit.convertFrom(fromVal, unit);
|
|
1891
|
+
} catch (e) {
|
|
1892
|
+
retObj.msg.push(e.toString());
|
|
1893
|
+
retObj.status = 'error';
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
if (retObj.status == 'succeeded') {
|
|
1897
|
+
retObj.unitToExp = unitToExp;
|
|
1898
|
+
retObj.fromUnitIsSpecial = unit.isSpecial_;
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
return retObj;
|
|
1905
|
+
}
|
|
1906
|
+
/**
|
|
1907
|
+
* Checks the given value as to whether it is suitable as a "from" value in a
|
|
1908
|
+
* unit conversion. If it is not, the responseObj will have its status set
|
|
1909
|
+
* to 'error' and a message added.
|
|
1910
|
+
* @param fromVal The value to check
|
|
1911
|
+
* @param responseObj the object that will be updated if the value is not
|
|
1912
|
+
* usable.
|
|
1913
|
+
*/
|
|
1914
|
+
|
|
1915
|
+
}, {
|
|
1916
|
+
key: "_checkFromVal",
|
|
1917
|
+
value: function _checkFromVal(fromVal, responseObj) {
|
|
1918
|
+
if (fromVal === null || isNaN(fromVal) || typeof fromVal !== 'number' && !intUtils_.isNumericString(fromVal)) {
|
|
1919
|
+
responseObj.status = 'error';
|
|
1920
|
+
if (!responseObj.msg) responseObj.msg = [];
|
|
1921
|
+
responseObj.msg.push('No "from" value, or an invalid "from" value, ' + 'was specified.');
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1820
1924
|
/**
|
|
1821
1925
|
* This method accepts a term and looks for units that include it as
|
|
1822
1926
|
* a synonym - or that include the term in its name.
|
|
@@ -1862,13 +1966,18 @@ var UcumLhcUtils = /*#__PURE__*/function () {
|
|
|
1862
1966
|
* true indicates suggestions are wanted; false indicates they are not,
|
|
1863
1967
|
* and is the default if the parameter is not specified;
|
|
1864
1968
|
* @returns a hash containing:
|
|
1969
|
+
* 'status' will be 'valid' (uName is a valid UCUM code), 'invalid'
|
|
1970
|
+
* (the uStr is not a valid UCUM code, and substitutions or
|
|
1971
|
+
* suggestions may or may not be returned, depending on what was
|
|
1972
|
+
* requested and found); or 'error' (an input or programming error
|
|
1973
|
+
* occurred);
|
|
1865
1974
|
* 'unit' the unit object (or null if there were problems creating the
|
|
1866
1975
|
* unit);
|
|
1867
1976
|
* 'origString' the possibly updated unit string passed in;
|
|
1868
1977
|
* 'retMsg' an array of user messages (informational, error or warning) if
|
|
1869
1978
|
* any were generated (IF any were generated, otherwise will be an
|
|
1870
1979
|
* empty array); and
|
|
1871
|
-
*
|
|
1980
|
+
* 'suggestions' is an array of 1 or more hash objects. Each hash
|
|
1872
1981
|
* contains three elements:
|
|
1873
1982
|
* 'msg' which is a message indicating what unit expression the
|
|
1874
1983
|
* suggestions are for;
|
|
@@ -1915,8 +2024,18 @@ var UcumLhcUtils = /*#__PURE__*/function () {
|
|
|
1915
2024
|
} // end if the unit was not found as a unit name
|
|
1916
2025
|
|
|
1917
2026
|
} // end if a unit expression was specified
|
|
2027
|
+
// Set the status field
|
|
1918
2028
|
|
|
1919
2029
|
|
|
2030
|
+
if (!retObj.unit) {
|
|
2031
|
+
// No unit was found; check whether origString has a value
|
|
2032
|
+
retObj.status = !retObj.origString ? 'error' : 'invalid';
|
|
2033
|
+
} else {
|
|
2034
|
+
// Check whether substitutions were made to the unit string in order to
|
|
2035
|
+
// find the unit
|
|
2036
|
+
retObj.status = retObj.origString === uName ? 'valid' : 'invalid';
|
|
2037
|
+
}
|
|
2038
|
+
|
|
1920
2039
|
return retObj;
|
|
1921
2040
|
} // end getSpecifiedUnit
|
|
1922
2041
|
|
|
@@ -2419,8 +2538,8 @@ var Unit = /*#__PURE__*/function () {
|
|
|
2419
2538
|
key: "convertFrom",
|
|
2420
2539
|
value: function convertFrom(num, fromUnit) {
|
|
2421
2540
|
var newNum = 0.0;
|
|
2422
|
-
if (this.isArbitrary_) throw new Error("Attempt to convert arbitrary unit ".concat(this.
|
|
2423
|
-
if (fromUnit.isArbitrary_) throw new Error("Attempt to convert
|
|
2541
|
+
if (this.isArbitrary_) throw new Error("Attempt to convert to arbitrary unit \"".concat(this.csCode_, "\""));
|
|
2542
|
+
if (fromUnit.isArbitrary_) throw new Error("Attempt to convert arbitrary unit \"".concat(fromUnit.csCode_, "\"")); // reject request if both units have dimensions that are not equal
|
|
2424
2543
|
|
|
2425
2544
|
if (fromUnit.dim_ && this.dim_ && !fromUnit.dim_.equals(this.dim_)) {
|
|
2426
2545
|
// check first to see if a mole<->mass conversion is appropriate
|
|
@@ -2442,40 +2561,28 @@ var Unit = /*#__PURE__*/function () {
|
|
|
2442
2561
|
}
|
|
2443
2562
|
|
|
2444
2563
|
var fromCnv = fromUnit.cnv_;
|
|
2445
|
-
var fromMag = fromUnit.magnitude_;
|
|
2446
|
-
|
|
2447
|
-
// "from" unit's magnitude by the number passed in and then divide
|
|
2448
|
-
// that result by this unit's magnitude. Do this for units with
|
|
2449
|
-
// and without dimension vectors. PROBLEM with 2 non-commensurable
|
|
2450
|
-
// units with no dimension vector or function, e.g., byte to mol
|
|
2451
|
-
|
|
2452
|
-
if (fromCnv === this.cnv_) {
|
|
2453
|
-
newNum = num * fromMag / this.magnitude_;
|
|
2454
|
-
} // else use a function to get the number to be returned
|
|
2455
|
-
else {
|
|
2456
|
-
var x = 0.0;
|
|
2564
|
+
var fromMag = fromUnit.magnitude_;
|
|
2565
|
+
var x;
|
|
2457
2566
|
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2567
|
+
if (fromCnv != null) {
|
|
2568
|
+
// turn num * fromUnit.magnitude into its ratio scale equivalent,
|
|
2569
|
+
// e.g., convert Celsius to Kelvin
|
|
2570
|
+
var fromFunc = _ucumFunctions.default.forName(fromCnv);
|
|
2462
2571
|
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
if (this.cnv_ != null) {
|
|
2469
|
-
// turn mag * origUnit on ratio scale into a non-ratio unit,
|
|
2470
|
-
// e.g. convert Kelvin to Fahrenheit
|
|
2471
|
-
var toFunc = _ucumFunctions.default.forName(this.cnv_);
|
|
2572
|
+
x = fromFunc.cnvFrom(num * fromUnit.cnvPfx_) * fromMag; //x = fromFunc.cnvFrom(num * fromMag) * fromUnit.cnvPfx_;
|
|
2573
|
+
} else {
|
|
2574
|
+
x = num * fromMag;
|
|
2575
|
+
}
|
|
2472
2576
|
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
} // end if either unit has a conversion function
|
|
2577
|
+
if (this.cnv_ != null) {
|
|
2578
|
+
// turn mag * origUnit on ratio scale into a non-ratio unit,
|
|
2579
|
+
// e.g. convert Kelvin to Fahrenheit
|
|
2580
|
+
var toFunc = _ucumFunctions.default.forName(this.cnv_);
|
|
2478
2581
|
|
|
2582
|
+
newNum = toFunc.cnvTo(x / this.magnitude_) / this.cnvPfx_;
|
|
2583
|
+
} else {
|
|
2584
|
+
newNum = x / this.magnitude_;
|
|
2585
|
+
}
|
|
2479
2586
|
|
|
2480
2587
|
return newNum;
|
|
2481
2588
|
} // end convertFrom
|
|
@@ -2690,6 +2797,7 @@ var Unit = /*#__PURE__*/function () {
|
|
|
2690
2797
|
else if (unit2.cnv_ != null) {
|
|
2691
2798
|
if (!retUnit.dim_ || retUnit.dim_.isZero()) {
|
|
2692
2799
|
retUnit.cnvPfx_ = unit2.cnvPfx_ * retUnit.magnitude_;
|
|
2800
|
+
retUnit.magnitude_ = unit2.magnitude_;
|
|
2693
2801
|
retUnit.cnv_ = unit2.cnv_;
|
|
2694
2802
|
} else throw new Error("Attempt to multiply non-ratio unit ".concat(unit2.name_));
|
|
2695
2803
|
} // end if unit2 has a conversion function
|
|
@@ -2723,7 +2831,9 @@ var Unit = /*#__PURE__*/function () {
|
|
|
2723
2831
|
// if (!retUnit.isMole_)
|
|
2724
2832
|
// retUnit.isMole_ = unit2.isMole_ ;
|
|
2725
2833
|
|
|
2726
|
-
if (!retUnit.isArbitrary_) retUnit.isArbitrary_ = unit2.isArbitrary_;
|
|
2834
|
+
if (!retUnit.isArbitrary_) retUnit.isArbitrary_ = unit2.isArbitrary_; // Likewise for special units
|
|
2835
|
+
|
|
2836
|
+
if (!retUnit.isSpecial_) retUnit.isSpecial_ = unit2.isSpecial_;
|
|
2727
2837
|
return retUnit;
|
|
2728
2838
|
} // end multiplyThese
|
|
2729
2839
|
|
|
@@ -3280,6 +3390,7 @@ var UnitString = /*#__PURE__*/function () {
|
|
|
3280
3390
|
if (intUtils_.isIntegerUnit(finalUnit) || typeof finalUnit === 'number') {
|
|
3281
3391
|
finalUnit = new Unit({
|
|
3282
3392
|
'csCode_': origString,
|
|
3393
|
+
'ciCode_': origString,
|
|
3283
3394
|
'magnitude_': finalUnit,
|
|
3284
3395
|
'name_': origString
|
|
3285
3396
|
});
|
|
@@ -4392,24 +4503,30 @@ var UnitString = /*#__PURE__*/function () {
|
|
|
4392
4503
|
if (!befAnnoText && !aftAnnoText) {
|
|
4393
4504
|
var tryBrackets = '[' + annoText.substring(1, annoText.length - 1) + ']';
|
|
4394
4505
|
|
|
4395
|
-
var mkUnitRet = this._makeUnit(tryBrackets, origString); //
|
|
4396
|
-
//
|
|
4506
|
+
var mkUnitRet = this._makeUnit(tryBrackets, origString); // Nearly anything inside braces is valid, so we don't want to change the
|
|
4507
|
+
// unit, but we can put the found unit in the message as a sort of
|
|
4508
|
+
// warning.
|
|
4397
4509
|
|
|
4398
4510
|
|
|
4399
4511
|
if (mkUnitRet[0]) {
|
|
4400
|
-
retUnit =
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
if (this.retMsg_.length > msgLen) {
|
|
4407
|
-
this.retMsg_.pop();
|
|
4408
|
-
}
|
|
4409
|
-
|
|
4410
|
-
uCode = 1;
|
|
4411
|
-
retUnit = 1;
|
|
4512
|
+
retUnit = uCode;
|
|
4513
|
+
this.retMsg_.push("".concat(annoText, " is a valid unit expression, but ") + "did you mean ".concat(tryBrackets, " (").concat(mkUnitRet[0].name_, ")?"));
|
|
4514
|
+
} else {
|
|
4515
|
+
// remove error message generated for trybrackets
|
|
4516
|
+
if (this.retMsg_.length > msgLen) {
|
|
4517
|
+
this.retMsg_.pop();
|
|
4412
4518
|
}
|
|
4519
|
+
} // This is the case where the string is only this annotation.
|
|
4520
|
+
// Create and return a unit object, as we do for numeric units in
|
|
4521
|
+
// parseString.
|
|
4522
|
+
|
|
4523
|
+
|
|
4524
|
+
retUnit = new Unit({
|
|
4525
|
+
'csCode_': annoText,
|
|
4526
|
+
'ciCode_': annoText,
|
|
4527
|
+
'magnitude_': 1,
|
|
4528
|
+
'name_': annoText
|
|
4529
|
+
});
|
|
4413
4530
|
} // end if it's only an annotation
|
|
4414
4531
|
else {
|
|
4415
4532
|
// if there's text before and no text after, assume the text before
|
|
@@ -4494,6 +4611,7 @@ var UnitString = /*#__PURE__*/function () {
|
|
|
4494
4611
|
if (intUtils_.isIntegerUnit(finalUnit)) {
|
|
4495
4612
|
finalUnit = new Unit({
|
|
4496
4613
|
'csCode_': finalUnit,
|
|
4614
|
+
'ciCode_': finalUnit,
|
|
4497
4615
|
'magnitude_': Number(finalUnit),
|
|
4498
4616
|
'name_': finalUnit
|
|
4499
4617
|
});
|
|
@@ -4509,6 +4627,7 @@ var UnitString = /*#__PURE__*/function () {
|
|
|
4509
4627
|
if (intUtils_.isIntegerUnit(nextUnit)) {
|
|
4510
4628
|
nextUnit = new Unit({
|
|
4511
4629
|
'csCode_': nextUnit,
|
|
4630
|
+
'ciCode_': nextUnit,
|
|
4512
4631
|
'magnitude_': Number(nextUnit),
|
|
4513
4632
|
'name_': nextUnit
|
|
4514
4633
|
});
|
|
@@ -4734,6 +4853,11 @@ var UnitTablesFactory = /*#__PURE__*/function () {
|
|
|
4734
4853
|
*/
|
|
4735
4854
|
|
|
4736
4855
|
this.massDimIndex_ = 0;
|
|
4856
|
+
/**
|
|
4857
|
+
* Map of indices in the dimension vector to base unit symbols.
|
|
4858
|
+
*/
|
|
4859
|
+
|
|
4860
|
+
this.dimVecIndexToBaseUnit_ = {};
|
|
4737
4861
|
}
|
|
4738
4862
|
/**
|
|
4739
4863
|
* Provides the number of unit objects written to the tables, using the
|
|
@@ -4774,6 +4898,17 @@ var UnitTablesFactory = /*#__PURE__*/function () {
|
|
|
4774
4898
|
} catch (err) {// do nothing - throws error if the property is null
|
|
4775
4899
|
// and that's OK here.
|
|
4776
4900
|
}
|
|
4901
|
+
|
|
4902
|
+
if (theUnit.isBase_) {
|
|
4903
|
+
var dimVec = theUnit.dim_.dimVec_;
|
|
4904
|
+
var nonZeroIndex;
|
|
4905
|
+
|
|
4906
|
+
for (var i = 0, len = dimVec.length; nonZeroIndex == undefined && i < len; ++i) {
|
|
4907
|
+
if (dimVec[i] != 0) nonZeroIndex = i;
|
|
4908
|
+
}
|
|
4909
|
+
|
|
4910
|
+
this.dimVecIndexToBaseUnit_[nonZeroIndex] = theUnit.csCode_;
|
|
4911
|
+
}
|
|
4777
4912
|
} // end addUnit
|
|
4778
4913
|
|
|
4779
4914
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lhncbc/ucum-lhc",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "Implements Unified Code for Units of Measure (UCUM) functions in a javascript library",
|
|
5
5
|
"main": "source-cjs/ucumPkg.js",
|
|
6
6
|
"homepage": "https://lhncbc.github.io/ucum-lhc/",
|
package/source/config.js
CHANGED
|
@@ -24,6 +24,7 @@ export var Ucum = {
|
|
|
24
24
|
*/
|
|
25
25
|
dimLen_: 7,
|
|
26
26
|
|
|
27
|
+
|
|
27
28
|
/**
|
|
28
29
|
* The characters used as valid operators in a UCUM unit expression,
|
|
29
30
|
* where '.' is for multiplication and '/' is for division.
|
|
@@ -63,14 +64,14 @@ export var Ucum = {
|
|
|
63
64
|
* displaying messages on a web site; should be blank when output is
|
|
64
65
|
* to a file.
|
|
65
66
|
*/
|
|
66
|
-
openEmphHTML_ : '<span class="emphSpan">',
|
|
67
|
+
openEmphHTML_ : ' <span class="emphSpan">',
|
|
67
68
|
|
|
68
69
|
/**
|
|
69
70
|
* Closing HTML used to emphasize portions of error messages. Used when
|
|
70
71
|
* displaying messages on a web site; should be blank when output is
|
|
71
72
|
* to a file.
|
|
72
73
|
*/
|
|
73
|
-
closeEmphHTML_ : '</span>' ,
|
|
74
|
+
closeEmphHTML_ : '</span> ' ,
|
|
74
75
|
|
|
75
76
|
/**
|
|
76
77
|
* Message that is displayed when annotations are included in a unit
|
package/source/ucumLhcUtils.js
CHANGED
|
@@ -130,19 +130,12 @@ export class UcumLhcUtils {
|
|
|
130
130
|
|
|
131
131
|
let resp = this.getSpecifiedUnit(uStr, valConv, suggest);
|
|
132
132
|
let theUnit = resp['unit'];
|
|
133
|
-
let retObj = {}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
'
|
|
138
|
-
|
|
139
|
-
else {
|
|
140
|
-
retObj = {'status': resp['origString'] === uStr ? 'valid': 'invalid',
|
|
141
|
-
'ucumCode': resp['origString'],
|
|
142
|
-
'unit': {'code': theUnit.csCode_,
|
|
143
|
-
'name': theUnit.name_,
|
|
144
|
-
'guidance': theUnit.guidance_ }};
|
|
145
|
-
}
|
|
133
|
+
let retObj = !theUnit ? {'ucumCode': null} :
|
|
134
|
+
{'ucumCode': resp['origString'],
|
|
135
|
+
'unit': {'code': theUnit.csCode_,
|
|
136
|
+
'name': theUnit.name_,
|
|
137
|
+
'guidance': theUnit.guidance_ }};
|
|
138
|
+
retObj.status = resp.status;
|
|
146
139
|
if (resp['suggestions']) {
|
|
147
140
|
retObj['suggestions'] = resp['suggestions'];
|
|
148
141
|
}
|
|
@@ -228,12 +221,7 @@ export class UcumLhcUtils {
|
|
|
228
221
|
returnObj['status'] = 'error';
|
|
229
222
|
returnObj['msg'].push('No "from" unit expression specified.');
|
|
230
223
|
}
|
|
231
|
-
|
|
232
|
-
!intUtils_.isNumericString(fromVal))) {
|
|
233
|
-
returnObj['status'] = 'error';
|
|
234
|
-
returnObj['msg'].push('No "from" value, or an invalid "from" value, ' +
|
|
235
|
-
'was specified.');
|
|
236
|
-
}
|
|
224
|
+
this._checkFromVal(fromVal, returnObj);
|
|
237
225
|
if (toUnitCode) {
|
|
238
226
|
toUnitCode = toUnitCode.trim();
|
|
239
227
|
}
|
|
@@ -337,6 +325,110 @@ export class UcumLhcUtils {
|
|
|
337
325
|
} // end convertUnitTo
|
|
338
326
|
|
|
339
327
|
|
|
328
|
+
/**
|
|
329
|
+
* Converts the given unit string into its base units, their exponents, and
|
|
330
|
+
* a magnitude, and returns that data.
|
|
331
|
+
* @param fromUnit the unit string to be converted to base units information
|
|
332
|
+
* @param fromVal the number of "from" units to be converted
|
|
333
|
+
* @returns an object with the properties:
|
|
334
|
+
* 'status' indicates whether the result succeeded. The value will be one of:
|
|
335
|
+
* 'succeeded': the conversion was successfully calculated (which can be
|
|
336
|
+
* true even if it was already in base units);
|
|
337
|
+
* 'invalid': fromUnit is not a valid UCUM code;
|
|
338
|
+
* 'failed': the conversion could not be made (e.g., if it is an "arbitrary" unit);
|
|
339
|
+
* 'error': if an error occurred (an input or programming error)
|
|
340
|
+
* 'msg': an array of one or more messages, if the string is invalid or
|
|
341
|
+
* an error occurred, indicating the problem, or a suggestion of a
|
|
342
|
+
* substitution such as the substitution of 'G' for 'Gauss', or
|
|
343
|
+
* an empty array if no messages were generated. There can also be a
|
|
344
|
+
* message that is just informational or warning.
|
|
345
|
+
* 'magnitude': the new value when fromVal units of fromUnits is expressed in the base units.
|
|
346
|
+
* 'fromUnitIsSpecial': whether the input unit fromUnit is a "special unit"
|
|
347
|
+
* as defined in UCUM. This means there is some function applied to convert
|
|
348
|
+
* between fromUnit and the base units, so the returned magnitude is likely not
|
|
349
|
+
* useful as a scale factor for other conversions (i.e., it only has validity
|
|
350
|
+
* and usefulness for the input values that produced it).
|
|
351
|
+
* 'unitToExp': a map of base units in uStr to their exponent
|
|
352
|
+
*/
|
|
353
|
+
convertToBaseUnits(fromUnit, fromVal) {
|
|
354
|
+
let retObj = {};
|
|
355
|
+
this._checkFromVal(fromVal, retObj);
|
|
356
|
+
if (!retObj.status) { // could be set to 'error' by _checkFromVal
|
|
357
|
+
let inputUnitLookup = this.getSpecifiedUnit(fromUnit, 'validate');
|
|
358
|
+
retObj = {status: inputUnitLookup.status == 'valid' ? 'succeeded' : inputUnitLookup.status};
|
|
359
|
+
let unit = inputUnitLookup.unit;
|
|
360
|
+
retObj.msg = inputUnitLookup.retMsg || [];
|
|
361
|
+
if (!unit) {
|
|
362
|
+
if (inputUnitLookup.retMsg?.length == 0)
|
|
363
|
+
retObj.msg.push('Could not find unit information for '+fromUnit);
|
|
364
|
+
}
|
|
365
|
+
else if (unit.isArbitrary_) {
|
|
366
|
+
retObj.msg.push('Arbitrary units cannot be converted to base units or other units.');
|
|
367
|
+
retObj.status = 'failed';
|
|
368
|
+
}
|
|
369
|
+
else if (retObj.status == 'succeeded') {
|
|
370
|
+
let unitToExp = {};
|
|
371
|
+
let dimVec = unit.dim_?.dimVec_
|
|
372
|
+
let baseUnitString = '1';
|
|
373
|
+
if (dimVec) {
|
|
374
|
+
let dimVecIndexToBaseUnit = UnitTables.getInstance().dimVecIndexToBaseUnit_;
|
|
375
|
+
for (let i=0, len=dimVec.length; i<len; ++i) {
|
|
376
|
+
let exp = dimVec[i];
|
|
377
|
+
if (exp) {
|
|
378
|
+
unitToExp[dimVecIndexToBaseUnit[i]] = exp;
|
|
379
|
+
baseUnitString += '.' + dimVecIndexToBaseUnit[i] + exp;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// The unit might have a conversion function, which has to be applied; we
|
|
385
|
+
// cannot just assume unit_.magnitude_ is the magnitude in base units.
|
|
386
|
+
let retUnitLookup = this.getSpecifiedUnit(baseUnitString, 'validate');
|
|
387
|
+
// There should not be any error in retUnitLookup, unless there is a bug.
|
|
388
|
+
let retUnit = retUnitLookup.unit;
|
|
389
|
+
if (retUnitLookup.status !== 'valid') {
|
|
390
|
+
retObj.msg.push('Unable construct base unit string; tried '+baseUnitString);
|
|
391
|
+
retObj.status = 'error';
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
try {
|
|
395
|
+
retObj.magnitude = retUnit.convertFrom(fromVal, unit);
|
|
396
|
+
}
|
|
397
|
+
catch (e) {
|
|
398
|
+
retObj.msg.push(e.toString());
|
|
399
|
+
retObj.status = 'error';
|
|
400
|
+
}
|
|
401
|
+
if (retObj.status == 'succeeded') {
|
|
402
|
+
retObj.unitToExp = unitToExp;
|
|
403
|
+
retObj.fromUnitIsSpecial = unit.isSpecial_;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return retObj;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Checks the given value as to whether it is suitable as a "from" value in a
|
|
414
|
+
* unit conversion. If it is not, the responseObj will have its status set
|
|
415
|
+
* to 'error' and a message added.
|
|
416
|
+
* @param fromVal The value to check
|
|
417
|
+
* @param responseObj the object that will be updated if the value is not
|
|
418
|
+
* usable.
|
|
419
|
+
*/
|
|
420
|
+
_checkFromVal(fromVal, responseObj) {
|
|
421
|
+
if (fromVal === null || isNaN(fromVal) || (typeof fromVal !== 'number' &&
|
|
422
|
+
!intUtils_.isNumericString(fromVal))) {
|
|
423
|
+
responseObj.status = 'error';
|
|
424
|
+
if (!responseObj.msg)
|
|
425
|
+
responseObj.msg = [];
|
|
426
|
+
responseObj.msg.push('No "from" value, or an invalid "from" value, ' +
|
|
427
|
+
'was specified.');
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
|
|
340
432
|
/**
|
|
341
433
|
* This method accepts a term and looks for units that include it as
|
|
342
434
|
* a synonym - or that include the term in its name.
|
|
@@ -380,13 +472,18 @@ export class UcumLhcUtils {
|
|
|
380
472
|
* true indicates suggestions are wanted; false indicates they are not,
|
|
381
473
|
* and is the default if the parameter is not specified;
|
|
382
474
|
* @returns a hash containing:
|
|
475
|
+
* 'status' will be 'valid' (uName is a valid UCUM code), 'invalid'
|
|
476
|
+
* (the uStr is not a valid UCUM code, and substitutions or
|
|
477
|
+
* suggestions may or may not be returned, depending on what was
|
|
478
|
+
* requested and found); or 'error' (an input or programming error
|
|
479
|
+
* occurred);
|
|
383
480
|
* 'unit' the unit object (or null if there were problems creating the
|
|
384
481
|
* unit);
|
|
385
482
|
* 'origString' the possibly updated unit string passed in;
|
|
386
483
|
* 'retMsg' an array of user messages (informational, error or warning) if
|
|
387
484
|
* any were generated (IF any were generated, otherwise will be an
|
|
388
485
|
* empty array); and
|
|
389
|
-
*
|
|
486
|
+
* 'suggestions' is an array of 1 or more hash objects. Each hash
|
|
390
487
|
* contains three elements:
|
|
391
488
|
* 'msg' which is a message indicating what unit expression the
|
|
392
489
|
* suggestions are for;
|
|
@@ -441,6 +538,17 @@ export class UcumLhcUtils {
|
|
|
441
538
|
} // end if the unit was not found as a unit name
|
|
442
539
|
} // end if a unit expression was specified
|
|
443
540
|
|
|
541
|
+
// Set the status field
|
|
542
|
+
if (!retObj.unit) {
|
|
543
|
+
// No unit was found; check whether origString has a value
|
|
544
|
+
retObj.status = !retObj.origString ? 'error' : 'invalid';
|
|
545
|
+
}
|
|
546
|
+
else {
|
|
547
|
+
// Check whether substitutions were made to the unit string in order to
|
|
548
|
+
// find the unit
|
|
549
|
+
retObj.status = retObj.origString === uName ? 'valid': 'invalid';
|
|
550
|
+
}
|
|
551
|
+
|
|
444
552
|
return retObj;
|
|
445
553
|
|
|
446
554
|
} // end getSpecifiedUnit
|
|
@@ -512,7 +620,3 @@ export class UcumLhcUtils {
|
|
|
512
620
|
UcumLhcUtils.getInstance = function(){
|
|
513
621
|
return new UcumLhcUtils();
|
|
514
622
|
} ;
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|