@lhncbc/ucum-lhc 5.0.0 → 5.0.3
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/README.md +50 -12
- package/browser-dist/ucum-lhc.js +731 -1265
- package/data/ucumDefs.min.json +1 -1
- package/package.json +1 -1
- package/source/ucumLhcUtils.js +2 -2
- package/source/ucumXmlDocument.js +5 -2
- package/source/unit.js +2 -1
- package/source/unitString.js +142 -130
- package/source-cjs/config.js +1 -12
- package/source-cjs/config.js.map +1 -1
- package/source-cjs/dimension.js +20 -63
- package/source-cjs/dimension.js.map +1 -1
- package/source-cjs/jsonArrayPack.js +7 -25
- package/source-cjs/jsonArrayPack.js.map +1 -1
- package/source-cjs/prefix.js +12 -26
- package/source-cjs/prefix.js.map +1 -1
- package/source-cjs/prefixTables.js +10 -24
- package/source-cjs/prefixTables.js.map +1 -1
- package/source-cjs/ucumFunctions.js +35 -32
- package/source-cjs/ucumFunctions.js.map +1 -1
- package/source-cjs/ucumInternalUtils.js +5 -13
- package/source-cjs/ucumInternalUtils.js.map +1 -1
- package/source-cjs/ucumJsonDefs.js +1 -16
- package/source-cjs/ucumJsonDefs.js.map +1 -1
- package/source-cjs/ucumLhcUtils.js +28 -92
- package/source-cjs/ucumLhcUtils.js.map +1 -1
- package/source-cjs/ucumPkg.js +1 -6
- package/source-cjs/ucumPkg.js.map +1 -1
- package/source-cjs/ucumXmlDocument.js +162 -184
- package/source-cjs/ucumXmlDocument.js.map +1 -1
- package/source-cjs/unit.js +97 -181
- package/source-cjs/unit.js.map +1 -1
- package/source-cjs/unitString.js +521 -608
- package/source-cjs/unitString.js.map +1 -1
- package/source-cjs/unitTables.js +33 -139
- package/source-cjs/unitTables.js.map +1 -1
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.UcumXmlDocument = void 0;
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* This class handles opening, reading and parsing the XML file of ucum
|
|
10
9
|
* definitions (prefixes, base units, and unit atoms).
|
|
@@ -13,31 +12,21 @@ exports.UcumXmlDocument = void 0;
|
|
|
13
12
|
*
|
|
14
13
|
*/
|
|
15
14
|
var Prefix = require("./prefix.js").Prefix;
|
|
16
|
-
|
|
17
15
|
var PrefixTables = require("./prefixTables.js").PrefixTables;
|
|
18
|
-
|
|
19
16
|
var Unit = require("./unit.js").Unit;
|
|
20
|
-
|
|
21
17
|
var UnitString = require("./unitString.js").UnitString;
|
|
22
|
-
|
|
23
18
|
var UnitTables = require('./unitTables.js').UnitTables;
|
|
24
|
-
|
|
25
19
|
var packArray = require('./jsonArrayPack.js').packArray;
|
|
26
|
-
|
|
27
20
|
var jsonfile = require('jsonfile');
|
|
28
|
-
|
|
29
21
|
var xmldoc = require('xmldoc');
|
|
30
|
-
|
|
31
22
|
var fs = require('fs');
|
|
32
|
-
|
|
33
23
|
var essenceFile_ = '../data/ucum-essence.xml';
|
|
24
|
+
|
|
34
25
|
/**
|
|
35
26
|
* The full xml document
|
|
36
27
|
* @type XmlDocument
|
|
37
28
|
*/
|
|
38
|
-
|
|
39
29
|
var xmlInput_ = null;
|
|
40
|
-
|
|
41
30
|
class UcumXmlDocument {
|
|
42
31
|
/**
|
|
43
32
|
* Constructor. This reads the XML document (essenceFile_) into the
|
|
@@ -49,29 +38,30 @@ class UcumXmlDocument {
|
|
|
49
38
|
constructor() {
|
|
50
39
|
// read the XML file and create an xmlDocument object from it.
|
|
51
40
|
let data = fs.readFileSync(essenceFile_);
|
|
52
|
-
xmlInput_ = new xmldoc.XmlDocument(data);
|
|
41
|
+
xmlInput_ = new xmldoc.XmlDocument(data);
|
|
42
|
+
|
|
43
|
+
// Array of unit codes in the ucum-essence.xml file that indicate a
|
|
53
44
|
// mole based unit. The moleExp_ attribute for these units needs to be
|
|
54
45
|
// set, but there doesn't seem to be an algorithmic way to find these.
|
|
55
46
|
// Creation of unit objects after this file is processed will pick up
|
|
56
47
|
// the moleExp_ value from the base mole unit, but the ones defined in
|
|
57
48
|
// this file will not necessarily do that.
|
|
49
|
+
this.moleCodes_ = ['mol', 'eq', 'osm', 'kat', 'U'];
|
|
58
50
|
|
|
59
|
-
|
|
51
|
+
// Make this a singleton. See UnitTables constructor for details.
|
|
60
52
|
|
|
61
53
|
let holdThis = UcumXmlDocument.prototype;
|
|
62
|
-
|
|
63
54
|
exports.UcumXmlDocument = UcumXmlDocument = function () {
|
|
64
55
|
throw new Error('UcumXmlDocument is a Singleton. ' + 'Use UcumXmlDocument.getInstance() instead.');
|
|
65
56
|
};
|
|
66
|
-
|
|
67
57
|
if (exports) exports.UcumXmlDocument = UcumXmlDocument;
|
|
68
58
|
UcumXmlDocument.prototype = holdThis;
|
|
69
59
|
let self = this;
|
|
70
|
-
|
|
71
60
|
UcumXmlDocument.getInstance = function () {
|
|
72
61
|
return self;
|
|
73
62
|
};
|
|
74
63
|
}
|
|
64
|
+
|
|
75
65
|
/**
|
|
76
66
|
* This method controls parsing of the XML into objects used by this
|
|
77
67
|
* program. It uses separate methods to parse the prefixes, the
|
|
@@ -79,16 +69,16 @@ class UcumXmlDocument {
|
|
|
79
69
|
*
|
|
80
70
|
* @returns nothing
|
|
81
71
|
*/
|
|
82
|
-
|
|
83
|
-
|
|
84
72
|
parseXml() {
|
|
85
73
|
this.parsePrefixes(xmlInput_.childrenNamed("prefix"));
|
|
86
74
|
this.parseBaseUnits(xmlInput_.childrenNamed("base-unit"));
|
|
87
|
-
this.parseUnitStrings(xmlInput_.childrenNamed("unit"));
|
|
75
|
+
this.parseUnitStrings(xmlInput_.childrenNamed("unit"));
|
|
88
76
|
|
|
77
|
+
// Create or replace the json file of the prefix and unit definitions
|
|
89
78
|
this.writeJsonFile();
|
|
90
79
|
this.writeVersionText();
|
|
91
80
|
}
|
|
81
|
+
|
|
92
82
|
/**
|
|
93
83
|
* Creates prefix objects from the xml prefix nodes passed in and gets
|
|
94
84
|
* them added to the prefix tables.
|
|
@@ -98,39 +88,38 @@ class UcumXmlDocument {
|
|
|
98
88
|
*
|
|
99
89
|
* @returns nothing
|
|
100
90
|
*/
|
|
101
|
-
|
|
102
|
-
|
|
103
91
|
parsePrefixes(prefixes) {
|
|
104
92
|
let plen = prefixes.length;
|
|
105
|
-
|
|
106
93
|
for (let p = 0; p < plen; p++) {
|
|
107
94
|
let curPfx = prefixes[p];
|
|
108
95
|
let attrs = {};
|
|
109
96
|
attrs["code_"] = curPfx.attr.Code;
|
|
110
97
|
attrs["ciCode_"] = curPfx.attr.CODE;
|
|
111
98
|
attrs["name_"] = curPfx.childNamed('name').val;
|
|
112
|
-
attrs["printSymbol_"] = curPfx.childNamed('printSymbol').val;
|
|
99
|
+
attrs["printSymbol_"] = curPfx.childNamed('printSymbol').val;
|
|
100
|
+
|
|
101
|
+
// Set the prefix value. If there is a <sup> element in the
|
|
113
102
|
// value node, then this is a base 10 based prefix (10 to the x power).
|
|
114
103
|
// Set the value to 10 taken to the indicated power.
|
|
115
104
|
// Otherwise this is not 10 based and the value contains the
|
|
116
105
|
// actual value for the prefix.
|
|
117
|
-
|
|
118
106
|
let pValNode = curPfx.childNamed('value');
|
|
119
107
|
attrs["value_"] = null;
|
|
120
108
|
attrs["exp_"] = pValNode.childNamed('sup');
|
|
121
|
-
|
|
122
109
|
if (attrs["exp_"] != null) {
|
|
123
110
|
attrs["exp_"] = attrs["exp_"].val;
|
|
124
|
-
|
|
111
|
+
// Use parseFloat('1eSOMETHING') instead of Math.pow() to avoid
|
|
112
|
+
// small number changes like 1.0000000000000001e-21. See LF-2830.
|
|
113
|
+
// attrs["value_"] = Math.pow(10, attrs["exp_"]);
|
|
114
|
+
attrs["value_"] = parseFloat(`1e${attrs["exp_"]}`);
|
|
125
115
|
} else {
|
|
126
116
|
attrs["value_"] = pValNode.val;
|
|
127
117
|
attrs["exp_"] = null;
|
|
128
|
-
}
|
|
129
|
-
// create the prefix object and then add it to the prefix tables.
|
|
130
|
-
|
|
118
|
+
}
|
|
131
119
|
|
|
120
|
+
// Make sure the prefix has not already been created. If it hasn't,
|
|
121
|
+
// create the prefix object and then add it to the prefix tables.
|
|
132
122
|
let ptab = PrefixTables.getInstance();
|
|
133
|
-
|
|
134
123
|
if (ptab.isDefined(attrs["code_"])) {
|
|
135
124
|
throw new Error('Prefix constructor called for prefix already ' + `defined; code = ${attrs["code_"]}`);
|
|
136
125
|
} else {
|
|
@@ -150,12 +139,9 @@ class UcumXmlDocument {
|
|
|
150
139
|
*
|
|
151
140
|
* @returns nothing
|
|
152
141
|
*/
|
|
153
|
-
|
|
154
|
-
|
|
155
142
|
parseBaseUnits(unitNodes) {
|
|
156
143
|
let blen = unitNodes.length;
|
|
157
144
|
let utab = UnitTables.getInstance();
|
|
158
|
-
|
|
159
145
|
for (let b = 0; b < blen; b++) {
|
|
160
146
|
let curBUnit = unitNodes[b];
|
|
161
147
|
let attrs = {};
|
|
@@ -183,14 +169,11 @@ class UcumXmlDocument {
|
|
|
183
169
|
*
|
|
184
170
|
* @returns nothing
|
|
185
171
|
*/
|
|
186
|
-
|
|
187
|
-
|
|
188
172
|
parseUnitStrings(unitStrings) {
|
|
189
173
|
let utab = UnitTables.getInstance();
|
|
190
174
|
let uStrParser = UnitString.getInstance();
|
|
191
175
|
let stopNow = false;
|
|
192
176
|
let alen = unitStrings.length;
|
|
193
|
-
|
|
194
177
|
for (let a = 0; a < alen && !stopNow; a++) {
|
|
195
178
|
let haveUnit = true;
|
|
196
179
|
let curUA = unitStrings[a];
|
|
@@ -201,14 +184,14 @@ class UcumXmlDocument {
|
|
|
201
184
|
attrs['csCode_'] = curUA.attr.Code;
|
|
202
185
|
if (curUA.attr.CODE) attrs['ciCode_'] = curUA.attr.CODE;else attrs['ciCode_'] = curUA.attr.Code.toUpperCase();
|
|
203
186
|
attrs['property_'] = curUA.childNamed('property').val;
|
|
204
|
-
|
|
205
187
|
if (curUA.childNamed('printSymbol')) {
|
|
206
188
|
let sym = curUA.childNamed('printSymbol');
|
|
207
189
|
let symVal = sym.val;
|
|
208
190
|
symVal = symVal.replace(/\n/g, "");
|
|
209
191
|
symVal = symVal.trim();
|
|
210
192
|
let symI = sym.childNamed('i');
|
|
211
|
-
if (symI)
|
|
193
|
+
if (symI)
|
|
194
|
+
//symVal = '<i>' + symI.val + '</>';
|
|
212
195
|
symVal = symI.toString({
|
|
213
196
|
compressed: true
|
|
214
197
|
});
|
|
@@ -222,68 +205,69 @@ class UcumXmlDocument {
|
|
|
222
205
|
});
|
|
223
206
|
attrs['printSymbol_'] = symVal;
|
|
224
207
|
}
|
|
225
|
-
|
|
226
208
|
if (curUA.attr.isMetric === "yes") attrs['isMetric_'] = true;else attrs['isMetric_'] = false;
|
|
227
209
|
if (curUA.attr.isArbitrary) attrs['isArbitrary_'] = true;else attrs['isArbitrary_'] = false;
|
|
228
|
-
|
|
229
210
|
if (curUA.attr.class) {
|
|
230
211
|
attrs['class_'] = curUA.attr.class;
|
|
231
212
|
}
|
|
232
|
-
|
|
233
213
|
let valNode = curUA.childNamed('value');
|
|
234
|
-
if (this.moleCodes_.indexOf(curUA.attr.Code) !== -1) attrs['moleExp_'] = 1;else attrs['moleExp_'] = 0;
|
|
214
|
+
if (this.moleCodes_.indexOf(curUA.attr.Code) !== -1) attrs['moleExp_'] = 1;else attrs['moleExp_'] = 0;
|
|
235
215
|
|
|
216
|
+
// Process special units
|
|
236
217
|
if (curUA.attr.isSpecial) {
|
|
237
218
|
attrs['isSpecial_'] = curUA.attr.isSpecial === "yes";
|
|
238
219
|
let funcNode = valNode.childNamed('function');
|
|
239
220
|
attrs['cnv_'] = funcNode.attr.name;
|
|
240
221
|
attrs['csUnitString_'] = funcNode.attr.Unit;
|
|
241
|
-
|
|
242
222
|
if (attrs['csUnitString_'] === '1') {
|
|
243
223
|
attrs['baseFactor_'] = 1;
|
|
244
224
|
} else if (attrs['csCode_'] === '[pH]') {
|
|
245
225
|
attrs['baseFactor_'] = parseFloat(funcNode.attr.value);
|
|
246
226
|
} else {
|
|
247
227
|
let slashPos = attrs['csUnitString_'].indexOf('/');
|
|
248
|
-
let ar = [];
|
|
228
|
+
let ar = [];
|
|
249
229
|
|
|
230
|
+
// unit string = K/9 or K/4 or m2/s4/Hz
|
|
250
231
|
if (slashPos >= 0) {
|
|
251
232
|
ar = attrs['csUnitString_'].split('/');
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
|
|
233
|
+
}
|
|
234
|
+
// unit string = K/9 or K/4
|
|
255
235
|
if (slashPos >= 0 && ar.length === 2) {
|
|
256
236
|
attrs['csUnitString_'] = ar[0];
|
|
257
237
|
attrs['baseFactor_'] = parseFloat(funcNode.attr.value / ar[1]);
|
|
258
|
-
}
|
|
238
|
+
}
|
|
239
|
+
// unit string = 10*-5.Pa
|
|
259
240
|
else if (attrs['csCode_'] === 'B[SPL]') {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
241
|
+
attrs['baseFactor_'] = Math.pow(10, -5) * 2;
|
|
242
|
+
attrs['csUnitString_'] = "Pa";
|
|
243
|
+
}
|
|
244
|
+
// unit string = m1/s4/Hz, K, deg, V, mV, uV, nV, W, kW
|
|
245
|
+
else {
|
|
246
|
+
attrs['baseFactor_'] = parseFloat(funcNode.attr.value);
|
|
247
|
+
}
|
|
266
248
|
} // end if the unit string is not 1
|
|
267
|
-
|
|
268
249
|
} // end if the unit is special
|
|
269
250
|
else {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
251
|
+
// what I'm calling the unit string is the string that defines the
|
|
252
|
+
// unit based on other units, e.g., rad2 (radian squared) to define
|
|
253
|
+
// a steradian unit. It's not necessarily a proper base unit, although
|
|
254
|
+
// it ultimately builds on base units.
|
|
255
|
+
attrs['csUnitString_'] = valNode.attr.Unit;
|
|
256
|
+
attrs['ciUnitString_'] = valNode.attr.UNIT;
|
|
257
|
+
|
|
258
|
+
// what I'm calling the factor here (string and number versions)
|
|
259
|
+
// is the magnitude used in conjunction with the unit string to define
|
|
260
|
+
// the new unit, e.g., 3 for a yard that is based in the definition
|
|
261
|
+
// of feet.
|
|
262
|
+
|
|
263
|
+
attrs['baseFactorStr_'] = valNode.attr.value;
|
|
264
|
+
if (attrs['csCode_'] === '[pi]') attrs['baseFactor_'] = parseFloat(attrs['baseFactorStr_']);else if (valNode.childNamed('sup')) {
|
|
265
|
+
attrs['baseFactor_'] = parseFloat(valNode.attr.value);
|
|
266
|
+
} else {
|
|
267
|
+
attrs['baseFactor_'] = parseFloat(valNode.val);
|
|
268
|
+
}
|
|
269
|
+
} // end if this is not a special unit
|
|
279
270
|
|
|
280
|
-
attrs['baseFactorStr_'] = valNode.attr.value;
|
|
281
|
-
if (attrs['csCode_'] === '[pi]') attrs['baseFactor_'] = parseFloat(attrs['baseFactorStr_']);else if (valNode.childNamed('sup')) {
|
|
282
|
-
attrs['baseFactor_'] = parseFloat(valNode.attr.value);
|
|
283
|
-
} else {
|
|
284
|
-
attrs['baseFactor_'] = parseFloat(valNode.val);
|
|
285
|
-
}
|
|
286
|
-
} // end if this is not a special unit
|
|
287
271
|
// Arbitrary units are defined in the UCUM spec as "not of any
|
|
288
272
|
// specific dimension and are not commensurable with any other
|
|
289
273
|
// unit" (3.2.24). All arbitrary units in the units definition
|
|
@@ -292,118 +276,123 @@ class UcumXmlDocument {
|
|
|
292
276
|
// unit string is the "international unit" with a code of [iU],
|
|
293
277
|
// which is also an arbitrary unit - with a unit string of 1.
|
|
294
278
|
// So I am assuming [IU] is just another code for the same unit.
|
|
295
|
-
|
|
296
|
-
|
|
297
279
|
if (attrs['isArbitrary_'] === true) {
|
|
298
280
|
attrs['magnitude_'] = 1;
|
|
299
281
|
attrs['dim_'] = null;
|
|
300
|
-
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// units with class = "dimless" don't have dimension arrays.
|
|
301
285
|
// They're things like the number pi or the number 10 or percent.
|
|
302
286
|
// Haven't figured out how to handle them yet.
|
|
303
287
|
else if (attrs['class_'] === 'dimless' || attrs['csCode_'] === 'mol') {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
288
|
+
attrs['dim_'] = null;
|
|
289
|
+
// figure the magnitude based on the unit string
|
|
290
|
+
// if it's 1, the magnitude is the value specified for
|
|
291
|
+
// the base factor, e.g., 3.141592653589793238462 ... for pi
|
|
292
|
+
if (attrs['csUnitString_'] === '1') {
|
|
293
|
+
attrs['magnitude_'] = attrs['baseFactor_'];
|
|
294
|
+
}
|
|
295
|
+
// else if the unit string starts with 10*, the magnitude is
|
|
296
|
+
// 10 to the power specified following 10* e.g., unit = 10*-2
|
|
297
|
+
// for the "%" unit. Except for the mole, which is that
|
|
298
|
+
// multiplied by the base factor, which in this case (only,
|
|
299
|
+
// I think) is not 1.
|
|
300
|
+
else if (attrs['csUnitString_'].substr(0, 3) == "10*") {
|
|
301
|
+
let exp = parseInt(attrs['csUnitString_'].substr(3));
|
|
302
|
+
attrs['magnitude_'] = Math.pow(10, exp);
|
|
303
|
+
if (attrs['baseFactor_'] !== 1) {
|
|
304
|
+
attrs['magnitude_'] *= attrs['baseFactor_'];
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
// else I don't know what it is.
|
|
308
|
+
else {
|
|
309
|
+
attrs['defError_'] = true;
|
|
310
|
+
console.log('unexpected dimless unit definition, unit code ' + 'is ' + attrs['csCode_']);
|
|
311
|
+
}
|
|
312
|
+
} // end if this is a unit with class = dimless
|
|
313
|
+
|
|
314
|
+
// Handle carat of gold alloys - which doesn't get a dimension
|
|
315
|
+
//
|
|
316
|
+
else if (attrs['csCode_'] === "[car_Au]") {
|
|
317
|
+
attrs['magnitude_'] = 1 / 24;
|
|
318
|
+
attrs['dim_'] = null;
|
|
319
|
+
} else {
|
|
320
|
+
// Make sure there's a unit string to base the new unit on. There
|
|
321
|
+
// should be, but I'm just checking here to make sure. And omit
|
|
322
|
+
// ones with a unit string of 1. That won't do us any good.
|
|
323
|
+
if (attrs['csUnitString_'] && attrs['csUnitString_'] !== '1' && attrs['csUnitString_'] !== 1) {
|
|
324
|
+
haveUnit = false;
|
|
325
|
+
// Handle some special cases
|
|
326
|
+
// 1. the Oersted unit, whose string is /[pi].A/m and whose
|
|
327
|
+
// value is 250. Set the baseFactor to 250/[pi] and
|
|
328
|
+
// the unit string to A/m
|
|
329
|
+
if (attrs['csCode_'] === 'Oe') {
|
|
330
|
+
attrs['baseFactor_'] = 250 / Math.PI;
|
|
331
|
+
attrs['csUnitString_'] = "A/m";
|
|
332
|
+
}
|
|
333
|
+
// 2. Strings that start with '/'. Set the function to
|
|
334
|
+
// the inverse function and trim the '/' off the front
|
|
335
|
+
// of the string.
|
|
336
|
+
else if (attrs['csUnitString_'][0] === '/') {
|
|
337
|
+
attrs['cnv_'] = 'inv';
|
|
338
|
+
attrs['csUnitString_'] = attrs['csUnitString_'].substr(1);
|
|
339
|
+
}
|
|
340
|
+
// 3. the Svedberg unit, whose string is 10*-13.s. Set the
|
|
341
|
+
// base factor to 10*-13 and the unit string to s.
|
|
342
|
+
else if (attrs['csCode_'] === '[S]') {
|
|
343
|
+
attrs['baseFactor_'] = Math.pow(10, -13);
|
|
344
|
+
attrs['csUnitString_'] = 's';
|
|
345
|
+
}
|
|
346
|
+
// 4. permeability of vaccuum - code [mu_0], unit given is
|
|
347
|
+
// 4.[pi].10*-7.N/A2
|
|
348
|
+
else if (attrs['csCode_'] === '[mu_0]') {
|
|
349
|
+
attrs['baseFactor_'] = 4 * Math.PI * Math.pow(10, -7);
|
|
350
|
+
attrs['csUnitString_'] = 'N/A2';
|
|
351
|
+
}
|
|
352
|
+
// The unit string parser will use the unit(s) named in the
|
|
353
|
+
// string to create a new unit with the appropriate dimension
|
|
354
|
+
// object and magnitude before it's multiplied by the one
|
|
355
|
+
// specified in the input node.
|
|
356
|
+
try {
|
|
357
|
+
let retObj = uStrParser.parseString(attrs['csUnitString_'], 'validate', false);
|
|
358
|
+
let ret = retObj[0];
|
|
359
|
+
let retString = retObj[1];
|
|
360
|
+
let retMsg = retObj[2];
|
|
361
|
+
|
|
362
|
+
// Get the dimension object and magnitude (and adjust by
|
|
363
|
+
// specified magnitude factor) from the unit created and
|
|
364
|
+
// assign them to the attributes we'll use to create the
|
|
365
|
+
// unit for this listing.
|
|
366
|
+
if (ret) {
|
|
367
|
+
attrs['dim_'] = ret.getProperty('dim_');
|
|
368
|
+
let newMag = ret.getProperty('magnitude_');
|
|
369
|
+
newMag *= attrs['baseFactor_'];
|
|
370
|
+
attrs['magnitude_'] = newMag;
|
|
371
|
+
haveUnit = true;
|
|
372
|
+
}
|
|
373
|
+
// if there's no unit, report an error
|
|
323
374
|
else {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
// should be, but I'm just checking here to make sure. And omit
|
|
336
|
-
// ones with a unit string of 1. That won't do us any good.
|
|
337
|
-
if (attrs['csUnitString_'] && attrs['csUnitString_'] !== '1' && attrs['csUnitString_'] !== 1) {
|
|
338
|
-
haveUnit = false; // Handle some special cases
|
|
339
|
-
// 1. the Oersted unit, whose string is /[pi].A/m and whose
|
|
340
|
-
// value is 250. Set the baseFactor to 250/[pi] and
|
|
341
|
-
// the unit string to A/m
|
|
342
|
-
|
|
343
|
-
if (attrs['csCode_'] === 'Oe') {
|
|
344
|
-
attrs['baseFactor_'] = 250 / Math.PI;
|
|
345
|
-
attrs['csUnitString_'] = "A/m";
|
|
346
|
-
} // 2. Strings that start with '/'. Set the function to
|
|
347
|
-
// the inverse function and trim the '/' off the front
|
|
348
|
-
// of the string.
|
|
349
|
-
else if (attrs['csUnitString_'][0] === '/') {
|
|
350
|
-
attrs['cnv_'] = 'inv';
|
|
351
|
-
attrs['csUnitString_'] = attrs['csUnitString_'].substr(1);
|
|
352
|
-
} // 3. the Svedberg unit, whose string is 10*-13.s. Set the
|
|
353
|
-
// base factor to 10*-13 and the unit string to s.
|
|
354
|
-
else if (attrs['csCode_'] === '[S]') {
|
|
355
|
-
attrs['baseFactor_'] = Math.pow(10, -13);
|
|
356
|
-
attrs['csUnitString_'] = 's';
|
|
357
|
-
} // 4. permeability of vaccuum - code [mu_0], unit given is
|
|
358
|
-
// 4.[pi].10*-7.N/A2
|
|
359
|
-
else if (attrs['csCode_'] === '[mu_0]') {
|
|
360
|
-
attrs['baseFactor_'] = 4 * Math.PI * Math.pow(10, -7);
|
|
361
|
-
attrs['csUnitString_'] = 'N/A2';
|
|
362
|
-
} // The unit string parser will use the unit(s) named in the
|
|
363
|
-
// string to create a new unit with the appropriate dimension
|
|
364
|
-
// object and magnitude before it's multiplied by the one
|
|
365
|
-
// specified in the input node.
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
try {
|
|
369
|
-
let retObj = uStrParser.parseString(attrs['csUnitString_'], 'validate', false);
|
|
370
|
-
let ret = retObj[0];
|
|
371
|
-
let retString = retObj[1];
|
|
372
|
-
let retMsg = retObj[2]; // Get the dimension object and magnitude (and adjust by
|
|
373
|
-
// specified magnitude factor) from the unit created and
|
|
374
|
-
// assign them to the attributes we'll use to create the
|
|
375
|
-
// unit for this listing.
|
|
376
|
-
|
|
377
|
-
if (ret) {
|
|
378
|
-
attrs['dim_'] = ret.getProperty('dim_');
|
|
379
|
-
let newMag = ret.getProperty('magnitude_');
|
|
380
|
-
newMag *= attrs['baseFactor_'];
|
|
381
|
-
attrs['magnitude_'] = newMag;
|
|
382
|
-
haveUnit = true;
|
|
383
|
-
} // if there's no unit, report an error
|
|
384
|
-
else {
|
|
385
|
-
attrs['defError_'] = true;
|
|
386
|
-
console.log(`unit definition error; code = ${attrs['csCode_']}; ` + `msg = ${retMsg}`);
|
|
387
|
-
attrs['dim_'] = null;
|
|
388
|
-
attrs['magnitude_'] = null;
|
|
389
|
-
}
|
|
390
|
-
} catch (err) {
|
|
391
|
-
console.log('error thrown from unit parsing code for unit name ' + attrs['name_'] + '\n' + err.message);
|
|
392
|
-
stopNow = true;
|
|
393
|
-
}
|
|
394
|
-
} // end if there is a unit string to parse
|
|
395
|
-
|
|
396
|
-
} // end if this is not a dimless unit
|
|
397
|
-
|
|
375
|
+
attrs['defError_'] = true;
|
|
376
|
+
console.log(`unit definition error; code = ${attrs['csCode_']}; ` + `msg = ${retMsg}`);
|
|
377
|
+
attrs['dim_'] = null;
|
|
378
|
+
attrs['magnitude_'] = null;
|
|
379
|
+
}
|
|
380
|
+
} catch (err) {
|
|
381
|
+
console.log('error thrown from unit parsing code for unit name ' + attrs['name_'] + '\n' + err.message);
|
|
382
|
+
stopNow = true;
|
|
383
|
+
}
|
|
384
|
+
} // end if there is a unit string to parse
|
|
385
|
+
} // end if this is not a dimless unit
|
|
398
386
|
|
|
399
387
|
if (haveUnit) {
|
|
400
388
|
// Now create the unit we want based on the attributes we've
|
|
401
389
|
// accumulated from the xml input and from figuring the dimension
|
|
402
390
|
// and magnitude. Add it to the unit tables
|
|
403
391
|
let newUnit = new Unit(attrs);
|
|
404
|
-
utab.addUnit(newUnit);
|
|
405
|
-
// for debugging. This is a temporary file.
|
|
392
|
+
utab.addUnit(newUnit);
|
|
406
393
|
|
|
394
|
+
// for now, create a list of the units created and save it to a file
|
|
395
|
+
// for debugging. This is a temporary file.
|
|
407
396
|
let uList = utab.printUnits();
|
|
408
397
|
fs.writeFileSync('UnitsList.txt', uList, {
|
|
409
398
|
encoding: 'utf8',
|
|
@@ -411,9 +400,7 @@ class UcumXmlDocument {
|
|
|
411
400
|
flag: 'w'
|
|
412
401
|
});
|
|
413
402
|
} // end if have a parsed unit
|
|
414
|
-
|
|
415
403
|
} // end for a => - to alen
|
|
416
|
-
|
|
417
404
|
} // end parseUnitStrings
|
|
418
405
|
|
|
419
406
|
/**
|
|
@@ -422,8 +409,6 @@ class UcumXmlDocument {
|
|
|
422
409
|
*
|
|
423
410
|
* This creates or replace the file "ucumDefs.json" in the data directory.
|
|
424
411
|
*/
|
|
425
|
-
|
|
426
|
-
|
|
427
412
|
writeJsonFile() {
|
|
428
413
|
let licenseText = "The following data (prefixes and units) was generated " + "by the UCUM LHC code from the UCUM data and selected " + "LOINC combinations of UCUM units. The license for " + "the UCUM LHC code (demo and library code as well as " + "the combined units) is located at " + "https://github.com/lhncbc/ucum-lhc/blob/LICENSE.md.";
|
|
429
414
|
let pfxTabs = PrefixTables.getInstance();
|
|
@@ -457,8 +442,6 @@ class UcumXmlDocument {
|
|
|
457
442
|
* current Date object value to "ucumDefs" so that this does not run
|
|
458
443
|
* into problems with a previously existing file.
|
|
459
444
|
*/
|
|
460
|
-
|
|
461
|
-
|
|
462
445
|
writeVersionText() {
|
|
463
446
|
let rootNode = xmlInput_;
|
|
464
447
|
let versionNum = rootNode.attr.version;
|
|
@@ -481,8 +464,6 @@ class UcumXmlDocument {
|
|
|
481
464
|
flag: 'w'
|
|
482
465
|
});
|
|
483
466
|
} // end writeVersionText
|
|
484
|
-
|
|
485
|
-
|
|
486
467
|
} // end UcumXmlDocument
|
|
487
468
|
|
|
488
469
|
/**
|
|
@@ -496,15 +477,12 @@ class UcumXmlDocument {
|
|
|
496
477
|
*
|
|
497
478
|
* @return the singleton UcumXmlDocument object.
|
|
498
479
|
*/
|
|
499
|
-
|
|
500
|
-
|
|
501
480
|
exports.UcumXmlDocument = UcumXmlDocument;
|
|
502
|
-
|
|
503
481
|
UcumXmlDocument.getInstance = function () {
|
|
504
482
|
return new UcumXmlDocument();
|
|
505
|
-
};
|
|
506
|
-
// getInstance method set.
|
|
507
|
-
|
|
483
|
+
};
|
|
508
484
|
|
|
485
|
+
// Perform the first request for the document object, to get the
|
|
486
|
+
// getInstance method set.
|
|
509
487
|
UcumXmlDocument.getInstance();
|
|
510
488
|
//# sourceMappingURL=ucumXmlDocument.js.map
|