edfcore 0.6.102 → 0.6.104
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/dist/annotations-query.d.ts.map +1 -1
- package/dist/annotations-query.js +3 -2
- package/dist/annotations-query.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/decode/physical.d.ts +0 -13
- package/dist/decode/physical.d.ts.map +1 -1
- package/dist/decode/physical.js +27 -0
- package/dist/decode/physical.js.map +1 -1
- package/dist/header/lookup.d.ts +16 -0
- package/dist/header/lookup.d.ts.map +1 -1
- package/dist/header/lookup.js +26 -1
- package/dist/header/lookup.js.map +1 -1
- package/docs/CHANGELOG.md +27 -0
- package/package.json +1 -1
- package/src/annotations-query.ts +8 -2
- package/src/constants.ts +1 -1
- package/src/decode/physical.ts +32 -1
- package/src/header/lookup.ts +34 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotations-query.d.ts","sourceRoot":"","sources":["../src/annotations-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAErE;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,SAAS,aAAa,EAAE,EACrC,MAAM,EAAE,mBAAmB,GAC1B,SAAS,aAAa,EAAE,CAsB1B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,SAAS,aAAa,EAAE,EACrC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,GACnD,SAAS,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"annotations-query.d.ts","sourceRoot":"","sources":["../src/annotations-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAErE;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,SAAS,aAAa,EAAE,EACrC,MAAM,EAAE,mBAAmB,GAC1B,SAAS,aAAa,EAAE,CAsB1B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,SAAS,aAAa,EAAE,EACrC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,GACnD,SAAS,aAAa,EAAE,CAgB1B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,SAAS,aAAa,EAAE,GACpC,aAAa,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAQlE;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,SAAS,aAAa,EAAE,EACrC,OAAO,EAAE,MAAM,GACd,SAAS,aAAa,EAAE,CAS1B"}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* one puts events in the neighbouring window on exactly the files that bother to state their
|
|
19
19
|
* offset.
|
|
20
20
|
*/
|
|
21
|
-
import { matchesText } from './header/lookup.js';
|
|
21
|
+
import { assertMatcher, matchesText } from './header/lookup.js';
|
|
22
22
|
import { secondsToTicks } from './tal/ticks.js';
|
|
23
23
|
/**
|
|
24
24
|
* The annotations that overlap a time window, in the recording's own timebase.
|
|
@@ -72,7 +72,8 @@ export function filterAnnotationsByText(annotations, match) {
|
|
|
72
72
|
? // Not `match.test` directly: a `g` or `y` flag makes `test` stateful across the array
|
|
73
73
|
// and silently returns about half the true matches. See `matchesText`.
|
|
74
74
|
matchesText(match)
|
|
75
|
-
: match
|
|
75
|
+
: assertMatcher(match, 'filterAnnotationsByText', 'a string matched verbatim, a RegExp, or a predicate on the text', 'pass the label as a string, or (text) => text.trim() === label for a file whose ' +
|
|
76
|
+
'vocabulary is padded');
|
|
76
77
|
return Object.freeze(annotations.filter((annotation) => test(annotation.text)));
|
|
77
78
|
}
|
|
78
79
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotations-query.js","sourceRoot":"","sources":["../src/annotations-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"annotations-query.js","sourceRoot":"","sources":["../src/annotations-query.ts"],"names":[],"mappings":"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"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -109,5 +109,5 @@ export declare const SIGNAL_FIELD_BLOCK_OFFSETS: {
|
|
|
109
109
|
readonly reserved: 224;
|
|
110
110
|
};
|
|
111
111
|
/** Published package version. Kept in sync with package.json by a test. */
|
|
112
|
-
export declare const VERSION = "0.6.
|
|
112
|
+
export declare const VERSION = "0.6.104";
|
|
113
113
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.js
CHANGED
|
@@ -30,19 +30,6 @@ export declare function scalingError(signal: EdfSignal, tail?: {
|
|
|
30
30
|
readonly consequence?: string;
|
|
31
31
|
readonly nextStep?: string;
|
|
32
32
|
}): EdfScalingError;
|
|
33
|
-
/**
|
|
34
|
-
* `physical = bitValue * (offset + digital)`, in float64 throughout.
|
|
35
|
-
*
|
|
36
|
-
* THIS EXPRESSION IS PINNED AND MUST NOT BE "SIMPLIFIED". It is numerically worse than
|
|
37
|
-
* `physicalMinimum + (digital - digitalMinimum) * gain`, and that is not an accident: it is
|
|
38
|
-
* EDFlib's exact form, kept verbatim so edfcore reproduces pyEDFlib/EDFlib float64 output
|
|
39
|
-
* bit for bit. The two forms disagree by up to ~9.3e-10 LSB — ten orders of magnitude below
|
|
40
|
-
* the quantisation floor, and on asymmetric ranges they differ on nearly half the samples by
|
|
41
|
-
* one ULP. Rewriting this line breaks the golden-value tests, and rightly so.
|
|
42
|
-
*
|
|
43
|
-
* Throws `EdfScalingError` when `signal.scale` is `undefined`. edfcore never fabricates a gain,
|
|
44
|
-
* and `decodeDigital` keeps working on such a signal.
|
|
45
|
-
*/
|
|
46
33
|
export declare function toPhysical(signal: EdfSignal, digital: ArrayLike<number>, out?: Float64Array, options?: MaterializeOptions): Float64Array;
|
|
47
34
|
/**
|
|
48
35
|
* The signal's declared physical bounds, in ascending order.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"physical.d.ts","sourceRoot":"","sources":["../../src/decode/physical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAkB,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"physical.d.ts","sourceRoot":"","sources":["../../src/decode/physical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAkB,eAAe,EAAE,MAAM,cAAc,CAAC;AAG/D,OAAO,KAAK,EAAqC,SAAS,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAiKvD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,SAAS,EACjB,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACnE,eAAe,CAkBjB;AAiGD,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,EAC1B,GAAG,CAAC,EAAE,YAAY,EAClB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,YAAY,CAcd;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG;IAClD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAcA;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,UAAU,EACnB,GAAG,CAAC,EAAE,UAAU,EAChB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,UAAU,CAuBZ"}
|
package/dist/decode/physical.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { EdfBudgetError, EdfScalingError } from '../errors.js';
|
|
12
12
|
import { resolveMaterializeBudget } from '../options.js';
|
|
13
|
+
import { describeValue } from '../text/describe.js';
|
|
13
14
|
const BYTES_PER_FLOAT64 = 8;
|
|
14
15
|
const BYTES_PER_INT32 = 4;
|
|
15
16
|
/** The physical dimension that marks a log-compressed channel (EDFlib `edffloat.html`). */
|
|
@@ -209,7 +210,31 @@ function resolveInt32Out(out, length, options) {
|
|
|
209
210
|
* Throws `EdfScalingError` when `signal.scale` is `undefined`. edfcore never fabricates a gain,
|
|
210
211
|
* and `decodeDigital` keeps working on such a signal.
|
|
211
212
|
*/
|
|
213
|
+
/**
|
|
214
|
+
* The SIGNAL, before any field of it is read.
|
|
215
|
+
*
|
|
216
|
+
* `EdfChunkSignal` is the other per-signal shape and it is the one a reader has in hand after a
|
|
217
|
+
* read, so `toPhysical(chunk.signals[0], chunk.signals[0].digital)` is the call the arguments
|
|
218
|
+
* suggest. It has no `scale`, so `toPhysical` took the no-gain branch and `scalingError` then read
|
|
219
|
+
* `signal.raw.digitalMinimum` off it — V8's `Cannot read properties of undefined`, thrown from
|
|
220
|
+
* inside the builder of the error that was meant to explain the problem.
|
|
221
|
+
*
|
|
222
|
+
* `physicalRangeOf` got further, and worse. It reported `signal undefined "undefined" declares
|
|
223
|
+
* physical minimum "undefined"` and sent the reader to `header.diagnostics` for a signal that is not
|
|
224
|
+
* there: a complaint about the FILE for a mistake in the argument, which is the one confusion
|
|
225
|
+
* `byteSource` says this package works hardest to avoid (fixed in 0.6.104).
|
|
226
|
+
*/
|
|
227
|
+
function assertSignal(signal, call) {
|
|
228
|
+
if (typeof signal?.index === 'number' && typeof signal.physicalMinimum === 'number')
|
|
229
|
+
return;
|
|
230
|
+
const chunk = typeof signal?.signalIndex === 'number';
|
|
231
|
+
throw new RangeError(`${call}(): the signal is ${chunk
|
|
232
|
+
? 'a chunk signal, which carries the samples rather than the declaration they are scaled by'
|
|
233
|
+
: `${describeValue(signal)}, not one of header.signals`}. Next: pass header.signals[chunkSignal.signalIndex], or resolve it with ` +
|
|
234
|
+
'getSignal(header, label).');
|
|
235
|
+
}
|
|
212
236
|
export function toPhysical(signal, digital, out, options) {
|
|
237
|
+
assertSignal(signal, 'toPhysical');
|
|
213
238
|
const scale = signal.scale;
|
|
214
239
|
if (scale === undefined)
|
|
215
240
|
throw scalingError(signal);
|
|
@@ -241,6 +266,7 @@ export function toPhysical(signal, digital, out, options) {
|
|
|
241
266
|
* reporting no error at all.
|
|
242
267
|
*/
|
|
243
268
|
export function physicalRangeOf(signal) {
|
|
269
|
+
assertSignal(signal, 'physicalRangeOf');
|
|
244
270
|
const { physicalMinimum, physicalMaximum } = signal;
|
|
245
271
|
if (!Number.isFinite(physicalMinimum) || !Number.isFinite(physicalMaximum)) {
|
|
246
272
|
throw new RangeError(`signal ${signal.index} "${signal.label}" declares physical minimum ` +
|
|
@@ -261,6 +287,7 @@ export function physicalRangeOf(signal) {
|
|
|
261
287
|
* are empty and collapse every sample onto a single value.
|
|
262
288
|
*/
|
|
263
289
|
export function clampToDigitalRange(signal, digital, out, options) {
|
|
290
|
+
assertSignal(signal, 'clampToDigitalRange');
|
|
264
291
|
const low = Math.min(signal.digitalMinimum, signal.digitalMaximum);
|
|
265
292
|
const high = Math.max(signal.digitalMinimum, signal.digitalMaximum);
|
|
266
293
|
if (!Number.isFinite(low) || !Number.isFinite(high)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"physical.js","sourceRoot":"","sources":["../../src/decode/physical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"physical.js","sourceRoot":"","sources":["../../src/decode/physical.ts"],"names":[],"mappings":"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"}
|
package/dist/header/lookup.d.ts
CHANGED
|
@@ -45,6 +45,22 @@ export declare function getSignal(header: EdfHeader, selector: number | string):
|
|
|
45
45
|
* argument, and a module-level `const PATTERN = /x/g` shared with a `String.replace` elsewhere
|
|
46
46
|
* would then behave differently depending on whether edfcore had been called first.
|
|
47
47
|
*/
|
|
48
|
+
/**
|
|
49
|
+
* A matcher that arrived but is not one of the kinds the call takes.
|
|
50
|
+
*
|
|
51
|
+
* `assertSelector` above checks that one arrived; it never checked WHAT arrived, and `test` is then
|
|
52
|
+
* assigned from whatever did. `matchSignals(header, 'Fp1')` — a plain string, which this module's
|
|
53
|
+
* own docblock says is `findSignals`'s case — reached `test(signal.label)` and threw V8's "test is
|
|
54
|
+
* not a function": an internal name, no `Next:` clause, and no mention of the function that does
|
|
55
|
+
* take a label.
|
|
56
|
+
*
|
|
57
|
+
* `filterAnnotationsByText` did the same and worse. A predicate is only called once there is
|
|
58
|
+
* something to call it on, so a wrong matcher returned `[]` for a recording with no events and
|
|
59
|
+
* threw for the same argument on the next file — the third time in this package that the quality of
|
|
60
|
+
* a refusal depended on the data rather than on the call (0.6.79, 0.6.86, and this one, fixed in
|
|
61
|
+
* 0.6.103).
|
|
62
|
+
*/
|
|
63
|
+
export declare function assertMatcher<T>(match: T, call: string, accepts: string, instead: string): T;
|
|
48
64
|
export declare function matchesText(match: RegExp): (text: string) => boolean;
|
|
49
65
|
/**
|
|
50
66
|
* Every data signal whose label matches a pattern.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lookup.d.ts","sourceRoot":"","sources":["../../src/header/lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"lookup.d.ts","sourceRoot":"","sources":["../../src/header/lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGxD;AAwBD,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,SAAS,EAAE,CAIlF;AA6CD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAgDjF;AAED;;;;;;;;;;;;;;GAcG;AACH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,CAM5F;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAQpE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,GAC3C,SAAS,SAAS,EAAE,CAetB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAEjE"}
|
package/dist/header/lookup.js
CHANGED
|
@@ -14,6 +14,7 @@ import { trimEdfField } from '../bytes/latin1.js';
|
|
|
14
14
|
import { BDF_ANNOTATIONS_LABEL, EDF_ANNOTATIONS_LABEL } from '../constants.js';
|
|
15
15
|
import { EdfAmbiguousChannelError, EdfChannelNotFoundError } from '../errors.js';
|
|
16
16
|
import { ticksToSeconds } from '../tal/ticks.js';
|
|
17
|
+
import { describeValue } from '../text/describe.js';
|
|
17
18
|
/**
|
|
18
19
|
* True for the two reserved annotation labels, matched on the trimmed text and case-sensitively.
|
|
19
20
|
*
|
|
@@ -150,6 +151,27 @@ export function getSignal(header, selector) {
|
|
|
150
151
|
* argument, and a module-level `const PATTERN = /x/g` shared with a `String.replace` elsewhere
|
|
151
152
|
* would then behave differently depending on whether edfcore had been called first.
|
|
152
153
|
*/
|
|
154
|
+
/**
|
|
155
|
+
* A matcher that arrived but is not one of the kinds the call takes.
|
|
156
|
+
*
|
|
157
|
+
* `assertSelector` above checks that one arrived; it never checked WHAT arrived, and `test` is then
|
|
158
|
+
* assigned from whatever did. `matchSignals(header, 'Fp1')` — a plain string, which this module's
|
|
159
|
+
* own docblock says is `findSignals`'s case — reached `test(signal.label)` and threw V8's "test is
|
|
160
|
+
* not a function": an internal name, no `Next:` clause, and no mention of the function that does
|
|
161
|
+
* take a label.
|
|
162
|
+
*
|
|
163
|
+
* `filterAnnotationsByText` did the same and worse. A predicate is only called once there is
|
|
164
|
+
* something to call it on, so a wrong matcher returned `[]` for a recording with no events and
|
|
165
|
+
* threw for the same argument on the next file — the third time in this package that the quality of
|
|
166
|
+
* a refusal depended on the data rather than on the call (0.6.79, 0.6.86, and this one, fixed in
|
|
167
|
+
* 0.6.103).
|
|
168
|
+
*/
|
|
169
|
+
export function assertMatcher(match, call, accepts, instead) {
|
|
170
|
+
if (typeof match === 'function')
|
|
171
|
+
return match;
|
|
172
|
+
throw new RangeError(`${call}(): the matcher is ${describeValue(match)}, and this call takes ${accepts}. ` +
|
|
173
|
+
`Next: ${instead}.`);
|
|
174
|
+
}
|
|
153
175
|
export function matchesText(match) {
|
|
154
176
|
const pattern = new RegExp(match.source, match.flags);
|
|
155
177
|
return (text) => {
|
|
@@ -173,7 +195,10 @@ export function matchesText(match) {
|
|
|
173
195
|
*/
|
|
174
196
|
export function matchSignals(header, match) {
|
|
175
197
|
assertSelector(match, 'matchSignals', 'a RegExp, or a function taking a label');
|
|
176
|
-
const test = match instanceof RegExp
|
|
198
|
+
const test = match instanceof RegExp
|
|
199
|
+
? matchesText(match)
|
|
200
|
+
: assertMatcher(match, 'matchSignals', 'a RegExp or a predicate on the label', 'pass a RegExp for a pattern, or findSignals(header, label) for an exact label — the ' +
|
|
201
|
+
'case this function deliberately does not cover');
|
|
177
202
|
return Object.freeze(header.signals.filter((signal) => signal.kind === 'data' && test(signal.label)));
|
|
178
203
|
}
|
|
179
204
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lookup.js","sourceRoot":"","sources":["../../src/header/lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"lookup.js","sourceRoot":"","sources":["../../src/header/lookup.ts"],"names":[],"mappings":"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"}
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,33 @@ alone does not tell you whether you were affected.
|
|
|
6
6
|
edfcore is pre-1.0. Patch releases have carried behaviour changes where the old behaviour was a
|
|
7
7
|
defect; those are called out below.
|
|
8
8
|
|
|
9
|
+
## 0.6.104
|
|
10
|
+
|
|
11
|
+
- **Fixed** `toPhysical`, `physicalRangeOf` and `clampToDigitalRange` when handed a chunk signal
|
|
12
|
+
instead of the header's declaration.
|
|
13
|
+
- `toPhysical(chunk.signals[0], chunk.signals[0].digital)` is the call the argument list suggests, and
|
|
14
|
+
it is wrong: the scale lives on the header's signal. A chunk signal has no `scale`, so `toPhysical`
|
|
15
|
+
took its no-gain branch and `scalingError` then read `signal.raw.digitalMinimum` off it — a
|
|
16
|
+
`TypeError` thrown from inside the builder of the error meant to explain the problem.
|
|
17
|
+
- `physicalRangeOf` got further and worse. It reported `signal undefined "undefined" declares physical
|
|
18
|
+
minimum "undefined" … Next: read header.diagnostics for this signal`: a complaint about the FILE
|
|
19
|
+
for a mistake in the argument, pointing at a signal that is not there.
|
|
20
|
+
- All three now name the chunk signal as what it is and point at `header.signals[…]`. A real signal
|
|
21
|
+
that genuinely has no gain still gets the `EdfScalingError` it always did.
|
|
22
|
+
|
|
23
|
+
## 0.6.103
|
|
24
|
+
|
|
25
|
+
- **Fixed** `matchSignals` and `filterAnnotationsByText` throwing V8's "test is not a function" for a
|
|
26
|
+
matcher of the wrong kind.
|
|
27
|
+
- 0.6.86 checked that a matcher arrived and not what it was. `matchSignals(header, 'Fp1')` is the
|
|
28
|
+
likeliest wrong argument the function has — a caller who wants one channel reaches for the one
|
|
29
|
+
whose name says match — and it is the case `matchSignals`'s own docblock hands to `findSignals`.
|
|
30
|
+
The refusal now says so, and names it.
|
|
31
|
+
- `filterAnnotationsByText` was worse: a predicate is only called once there is something to call it
|
|
32
|
+
on, so a wrong matcher returned `[]` for a recording with no events and threw for the same argument
|
|
33
|
+
on the next file. That is the third time the quality of a refusal here depended on the data rather
|
|
34
|
+
than on the call (0.6.79, 0.6.86, this one).
|
|
35
|
+
|
|
9
36
|
## 0.6.102
|
|
10
37
|
|
|
11
38
|
- **Fixed** the three I/O adapters that had no argument check: `blobSource`, `httpSource` and
|
package/package.json
CHANGED
package/src/annotations-query.ts
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* offset.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import { matchesText } from './header/lookup.js';
|
|
22
|
+
import { assertMatcher, matchesText } from './header/lookup.js';
|
|
23
23
|
import { secondsToTicks } from './tal/ticks.js';
|
|
24
24
|
import type { EdfAnnotation, EdfAnnotationWindow } from './types.js';
|
|
25
25
|
|
|
@@ -85,7 +85,13 @@ export function filterAnnotationsByText(
|
|
|
85
85
|
? // Not `match.test` directly: a `g` or `y` flag makes `test` stateful across the array
|
|
86
86
|
// and silently returns about half the true matches. See `matchesText`.
|
|
87
87
|
matchesText(match)
|
|
88
|
-
:
|
|
88
|
+
: assertMatcher(
|
|
89
|
+
match,
|
|
90
|
+
'filterAnnotationsByText',
|
|
91
|
+
'a string matched verbatim, a RegExp, or a predicate on the text',
|
|
92
|
+
'pass the label as a string, or (text) => text.trim() === label for a file whose ' +
|
|
93
|
+
'vocabulary is padded',
|
|
94
|
+
);
|
|
89
95
|
return Object.freeze(annotations.filter((annotation) => test(annotation.text)));
|
|
90
96
|
}
|
|
91
97
|
|
package/src/constants.ts
CHANGED
package/src/decode/physical.ts
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
|
|
12
12
|
import { EdfBudgetError, EdfScalingError } from '../errors.js';
|
|
13
13
|
import { resolveMaterializeBudget } from '../options.js';
|
|
14
|
-
import
|
|
14
|
+
import { describeValue } from '../text/describe.js';
|
|
15
|
+
import type { EdfChunkSignal, EdfDiagnosticCode, EdfSignal } from '../types.js';
|
|
15
16
|
import type { MaterializeOptions } from './digital.js';
|
|
16
17
|
|
|
17
18
|
export type { MaterializeOptions } from './digital.js';
|
|
@@ -280,12 +281,40 @@ function resolveInt32Out(
|
|
|
280
281
|
* Throws `EdfScalingError` when `signal.scale` is `undefined`. edfcore never fabricates a gain,
|
|
281
282
|
* and `decodeDigital` keeps working on such a signal.
|
|
282
283
|
*/
|
|
284
|
+
/**
|
|
285
|
+
* The SIGNAL, before any field of it is read.
|
|
286
|
+
*
|
|
287
|
+
* `EdfChunkSignal` is the other per-signal shape and it is the one a reader has in hand after a
|
|
288
|
+
* read, so `toPhysical(chunk.signals[0], chunk.signals[0].digital)` is the call the arguments
|
|
289
|
+
* suggest. It has no `scale`, so `toPhysical` took the no-gain branch and `scalingError` then read
|
|
290
|
+
* `signal.raw.digitalMinimum` off it — V8's `Cannot read properties of undefined`, thrown from
|
|
291
|
+
* inside the builder of the error that was meant to explain the problem.
|
|
292
|
+
*
|
|
293
|
+
* `physicalRangeOf` got further, and worse. It reported `signal undefined "undefined" declares
|
|
294
|
+
* physical minimum "undefined"` and sent the reader to `header.diagnostics` for a signal that is not
|
|
295
|
+
* there: a complaint about the FILE for a mistake in the argument, which is the one confusion
|
|
296
|
+
* `byteSource` says this package works hardest to avoid (fixed in 0.6.104).
|
|
297
|
+
*/
|
|
298
|
+
function assertSignal(signal: EdfSignal, call: string): void {
|
|
299
|
+
if (typeof signal?.index === 'number' && typeof signal.physicalMinimum === 'number') return;
|
|
300
|
+
const chunk = typeof (signal as unknown as EdfChunkSignal | undefined)?.signalIndex === 'number';
|
|
301
|
+
throw new RangeError(
|
|
302
|
+
`${call}(): the signal is ${
|
|
303
|
+
chunk
|
|
304
|
+
? 'a chunk signal, which carries the samples rather than the declaration they are scaled by'
|
|
305
|
+
: `${describeValue(signal)}, not one of header.signals`
|
|
306
|
+
}. Next: pass header.signals[chunkSignal.signalIndex], or resolve it with ` +
|
|
307
|
+
'getSignal(header, label).',
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
|
|
283
311
|
export function toPhysical(
|
|
284
312
|
signal: EdfSignal,
|
|
285
313
|
digital: ArrayLike<number>,
|
|
286
314
|
out?: Float64Array,
|
|
287
315
|
options?: MaterializeOptions,
|
|
288
316
|
): Float64Array {
|
|
317
|
+
assertSignal(signal, 'toPhysical');
|
|
289
318
|
const scale = signal.scale;
|
|
290
319
|
if (scale === undefined) throw scalingError(signal);
|
|
291
320
|
|
|
@@ -321,6 +350,7 @@ export function physicalRangeOf(signal: EdfSignal): {
|
|
|
321
350
|
readonly low: number;
|
|
322
351
|
readonly high: number;
|
|
323
352
|
} {
|
|
353
|
+
assertSignal(signal, 'physicalRangeOf');
|
|
324
354
|
const { physicalMinimum, physicalMaximum } = signal;
|
|
325
355
|
if (!Number.isFinite(physicalMinimum) || !Number.isFinite(physicalMaximum)) {
|
|
326
356
|
throw new RangeError(
|
|
@@ -349,6 +379,7 @@ export function clampToDigitalRange(
|
|
|
349
379
|
out?: Int32Array,
|
|
350
380
|
options?: MaterializeOptions,
|
|
351
381
|
): Int32Array {
|
|
382
|
+
assertSignal(signal, 'clampToDigitalRange');
|
|
352
383
|
const low = Math.min(signal.digitalMinimum, signal.digitalMaximum);
|
|
353
384
|
const high = Math.max(signal.digitalMinimum, signal.digitalMaximum);
|
|
354
385
|
if (!Number.isFinite(low) || !Number.isFinite(high)) {
|
package/src/header/lookup.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { trimEdfField } from '../bytes/latin1.js';
|
|
|
15
15
|
import { BDF_ANNOTATIONS_LABEL, EDF_ANNOTATIONS_LABEL } from '../constants.js';
|
|
16
16
|
import { EdfAmbiguousChannelError, EdfChannelNotFoundError } from '../errors.js';
|
|
17
17
|
import { ticksToSeconds } from '../tal/ticks.js';
|
|
18
|
+
import { describeValue } from '../text/describe.js';
|
|
18
19
|
import type { EdfHeader, EdfSignal } from '../types.js';
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -174,6 +175,29 @@ export function getSignal(header: EdfHeader, selector: number | string): EdfSign
|
|
|
174
175
|
* argument, and a module-level `const PATTERN = /x/g` shared with a `String.replace` elsewhere
|
|
175
176
|
* would then behave differently depending on whether edfcore had been called first.
|
|
176
177
|
*/
|
|
178
|
+
/**
|
|
179
|
+
* A matcher that arrived but is not one of the kinds the call takes.
|
|
180
|
+
*
|
|
181
|
+
* `assertSelector` above checks that one arrived; it never checked WHAT arrived, and `test` is then
|
|
182
|
+
* assigned from whatever did. `matchSignals(header, 'Fp1')` — a plain string, which this module's
|
|
183
|
+
* own docblock says is `findSignals`'s case — reached `test(signal.label)` and threw V8's "test is
|
|
184
|
+
* not a function": an internal name, no `Next:` clause, and no mention of the function that does
|
|
185
|
+
* take a label.
|
|
186
|
+
*
|
|
187
|
+
* `filterAnnotationsByText` did the same and worse. A predicate is only called once there is
|
|
188
|
+
* something to call it on, so a wrong matcher returned `[]` for a recording with no events and
|
|
189
|
+
* threw for the same argument on the next file — the third time in this package that the quality of
|
|
190
|
+
* a refusal depended on the data rather than on the call (0.6.79, 0.6.86, and this one, fixed in
|
|
191
|
+
* 0.6.103).
|
|
192
|
+
*/
|
|
193
|
+
export function assertMatcher<T>(match: T, call: string, accepts: string, instead: string): T {
|
|
194
|
+
if (typeof match === 'function') return match;
|
|
195
|
+
throw new RangeError(
|
|
196
|
+
`${call}(): the matcher is ${describeValue(match)}, and this call takes ${accepts}. ` +
|
|
197
|
+
`Next: ${instead}.`,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
177
201
|
export function matchesText(match: RegExp): (text: string) => boolean {
|
|
178
202
|
const pattern = new RegExp(match.source, match.flags);
|
|
179
203
|
return (text: string): boolean => {
|
|
@@ -201,7 +225,16 @@ export function matchSignals(
|
|
|
201
225
|
match: RegExp | ((label: string) => boolean),
|
|
202
226
|
): readonly EdfSignal[] {
|
|
203
227
|
assertSelector(match, 'matchSignals', 'a RegExp, or a function taking a label');
|
|
204
|
-
const test =
|
|
228
|
+
const test =
|
|
229
|
+
match instanceof RegExp
|
|
230
|
+
? matchesText(match)
|
|
231
|
+
: assertMatcher(
|
|
232
|
+
match,
|
|
233
|
+
'matchSignals',
|
|
234
|
+
'a RegExp or a predicate on the label',
|
|
235
|
+
'pass a RegExp for a pattern, or findSignals(header, label) for an exact label — the ' +
|
|
236
|
+
'case this function deliberately does not cover',
|
|
237
|
+
);
|
|
205
238
|
return Object.freeze(
|
|
206
239
|
header.signals.filter((signal) => signal.kind === 'data' && test(signal.label)),
|
|
207
240
|
);
|