edfcore 0.3.54 → 0.3.56
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 +47 -0
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +37 -1
- package/dist/stream.js.map +1 -1
- package/dist/time/window.d.ts.map +1 -1
- package/dist/time/window.js +26 -2
- package/dist/time/window.js.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +1 -1
- package/src/stream.ts +41 -1
- package/src/time/window.ts +26 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,53 @@ 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.56
|
|
10
|
+
|
|
11
|
+
- **Fixed** `trimToWindow` dropping the sample whose own start time the window was aligned to.
|
|
12
|
+
- `gridSampleStartTicks` and `sampleStartTicksOf` round a sample's start **up** to a whole tick,
|
|
13
|
+
deliberately, so that flooring it back names the same sample. `trimToWindow` selected on the
|
|
14
|
+
sample's exact rational start instead. When a boundary is not a whole tick the published start
|
|
15
|
+
is strictly later than the exact one, so the sample no longer qualified for a window beginning
|
|
16
|
+
at its own published start and the trim began at `n + 1`.
|
|
17
|
+
- 256 samples in a one-second record — the commonest EEG geometry there is — puts sample 1 at
|
|
18
|
+
39,062.5 ticks, published as 39,063. **Half of all sample indices** were affected at that rate.
|
|
19
|
+
At 128 samples per 0.29 s a one-sample-wide window aligned to a sample start came back
|
|
20
|
+
**empty**.
|
|
21
|
+
- 0.3.32 fixed this exact mismatch in `readTriggers` and wrote down the rule it settled on:
|
|
22
|
+
"`sampleAt`, `sampleStartTicksOf`, a window bound and `readTriggers` all name the same sample."
|
|
23
|
+
The window bound was the one of the four still using the other rounding.
|
|
24
|
+
- Both edges stay a bigint product of on-disk quantities — no division, no sample rate, no float
|
|
25
|
+
bound. Sample `j` is in the window when `ceil(j * D / S)` is in `[R, Rend)`, and since
|
|
26
|
+
`ceil(x) >= R` iff `x > R - 1`, that is `floorDiv((R - 1) * S, D) + 1` and
|
|
27
|
+
`floorDiv((Rend - 1) * S, D)`.
|
|
28
|
+
- Identical to the old form whenever a boundary falls on a whole tick, so **no window on a
|
|
29
|
+
power-of-ten geometry moves**, and the whole existing suite passed unchanged. A sample admitted
|
|
30
|
+
by the new rule starts at most one tick — 100 ns, below the resolution edfcore reports in —
|
|
31
|
+
before the bound, and it is exactly the sample the caller aligned to.
|
|
32
|
+
|
|
33
|
+
## 0.3.55
|
|
34
|
+
|
|
35
|
+
- **Fixed** `streamRecords` never comparing record onsets across a chunk boundary, so an
|
|
36
|
+
always-fatal `TIMELINE_NOT_MONOTONIC` was suppressed and chunks were yielded in reverse time
|
|
37
|
+
order — and whether it fired at all depended on `chunkRecords`.
|
|
38
|
+
- `readRecords` runs `assertMonotonicOnsetArray` over the onsets of the chunk it just read, so
|
|
39
|
+
every adjacent pair **inside** a chunk is checked and no pair that straddles two is.
|
|
40
|
+
`readWindow` hands a whole contiguous run to one call, so it checks all of them; splitting the
|
|
41
|
+
same run into `chunkRecords`-sized reads checked none of the seams.
|
|
42
|
+
- On an eight-record file whose only backwards pair is 3 → 4, `readWindow` threw and
|
|
43
|
+
`streamRecords` threw at `chunkRecords` 3 and 5 while returning the data at 1, 2, 4 and 256.
|
|
44
|
+
At `chunkRecords: 1` **every** pair is a seam, so nothing was checked at all and the chunks came
|
|
45
|
+
back at 0, 1, 2, 4, 3, 5, 6, 7 seconds.
|
|
46
|
+
- `chunkRecords` is documented as "the unit of I/O and of memory". A performance knob must never
|
|
47
|
+
decide whether a file is refused — the fourth time that shape has been swept out of this
|
|
48
|
+
package.
|
|
49
|
+
- A consumer that places each chunk at its own `startSeconds`, which is what the docs prescribe,
|
|
50
|
+
silently overwrote earlier trace with later samples.
|
|
51
|
+
- The seam check costs no extra read. A chunk's span is `lastOnset + recordDuration - firstOnset`,
|
|
52
|
+
so its last record's onset is `startTicks + durationTicks - recordDurationTicks`, already on the
|
|
53
|
+
same rebased axis as the next chunk's `startTicks`. It is reset per run, because `readWindow` does
|
|
54
|
+
not compare across a gap either and a streamed chunk must stay the object a read would give.
|
|
55
|
+
|
|
9
56
|
## 0.3.54
|
|
10
57
|
|
|
11
58
|
- **Fixed** `decodeStatusWord` reading the BioSemi quality flags from the wrong bits. Both
|
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.56";
|
|
113
113
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.js
CHANGED
package/dist/stream.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAe,eAAe,EAAE,MAAM,YAAY,CAAC;AAKpG;;;;;;;GAOG;AACH,wBAAuB,aAAa,CAClC,SAAS,EAAE,YAAY,EACvB,SAAS,EAAE,eAAe,EAC1B,OAAO,CAAC,EAAE,WAAW,GACpB,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,CAAC,CAgF3C"}
|
package/dist/stream.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* `readWindow` chunk would, so a consumer sees the discontinuities rather than a smooth lie.
|
|
14
14
|
*/
|
|
15
15
|
import { readRecords, resolveSignals } from './recording.js';
|
|
16
|
+
import { assertMonotonicOnsets } from './time/timeline.js';
|
|
16
17
|
import { resolveTimeWindow } from './time/window.js';
|
|
17
18
|
/** How many records to read at a time when the caller does not say. */
|
|
18
19
|
const DEFAULT_STREAM_RECORDS = 256;
|
|
@@ -38,8 +39,12 @@ export async function* streamRecords(recording, selection, options) {
|
|
|
38
39
|
// Every other selection error in the package surfaces on the spot; this one waited for data.
|
|
39
40
|
resolveSignals(recording.header, selection.signalIndices);
|
|
40
41
|
const ranges = resolveTimeWindow(recording.timeline, recording.index, selection.startSeconds, selection.durationSeconds);
|
|
42
|
+
const recordDurationTicks = recording.header.recordDurationTicks;
|
|
41
43
|
for (const run of ranges) {
|
|
42
44
|
let scanned = 0;
|
|
45
|
+
// The last record of the previous chunk of THIS run. Reset per run, because `readWindow` does
|
|
46
|
+
// not compare across a gap either and a streamed chunk must be the same object it would get.
|
|
47
|
+
let previousRecord;
|
|
43
48
|
while (scanned < run.count) {
|
|
44
49
|
const records = {
|
|
45
50
|
start: run.start + scanned,
|
|
@@ -47,7 +52,38 @@ export async function* streamRecords(recording, selection, options) {
|
|
|
47
52
|
};
|
|
48
53
|
// readRecords, not a private path: the chunk a consumer gets from streaming and the chunk
|
|
49
54
|
// it gets from reading must be the same object in every respect, including its diagnostics.
|
|
50
|
-
|
|
55
|
+
const chunk = await readRecords(recording, { signalIndices: selection.signalIndices, records }, options);
|
|
56
|
+
/*
|
|
57
|
+
* The one pair `readRecords` structurally cannot see: the SEAM between two chunks.
|
|
58
|
+
*
|
|
59
|
+
* It runs `assertMonotonicOnsetArray` over the onsets of the chunk it just read, so every
|
|
60
|
+
* adjacent pair inside a chunk is compared and no pair that straddles two is. `readWindow`
|
|
61
|
+
* hands a whole contiguous run to one call and therefore checks all of them; splitting the
|
|
62
|
+
* same run into `chunkRecords`-sized reads checked none of the seams.
|
|
63
|
+
*
|
|
64
|
+
* TIMELINE_NOT_MONOTONIC is ALWAYS fatal — `readWindow` on the identical window throws —
|
|
65
|
+
* and the streaming path returned the data instead, in reverse time order: a consumer that
|
|
66
|
+
* places each chunk at its own `startSeconds`, which is what the docs prescribe, overwrote
|
|
67
|
+
* earlier trace with later samples. Worse, whether it fired at all depended on
|
|
68
|
+
* `chunkRecords`: on one eight-record file it threw at 3 and 5 and stayed silent at 1, 2, 4
|
|
69
|
+
* and 256, and `chunkRecords` is documented as a memory knob. A performance parameter must
|
|
70
|
+
* never decide whether a file is refused (fixed in 0.3.55).
|
|
71
|
+
*
|
|
72
|
+
* No extra read: a chunk's span is `lastOnset + recordDuration - firstOnset`, so its last
|
|
73
|
+
* record's onset is `startTicks + durationTicks - recordDurationTicks`, on the same rebased
|
|
74
|
+
* axis as the next chunk's `startTicks`.
|
|
75
|
+
*/
|
|
76
|
+
if (previousRecord !== undefined) {
|
|
77
|
+
assertMonotonicOnsets(previousRecord, {
|
|
78
|
+
recordIndex: records.start,
|
|
79
|
+
onsetTicks: chunk.startTicks,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
previousRecord = {
|
|
83
|
+
recordIndex: records.start + records.count - 1,
|
|
84
|
+
onsetTicks: chunk.startTicks + chunk.durationTicks - recordDurationTicks,
|
|
85
|
+
};
|
|
86
|
+
yield chunk;
|
|
51
87
|
scanned += records.count;
|
|
52
88
|
}
|
|
53
89
|
}
|
package/dist/stream.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,uEAAuE;AACvE,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAEnC;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,aAAa,CAClC,SAAuB,EACvB,SAA0B,EAC1B,OAAqB;IAErB,MAAM,YAAY,GAAG,SAAS,CAAC,YAAY,IAAI,sBAAsB,CAAC;IACtE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,UAAU,CAClB,2EAA2E,YAAY,IAAI;YACzF,mFAAmF,CACtF,CAAC;IACJ,CAAC;IAED,+FAA+F;IAC/F,+FAA+F;IAC/F,2FAA2F;IAC3F,sFAAsF;IACtF,6FAA6F;IAC7F,6FAA6F;IAC7F,cAAc,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;IAE1D,MAAM,MAAM,GAAG,iBAAiB,CAC9B,SAAS,CAAC,QAAQ,EAClB,SAAS,CAAC,KAAK,EACf,SAAS,CAAC,YAAY,EACtB,SAAS,CAAC,eAAe,CAC1B,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,OAAO,OAAO,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAgB;gBAC3B,KAAK,EAAE,GAAG,CAAC,KAAK,GAAG,OAAO;gBAC1B,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC;aACnD,CAAC;YACF,0FAA0F;YAC1F,4FAA4F;YAC5F,MAAM,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,uEAAuE;AACvE,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAEnC;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,aAAa,CAClC,SAAuB,EACvB,SAA0B,EAC1B,OAAqB;IAErB,MAAM,YAAY,GAAG,SAAS,CAAC,YAAY,IAAI,sBAAsB,CAAC;IACtE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,UAAU,CAClB,2EAA2E,YAAY,IAAI;YACzF,mFAAmF,CACtF,CAAC;IACJ,CAAC;IAED,+FAA+F;IAC/F,+FAA+F;IAC/F,2FAA2F;IAC3F,sFAAsF;IACtF,6FAA6F;IAC7F,6FAA6F;IAC7F,cAAc,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;IAE1D,MAAM,MAAM,GAAG,iBAAiB,CAC9B,SAAS,CAAC,QAAQ,EAClB,SAAS,CAAC,KAAK,EACf,SAAS,CAAC,YAAY,EACtB,SAAS,CAAC,eAAe,CAC1B,CAAC;IAEF,MAAM,mBAAmB,GAAG,SAAS,CAAC,MAAM,CAAC,mBAAmB,CAAC;IAEjE,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,8FAA8F;QAC9F,6FAA6F;QAC7F,IAAI,cAAuE,CAAC;QAE5E,OAAO,OAAO,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAgB;gBAC3B,KAAK,EAAE,GAAG,CAAC,KAAK,GAAG,OAAO;gBAC1B,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC;aACnD,CAAC;YACF,0FAA0F;YAC1F,4FAA4F;YAC5F,MAAM,KAAK,GAAG,MAAM,WAAW,CAC7B,SAAS,EACT,EAAE,aAAa,EAAE,SAAS,CAAC,aAAa,EAAE,OAAO,EAAE,EACnD,OAAO,CACR,CAAC;YAEF;;;;;;;;;;;;;;;;;;;eAmBG;YACH,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;gBACjC,qBAAqB,CAAC,cAAc,EAAE;oBACpC,WAAW,EAAE,OAAO,CAAC,KAAK;oBAC1B,UAAU,EAAE,KAAK,CAAC,UAAU;iBAC7B,CAAC,CAAC;YACL,CAAC;YACD,cAAc,GAAG;gBACf,WAAW,EAAE,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,CAAC;gBAC9C,UAAU,EAAE,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,aAAa,GAAG,mBAAmB;aACzE,CAAC;YAEF,MAAM,KAAK,CAAC;YACZ,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC;QAC3B,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../../src/time/window.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,cAAc,EAEd,WAAW,EACX,WAAW,EACZ,MAAM,aAAa,CAAC;AAyBrB;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,WAAW,EACrB,KAAK,EAAE,cAAc,EACrB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB,SAAS,WAAW,EAAE,CA8FxB;AAwED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,cAAc,EAC3B,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB,cAAc,
|
|
1
|
+
{"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../../src/time/window.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,cAAc,EAEd,WAAW,EACX,WAAW,EACZ,MAAM,aAAa,CAAC;AAyBrB;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,WAAW,EACrB,KAAK,EAAE,cAAc,EACrB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB,SAAS,WAAW,EAAE,CA8FxB;AAwED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,cAAc,EAC3B,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB,cAAc,CA4EhB"}
|
package/dist/time/window.js
CHANGED
|
@@ -239,8 +239,32 @@ export function trimToWindow(header, chunkSignal, startSeconds, durationSeconds)
|
|
|
239
239
|
const samplesPerRecordTicks = BigInt(samplesPerRecord);
|
|
240
240
|
const relativeStartTicks = windowStartTicks - chunkStartTicks;
|
|
241
241
|
const relativeEndTicks = relativeStartTicks + windowDurationTicks;
|
|
242
|
-
|
|
243
|
-
|
|
242
|
+
/*
|
|
243
|
+
* Compared against the start tick each sample PUBLISHES, not against its exact rational start.
|
|
244
|
+
*
|
|
245
|
+
* `gridSampleStartTicks` and `sampleStartTicksOf` round a sample's start UP to a whole tick, on
|
|
246
|
+
* purpose, so that flooring it back names the same sample. A boundary need not fall on a whole
|
|
247
|
+
* tick: 256 samples in a one-second record — the commonest EEG geometry there is — puts sample 1
|
|
248
|
+
* at 39,062.5 ticks, published as 39,063. Selecting on the EXACT start then excluded that sample
|
|
249
|
+
* from a window beginning at its own published start, because 39,063 is later than 39,062.5. Half
|
|
250
|
+
* of all indices were affected at that rate; at 128 samples per 0.29 s a one-sample-wide window
|
|
251
|
+
* aligned to a sample start came back EMPTY.
|
|
252
|
+
*
|
|
253
|
+
* 0.3.32 fixed the same mismatch in `readTriggers` and recorded the rule it settled on:
|
|
254
|
+
* "`sampleAt`, `sampleStartTicksOf`, a window bound and `readTriggers` all name the same sample."
|
|
255
|
+
* The window bound was the one of the four still using the other rounding (fixed in 0.3.56).
|
|
256
|
+
*
|
|
257
|
+
* Sample j is in the window when `ceil(j * D / S)` is in `[R, Rend)`, and since
|
|
258
|
+
* `ceil(x) >= R <=> x > R - 1`, both edges stay a bigint product of on-disk quantities:
|
|
259
|
+
* first: smallest j with j*D > (R-1)*S -> floorDiv((R-1)*S, D) + 1
|
|
260
|
+
* last: largest j with j*D <= (Rend-1)*S -> floorDiv((Rend-1)*S, D)
|
|
261
|
+
* Identical to the old form whenever a boundary is a whole tick, so no window on a
|
|
262
|
+
* power-of-ten geometry moves; a sample admitted by the new rule starts at most one tick — 100
|
|
263
|
+
* ns, below the resolution edfcore reports in — before the bound, and it is precisely the sample
|
|
264
|
+
* the caller aligned to.
|
|
265
|
+
*/
|
|
266
|
+
const firstIndex = clampToInt(floorDiv((relativeStartTicks - 1n) * samplesPerRecordTicks, durationTicks) + 1n, 0, available);
|
|
267
|
+
const lastIndex = clampToInt(floorDiv((relativeEndTicks - 1n) * samplesPerRecordTicks, durationTicks), -1, available - 1);
|
|
244
268
|
const sampleCount = lastIndex < firstIndex ? 0 : lastIndex - firstIndex + 1;
|
|
245
269
|
return trimmed(chunkSignal, signal, firstIndex, sampleCount, gridSampleStart(chunkStartTicks, BigInt(firstIndex), durationTicks, samplesPerRecordTicks));
|
|
246
270
|
}
|
package/dist/time/window.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"window.js","sourceRoot":"","sources":["../../src/time/window.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"window.js","sourceRoot":"","sources":["../../src/time/window.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
package/src/stream.ts
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import { readRecords, resolveSignals } from './recording.js';
|
|
17
|
+
import { assertMonotonicOnsets } from './time/timeline.js';
|
|
17
18
|
import { resolveTimeWindow } from './time/window.js';
|
|
18
19
|
import type { EdfChunk, EdfRecording, ReadOptions, RecordRange, StreamSelection } from './types.js';
|
|
19
20
|
|
|
@@ -56,8 +57,14 @@ export async function* streamRecords(
|
|
|
56
57
|
selection.durationSeconds,
|
|
57
58
|
);
|
|
58
59
|
|
|
60
|
+
const recordDurationTicks = recording.header.recordDurationTicks;
|
|
61
|
+
|
|
59
62
|
for (const run of ranges) {
|
|
60
63
|
let scanned = 0;
|
|
64
|
+
// The last record of the previous chunk of THIS run. Reset per run, because `readWindow` does
|
|
65
|
+
// not compare across a gap either and a streamed chunk must be the same object it would get.
|
|
66
|
+
let previousRecord: { recordIndex: number; onsetTicks: bigint } | undefined;
|
|
67
|
+
|
|
61
68
|
while (scanned < run.count) {
|
|
62
69
|
const records: RecordRange = {
|
|
63
70
|
start: run.start + scanned,
|
|
@@ -65,11 +72,44 @@ export async function* streamRecords(
|
|
|
65
72
|
};
|
|
66
73
|
// readRecords, not a private path: the chunk a consumer gets from streaming and the chunk
|
|
67
74
|
// it gets from reading must be the same object in every respect, including its diagnostics.
|
|
68
|
-
|
|
75
|
+
const chunk = await readRecords(
|
|
69
76
|
recording,
|
|
70
77
|
{ signalIndices: selection.signalIndices, records },
|
|
71
78
|
options,
|
|
72
79
|
);
|
|
80
|
+
|
|
81
|
+
/*
|
|
82
|
+
* The one pair `readRecords` structurally cannot see: the SEAM between two chunks.
|
|
83
|
+
*
|
|
84
|
+
* It runs `assertMonotonicOnsetArray` over the onsets of the chunk it just read, so every
|
|
85
|
+
* adjacent pair inside a chunk is compared and no pair that straddles two is. `readWindow`
|
|
86
|
+
* hands a whole contiguous run to one call and therefore checks all of them; splitting the
|
|
87
|
+
* same run into `chunkRecords`-sized reads checked none of the seams.
|
|
88
|
+
*
|
|
89
|
+
* TIMELINE_NOT_MONOTONIC is ALWAYS fatal — `readWindow` on the identical window throws —
|
|
90
|
+
* and the streaming path returned the data instead, in reverse time order: a consumer that
|
|
91
|
+
* places each chunk at its own `startSeconds`, which is what the docs prescribe, overwrote
|
|
92
|
+
* earlier trace with later samples. Worse, whether it fired at all depended on
|
|
93
|
+
* `chunkRecords`: on one eight-record file it threw at 3 and 5 and stayed silent at 1, 2, 4
|
|
94
|
+
* and 256, and `chunkRecords` is documented as a memory knob. A performance parameter must
|
|
95
|
+
* never decide whether a file is refused (fixed in 0.3.55).
|
|
96
|
+
*
|
|
97
|
+
* No extra read: a chunk's span is `lastOnset + recordDuration - firstOnset`, so its last
|
|
98
|
+
* record's onset is `startTicks + durationTicks - recordDurationTicks`, on the same rebased
|
|
99
|
+
* axis as the next chunk's `startTicks`.
|
|
100
|
+
*/
|
|
101
|
+
if (previousRecord !== undefined) {
|
|
102
|
+
assertMonotonicOnsets(previousRecord, {
|
|
103
|
+
recordIndex: records.start,
|
|
104
|
+
onsetTicks: chunk.startTicks,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
previousRecord = {
|
|
108
|
+
recordIndex: records.start + records.count - 1,
|
|
109
|
+
onsetTicks: chunk.startTicks + chunk.durationTicks - recordDurationTicks,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
yield chunk;
|
|
73
113
|
scanned += records.count;
|
|
74
114
|
}
|
|
75
115
|
}
|
package/src/time/window.ts
CHANGED
|
@@ -293,13 +293,37 @@ export function trimToWindow(
|
|
|
293
293
|
const relativeStartTicks = windowStartTicks - chunkStartTicks;
|
|
294
294
|
const relativeEndTicks = relativeStartTicks + windowDurationTicks;
|
|
295
295
|
|
|
296
|
+
/*
|
|
297
|
+
* Compared against the start tick each sample PUBLISHES, not against its exact rational start.
|
|
298
|
+
*
|
|
299
|
+
* `gridSampleStartTicks` and `sampleStartTicksOf` round a sample's start UP to a whole tick, on
|
|
300
|
+
* purpose, so that flooring it back names the same sample. A boundary need not fall on a whole
|
|
301
|
+
* tick: 256 samples in a one-second record — the commonest EEG geometry there is — puts sample 1
|
|
302
|
+
* at 39,062.5 ticks, published as 39,063. Selecting on the EXACT start then excluded that sample
|
|
303
|
+
* from a window beginning at its own published start, because 39,063 is later than 39,062.5. Half
|
|
304
|
+
* of all indices were affected at that rate; at 128 samples per 0.29 s a one-sample-wide window
|
|
305
|
+
* aligned to a sample start came back EMPTY.
|
|
306
|
+
*
|
|
307
|
+
* 0.3.32 fixed the same mismatch in `readTriggers` and recorded the rule it settled on:
|
|
308
|
+
* "`sampleAt`, `sampleStartTicksOf`, a window bound and `readTriggers` all name the same sample."
|
|
309
|
+
* The window bound was the one of the four still using the other rounding (fixed in 0.3.56).
|
|
310
|
+
*
|
|
311
|
+
* Sample j is in the window when `ceil(j * D / S)` is in `[R, Rend)`, and since
|
|
312
|
+
* `ceil(x) >= R <=> x > R - 1`, both edges stay a bigint product of on-disk quantities:
|
|
313
|
+
* first: smallest j with j*D > (R-1)*S -> floorDiv((R-1)*S, D) + 1
|
|
314
|
+
* last: largest j with j*D <= (Rend-1)*S -> floorDiv((Rend-1)*S, D)
|
|
315
|
+
* Identical to the old form whenever a boundary is a whole tick, so no window on a
|
|
316
|
+
* power-of-ten geometry moves; a sample admitted by the new rule starts at most one tick — 100
|
|
317
|
+
* ns, below the resolution edfcore reports in — before the bound, and it is precisely the sample
|
|
318
|
+
* the caller aligned to.
|
|
319
|
+
*/
|
|
296
320
|
const firstIndex = clampToInt(
|
|
297
|
-
|
|
321
|
+
floorDiv((relativeStartTicks - 1n) * samplesPerRecordTicks, durationTicks) + 1n,
|
|
298
322
|
0,
|
|
299
323
|
available,
|
|
300
324
|
);
|
|
301
325
|
const lastIndex = clampToInt(
|
|
302
|
-
|
|
326
|
+
floorDiv((relativeEndTicks - 1n) * samplesPerRecordTicks, durationTicks),
|
|
303
327
|
-1,
|
|
304
328
|
available - 1,
|
|
305
329
|
);
|