edfcore 0.3.21 → 0.3.22
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/CHANGELOG.md +22 -0
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/decode/physical.d.ts.map +1 -1
- package/dist/decode/physical.js +24 -1
- package/dist/decode/physical.js.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +1 -1
- package/src/decode/physical.ts +32 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,28 @@ 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.3.22
|
|
10
|
+
|
|
11
|
+
- **Fixed** `toPhysical` inventing a header defect when called on an annotations channel.
|
|
12
|
+
`parseSignalHeaders` deliberately never runs `buildScale` over one — its physical and digital
|
|
13
|
+
fields describe nothing a caller may use, and checking them "would report a defect about a number
|
|
14
|
+
nobody may use" — so such a signal has no scale AND no diagnostic. `describeScalingFailure` was
|
|
15
|
+
applied to it anyway, re-running the four data-signal tests over those unused fields and
|
|
16
|
+
confidently naming a cause the header never evaluated.
|
|
17
|
+
- A channel declaring `0`/`0` was refused with **`DEGENERATE_PHYSICAL_RANGE`**, a message asserting
|
|
18
|
+
a header defect. The conventional `-1`/`1` one was refused with `SCALE_UNAVAILABLE` and the words
|
|
19
|
+
*"the header recorded the reason rather than the signal"*. Both sent the caller to a
|
|
20
|
+
`header.diagnostics` entry that does not exist, and neither ever said the actual reason.
|
|
21
|
+
- It now says what the channel is: its bytes are EDF+ TAL text rather than measurements, so no
|
|
22
|
+
scale was ever built for it. `describeScalingFailure` only ever names a cause `buildScale`
|
|
23
|
+
actually evaluated, which is what its own comment promises.
|
|
24
|
+
- The next step changed too. Every other scaling failure ends "decodeDigital() still works on this
|
|
25
|
+
signal", which is true for a data signal whose ranges are unusable and **false here** — decoding
|
|
26
|
+
TAL text as samples produces numbers that look exactly like a signal, the one failure this
|
|
27
|
+
package exists to prevent. For the annotations channel it points at `readAnnotations` instead.
|
|
28
|
+
- `physical-values.md` said "Each condition also appears in `header.diagnostics` at parse time".
|
|
29
|
+
That was false for every annotations channel; the exception is now written down beside the rule.
|
|
30
|
+
|
|
9
31
|
## 0.3.21
|
|
10
32
|
|
|
11
33
|
- **Fixed** a non-finite `maxMaterializeBytes` producing two different wrong diagnoses, neither
|
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.3.
|
|
112
|
+
export declare const VERSION = "0.3.22";
|
|
113
113
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"physical.d.ts","sourceRoot":"","sources":["../../src/decode/physical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAqB,SAAS,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"physical.d.ts","sourceRoot":"","sources":["../../src/decode/physical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAqB,SAAS,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAqLvD;;;;;;;;;;;;GAYG;AACH,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,CAad;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,CAaA;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,CAsBZ"}
|
package/dist/decode/physical.js
CHANGED
|
@@ -36,6 +36,28 @@ function assertWithinBudget(requiredBytes, what, options) {
|
|
|
36
36
|
*/
|
|
37
37
|
function describeScalingFailure(signal) {
|
|
38
38
|
const digitalSpec = 'EDF+ additional specification 5: "Digital maximum must be larger than Digital minimum"';
|
|
39
|
+
// FIRST, and ahead of the four re-derived tests. `parseSignalHeaders` deliberately does not run
|
|
40
|
+
// `buildScale` over an annotations channel — its physical and digital fields describe nothing a
|
|
41
|
+
// caller may use, and checking them "would report a defect about a number nobody may use". So
|
|
42
|
+
// such a signal has no scale AND no diagnostic, and re-running the four tests over those unused
|
|
43
|
+
// fields named a cause the header never evaluated: an annotations channel declaring 0/0 was
|
|
44
|
+
// refused with DEGENERATE_PHYSICAL_RANGE asserting a header defect, and the conventional -1/1
|
|
45
|
+
// one with SCALE_UNAVAILABLE saying "the header recorded the reason" — sending the reader to a
|
|
46
|
+
// `header.diagnostics` entry that does not exist, in both cases. Neither ever said the real
|
|
47
|
+
// reason (fixed in 0.3.22).
|
|
48
|
+
if (signal.kind === 'annotations') {
|
|
49
|
+
return {
|
|
50
|
+
code: 'SCALE_UNAVAILABLE',
|
|
51
|
+
reason: "is this file's annotations channel: its bytes are EDF+ TAL text rather than " +
|
|
52
|
+
'measurements, so no scale was ever built for it and its physical fields describe ' +
|
|
53
|
+
'nothing',
|
|
54
|
+
specReference: 'EDF+ specification 2.2.4 (the EDF Annotations signal)',
|
|
55
|
+
// NOT "decodeDigital() still works on this signal". It does, and it produces numbers that
|
|
56
|
+
// look exactly like a signal — the one failure this package exists to prevent.
|
|
57
|
+
nextStep: 'Next: read this channel with readAnnotations(recording, records), and pass only ' +
|
|
58
|
+
'header.dataSignalIndices to a sample read.',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
39
61
|
if (signal.digitalMinimum === signal.digitalMaximum) {
|
|
40
62
|
return {
|
|
41
63
|
code: 'DEGENERATE_DIGITAL_RANGE',
|
|
@@ -82,7 +104,8 @@ function scalingError(signal) {
|
|
|
82
104
|
`physical minimum "${signal.raw.physicalMinimum}", physical maximum ` +
|
|
83
105
|
`"${signal.raw.physicalMaximum}", physical dimension "${signal.raw.physicalDimension}". ` +
|
|
84
106
|
(failure.specReference === undefined ? '' : `${failure.specReference}. `) +
|
|
85
|
-
|
|
107
|
+
(failure.nextStep ??
|
|
108
|
+
'Next: decodeDigital() still works on this signal; edfcore will not invent a gain.');
|
|
86
109
|
return new EdfScalingError(message, {
|
|
87
110
|
code: failure.code,
|
|
88
111
|
signalIndex: signal.index,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"physical.js","sourceRoot":"","sources":["../../src/decode/physical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,6BAA6B,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAM/D,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B,2FAA2F;AAC3F,MAAM,yBAAyB,GAAG,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"physical.js","sourceRoot":"","sources":["../../src/decode/physical.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
package/src/decode/physical.ts
CHANGED
|
@@ -27,6 +27,12 @@ interface ScalingFailure {
|
|
|
27
27
|
/** Completes the sentence `signal 7 "EMG Chin" ...`. */
|
|
28
28
|
readonly reason: string;
|
|
29
29
|
readonly specReference: string | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* What to do instead. Defaults to "decodeDigital still works on this signal", which is true for
|
|
32
|
+
* every DATA signal whose header ranges are unusable — and false for the annotations channel,
|
|
33
|
+
* where decoding TAL text as samples is the exact mistake this package exists to prevent.
|
|
34
|
+
*/
|
|
35
|
+
readonly nextStep?: string;
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
function assertWithinBudget(
|
|
@@ -59,6 +65,30 @@ function assertWithinBudget(
|
|
|
59
65
|
function describeScalingFailure(signal: EdfSignal): ScalingFailure {
|
|
60
66
|
const digitalSpec =
|
|
61
67
|
'EDF+ additional specification 5: "Digital maximum must be larger than Digital minimum"';
|
|
68
|
+
// FIRST, and ahead of the four re-derived tests. `parseSignalHeaders` deliberately does not run
|
|
69
|
+
// `buildScale` over an annotations channel — its physical and digital fields describe nothing a
|
|
70
|
+
// caller may use, and checking them "would report a defect about a number nobody may use". So
|
|
71
|
+
// such a signal has no scale AND no diagnostic, and re-running the four tests over those unused
|
|
72
|
+
// fields named a cause the header never evaluated: an annotations channel declaring 0/0 was
|
|
73
|
+
// refused with DEGENERATE_PHYSICAL_RANGE asserting a header defect, and the conventional -1/1
|
|
74
|
+
// one with SCALE_UNAVAILABLE saying "the header recorded the reason" — sending the reader to a
|
|
75
|
+
// `header.diagnostics` entry that does not exist, in both cases. Neither ever said the real
|
|
76
|
+
// reason (fixed in 0.3.22).
|
|
77
|
+
if (signal.kind === 'annotations') {
|
|
78
|
+
return {
|
|
79
|
+
code: 'SCALE_UNAVAILABLE',
|
|
80
|
+
reason:
|
|
81
|
+
"is this file's annotations channel: its bytes are EDF+ TAL text rather than " +
|
|
82
|
+
'measurements, so no scale was ever built for it and its physical fields describe ' +
|
|
83
|
+
'nothing',
|
|
84
|
+
specReference: 'EDF+ specification 2.2.4 (the EDF Annotations signal)',
|
|
85
|
+
// NOT "decodeDigital() still works on this signal". It does, and it produces numbers that
|
|
86
|
+
// look exactly like a signal — the one failure this package exists to prevent.
|
|
87
|
+
nextStep:
|
|
88
|
+
'Next: read this channel with readAnnotations(recording, records), and pass only ' +
|
|
89
|
+
'header.dataSignalIndices to a sample read.',
|
|
90
|
+
};
|
|
91
|
+
}
|
|
62
92
|
if (signal.digitalMinimum === signal.digitalMaximum) {
|
|
63
93
|
return {
|
|
64
94
|
code: 'DEGENERATE_DIGITAL_RANGE',
|
|
@@ -111,7 +141,8 @@ function scalingError(signal: EdfSignal): EdfScalingError {
|
|
|
111
141
|
`physical minimum "${signal.raw.physicalMinimum}", physical maximum ` +
|
|
112
142
|
`"${signal.raw.physicalMaximum}", physical dimension "${signal.raw.physicalDimension}". ` +
|
|
113
143
|
(failure.specReference === undefined ? '' : `${failure.specReference}. `) +
|
|
114
|
-
|
|
144
|
+
(failure.nextStep ??
|
|
145
|
+
'Next: decodeDigital() still works on this signal; edfcore will not invent a gain.');
|
|
115
146
|
return new EdfScalingError(message, {
|
|
116
147
|
code: failure.code,
|
|
117
148
|
signalIndex: signal.index,
|