@lhncbc/ucum-lhc 4.1.8 → 4.2.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 +120 -35
- package/package.json +1 -1
- package/source/config.js +3 -2
- package/source/ucumLhcUtils.js +70 -0
- package/source/unit.js +28 -34
- package/source/unitString.js +3 -2
- 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 +70 -0
- 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 +3 -0
- 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
|
|
@@ -1817,6 +1817,81 @@ var UcumLhcUtils = /*#__PURE__*/function () {
|
|
|
1817
1817
|
return returnObj;
|
|
1818
1818
|
} // end convertUnitTo
|
|
1819
1819
|
|
|
1820
|
+
/**
|
|
1821
|
+
* Converts the given unit string into its base units, their exponents, and
|
|
1822
|
+
* a magnitude, and returns that data.
|
|
1823
|
+
* @param fromUnit the unit string to be converted to base units information
|
|
1824
|
+
* @param fromVal the number of "from" units to be converted
|
|
1825
|
+
* @returns an object with the properties:
|
|
1826
|
+
* 'msg': an array of one or more messages, if the string is invalid or
|
|
1827
|
+
* an error occurred, indicating the problem, or a suggestion of a
|
|
1828
|
+
* substitution such as the substitution of 'G' for 'Gauss', or
|
|
1829
|
+
* an empty array if no messages were generated. If this is not empty,
|
|
1830
|
+
* no other information will be returned.
|
|
1831
|
+
* 'magnitude': the new value when fromVal units of fromUnits is expressed in the base units.
|
|
1832
|
+
* 'fromUnitIsSpecial': whether the input unit fromUnit is a "special unit"
|
|
1833
|
+
* as defined in UCUM. This means there is some function applied to convert
|
|
1834
|
+
* between fromUnit and the base units, so the returned magnitude is likely not
|
|
1835
|
+
* useful as a scale factor for other conversions (i.e., it only has validity
|
|
1836
|
+
* and usefulness for the input values that produced it).
|
|
1837
|
+
* 'unitToExp': a map of base units in uStr to their exponent
|
|
1838
|
+
*/
|
|
1839
|
+
|
|
1840
|
+
}, {
|
|
1841
|
+
key: "convertToBaseUnits",
|
|
1842
|
+
value: function convertToBaseUnits(fromUnit, fromVal) {
|
|
1843
|
+
var inputUnitLookup = this.getSpecifiedUnit(fromUnit, 'validate');
|
|
1844
|
+
var retObj = {};
|
|
1845
|
+
var unit = inputUnitLookup.unit;
|
|
1846
|
+
retObj.msg = inputUnitLookup.retMsg || [];
|
|
1847
|
+
|
|
1848
|
+
if (!unit) {
|
|
1849
|
+
var _inputUnitLookup$retM;
|
|
1850
|
+
|
|
1851
|
+
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);
|
|
1852
|
+
} else if (unit.isArbitrary_) {
|
|
1853
|
+
retObj.msg.push('Arbitrary units cannot be converted to base units or other units.');
|
|
1854
|
+
} else if (retObj.msg.length == 0) {
|
|
1855
|
+
var _unit$dim_, _retUnitLookup$retMsg;
|
|
1856
|
+
|
|
1857
|
+
var unitToExp = {};
|
|
1858
|
+
var dimVec = (_unit$dim_ = unit.dim_) === null || _unit$dim_ === void 0 ? void 0 : _unit$dim_.dimVec_;
|
|
1859
|
+
var baseUnitString = '1';
|
|
1860
|
+
|
|
1861
|
+
if (dimVec) {
|
|
1862
|
+
var dimVecIndexToBaseUnit = UnitTables.getInstance().dimVecIndexToBaseUnit_;
|
|
1863
|
+
|
|
1864
|
+
for (var i = 0, len = dimVec.length; i < len; ++i) {
|
|
1865
|
+
var exp = dimVec[i];
|
|
1866
|
+
|
|
1867
|
+
if (exp) {
|
|
1868
|
+
unitToExp[dimVecIndexToBaseUnit[i]] = exp;
|
|
1869
|
+
baseUnitString += '.' + dimVecIndexToBaseUnit[i] + exp;
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
} // The unit might have a conversion function, which has to be applied; we
|
|
1873
|
+
// cannot just assume unit_.magnitude_ is the magnitude in base units.
|
|
1874
|
+
|
|
1875
|
+
|
|
1876
|
+
var retUnitLookup = this.getSpecifiedUnit(baseUnitString, 'validate'); // There should not be any error in retUnitLookup, unless there is a bug.
|
|
1877
|
+
|
|
1878
|
+
var retUnit = retUnitLookup.unit;
|
|
1879
|
+
if (!retUnit && ((_retUnitLookup$retMsg = retUnitLookup.retMsg) === null || _retUnitLookup$retMsg === void 0 ? void 0 : _retUnitLookup$retMsg.length) == 0) retObj.msg.push('Unable construct base unit string; tried ' + baseUnitString);else {
|
|
1880
|
+
try {
|
|
1881
|
+
retObj.magnitude = retUnit.convertFrom(fromVal, unit);
|
|
1882
|
+
} catch (e) {
|
|
1883
|
+
retObj.msg.push(e.toString());
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
if (retObj.msg.length == 0) {
|
|
1887
|
+
retObj.unitToExp = unitToExp;
|
|
1888
|
+
retObj.fromUnitIsSpecial = unit.isSpecial_;
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
return retObj;
|
|
1894
|
+
}
|
|
1820
1895
|
/**
|
|
1821
1896
|
* This method accepts a term and looks for units that include it as
|
|
1822
1897
|
* a synonym - or that include the term in its name.
|
|
@@ -2419,8 +2494,8 @@ var Unit = /*#__PURE__*/function () {
|
|
|
2419
2494
|
key: "convertFrom",
|
|
2420
2495
|
value: function convertFrom(num, fromUnit) {
|
|
2421
2496
|
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
|
|
2497
|
+
if (this.isArbitrary_) throw new Error("Attempt to convert to arbitrary unit \"".concat(this.csCode_, "\""));
|
|
2498
|
+
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
2499
|
|
|
2425
2500
|
if (fromUnit.dim_ && this.dim_ && !fromUnit.dim_.equals(this.dim_)) {
|
|
2426
2501
|
// check first to see if a mole<->mass conversion is appropriate
|
|
@@ -2442,40 +2517,28 @@ var Unit = /*#__PURE__*/function () {
|
|
|
2442
2517
|
}
|
|
2443
2518
|
|
|
2444
2519
|
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;
|
|
2457
|
-
|
|
2458
|
-
if (fromCnv != null) {
|
|
2459
|
-
// turn num * fromUnit.magnitude into its ratio scale equivalent,
|
|
2460
|
-
// e.g., convert Celsius to Kelvin
|
|
2461
|
-
var fromFunc = _ucumFunctions.default.forName(fromCnv);
|
|
2520
|
+
var fromMag = fromUnit.magnitude_;
|
|
2521
|
+
var x;
|
|
2462
2522
|
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2523
|
+
if (fromCnv != null) {
|
|
2524
|
+
// turn num * fromUnit.magnitude into its ratio scale equivalent,
|
|
2525
|
+
// e.g., convert Celsius to Kelvin
|
|
2526
|
+
var fromFunc = _ucumFunctions.default.forName(fromCnv);
|
|
2467
2527
|
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2528
|
+
x = fromFunc.cnvFrom(num * fromUnit.cnvPfx_) * fromMag; //x = fromFunc.cnvFrom(num * fromMag) * fromUnit.cnvPfx_;
|
|
2529
|
+
} else {
|
|
2530
|
+
x = num * fromMag;
|
|
2531
|
+
}
|
|
2472
2532
|
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
} // end if either unit has a conversion function
|
|
2533
|
+
if (this.cnv_ != null) {
|
|
2534
|
+
// turn mag * origUnit on ratio scale into a non-ratio unit,
|
|
2535
|
+
// e.g. convert Kelvin to Fahrenheit
|
|
2536
|
+
var toFunc = _ucumFunctions.default.forName(this.cnv_);
|
|
2478
2537
|
|
|
2538
|
+
newNum = toFunc.cnvTo(x / this.magnitude_) / this.cnvPfx_;
|
|
2539
|
+
} else {
|
|
2540
|
+
newNum = x / this.magnitude_;
|
|
2541
|
+
}
|
|
2479
2542
|
|
|
2480
2543
|
return newNum;
|
|
2481
2544
|
} // end convertFrom
|
|
@@ -2690,6 +2753,7 @@ var Unit = /*#__PURE__*/function () {
|
|
|
2690
2753
|
else if (unit2.cnv_ != null) {
|
|
2691
2754
|
if (!retUnit.dim_ || retUnit.dim_.isZero()) {
|
|
2692
2755
|
retUnit.cnvPfx_ = unit2.cnvPfx_ * retUnit.magnitude_;
|
|
2756
|
+
retUnit.magnitude_ = unit2.magnitude_;
|
|
2693
2757
|
retUnit.cnv_ = unit2.cnv_;
|
|
2694
2758
|
} else throw new Error("Attempt to multiply non-ratio unit ".concat(unit2.name_));
|
|
2695
2759
|
} // end if unit2 has a conversion function
|
|
@@ -2723,7 +2787,9 @@ var Unit = /*#__PURE__*/function () {
|
|
|
2723
2787
|
// if (!retUnit.isMole_)
|
|
2724
2788
|
// retUnit.isMole_ = unit2.isMole_ ;
|
|
2725
2789
|
|
|
2726
|
-
if (!retUnit.isArbitrary_) retUnit.isArbitrary_ = unit2.isArbitrary_;
|
|
2790
|
+
if (!retUnit.isArbitrary_) retUnit.isArbitrary_ = unit2.isArbitrary_; // Likewise for special units
|
|
2791
|
+
|
|
2792
|
+
if (!retUnit.isSpecial_) retUnit.isSpecial_ = unit2.isSpecial_;
|
|
2727
2793
|
return retUnit;
|
|
2728
2794
|
} // end multiplyThese
|
|
2729
2795
|
|
|
@@ -3280,6 +3346,7 @@ var UnitString = /*#__PURE__*/function () {
|
|
|
3280
3346
|
if (intUtils_.isIntegerUnit(finalUnit) || typeof finalUnit === 'number') {
|
|
3281
3347
|
finalUnit = new Unit({
|
|
3282
3348
|
'csCode_': origString,
|
|
3349
|
+
'ciCode_': origString,
|
|
3283
3350
|
'magnitude_': finalUnit,
|
|
3284
3351
|
'name_': origString
|
|
3285
3352
|
});
|
|
@@ -4494,6 +4561,7 @@ var UnitString = /*#__PURE__*/function () {
|
|
|
4494
4561
|
if (intUtils_.isIntegerUnit(finalUnit)) {
|
|
4495
4562
|
finalUnit = new Unit({
|
|
4496
4563
|
'csCode_': finalUnit,
|
|
4564
|
+
'ciCode_': finalUnit,
|
|
4497
4565
|
'magnitude_': Number(finalUnit),
|
|
4498
4566
|
'name_': finalUnit
|
|
4499
4567
|
});
|
|
@@ -4509,6 +4577,7 @@ var UnitString = /*#__PURE__*/function () {
|
|
|
4509
4577
|
if (intUtils_.isIntegerUnit(nextUnit)) {
|
|
4510
4578
|
nextUnit = new Unit({
|
|
4511
4579
|
'csCode_': nextUnit,
|
|
4580
|
+
'ciCode_': nextUnit,
|
|
4512
4581
|
'magnitude_': Number(nextUnit),
|
|
4513
4582
|
'name_': nextUnit
|
|
4514
4583
|
});
|
|
@@ -4734,6 +4803,11 @@ var UnitTablesFactory = /*#__PURE__*/function () {
|
|
|
4734
4803
|
*/
|
|
4735
4804
|
|
|
4736
4805
|
this.massDimIndex_ = 0;
|
|
4806
|
+
/**
|
|
4807
|
+
* Map of indices in the dimension vector to base unit symbols.
|
|
4808
|
+
*/
|
|
4809
|
+
|
|
4810
|
+
this.dimVecIndexToBaseUnit_ = {};
|
|
4737
4811
|
}
|
|
4738
4812
|
/**
|
|
4739
4813
|
* Provides the number of unit objects written to the tables, using the
|
|
@@ -4774,6 +4848,17 @@ var UnitTablesFactory = /*#__PURE__*/function () {
|
|
|
4774
4848
|
} catch (err) {// do nothing - throws error if the property is null
|
|
4775
4849
|
// and that's OK here.
|
|
4776
4850
|
}
|
|
4851
|
+
|
|
4852
|
+
if (theUnit.isBase_) {
|
|
4853
|
+
var dimVec = theUnit.dim_.dimVec_;
|
|
4854
|
+
var nonZeroIndex;
|
|
4855
|
+
|
|
4856
|
+
for (var i = 0, len = dimVec.length; nonZeroIndex == undefined && i < len; ++i) {
|
|
4857
|
+
if (dimVec[i] != 0) nonZeroIndex = i;
|
|
4858
|
+
}
|
|
4859
|
+
|
|
4860
|
+
this.dimVecIndexToBaseUnit_[nonZeroIndex] = theUnit.csCode_;
|
|
4861
|
+
}
|
|
4777
4862
|
} // end addUnit
|
|
4778
4863
|
|
|
4779
4864
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lhncbc/ucum-lhc",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.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
|
@@ -337,6 +337,76 @@ export class UcumLhcUtils {
|
|
|
337
337
|
} // end convertUnitTo
|
|
338
338
|
|
|
339
339
|
|
|
340
|
+
/**
|
|
341
|
+
* Converts the given unit string into its base units, their exponents, and
|
|
342
|
+
* a magnitude, and returns that data.
|
|
343
|
+
* @param fromUnit the unit string to be converted to base units information
|
|
344
|
+
* @param fromVal the number of "from" units to be converted
|
|
345
|
+
* @returns an object with the properties:
|
|
346
|
+
* 'msg': an array of one or more messages, if the string is invalid or
|
|
347
|
+
* an error occurred, indicating the problem, or a suggestion of a
|
|
348
|
+
* substitution such as the substitution of 'G' for 'Gauss', or
|
|
349
|
+
* an empty array if no messages were generated. If this is not empty,
|
|
350
|
+
* no other information will be returned.
|
|
351
|
+
* 'magnitude': the new value when fromVal units of fromUnits is expressed in the base units.
|
|
352
|
+
* 'fromUnitIsSpecial': whether the input unit fromUnit is a "special unit"
|
|
353
|
+
* as defined in UCUM. This means there is some function applied to convert
|
|
354
|
+
* between fromUnit and the base units, so the returned magnitude is likely not
|
|
355
|
+
* useful as a scale factor for other conversions (i.e., it only has validity
|
|
356
|
+
* and usefulness for the input values that produced it).
|
|
357
|
+
* 'unitToExp': a map of base units in uStr to their exponent
|
|
358
|
+
*/
|
|
359
|
+
convertToBaseUnits(fromUnit, fromVal) {
|
|
360
|
+
let inputUnitLookup = this.getSpecifiedUnit(fromUnit, 'validate');
|
|
361
|
+
let retObj = {};
|
|
362
|
+
let unit = inputUnitLookup.unit;
|
|
363
|
+
retObj.msg = inputUnitLookup.retMsg || [];
|
|
364
|
+
if (!unit) {
|
|
365
|
+
if (inputUnitLookup.retMsg?.length == 0)
|
|
366
|
+
retObj.msg.push('Could not find unit information for '+fromUnit);
|
|
367
|
+
}
|
|
368
|
+
else if (unit.isArbitrary_) {
|
|
369
|
+
retObj.msg.push('Arbitrary units cannot be converted to base units or other units.');
|
|
370
|
+
}
|
|
371
|
+
else if (retObj.msg.length == 0) {
|
|
372
|
+
let unitToExp = {};
|
|
373
|
+
let dimVec = unit.dim_?.dimVec_
|
|
374
|
+
let baseUnitString = '1';
|
|
375
|
+
if (dimVec) {
|
|
376
|
+
let dimVecIndexToBaseUnit = UnitTables.getInstance().dimVecIndexToBaseUnit_;
|
|
377
|
+
for (let i=0, len=dimVec.length; i<len; ++i) {
|
|
378
|
+
let exp = dimVec[i];
|
|
379
|
+
if (exp) {
|
|
380
|
+
unitToExp[dimVecIndexToBaseUnit[i]] = exp;
|
|
381
|
+
baseUnitString += '.' + dimVecIndexToBaseUnit[i] + exp;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// The unit might have a conversion function, which has to be applied; we
|
|
387
|
+
// cannot just assume unit_.magnitude_ is the magnitude in base units.
|
|
388
|
+
let retUnitLookup = this.getSpecifiedUnit(baseUnitString, 'validate');
|
|
389
|
+
// There should not be any error in retUnitLookup, unless there is a bug.
|
|
390
|
+
let retUnit = retUnitLookup.unit;
|
|
391
|
+
if (!retUnit && retUnitLookup.retMsg?.length == 0)
|
|
392
|
+
retObj.msg.push('Unable construct base unit string; tried '+baseUnitString);
|
|
393
|
+
else {
|
|
394
|
+
try {
|
|
395
|
+
retObj.magnitude = retUnit.convertFrom(fromVal, unit);
|
|
396
|
+
}
|
|
397
|
+
catch (e) {
|
|
398
|
+
retObj.msg.push(e.toString());
|
|
399
|
+
}
|
|
400
|
+
if (retObj.msg.length == 0) {
|
|
401
|
+
retObj.unitToExp = unitToExp;
|
|
402
|
+
retObj.fromUnitIsSpecial = unit.isSpecial_;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return retObj;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
|
|
340
410
|
/**
|
|
341
411
|
* This method accepts a term and looks for units that include it as
|
|
342
412
|
* a synonym - or that include the term in its name.
|
package/source/unit.js
CHANGED
|
@@ -340,6 +340,7 @@ export class Unit {
|
|
|
340
340
|
return match ;
|
|
341
341
|
}// end of fullEquals
|
|
342
342
|
|
|
343
|
+
|
|
343
344
|
/**
|
|
344
345
|
* This returns the value of the property named by the parameter
|
|
345
346
|
* passed in.
|
|
@@ -380,9 +381,9 @@ export class Unit {
|
|
|
380
381
|
let newNum = 0.0 ;
|
|
381
382
|
|
|
382
383
|
if (this.isArbitrary_)
|
|
383
|
-
throw (new Error(`Attempt to convert arbitrary unit ${this.
|
|
384
|
+
throw (new Error(`Attempt to convert to arbitrary unit "${this.csCode_}"`));
|
|
384
385
|
if (fromUnit.isArbitrary_)
|
|
385
|
-
throw (new Error(`Attempt to convert
|
|
386
|
+
throw (new Error(`Attempt to convert arbitrary unit "${fromUnit.csCode_}"`));
|
|
386
387
|
|
|
387
388
|
// reject request if both units have dimensions that are not equal
|
|
388
389
|
if (fromUnit.dim_ && this.dim_ && !(fromUnit.dim_.equals(this.dim_))) {
|
|
@@ -410,39 +411,27 @@ export class Unit {
|
|
|
410
411
|
let fromCnv = fromUnit.cnv_ ;
|
|
411
412
|
let fromMag = fromUnit.magnitude_ ;
|
|
412
413
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
newNum = (num * fromMag) / this.magnitude_;
|
|
414
|
+
let x;
|
|
415
|
+
if (fromCnv != null) {
|
|
416
|
+
// turn num * fromUnit.magnitude into its ratio scale equivalent,
|
|
417
|
+
// e.g., convert Celsius to Kelvin
|
|
418
|
+
let fromFunc = funcs.forName(fromCnv);
|
|
419
|
+
x = fromFunc.cnvFrom(num * fromUnit.cnvPfx_) * fromMag;
|
|
420
|
+
//x = fromFunc.cnvFrom(num * fromMag) * fromUnit.cnvPfx_;
|
|
421
421
|
}
|
|
422
|
-
// else use a function to get the number to be returned
|
|
423
422
|
else {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
// turn num * fromUnit.magnitude into its ratio scale equivalent,
|
|
427
|
-
// e.g., convert Celsius to Kelvin
|
|
428
|
-
let fromFunc = funcs.forName(fromCnv);
|
|
429
|
-
x = fromFunc.cnvFrom(num * fromUnit.cnvPfx_) * fromMag;
|
|
430
|
-
//x = fromFunc.cnvFrom(num * fromMag) * fromUnit.cnvPfx_;
|
|
431
|
-
}
|
|
432
|
-
else {
|
|
433
|
-
x = num * fromMag;
|
|
434
|
-
}
|
|
423
|
+
x = num * fromMag;
|
|
424
|
+
}
|
|
435
425
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
} // end if either unit has a conversion function
|
|
426
|
+
if (this.cnv_ != null) {
|
|
427
|
+
// turn mag * origUnit on ratio scale into a non-ratio unit,
|
|
428
|
+
// e.g. convert Kelvin to Fahrenheit
|
|
429
|
+
let toFunc = funcs.forName(this.cnv_);
|
|
430
|
+
newNum = toFunc.cnvTo(x / this.magnitude_) / this.cnvPfx_;
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
newNum = x / this.magnitude_;
|
|
434
|
+
}
|
|
446
435
|
|
|
447
436
|
return newNum;
|
|
448
437
|
|
|
@@ -666,6 +655,7 @@ export class Unit {
|
|
|
666
655
|
else if (unit2.cnv_ != null) {
|
|
667
656
|
if (!retUnit.dim_ || retUnit.dim_.isZero()) {
|
|
668
657
|
retUnit.cnvPfx_ = unit2.cnvPfx_ * retUnit.magnitude_;
|
|
658
|
+
retUnit.magnitude_ = unit2.magnitude_;
|
|
669
659
|
retUnit.cnv_ = unit2.cnv_ ;
|
|
670
660
|
}
|
|
671
661
|
else
|
|
@@ -716,8 +706,12 @@ export class Unit {
|
|
|
716
706
|
// via an arithmetic operation. Taint accordingly
|
|
717
707
|
// if (!retUnit.isMole_)
|
|
718
708
|
// retUnit.isMole_ = unit2.isMole_ ;
|
|
719
|
-
|
|
720
|
-
|
|
709
|
+
if (!retUnit.isArbitrary_)
|
|
710
|
+
retUnit.isArbitrary_ = unit2.isArbitrary_;
|
|
711
|
+
|
|
712
|
+
// Likewise for special units
|
|
713
|
+
if (!retUnit.isSpecial_)
|
|
714
|
+
retUnit.isSpecial_ = unit2.isSpecial_;
|
|
721
715
|
|
|
722
716
|
return retUnit ;
|
|
723
717
|
|
package/source/unitString.js
CHANGED
|
@@ -218,6 +218,7 @@ export class UnitString {
|
|
|
218
218
|
if (intUtils_.isIntegerUnit(finalUnit) || typeof finalUnit === 'number') {
|
|
219
219
|
finalUnit = new Unit({
|
|
220
220
|
'csCode_': origString,
|
|
221
|
+
'ciCode_': origString,
|
|
221
222
|
'magnitude_': finalUnit,
|
|
222
223
|
'name_': origString
|
|
223
224
|
});
|
|
@@ -1442,7 +1443,7 @@ export class UnitString {
|
|
|
1442
1443
|
|
|
1443
1444
|
let finalUnit = uArray[0]['un'];
|
|
1444
1445
|
if (intUtils_.isIntegerUnit(finalUnit)) {
|
|
1445
|
-
finalUnit = new Unit({'csCode_' : finalUnit,
|
|
1446
|
+
finalUnit = new Unit({'csCode_' : finalUnit, 'ciCode_' : finalUnit,
|
|
1446
1447
|
'magnitude_' : Number(finalUnit),
|
|
1447
1448
|
'name_' : finalUnit}) ;
|
|
1448
1449
|
}
|
|
@@ -1453,7 +1454,7 @@ export class UnitString {
|
|
|
1453
1454
|
for (let u2 = 1; (u2 < uLen) && !endProcessing; u2++) {
|
|
1454
1455
|
let nextUnit = uArray[u2]['un'];
|
|
1455
1456
|
if (intUtils_.isIntegerUnit(nextUnit)) {
|
|
1456
|
-
nextUnit = new Unit({'csCode_' : nextUnit ,
|
|
1457
|
+
nextUnit = new Unit({'csCode_' : nextUnit, 'ciCode_' : nextUnit,
|
|
1457
1458
|
'magnitude_' : Number(nextUnit),
|
|
1458
1459
|
'name_': nextUnit});
|
|
1459
1460
|
}
|
package/source/unitTables.js
CHANGED
|
@@ -97,6 +97,11 @@ class UnitTablesFactory {
|
|
|
97
97
|
* @type integer
|
|
98
98
|
*/
|
|
99
99
|
this.massDimIndex_ = 0;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Map of indices in the dimension vector to base unit symbols.
|
|
103
|
+
*/
|
|
104
|
+
this.dimVecIndexToBaseUnit_ = {};
|
|
100
105
|
}
|
|
101
106
|
|
|
102
107
|
|
|
@@ -138,6 +143,15 @@ class UnitTablesFactory {
|
|
|
138
143
|
// and that's OK here.
|
|
139
144
|
}
|
|
140
145
|
|
|
146
|
+
if (theUnit.isBase_) {
|
|
147
|
+
const dimVec = theUnit.dim_.dimVec_;
|
|
148
|
+
let nonZeroIndex;
|
|
149
|
+
for (let i=0, len=dimVec.length; nonZeroIndex==undefined && i<len; ++i) {
|
|
150
|
+
if (dimVec[i] != 0)
|
|
151
|
+
nonZeroIndex = i;
|
|
152
|
+
}
|
|
153
|
+
this.dimVecIndexToBaseUnit_[nonZeroIndex] = theUnit.csCode_;
|
|
154
|
+
}
|
|
141
155
|
} // end addUnit
|
|
142
156
|
|
|
143
157
|
|
package/source-cjs/config.js
CHANGED
|
@@ -65,14 +65,14 @@ var Ucum = {
|
|
|
65
65
|
* displaying messages on a web site; should be blank when output is
|
|
66
66
|
* to a file.
|
|
67
67
|
*/
|
|
68
|
-
openEmphHTML_: '<span class="emphSpan">',
|
|
68
|
+
openEmphHTML_: ' <span class="emphSpan">',
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
71
|
* Closing HTML used to emphasize portions of error messages. Used when
|
|
72
72
|
* displaying messages on a web site; should be blank when output is
|
|
73
73
|
* to a file.
|
|
74
74
|
*/
|
|
75
|
-
closeEmphHTML_: '</span>',
|
|
75
|
+
closeEmphHTML_: '</span> ',
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
78
|
* Message that is displayed when annotations are included in a unit
|
package/source-cjs/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../source/config.js"],"names":["Ucum","dimLen_","validOps_","codeSep_","valMsgStart_","valMsgEnd_","cnvMsgStart_","cnvMsgEnd_","openEmph_","closeEmph_","openEmphHTML_","closeEmphHTML_","bracesMsg_","needMoleWeightMsg_","csvCols_","inputKey_","specUnits_"],"mappings":";;;;;;;AAAA;;;;;;;AAQO,IAAIA,IAAI,GAAG;AAEhB;;;;;;AAMA;;AAEA;;;;;;AAMAC,EAAAA,OAAO,EAAE,CAhBO;;
|
|
1
|
+
{"version":3,"sources":["../source/config.js"],"names":["Ucum","dimLen_","validOps_","codeSep_","valMsgStart_","valMsgEnd_","cnvMsgStart_","cnvMsgEnd_","openEmph_","closeEmph_","openEmphHTML_","closeEmphHTML_","bracesMsg_","needMoleWeightMsg_","csvCols_","inputKey_","specUnits_"],"mappings":";;;;;;;AAAA;;;;;;;AAQO,IAAIA,IAAI,GAAG;AAEhB;;;;;;AAMA;;AAEA;;;;;;AAMAC,EAAAA,OAAO,EAAE,CAhBO;;AAmBhB;;;;AAIAC,EAAAA,SAAS,EAAE,CAAC,GAAD,EAAM,GAAN,CAvBK;;AA0BhB;;;;AAIAC,EAAAA,QAAQ,EAAG,IA9BK;AAgChB;AACAC,EAAAA,YAAY,EAAG,eAjCC;AAkChBC,EAAAA,UAAU,EAAG,GAlCG;AAmChBC,EAAAA,YAAY,EAAG,uBAnCC;AAoChBC,EAAAA,UAAU,EAAG,GApCG;;AAuClB;;;;;AAKEC,EAAAA,SAAS,EAAG,KA5CI;;AA8ChB;;;;;AAKAC,EAAAA,UAAU,EAAG,KAnDG;;AAqDhB;;;;;AAKAC,EAAAA,aAAa,EAAG,0BA1DA;;AA4DhB;;;;;AAKAC,EAAAA,cAAc,EAAG,UAjED;;AAmEhB;;;;AAIAC,EAAAA,UAAU,EAAG,8DACA,6DADA,GAEA,iCAzEG;;AA2EhB;;;;;AAKAC,EAAAA,kBAAkB,EAAG,0DACA,uDADA,GAEA,8CAlFL;;AAoFhB;;;;AAIAC,EAAAA,QAAQ,EAAG;AACT,2BAAwB,SADf;AAET,sBAAmB,gBAFV;AAGT,sBAAmB,OAHV;AAIT,gBAAa,WAJJ;AAKT,cAAW,SALF;AAMT,gBAAa,WANJ;AAOT,gBAAa;AAPJ,GAxFK;;AAkGhB;;;AAGAC,EAAAA,SAAS,EAAG,qBArGI;;AAuGhB;;;;;;;AAOCC,EAAAA,UAAU,EAAG;AAAE,gBAAa,gBAAf;AACE,uBAAoB;AADtB;AA9GE,CAAX","sourcesContent":["/*\n * This defines the namespace for the UCUM classes and provides\n * a place for the definition of global variables and constants.\n *\n * The javascript for this UCUM implementation uses syntax as\n * defined by the ECMAScript 6 standard\n */\n\nexport var Ucum = {\n\n /**\n * Flag indicating whether or not we're using case sensitive labels\n * I don't think we need this. I think we're just going with\n * case sensitive, per Clem. Gunther's code has this flag, but I\n * am removing it, at least for now. lm, 6/2016\n */\n //caseSensitive_: true ,\n\n /**\n * The number of elements in a Dimension array. Currently this\n * is set as a configuration variable, but when we get to the point\n * of loading the unit definitions from a file, this value will be\n * set from that.\n */\n dimLen_: 7,\n\n\n /**\n * The characters used as valid operators in a UCUM unit expression,\n * where '.' is for multiplication and '/' is for division.\n */\n validOps_: ['.', '/'],\n\n\n /**\n * The string used to separate a unit code and unit name when they\n * are displayed together\n */\n codeSep_ : ': ',\n\n // Message text variations for validation methods and conversion methods\n valMsgStart_ : 'Did you mean ',\n valMsgEnd_ : '?' ,\n cnvMsgStart_ : 'We assumed you meant ',\n cnvMsgEnd_ : '.',\n\n\n/**\n * Default opening string used to emphasize portions of error messages.\n * Used when NOT displaying messages on a web site, i.e., for output\n * from the library methods or to a file.\n */\n openEmph_ : ' ->',\n\n /**\n * Default closing string used to emphasize portions of error messages.\n * Used when NOT displaying messages on a web site, i.e., for output\n * from the library methods or to a file.\n */\n closeEmph_ : '<- ' ,\n\n /**\n * Opening HTML used to emphasize portions of error messages. Used when\n * displaying messages on a web site; should be blank when output is\n * to a file.\n */\n openEmphHTML_ : ' <span class=\"emphSpan\">',\n\n /**\n * Closing HTML used to emphasize portions of error messages. Used when\n * displaying messages on a web site; should be blank when output is\n * to a file.\n */\n closeEmphHTML_ : '</span> ' ,\n\n /**\n * Message that is displayed when annotations are included in a unit\n * string, to let the user know how they are interpreted.\n */\n bracesMsg_ : 'FYI - annotations (text in curly braces {}) are ignored, ' +\n 'except that an annotation without a leading symbol implies ' +\n 'the default unit 1 (the unity).',\n\n /**\n * Message that is displayed or returned when a conversion is requested\n * for two units where (only) a mass<->moles conversion is appropriate\n * but no molecular weight was specified.\n */\n needMoleWeightMsg_ : 'Did you wish to convert between mass and moles? The ' +\n 'molecular weight of the substance represented by the ' +\n 'units is required to perform the conversion.',\n\n /**\n * Hash that matches unit column names to names used in the csv file\n * that is submitted to the data updater.\n */\n csvCols_ : {\n 'case-sensitive code' : 'csCode_',\n 'LOINC property' : 'loincProperty_',\n 'name (display)' : 'name_',\n 'synonyms' : 'synonyms_',\n 'source' : 'source_',\n 'category' : 'category_',\n 'Guidance' : 'guidance_'\n } ,\n\n /**\n * Name of the column in the csv file that serves as the key\n */\n inputKey_ : 'case-sensitive code' ,\n\n /**\n * Special codes that contain operators within brackets. The operator\n * within these codes causes them to parse incorrectly if they are preceded\n * by a prefix, because the parsing algorithm splits them up on the operator.\n * So we use this object to identify them and substitute placeholders to\n * avoid that.\n */\n specUnits_ : { 'B[10.nV]' : 'specialUnitOne',\n '[m/s2/Hz^(1/2)]' : 'specialUnitTwo'}\n} ;\n\n\n"],"file":"config.js"}
|
|
@@ -333,6 +333,76 @@ class UcumLhcUtils {
|
|
|
333
333
|
return returnObj;
|
|
334
334
|
} // end convertUnitTo
|
|
335
335
|
|
|
336
|
+
/**
|
|
337
|
+
* Converts the given unit string into its base units, their exponents, and
|
|
338
|
+
* a magnitude, and returns that data.
|
|
339
|
+
* @param fromUnit the unit string to be converted to base units information
|
|
340
|
+
* @param fromVal the number of "from" units to be converted
|
|
341
|
+
* @returns an object with the properties:
|
|
342
|
+
* 'msg': an array of one or more messages, if the string is invalid or
|
|
343
|
+
* an error occurred, indicating the problem, or a suggestion of a
|
|
344
|
+
* substitution such as the substitution of 'G' for 'Gauss', or
|
|
345
|
+
* an empty array if no messages were generated. If this is not empty,
|
|
346
|
+
* no other information will be returned.
|
|
347
|
+
* 'magnitude': the new value when fromVal units of fromUnits is expressed in the base units.
|
|
348
|
+
* 'fromUnitIsSpecial': whether the input unit fromUnit is a "special unit"
|
|
349
|
+
* as defined in UCUM. This means there is some function applied to convert
|
|
350
|
+
* between fromUnit and the base units, so the returned magnitude is likely not
|
|
351
|
+
* useful as a scale factor for other conversions (i.e., it only has validity
|
|
352
|
+
* and usefulness for the input values that produced it).
|
|
353
|
+
* 'unitToExp': a map of base units in uStr to their exponent
|
|
354
|
+
*/
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
convertToBaseUnits(fromUnit, fromVal) {
|
|
358
|
+
let inputUnitLookup = this.getSpecifiedUnit(fromUnit, 'validate');
|
|
359
|
+
let retObj = {};
|
|
360
|
+
let unit = inputUnitLookup.unit;
|
|
361
|
+
retObj.msg = inputUnitLookup.retMsg || [];
|
|
362
|
+
|
|
363
|
+
if (!unit) {
|
|
364
|
+
if (inputUnitLookup.retMsg?.length == 0) retObj.msg.push('Could not find unit information for ' + fromUnit);
|
|
365
|
+
} else if (unit.isArbitrary_) {
|
|
366
|
+
retObj.msg.push('Arbitrary units cannot be converted to base units or other units.');
|
|
367
|
+
} else if (retObj.msg.length == 0) {
|
|
368
|
+
let unitToExp = {};
|
|
369
|
+
let dimVec = unit.dim_?.dimVec_;
|
|
370
|
+
let baseUnitString = '1';
|
|
371
|
+
|
|
372
|
+
if (dimVec) {
|
|
373
|
+
let dimVecIndexToBaseUnit = UnitTables.getInstance().dimVecIndexToBaseUnit_;
|
|
374
|
+
|
|
375
|
+
for (let i = 0, len = dimVec.length; i < len; ++i) {
|
|
376
|
+
let exp = dimVec[i];
|
|
377
|
+
|
|
378
|
+
if (exp) {
|
|
379
|
+
unitToExp[dimVecIndexToBaseUnit[i]] = exp;
|
|
380
|
+
baseUnitString += '.' + dimVecIndexToBaseUnit[i] + exp;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
} // The unit might have a conversion function, which has to be applied; we
|
|
384
|
+
// cannot just assume unit_.magnitude_ is the magnitude in base units.
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
let retUnitLookup = this.getSpecifiedUnit(baseUnitString, 'validate'); // There should not be any error in retUnitLookup, unless there is a bug.
|
|
388
|
+
|
|
389
|
+
let retUnit = retUnitLookup.unit;
|
|
390
|
+
if (!retUnit && retUnitLookup.retMsg?.length == 0) retObj.msg.push('Unable construct base unit string; tried ' + baseUnitString);else {
|
|
391
|
+
try {
|
|
392
|
+
retObj.magnitude = retUnit.convertFrom(fromVal, unit);
|
|
393
|
+
} catch (e) {
|
|
394
|
+
retObj.msg.push(e.toString());
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if (retObj.msg.length == 0) {
|
|
398
|
+
retObj.unitToExp = unitToExp;
|
|
399
|
+
retObj.fromUnitIsSpecial = unit.isSpecial_;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
return retObj;
|
|
405
|
+
}
|
|
336
406
|
/**
|
|
337
407
|
* This method accepts a term and looks for units that include it as
|
|
338
408
|
* a synonym - or that include the term in its name.
|