edfcore 0.3.133 → 0.3.135
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 +14 -0
- package/README.md +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/sample-locate.d.ts.map +1 -1
- package/dist/sample-locate.js +13 -7
- package/dist/sample-locate.js.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +1 -1
- package/src/sample-locate.ts +13 -7
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,20 @@ 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.135
|
|
10
|
+
|
|
11
|
+
- **Fixed** the README's claims table saying the pyEDFlib sample-scan parity covers "all five
|
|
12
|
+
files". `corpus-parity.test.ts` runs that sweep over `CASES`, which lists seven — the two Sleep-EDF
|
|
13
|
+
files, three teuniz.net generators, `chb01_01.edf` and `calib.rec`.
|
|
14
|
+
|
|
15
|
+
## 0.3.134
|
|
16
|
+
|
|
17
|
+
- **Completed** 0.3.133, which fixed only the three messages outside `resolveSignal`. That helper
|
|
18
|
+
is shared by `sampleAt` and `sampleStartTicksOf` and took a `caller` string, so its four messages
|
|
19
|
+
still said `sampleStartTicksOf():` when reached through `sampleStartSecondsOf`. The parameter is
|
|
20
|
+
gone and the messages name no function, which is what `envelope.ts` already does for its own
|
|
21
|
+
shared helpers.
|
|
22
|
+
|
|
9
23
|
## 0.3.133
|
|
10
24
|
|
|
11
25
|
- **Removed** the hard-coded `sampleStartTicksOf():` prefix from that function's three messages, the
|
package/README.md
CHANGED
|
@@ -326,7 +326,7 @@ What else those files establish, which synthetic fixtures cannot:
|
|
|
326
326
|
| Streaming equals reading | 42 streamed chunks concatenated and compared sample by sample |
|
|
327
327
|
| **Random access is real** | a 30-second window twelve hours in costs **under 64 KB** over HTTP |
|
|
328
328
|
| `validate` is usable as a CI gate | exits 0 on a real recording from a real sleep lab |
|
|
329
|
-
| The sample scan sees what pyEDFlib sees | whole-signal digital extremes, all
|
|
329
|
+
| The sample scan sees what pyEDFlib sees | whole-signal digital extremes, all seven files |
|
|
330
330
|
|
|
331
331
|
Those tests need the corpus and skip without it. `coverage.test.ts` always runs and says which
|
|
332
332
|
state you are in, because a skipped test and a passing one look identical in a summary line:
|
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.135";
|
|
113
113
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sample-locate.d.ts","sourceRoot":"","sources":["../src/sample-locate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAyB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"sample-locate.d.ts","sourceRoot":"","sources":["../src/sample-locate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAyB,MAAM,YAAY,CAAC;AA2FzF;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CACtB,SAAS,EAAE,YAAY,EACvB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,iBAAiB,GAAG,SAAS,CA4D/B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,YAAY,EACvB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,MAAM,CAoCR;AAED,wFAAwF;AACxF,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,YAAY,EACvB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,MAAM,CAER"}
|
package/dist/sample-locate.js
CHANGED
|
@@ -28,10 +28,16 @@
|
|
|
28
28
|
import { EdfChannelNotFoundError } from './errors.js';
|
|
29
29
|
import { segmentAt } from './record-index.js';
|
|
30
30
|
import { floorDiv, secondsToTicks, ticksToSeconds } from './tal/ticks.js';
|
|
31
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Shared by `sampleAt` and `sampleStartTicksOf`, so the messages name NO function — the rule
|
|
33
|
+
* `envelope.ts` states for its own shared helpers. `sampleStartSecondsOf` is a one-line delegation
|
|
34
|
+
* to `sampleStartTicksOf`, so a hard-coded name here reached a caller who never wrote it
|
|
35
|
+
* (completed in 0.3.134; 0.3.133 fixed only the three messages outside this function).
|
|
36
|
+
*/
|
|
37
|
+
function resolveSignal(recording, signalIndex) {
|
|
32
38
|
const signal = recording.header.signals[signalIndex];
|
|
33
39
|
if (signal === undefined) {
|
|
34
|
-
throw new EdfChannelNotFoundError(
|
|
40
|
+
throw new EdfChannelNotFoundError(`signalIndex ${signalIndex} is outside the ` +
|
|
35
41
|
`${recording.header.signals.length} signals this file declares. Next: pass an index from ` +
|
|
36
42
|
'header.dataSignalIndices, or resolve one with getSignal(header, label).', {
|
|
37
43
|
selector: signalIndex,
|
|
@@ -39,17 +45,17 @@ function resolveSignal(recording, signalIndex, caller) {
|
|
|
39
45
|
});
|
|
40
46
|
}
|
|
41
47
|
if (signal.kind === 'annotations') {
|
|
42
|
-
throw new RangeError(
|
|
48
|
+
throw new RangeError(`signal ${signalIndex} (${JSON.stringify(signal.label)}) is an annotations ` +
|
|
43
49
|
'channel, whose region holds TAL text rather than samples, so it has no sample grid. ' +
|
|
44
50
|
'Next: use onsetTicksFromFirstRecord on the annotations themselves.');
|
|
45
51
|
}
|
|
46
52
|
if (signal.samplesPerRecord <= 0) {
|
|
47
|
-
throw new RangeError(
|
|
53
|
+
throw new RangeError(`signal ${signalIndex} (${JSON.stringify(signal.label)}) declares ` +
|
|
48
54
|
`${signal.samplesPerRecord} samples per record, so it has no sample grid to index. ` +
|
|
49
55
|
'Next: check header.diagnostics for ZERO_SAMPLES_PER_RECORD.');
|
|
50
56
|
}
|
|
51
57
|
if (recording.header.recordDurationTicks <= 0n) {
|
|
52
|
-
throw new RangeError(
|
|
58
|
+
throw new RangeError('this file declares a record duration of zero, so records do not advance in ' +
|
|
53
59
|
'time and no elapsed time maps to a sample. This is legal EDF and a scoring file relies ' +
|
|
54
60
|
'on it. Next: index by record with readRecords().');
|
|
55
61
|
}
|
|
@@ -110,7 +116,7 @@ function probedIndexNeedsScan(recording) {
|
|
|
110
116
|
* running when that time arrives.
|
|
111
117
|
*/
|
|
112
118
|
export function sampleAt(recording, signalIndex, seconds) {
|
|
113
|
-
const signal = resolveSignal(recording, signalIndex
|
|
119
|
+
const signal = resolveSignal(recording, signalIndex);
|
|
114
120
|
if (!Number.isFinite(seconds)) {
|
|
115
121
|
throw new RangeError(`sampleAt(): seconds must be a finite number, received ${seconds}.`);
|
|
116
122
|
}
|
|
@@ -178,7 +184,7 @@ export function sampleAt(recording, signalIndex, seconds) {
|
|
|
178
184
|
* previous sample.
|
|
179
185
|
*/
|
|
180
186
|
export function sampleStartTicksOf(recording, signalIndex, sampleIndex) {
|
|
181
|
-
const signal = resolveSignal(recording, signalIndex
|
|
187
|
+
const signal = resolveSignal(recording, signalIndex);
|
|
182
188
|
if (!Number.isSafeInteger(sampleIndex)) {
|
|
183
189
|
throw new RangeError(`sampleIndex must be a whole number, received ${sampleIndex}.`);
|
|
184
190
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sample-locate.js","sourceRoot":"","sources":["../src/sample-locate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAG1E,SAAS,aAAa,CAAC,SAAuB,EAAE,WAAmB
|
|
1
|
+
{"version":3,"file":"sample-locate.js","sourceRoot":"","sources":["../src/sample-locate.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
package/src/sample-locate.ts
CHANGED
|
@@ -31,11 +31,17 @@ import { segmentAt } from './record-index.js';
|
|
|
31
31
|
import { floorDiv, secondsToTicks, ticksToSeconds } from './tal/ticks.js';
|
|
32
32
|
import type { EdfRecording, EdfSampleLocation, EdfSegment, EdfSignal } from './types.js';
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Shared by `sampleAt` and `sampleStartTicksOf`, so the messages name NO function — the rule
|
|
36
|
+
* `envelope.ts` states for its own shared helpers. `sampleStartSecondsOf` is a one-line delegation
|
|
37
|
+
* to `sampleStartTicksOf`, so a hard-coded name here reached a caller who never wrote it
|
|
38
|
+
* (completed in 0.3.134; 0.3.133 fixed only the three messages outside this function).
|
|
39
|
+
*/
|
|
40
|
+
function resolveSignal(recording: EdfRecording, signalIndex: number): EdfSignal {
|
|
35
41
|
const signal = recording.header.signals[signalIndex];
|
|
36
42
|
if (signal === undefined) {
|
|
37
43
|
throw new EdfChannelNotFoundError(
|
|
38
|
-
|
|
44
|
+
`signalIndex ${signalIndex} is outside the ` +
|
|
39
45
|
`${recording.header.signals.length} signals this file declares. Next: pass an index from ` +
|
|
40
46
|
'header.dataSignalIndices, or resolve one with getSignal(header, label).',
|
|
41
47
|
{
|
|
@@ -46,21 +52,21 @@ function resolveSignal(recording: EdfRecording, signalIndex: number, caller: str
|
|
|
46
52
|
}
|
|
47
53
|
if (signal.kind === 'annotations') {
|
|
48
54
|
throw new RangeError(
|
|
49
|
-
|
|
55
|
+
`signal ${signalIndex} (${JSON.stringify(signal.label)}) is an annotations ` +
|
|
50
56
|
'channel, whose region holds TAL text rather than samples, so it has no sample grid. ' +
|
|
51
57
|
'Next: use onsetTicksFromFirstRecord on the annotations themselves.',
|
|
52
58
|
);
|
|
53
59
|
}
|
|
54
60
|
if (signal.samplesPerRecord <= 0) {
|
|
55
61
|
throw new RangeError(
|
|
56
|
-
|
|
62
|
+
`signal ${signalIndex} (${JSON.stringify(signal.label)}) declares ` +
|
|
57
63
|
`${signal.samplesPerRecord} samples per record, so it has no sample grid to index. ` +
|
|
58
64
|
'Next: check header.diagnostics for ZERO_SAMPLES_PER_RECORD.',
|
|
59
65
|
);
|
|
60
66
|
}
|
|
61
67
|
if (recording.header.recordDurationTicks <= 0n) {
|
|
62
68
|
throw new RangeError(
|
|
63
|
-
|
|
69
|
+
'this file declares a record duration of zero, so records do not advance in ' +
|
|
64
70
|
'time and no elapsed time maps to a sample. This is legal EDF and a scoring file relies ' +
|
|
65
71
|
'on it. Next: index by record with readRecords().',
|
|
66
72
|
);
|
|
@@ -131,7 +137,7 @@ export function sampleAt(
|
|
|
131
137
|
signalIndex: number,
|
|
132
138
|
seconds: number,
|
|
133
139
|
): EdfSampleLocation | undefined {
|
|
134
|
-
const signal = resolveSignal(recording, signalIndex
|
|
140
|
+
const signal = resolveSignal(recording, signalIndex);
|
|
135
141
|
if (!Number.isFinite(seconds)) {
|
|
136
142
|
throw new RangeError(`sampleAt(): seconds must be a finite number, received ${seconds}.`);
|
|
137
143
|
}
|
|
@@ -209,7 +215,7 @@ export function sampleStartTicksOf(
|
|
|
209
215
|
signalIndex: number,
|
|
210
216
|
sampleIndex: number,
|
|
211
217
|
): bigint {
|
|
212
|
-
const signal = resolveSignal(recording, signalIndex
|
|
218
|
+
const signal = resolveSignal(recording, signalIndex);
|
|
213
219
|
if (!Number.isSafeInteger(sampleIndex)) {
|
|
214
220
|
throw new RangeError(`sampleIndex must be a whole number, received ${sampleIndex}.`);
|
|
215
221
|
}
|