edfcore 0.4.508 → 0.4.509
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/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 +35 -3
- package/dist/decode/physical.js.map +1 -1
- package/docs/CHANGELOG.md +21 -0
- package/package.json +1 -1
- package/src/constants.ts +1 -1
- package/src/decode/physical.ts +40 -4
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.4.
|
|
112
|
+
export declare const VERSION = "0.4.509";
|
|
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;AAEH,OAAO,EAAkB,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/D,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;AAEH,OAAO,EAAkB,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/D,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;AA0JvD;;;;;;;;;;;;;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;AA+CD;;;;;;;;;;;;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
|
@@ -27,7 +27,7 @@ function assertWithinBudget(requiredBytes, what, options) {
|
|
|
27
27
|
* Why `signal.scale` is `undefined`, re-derived from the signal itself.
|
|
28
28
|
*
|
|
29
29
|
* The header records the matching diagnostic at parse time, but a bare `EdfSignal` does not
|
|
30
|
-
* carry it, and `toPhysical` takes a signal. These
|
|
30
|
+
* carry it, and `toPhysical` takes a signal. These five tests are the same ones `header/scale.ts`
|
|
31
31
|
* applies, IN THE SAME ORDER — a signal can fail two of them at once, and the order is what
|
|
32
32
|
* decides which cause is named, so the code reported here is the code the header reported.
|
|
33
33
|
* `buildScale` owns that order; this function follows it. A signal that fails none
|
|
@@ -35,8 +35,9 @@ function assertWithinBudget(requiredBytes, what, options) {
|
|
|
35
35
|
* naming the wrong cause is worse than admitting the cause is not on hand.
|
|
36
36
|
*/
|
|
37
37
|
function describeScalingFailure(signal) {
|
|
38
|
-
const
|
|
39
|
-
|
|
38
|
+
const rangeSpec = 'EDF+ additional specification 5';
|
|
39
|
+
const digitalSpec = `${rangeSpec}: "Digital maximum must be larger than Digital minimum"`;
|
|
40
|
+
// FIRST, and ahead of the five re-derived tests. `parseSignalHeaders` deliberately does not run
|
|
40
41
|
// `buildScale` over an annotations channel — its physical and digital fields describe nothing a
|
|
41
42
|
// caller may use, and checking them "would report a defect about a number nobody may use". So
|
|
42
43
|
// such a signal has no scale AND no diagnostic, and re-running the four tests over those unused
|
|
@@ -90,6 +91,37 @@ function describeScalingFailure(signal) {
|
|
|
90
91
|
specReference: 'EDFlib edffloat.html',
|
|
91
92
|
};
|
|
92
93
|
}
|
|
94
|
+
// FIFTH, and the reason this function re-derives arithmetic rather than only reading fields:
|
|
95
|
+
// four finite fields can still imply a gain that is not finite. `buildScale` reports
|
|
96
|
+
// DEGENERATE_PHYSICAL_RANGE for that, and until 0.4.509 this fell through to the
|
|
97
|
+
// `SCALE_UNAVAILABLE` fallback below — whose text says the header holds the reason, while the
|
|
98
|
+
// header was in fact holding a different code. That is the same divergence 0.3.111 fixed
|
|
99
|
+
// between the two entry points, in the one arm nobody mirrored.
|
|
100
|
+
//
|
|
101
|
+
// Guarded on all four being finite, because a field that failed its grammar arrives here as
|
|
102
|
+
// NaN, and NaN would satisfy the non-finite test below and claim the gain as the cause. Its
|
|
103
|
+
// cause belongs to the field, was reported against the field, and is exactly the case the
|
|
104
|
+
// fallback's wording is true of.
|
|
105
|
+
if (Number.isFinite(signal.physicalMinimum) &&
|
|
106
|
+
Number.isFinite(signal.physicalMaximum) &&
|
|
107
|
+
Number.isFinite(signal.digitalMinimum) &&
|
|
108
|
+
Number.isFinite(signal.digitalMaximum)) {
|
|
109
|
+
// `buildScale`'s expression, not a simplification of it: the two must agree on which ranges
|
|
110
|
+
// are refused, and the pinned form is what decides the edge cases.
|
|
111
|
+
const bitValue = (signal.physicalMaximum - signal.physicalMinimum) /
|
|
112
|
+
(signal.digitalMaximum - signal.digitalMinimum);
|
|
113
|
+
const offset = signal.physicalMaximum / bitValue - signal.digitalMaximum;
|
|
114
|
+
if (bitValue === 0 || !Number.isFinite(bitValue) || !Number.isFinite(offset)) {
|
|
115
|
+
return {
|
|
116
|
+
code: 'DEGENERATE_PHYSICAL_RANGE',
|
|
117
|
+
reason: `declares the physical range ${signal.physicalMinimum}..${signal.physicalMaximum} ` +
|
|
118
|
+
`over the digital range ${signal.digitalMinimum}..${signal.digitalMaximum}, and the ` +
|
|
119
|
+
`gain those imply is not a usable float64 number (bitValue ${bitValue}, offset ` +
|
|
120
|
+
`${offset}), so every converted sample would be NaN or infinite`,
|
|
121
|
+
specReference: rangeSpec,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
93
125
|
return {
|
|
94
126
|
code: 'SCALE_UNAVAILABLE',
|
|
95
127
|
reason: 'has no usable scale, and the header recorded the reason rather than the signal',
|
|
@@ -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;AAMzD,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B,2FAA2F;AAC3F,MAAM,yBAAyB,GAAG,UAAU,CAAC;AAe7C,SAAS,kBAAkB,CACzB,aAAqB,EACrB,IAAY,EACZ,OAAuC;IAEvC,MAAM,WAAW,GAAG,wBAAwB,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;IAC3E,IAAI,aAAa,IAAI,WAAW;QAAE,OAAO;IACzC,MAAM,IAAI,cAAc,CACtB,aAAa,IAAI,YAAY,aAAa,0BAA0B,WAAW,QAAQ;QACrF,qFAAqF;QACrF,uEAAuE;QACvE,8BAA8B,EAChC,EAAE,aAAa,EAAE,WAAW,EAAE,CAC/B,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,sBAAsB,CAAC,MAAiB;IAC/C,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"physical.js","sourceRoot":"","sources":["../../src/decode/physical.ts"],"names":[],"mappings":"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"}
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,27 @@ 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.4.509
|
|
10
|
+
|
|
11
|
+
- **Fixed** `toPhysical` naming a different cause than the header for one class of unscalable
|
|
12
|
+
signal. `header/scale.ts` refuses to build a scale in five places; `decode/physical.ts`
|
|
13
|
+
re-derives which one applied, from the signal alone, because `toPhysical` never sees the header.
|
|
14
|
+
It re-derived four of the five. The missing one is the case where all four scale fields are
|
|
15
|
+
finite but the gain they imply is not — `-9.9E307`..`9.9E307` over `-32768`..`32767` gives a
|
|
16
|
+
bitValue of `Infinity` — which the header reports as `DEGENERATE_PHYSICAL_RANGE`.
|
|
17
|
+
- The cost was a message that pointed at nothing. Such a signal threw `SCALE_UNAVAILABLE`, whose
|
|
18
|
+
text reads "the header recorded the reason rather than the signal", so a caller who catches the
|
|
19
|
+
error and goes looking through `header.diagnostics` for `SCALE_UNAVAILABLE` finds no entry —
|
|
20
|
+
the entry is there under the other code. Both `error.code` and the reason are now the header's,
|
|
21
|
+
and the message quotes the bitValue and offset it computed.
|
|
22
|
+
- The re-derivation is guarded on all four fields being finite, because a field that failed its
|
|
23
|
+
grammar arrives as `NaN`, and `NaN` satisfies a non-finite test. That signal's cause belongs to
|
|
24
|
+
the field, was already reported against the field, and is the case the `SCALE_UNAVAILABLE`
|
|
25
|
+
wording is true of — so the fallback stays reachable and stays honest.
|
|
26
|
+
- This is the same divergence 0.3.111 fixed between the two entry points, in the one arm nobody
|
|
27
|
+
mirrored, so the count is now checked rather than trusted: a test reads `header/scale.ts` and
|
|
28
|
+
asserts it abandons a scale in exactly five places, against the five cases the contract covers.
|
|
29
|
+
|
|
9
30
|
## 0.4.508
|
|
10
31
|
|
|
11
32
|
- **Added** an enforcement of the `grid` prefix rule. `migrating-to-0-3.md` explains why three
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
package/src/decode/physical.ts
CHANGED
|
@@ -55,7 +55,7 @@ function assertWithinBudget(
|
|
|
55
55
|
* Why `signal.scale` is `undefined`, re-derived from the signal itself.
|
|
56
56
|
*
|
|
57
57
|
* The header records the matching diagnostic at parse time, but a bare `EdfSignal` does not
|
|
58
|
-
* carry it, and `toPhysical` takes a signal. These
|
|
58
|
+
* carry it, and `toPhysical` takes a signal. These five tests are the same ones `header/scale.ts`
|
|
59
59
|
* applies, IN THE SAME ORDER — a signal can fail two of them at once, and the order is what
|
|
60
60
|
* decides which cause is named, so the code reported here is the code the header reported.
|
|
61
61
|
* `buildScale` owns that order; this function follows it. A signal that fails none
|
|
@@ -63,9 +63,9 @@ function assertWithinBudget(
|
|
|
63
63
|
* naming the wrong cause is worse than admitting the cause is not on hand.
|
|
64
64
|
*/
|
|
65
65
|
function describeScalingFailure(signal: EdfSignal): ScalingFailure {
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
// FIRST, and ahead of the
|
|
66
|
+
const rangeSpec = 'EDF+ additional specification 5';
|
|
67
|
+
const digitalSpec = `${rangeSpec}: "Digital maximum must be larger than Digital minimum"`;
|
|
68
|
+
// FIRST, and ahead of the five re-derived tests. `parseSignalHeaders` deliberately does not run
|
|
69
69
|
// `buildScale` over an annotations channel — its physical and digital fields describe nothing a
|
|
70
70
|
// caller may use, and checking them "would report a defect about a number nobody may use". So
|
|
71
71
|
// such a signal has no scale AND no diagnostic, and re-running the four tests over those unused
|
|
@@ -125,6 +125,42 @@ function describeScalingFailure(signal: EdfSignal): ScalingFailure {
|
|
|
125
125
|
specReference: 'EDFlib edffloat.html',
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
|
+
// FIFTH, and the reason this function re-derives arithmetic rather than only reading fields:
|
|
129
|
+
// four finite fields can still imply a gain that is not finite. `buildScale` reports
|
|
130
|
+
// DEGENERATE_PHYSICAL_RANGE for that, and until 0.4.509 this fell through to the
|
|
131
|
+
// `SCALE_UNAVAILABLE` fallback below — whose text says the header holds the reason, while the
|
|
132
|
+
// header was in fact holding a different code. That is the same divergence 0.3.111 fixed
|
|
133
|
+
// between the two entry points, in the one arm nobody mirrored.
|
|
134
|
+
//
|
|
135
|
+
// Guarded on all four being finite, because a field that failed its grammar arrives here as
|
|
136
|
+
// NaN, and NaN would satisfy the non-finite test below and claim the gain as the cause. Its
|
|
137
|
+
// cause belongs to the field, was reported against the field, and is exactly the case the
|
|
138
|
+
// fallback's wording is true of.
|
|
139
|
+
if (
|
|
140
|
+
Number.isFinite(signal.physicalMinimum) &&
|
|
141
|
+
Number.isFinite(signal.physicalMaximum) &&
|
|
142
|
+
Number.isFinite(signal.digitalMinimum) &&
|
|
143
|
+
Number.isFinite(signal.digitalMaximum)
|
|
144
|
+
) {
|
|
145
|
+
// `buildScale`'s expression, not a simplification of it: the two must agree on which ranges
|
|
146
|
+
// are refused, and the pinned form is what decides the edge cases.
|
|
147
|
+
const bitValue =
|
|
148
|
+
(signal.physicalMaximum - signal.physicalMinimum) /
|
|
149
|
+
(signal.digitalMaximum - signal.digitalMinimum);
|
|
150
|
+
const offset = signal.physicalMaximum / bitValue - signal.digitalMaximum;
|
|
151
|
+
if (bitValue === 0 || !Number.isFinite(bitValue) || !Number.isFinite(offset)) {
|
|
152
|
+
return {
|
|
153
|
+
code: 'DEGENERATE_PHYSICAL_RANGE',
|
|
154
|
+
reason:
|
|
155
|
+
`declares the physical range ${signal.physicalMinimum}..${signal.physicalMaximum} ` +
|
|
156
|
+
`over the digital range ${signal.digitalMinimum}..${signal.digitalMaximum}, and the ` +
|
|
157
|
+
`gain those imply is not a usable float64 number (bitValue ${bitValue}, offset ` +
|
|
158
|
+
`${offset}), so every converted sample would be NaN or infinite`,
|
|
159
|
+
specReference: rangeSpec,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
128
164
|
return {
|
|
129
165
|
code: 'SCALE_UNAVAILABLE',
|
|
130
166
|
reason: 'has no usable scale, and the header recorded the reason rather than the signal',
|