nirs4all 0.2.6 → 0.2.7
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 +4 -0
- package/package.json +5 -5
- package/src/execution.js +43 -14
package/README.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
npm package name: `nirs4all`
|
|
4
4
|
|
|
5
|
+
The canonical source repository is `nirs4all-core`; the npm publication keeps
|
|
6
|
+
the bare `nirs4all` name because the lite->core rename applies only to the
|
|
7
|
+
Python distribution.
|
|
8
|
+
|
|
5
9
|
This package is the runtime surface that `nirs4all-web` should consume. The web
|
|
6
10
|
application lives in `nirs4all-web`; this directory is for the reusable
|
|
7
11
|
JavaScript/WASM binding and package metadata.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nirs4all",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "Portable nirs4all aggregate binding for JavaScript and WASM",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -22,6 +22,10 @@
|
|
|
22
22
|
"typecheck": "tsc --project tsconfig.typecheck.json"
|
|
23
23
|
},
|
|
24
24
|
"license": "(CECILL-2.1 OR AGPL-3.0-or-later)",
|
|
25
|
+
"homepage": "https://nirs4all-core.readthedocs.io/en/latest/",
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/GBeurier/nirs4all-core/issues"
|
|
28
|
+
},
|
|
25
29
|
"repository": {
|
|
26
30
|
"type": "git",
|
|
27
31
|
"url": "git+https://github.com/GBeurier/nirs4all-core.git",
|
|
@@ -78,9 +82,5 @@
|
|
|
78
82
|
"dag-ml-data-wasm": {
|
|
79
83
|
"optional": true
|
|
80
84
|
}
|
|
81
|
-
},
|
|
82
|
-
"publishConfig": {
|
|
83
|
-
"access": "public",
|
|
84
|
-
"provenance": true
|
|
85
85
|
}
|
|
86
86
|
}
|
package/src/execution.js
CHANGED
|
@@ -238,7 +238,7 @@ function computeSplit(methods, splitter, input) {
|
|
|
238
238
|
const indices = Array.from({ length: input.rows }, (_, i) => i);
|
|
239
239
|
return { kind: 'all', trainIndices: indices, testIndices: indices };
|
|
240
240
|
}
|
|
241
|
-
const splitOptions = { testSize: numberParam(splitter.params.test_size, 0.25) };
|
|
241
|
+
const splitOptions = { testSize: numberParam(splitter.params.test_size, 0.25, 'test_size') };
|
|
242
242
|
if (typeof methods.computeSplitIndices === 'function') {
|
|
243
243
|
const split = methods.computeSplitIndices(
|
|
244
244
|
'KennardStone',
|
|
@@ -280,17 +280,17 @@ function selectRows(data, rows, cols, indices) {
|
|
|
280
280
|
}
|
|
281
281
|
|
|
282
282
|
function savgolParams(params) {
|
|
283
|
-
const delta = numberParam(params.delta, 1);
|
|
284
|
-
if (delta
|
|
283
|
+
const delta = numberParam(params.delta, 1, 'delta');
|
|
284
|
+
if (Math.abs(delta - 1) > Number.EPSILON) {
|
|
285
285
|
throw new Error('Portable Savitzky-Golay execution currently supports delta=1 only.');
|
|
286
286
|
}
|
|
287
287
|
return [
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
288
|
+
integerParam(params.window_length ?? params.window, 11, 'window_length', { min: 1 }),
|
|
289
|
+
integerParam(params.polyorder, 3, 'polyorder', { min: 0 }),
|
|
290
|
+
integerParam(params.deriv, 0, 'deriv', { min: 0 }),
|
|
291
291
|
// scipy.signal.savgol_filter, and therefore nirs4all Python, default to interp.
|
|
292
292
|
savgolMode(params.mode ?? 'interp'),
|
|
293
|
-
numberParam(params.cval, 0),
|
|
293
|
+
numberParam(params.cval, 0, 'cval'),
|
|
294
294
|
];
|
|
295
295
|
}
|
|
296
296
|
|
|
@@ -322,23 +322,52 @@ function componentValues(step) {
|
|
|
322
322
|
if (step.param !== 'n_components') {
|
|
323
323
|
throw new Error("Portable execution only supports _range_ sweeps over 'n_components'.");
|
|
324
324
|
}
|
|
325
|
-
|
|
326
|
-
if (![start, stop, stride].every(Number.isFinite) || stride <= 0 || start > stop) {
|
|
325
|
+
if (step._range_.length !== 3) {
|
|
327
326
|
throw new Error('Invalid n_components _range_; expected [start, stop, positive_step].');
|
|
328
327
|
}
|
|
328
|
+
const start = integerParam(step._range_[0], undefined, 'n_components range start', { min: 1 });
|
|
329
|
+
const stop = integerParam(step._range_[1], undefined, 'n_components range stop', { min: 1 });
|
|
330
|
+
const stride = integerParam(step._range_[2], undefined, 'n_components range step', { min: 1 });
|
|
331
|
+
if (start > stop) {
|
|
332
|
+
throw new Error('Invalid n_components _range_; start must be <= stop.');
|
|
333
|
+
}
|
|
329
334
|
const values = [];
|
|
330
335
|
for (let value = start; value <= stop; value += stride) {
|
|
331
|
-
values.push(
|
|
336
|
+
values.push(value);
|
|
332
337
|
}
|
|
333
338
|
return values;
|
|
334
339
|
}
|
|
335
340
|
const params = step.model?.params ?? {};
|
|
336
|
-
return [
|
|
341
|
+
return [integerParam(params.n_components, 2, 'n_components', { min: 1 })];
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function numberParam(value, fallback, label) {
|
|
345
|
+
if (value == null) {
|
|
346
|
+
return fallback;
|
|
347
|
+
}
|
|
348
|
+
let n;
|
|
349
|
+
if (typeof value === 'number') {
|
|
350
|
+
n = value;
|
|
351
|
+
} else if (typeof value === 'string' && value.trim() !== '') {
|
|
352
|
+
n = Number(value);
|
|
353
|
+
} else {
|
|
354
|
+
throw new TypeError(`${label} must be numeric.`);
|
|
355
|
+
}
|
|
356
|
+
if (!Number.isFinite(n)) {
|
|
357
|
+
throw new RangeError(`${label} must be finite.`);
|
|
358
|
+
}
|
|
359
|
+
return n;
|
|
337
360
|
}
|
|
338
361
|
|
|
339
|
-
function
|
|
340
|
-
const n =
|
|
341
|
-
|
|
362
|
+
function integerParam(value, fallback, label, options = {}) {
|
|
363
|
+
const n = numberParam(value, fallback, label);
|
|
364
|
+
if (!Number.isInteger(n)) {
|
|
365
|
+
throw new RangeError(`${label} must be an integer.`);
|
|
366
|
+
}
|
|
367
|
+
if (options.min != null && n < options.min) {
|
|
368
|
+
throw new RangeError(`${label} must be >= ${options.min}.`);
|
|
369
|
+
}
|
|
370
|
+
return n;
|
|
342
371
|
}
|
|
343
372
|
|
|
344
373
|
function rmse(predictions, targets) {
|