edf2csv 0.4.65 → 0.4.67

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.
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/convert/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/convert/run.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Executing a conversion.\n *\n * Everything is written in a single pass over the data records. All rate groups are\n * open at once and fed from the same batch of bytes, so a file is read once no\n * matter how many output tables it produces, and memory stays flat.\n */\n\nimport { createWriteStream, fstatSync } from 'node:fs';\nimport { mkdir, readdir, stat, writeFile } from 'node:fs/promises';\nimport { createHash } from 'node:crypto';\nimport { createReadStream } from 'node:fs';\nimport { finished, pipeline } from 'node:stream/promises';\nimport type { Writable } from 'node:stream';\nimport { createGzip, gzipSync } from 'node:zlib';\nimport path from 'node:path';\n\nimport { EdfFile } from '../edf/reader.js';\nimport { describeFormat, formatRates, formatWallClock } from '../edf/header.js';\nimport type { Diagnostic } from '../edf/errors.js';\nimport { EdfError } from '../edf/errors.js';\nimport type { Annotation } from '../edf/annotations.js';\nimport { BufferedLineWriter, csvRow } from '../format/csv.js';\nimport { listed } from '../format/list.js';\nimport {\n fixed,\n makeSampleFormatter,\n makeTimeFormatter,\n newOffsetBudget,\n} from '../format/number.js';\nimport type { SampleFormatter } from '../format/number.js';\nimport { buildPlan, withoutFileRateWarning } from './plan.js';\nimport type { ConversionPlan, PlanOptions, RateGroup } from './plan.js';\nimport { deriveRecordStarts } from './timing.js';\nimport { sampleTimeIsInRange, toleranceFor } from './time-range.js';\nimport { VERSION as TOOL_VERSION } from '../version.js';\n\nexport { TOOL_VERSION };\n\nexport type ConversionErrorCode =\n | 'OUTPUT_EXISTS'\n | 'OUTPUT_UNWRITABLE'\n | 'INPUT_OUTPUT_COLLISION'\n | 'INPUT_UNREADABLE'\n | 'UNSUPPORTED_REQUEST'\n | 'CALLBACK_FAILED'\n | 'WRITE_FAILED';\n\n/**\n * Codes that mean the command cannot be carried out as written, rather than that something\n * about the file or the destination went wrong.\n *\n * The distinction is the one the exit codes draw: 1 is \"the file or the destination is the\n * problem\", 2 is \"the command line is the problem\". A caller with a `--stdout` conflict is\n * being told to change the flags — the hints say exactly that — so filing it under 1 sent\n * scripts looking at the disk. Exit 2 already covers checks that need the header first,\n * such as a `--channels` term matching nothing.\n */\nexport const USAGE_ERROR_CODES: ReadonlySet<ConversionErrorCode> = new Set(['UNSUPPORTED_REQUEST']);\n\nexport class ConversionError extends Error {\n readonly code: ConversionErrorCode;\n readonly hint: string | undefined;\n constructor(code: ConversionErrorCode, message: string, hint?: string, options?: ErrorOptions) {\n super(message, options);\n this.name = 'ConversionError';\n this.code = code;\n this.hint = hint;\n }\n}\n\nexport interface ConvertOptions extends PlanOptions {\n /** Destination directory. Defaults to the input file's name without its extension. */\n outputDir?: string | undefined;\n /** Overwrite an existing output directory. */\n force?: boolean | undefined;\n /** Record a SHA-256 of the input in metadata.json. Costs one extra read of the file. */\n checksum?: boolean | undefined;\n /**\n * Write the signal CSV to stdout instead of to a directory.\n *\n * Only valid when the conversion produces exactly one signal file: a mixed-rate\n * recording becomes several tables, and merging them into one stream would mean\n * inventing the samples this tool exists not to invent. No sidecar files are written.\n */\n toStdout?: boolean | undefined;\n onProgress?: ((progress: ConversionProgress) => void) | undefined;\n}\n\nexport interface ConversionProgress {\n recordsDone: number;\n recordsTotal: number;\n bytesWritten: number;\n}\n\nexport interface WrittenFile {\n name: string;\n rows: number;\n}\n\nexport interface ConvertResult {\n outputDir: string;\n files: WrittenFile[];\n annotationCount: number;\n diagnostics: Diagnostic[];\n plan: ConversionPlan;\n file: EdfFile;\n elapsedMs: number;\n}\n\ninterface OpenGroup {\n group: RateGroup;\n writer: BufferedLineWriter;\n formatters: SampleFormatter[];\n formatTime: (recordStart: number, sample: number) => string;\n rows: number;\n /** Resolves once a compressed stream's bytes have reached the file behind it. */\n settled: Promise<void>;\n}\n\nexport async function convert(inputPath: string, options: ConvertOptions = {}): Promise<ConvertResult> {\n const startedAt = Date.now();\n const file = await EdfFile.open(inputPath);\n\n try {\n /*\n Hashed before a record is read, and only published if the file held still.\n\n A checksum taken afterwards cannot be trusted whichever descriptor it goes through. A\n file overwritten in place keeps its inode, so the open handle sees the new bytes too,\n and the old ones are simply gone — there is nowhere left to read what was converted.\n Taking it first at least means the hash describes the file the header was read from.\n\n What makes it a guarantee rather than a hope is the check at the end: if size or\n modification time moved at any point, the hash is dropped and the run says why. So\n `sha256` present means the file demonstrably did not change while it was read, and a\n recording still being written gets a null and a warning instead of a plausible hash of\n the wrong bytes. (A change reverted within the same modification timestamp would slip\n through; nothing short of copying the input first can close that.)\n */\n const checksumAtOpen = options.checksum === true ? await file.sha256() : null;\n\n // One pass over the annotation channel supplies everything annotation-related:\n // where each record sits in time, and the full event list. It reads the whole\n // file even when a window was requested, because an annotation inside the window\n // may be stored in a record outside it.\n const annotationData =\n file.annotationSignals.length > 0\n ? await file.readAnnotations()\n : { annotations: [] as Annotation[], recordStarts: [] as (number | null)[], malformed: 0 };\n\n const timing = deriveRecordStarts(file, annotationData);\n\n const plan = buildPlan(\n {\n signals: file.header.signals,\n recordDuration: file.header.recordDuration,\n recordCount: file.recordCount,\n hasAnnotationChannel: file.annotationSignals.length > 0,\n recordStarts: timing.starts,\n },\n options,\n );\n plan.diagnostics.push(...timing.diagnostics);\n\n if (options.toStdout === true) {\n if (!plan.writeSignals) {\n throw new ConversionError(\n 'UNSUPPORTED_REQUEST',\n '--stdout has no signal data to write because --annotations-only was given.',\n 'Drop one of the two flags.',\n );\n }\n if (plan.groups.length !== 1) {\n throw new ConversionError(\n 'UNSUPPORTED_REQUEST',\n // Naming the rates is the point: the hint says to narrow the selection, and this\n // is what there is to narrow it to. The parenthetical used to repeat the count\n // that had just been given — \"produces 3 (its channels use 3 different sampling\n // rates)\" — which told nobody anything they could act on.\n `--stdout needs exactly one table, but this recording produces ${plan.groups.length}, ` +\n `one for each sampling rate its channels use ` +\n `(${listed(formatRates(plan.groups.map((g) => g.rate)).map((r) => `${r} Hz`))}).`,\n 'Narrow it to one rate with --channels, or convert to a directory instead.',\n );\n }\n const written = await writeSignalFiles(file, plan, null, timing.starts, options);\n if (rowsIn(written) === 0) plan.diagnostics.push(emptyWindow(plan.range, file.recordCount));\n if (await file.changedSinceOpen()) plan.diagnostics.push(inputChanged(false));\n return {\n outputDir: '-',\n files: written,\n annotationCount: 0,\n diagnostics: [...withoutFileRateWarning(file.diagnostics), ...plan.diagnostics],\n plan,\n file,\n elapsedMs: Date.now() - startedAt,\n };\n }\n\n const outputDir = options.outputDir ?? defaultOutputDir(inputPath);\n await assertInputDoesNotOverlapOutputs(inputPath, outputDir, file, plan, options);\n await prepareOutputDir(outputDir, options.force === true);\n\n const written: WrittenFile[] = [];\n\n if (plan.writeSignals && plan.groups.length > 0) {\n const signals = await writeSignalFiles(file, plan, outputDir, timing.starts, options);\n written.push(...signals);\n if (rowsIn(signals) === 0) plan.diagnostics.push(emptyWindow(plan.range, file.recordCount));\n } else if (plan.writeSignals) {\n /*\n Asked for signal data and given none to write.\n\n Every channel selected carries zero samples per record, so there is no table to make\n — `edf2csv rec.edf --channels unused` writes channels.csv and metadata.json and no\n signals.csv at all. The NO_SAMPLES warning explains the channel; nothing explained the\n missing file, and the documentation says signals.csv is written unless\n --annotations-only was passed. Someone looking for it should be told where it went.\n */\n plan.diagnostics.push({\n code: 'NO_SAMPLES',\n severity: 'warning',\n message:\n 'No signal file was written: every channel selected carries zero samples per data ' +\n 'record, so there is nothing to put in one.',\n hint:\n 'channels.csv still describes them. Run with --info to see which channels do carry ' +\n 'samples.',\n });\n }\n\n if (options.annotationsOnly === true && file.annotationSignals.length === 0) {\n plan.diagnostics.push({\n code: 'NO_ANNOTATIONS',\n severity: 'warning',\n message:\n '--annotations-only was requested but this recording has no annotation channel, ' +\n 'so there are no events to export.',\n hint: 'Plain EDF files carry no annotations. Convert without --annotations-only to get the signals.',\n });\n }\n\n let annotationsWritten = 0;\n if (file.annotationSignals.length > 0) {\n const result = await writeAnnotationsCsv(\n outputDir,\n annotationData.annotations,\n requestedAnnotationWindow(options, plan.range.recordingStartSeconds),\n options.gzip === true,\n );\n written.push(result);\n annotationsWritten = result.rows;\n }\n\n written.push(await writeChannelsCsv(outputDir, file, plan, options.gzip === true));\n\n /*\n The file moved under the conversion. Said out loud, because nothing else shows it.\n\n The CSVs are still correct for the records that were read, and metadata.json still\n describes the file as it was opened — so the record is consistent with the output\n whatever happens here. What stops being true is that the checksum describes the bytes\n that were converted, since an in-place overwrite leaves nowhere to read them from. It\n is dropped rather than guessed at.\n */\n const changed = await file.changedSinceOpen();\n if (changed) plan.diagnostics.push(inputChanged(options.checksum === true));\n\n await writeMetadata(\n outputDir,\n inputPath,\n file,\n plan,\n written,\n annotationsWritten,\n changed ? null : checksumAtOpen,\n );\n\n const stale = await findStaleOutput(outputDir, written);\n\n return {\n outputDir,\n files: written,\n annotationCount: annotationsWritten,\n diagnostics: [...withoutFileRateWarning(file.diagnostics), ...plan.diagnostics, ...stale],\n plan,\n file,\n elapsedMs: Date.now() - startedAt,\n };\n } finally {\n await file.close();\n }\n}\n\n/*\n Files this tool produces, used to spot leftovers from an earlier conversion.\n\n The rate part has to allow every shape a filename can now take, not just the plain ones:\n\n signals_256hz.csv an integer rate\n signals_12_5hz.csv a fractional rate, decimal point written as an underscore\n signals_1_000e-7hz.csv a rate small enough to need exponent form (0.2.2)\n signals_256hz.csv.gz any of the above, compressed (0.3.0)\n signals_0hz_2.csv a second group whose rate slug collided (0.2.1)\n\n The previous `[\\w.]+hz` matched neither of the last two — `-` and `+` are not word\n characters, and the collision suffix falls after the `hz`. Both were introduced by\n recent changes and both silently stopped being recognised as this tool's own output, so\n leftovers of exactly those kinds went unreported: the one situation the warning exists\n for. Requiring a digit after the underscore keeps a user's own `signals_notes.csv` out.\n*/\nconst OUTPUT_PATTERN =\n /^(signals(_\\d[\\w.+-]*hz(_\\d+)?)?\\.csv(\\.gz)?|annotations\\.csv(\\.gz)?|channels\\.csv(\\.gz)?|metadata\\.json)$/u;\n\n/**\n * Detect output from a previous run that this one did not replace.\n *\n * `--force` overwrites files but does not empty the directory, so converting a\n * mixed-rate recording and then a single-rate one into the same place leaves\n * `signals_256hz.csv` sitting next to a fresh `signals.csv`. Both look current.\n * Nothing is deleted here — the user is told, and decides.\n */\nasync function findStaleOutput(\n outputDir: string,\n written: readonly WrittenFile[],\n): Promise<Diagnostic[]> {\n const entries = await readdir(outputDir).catch(() => null);\n if (!entries) return [];\n\n // metadata.json is rewritten on every run but is not part of the reported file list.\n const fresh = new Set([...written.map((f) => f.name), 'metadata.json']);\n const stale = entries.filter((name) => OUTPUT_PATTERN.test(name) && !fresh.has(name)).sort();\n if (stale.length === 0) return [];\n\n return [\n {\n code: 'STALE_OUTPUT',\n severity: 'warning',\n message:\n `${stale.join(', ')} ${stale.length === 1 ? 'is' : 'are'} left over from an earlier ` +\n `conversion into this directory and ${stale.length === 1 ? 'was' : 'were'} not rewritten.`,\n hint: 'Delete them, or convert into a fresh directory, so the two runs do not get mixed up.',\n },\n ];\n}\n\nexport function defaultOutputDir(inputPath: string): string {\n const base = path.basename(inputPath, path.extname(inputPath));\n return path.join(path.dirname(inputPath), `${base}_csv`);\n}\n\n/** Never let an output target resolve to the recording being read, even with --force. */\nasync function assertInputDoesNotOverlapOutputs(\n inputPath: string,\n outputDir: string,\n file: EdfFile,\n plan: ConversionPlan,\n options: ConvertOptions,\n): Promise<void> {\n /*\n The names this run will actually write, compressed ones included.\n\n The rate files come from the plan and already carry `.csv.gz` under --gzip; the sidecars\n were spelled out here and did not. So a compressed run checked two names it would never\n write and missed the two it would: a recording sitting at <outdir>/channels.csv.gz was\n overwritten by its own conversion, with --force, reported as a success. The same file\n named signals.csv.gz was refused, which is what gives the oversight away.\n */\n const suffix = options.gzip === true ? '.csv.gz' : '.csv';\n const names = new Set(plan.groups.map((group) => group.fileName));\n if (file.annotationSignals.length > 0) names.add(`annotations${suffix}`);\n names.add(`channels${suffix}`);\n names.add('metadata.json');\n\n const inputResolved = path.resolve(inputPath);\n const inputInfo = await stat(inputPath);\n\n for (const name of names) {\n const target = path.join(outputDir, name);\n const targetResolved = path.resolve(target);\n const targetInfo = await stat(target).catch(() => null);\n const samePath = targetResolved === inputResolved;\n const sameFile =\n targetInfo !== null && targetInfo.dev === inputInfo.dev && targetInfo.ino === inputInfo.ino;\n if (!samePath && !sameFile) continue;\n\n throw new ConversionError(\n 'INPUT_OUTPUT_COLLISION',\n `Output file \"${target}\" is the same file as the input recording.`,\n 'Choose a separate directory with --out. The input was not modified.',\n );\n }\n}\n\nasync function prepareOutputDir(dir: string, force: boolean): Promise<void> {\n /*\n Claim the directory with a single atomic mkdir rather than asking whether it exists\n and then creating it.\n\n Checking first left a window between the two: two conversions started together both\n saw \"not there\", both proceeded, and both opened write streams on the same signals.csv.\n Neither reported anything — both exited 0, having half-written one file between them.\n A non-recursive mkdir cannot do that. Exactly one caller creates the directory; every\n other one gets EEXIST from the filesystem and takes the already-exists path below.\n\n Parents are still created recursively, since --out ./a/b/c should work. Only the final\n component is the claim.\n */\n const parent = path.dirname(dir);\n if (parent && parent !== dir) {\n try {\n await mkdir(parent, { recursive: true });\n } catch (cause: unknown) {\n // A parent that is a regular file surfaces as EEXIST naming the parent, which reads\n // as though the destination already exists rather than as \"you cannot put a\n // directory inside a file\". Name the real obstacle instead of the errno.\n const info = await stat(parent).catch(() => null);\n if (info && !info.isDirectory()) {\n throw new ConversionError(\n 'OUTPUT_UNWRITABLE',\n `Cannot create \"${dir}\": \"${parent}\" is a file, not a directory.`,\n 'Choose a destination whose parent directories are directories, with --out.',\n );\n }\n throw new ConversionError(\n 'OUTPUT_UNWRITABLE',\n `Cannot create \"${dir}\": ${describeFsError(cause)}.`,\n 'Check the path exists and that you have permission to write there.',\n );\n }\n }\n\n let claimed = true;\n try {\n await mkdir(dir);\n } catch (cause: unknown) {\n if ((cause as NodeJS.ErrnoException).code !== 'EEXIST') {\n throw new ConversionError(\n 'OUTPUT_UNWRITABLE',\n `Cannot create \"${dir}\": ${describeFsError(cause)}.`,\n 'Check the path exists and that you have permission to write there.',\n );\n }\n claimed = false;\n }\n\n if (!claimed) {\n const existing = await stat(dir).catch(() => null);\n\n // --force means \"replace my previous output\", not \"write output files into\n // whatever this happens to be\". Pointing it at a regular file needs saying so.\n if (existing && !existing.isDirectory()) {\n throw new ConversionError(\n 'OUTPUT_UNWRITABLE',\n `\"${dir}\" is a file, but the converted data needs a directory.`,\n 'Choose a directory with --out.',\n );\n }\n if (!force) {\n throw new ConversionError(\n 'OUTPUT_EXISTS',\n `\"${dir}\" already exists.`,\n 'Pass --force to overwrite it, or --out to choose a different directory.',\n );\n }\n }\n}\n\n/** Turn a Node filesystem error into something a person can act on. */\nfunction describeFsError(cause: unknown): string {\n const code = (cause as NodeJS.ErrnoException | undefined)?.code;\n if (code === 'EACCES' || code === 'EPERM') return 'permission denied';\n if (code === 'ENOSPC') return 'the disk is full';\n if (code === 'ENOTDIR') return 'part of the path is a file, not a directory';\n if (code === 'EROFS') return 'the filesystem is read-only';\n if (code === 'ENAMETOOLONG') return 'the path is too long';\n return cause instanceof Error ? cause.message : String(cause);\n}\n\nasync function writeSignalFiles(\n file: EdfFile,\n plan: ConversionPlan,\n outputDir: string | null,\n recordStarts: Float64Array | null,\n options: ConvertOptions,\n): Promise<WrittenFile[]> {\n // One budget for every table in this conversion, not one per table: see OffsetBudget.\n const offsets = newOffsetBudget();\n // Only the stdout path needs this; --out finds a full disk on its own, because it always\n // has another file to write afterwards. See auditStdout.\n const audit = outputDir === null ? auditStdout() : null;\n const open: OpenGroup[] = plan.groups.map((group) => {\n // A null directory means the single table goes to stdout. process.stdout is already a\n // writable stream, so the same buffered writer and backpressure handling apply.\n const target =\n outputDir === null ? process.stdout : createWriteStream(path.join(outputDir, group.fileName));\n const { stream, settled } = compressed(target, options.gzip === true);\n /*\n Under --gzip the writer feeds the compressor, so its byte count is the CSV before\n compression and says nothing about what reached the descriptor. The compressor's own\n output is what stdout is handed, so that is what is counted. `pipe` uses a 'data'\n listener of its own and a second one is delivered the same chunks.\n */\n if (audit && stream !== target) stream.on('data', (chunk: Buffer) => audit.count(chunk.length));\n const writer = new BufferedLineWriter(stream);\n writer.pushLine(csvRow(['time_s', ...group.channels.map((c) => c.column)]));\n return {\n group,\n writer,\n formatters: group.channels.map((c) => makeSampleFormatter(c.signal, c.decimals)),\n formatTime: makeTimeFormatter(\n group.samplesPerRecord,\n group.rate,\n group.timeDecimals,\n offsets,\n ),\n rows: 0,\n settled,\n };\n });\n\n try {\n const written = await streamSignalRows(file, plan, open, recordStarts, options);\n\n /*\n Checked once everything has been flushed and ended, and not when the reader hung up.\n\n `--stdout | head -1` closes the pipe on purpose, which is a shell idiom rather than a\n failure. A pipe is not a regular file, so auditStdout declines it anyway — the second\n guard is here because the cost of getting this one wrong is reporting a failure for a\n command that worked.\n */\n if (audit) {\n // Uncompressed, the writer hands its bytes straight to the descriptor; compressed,\n // they were counted on the compressor's way out.\n if (options.gzip !== true) {\n for (const entry of open) audit.count(entry.writer.bytesOut);\n }\n if (!open.some((entry) => entry.writer.hungUp)) audit.verify();\n }\n return written;\n } catch (cause) {\n for (const entry of open) entry.writer.destroy();\n\n /*\n Reading and writing both fail through here, and both were reported as writing.\n\n A recording that shrinks mid-conversion — still being written by the acquisition\n software, say — raises the reader's own error, which names the record and says the\n file changed size while it was being read. That precise diagnosis was then filed under\n `Writing to \"<dir>\" failed` and given the hint about freeing disk space, which sends\n someone to look at the one part of the system that was working.\n\n The reader's message and its advice are kept; only the note about partial output is\n added, since that much is true of either failure.\n */\n // A ConversionError arrived already saying what went wrong — a callback that threw, say.\n // Wrapping it again turned \"the onProgress callback threw\" into `Writing to \"out\"\n // failed: the onProgress callback threw`, under a hint about checking the destination.\n if (cause instanceof ConversionError) throw cause;\n\n if (cause instanceof EdfError) {\n const where = outputDir === null ? 'stdout' : `\"${outputDir}\"`;\n throw new ConversionError(\n 'INPUT_UNREADABLE',\n cause.message,\n `${cause.hint ? `${cause.hint} ` : ''}What was written to ${where} before it failed is ` +\n `incomplete and should not be used.`,\n );\n }\n\n const detail = cause instanceof Error ? cause.message : String(cause);\n throw new ConversionError(\n 'WRITE_FAILED',\n `Writing to ${outputDir === null ? 'stdout' : `\"${outputDir}\"`} failed: ${detail}`,\n writeHint(cause, outputDir === null),\n );\n }\n}\n\nasync function streamSignalRows(\n file: EdfFile,\n plan: ConversionPlan,\n open: OpenGroup[],\n recordStarts: Float64Array | null,\n options: ConvertOptions,\n): Promise<WrittenFile[]> {\n const { startSeconds, endSeconds, startRecord, endRecord } = plan.range;\n const { recordDuration } = file.header;\n let recordsDone = 0;\n\n /*\n Every destination has hung up, so nothing formatted from here on could reach anyone.\n `--stdout | head -1` is the usual way to arrive here: the reader takes one line and\n closes the pipe while the conversion is still near the start of the recording.\n\n Stopping also makes the reported row count mean what it says — rows that reached the\n consumer, rather than rows the loop went on formatting into a discarded buffer.\n */\n const allHungUp = (): boolean => open.length > 0 && open.every((entry) => entry.writer.hungUp);\n\n for await (const batch of file.readRecords({ startRecord, endRecord })) {\n if (allHungUp()) break;\n for (let r = 0; r < batch.recordCount; r++) {\n if (allHungUp()) break;\n const index = batch.firstRecordIndex + r;\n const recordStart = recordStarts ? (recordStarts[index] ?? index * recordDuration) : index * recordDuration;\n\n for (const entry of open) {\n const { group, writer, formatters, formatTime } = entry;\n const { channels, rate } = group;\n // Slack that never reaches the next sample; see toleranceFor.\n const slack = toleranceFor(rate);\n\n for (let sample = 0; sample < group.samplesPerRecord; sample++) {\n const time = recordStart + sample / rate;\n if (!sampleTimeIsInRange(time, startSeconds, endSeconds, slack)) continue;\n\n let row = formatTime(recordStart, sample);\n for (let c = 0; c < channels.length; c++) {\n const channel = channels[c];\n const format = formatters[c];\n if (!channel || !format) continue;\n row += ',' + format(file.sampleAt(batch, r, channel.signal, sample));\n }\n if (writer.hungUp) break;\n writer.pushLine(row);\n entry.rows++;\n\n /*\n Flushed inside the record, not only at the end of one.\n\n The buffer was drained once per record, so the rows of a single record piled up\n with nothing emptying them — memory followed samples-per-record rather than the\n batch size the writer exists to hold to. One record of 16,000,000 samples died\n with a heap out of memory under a 256 MB cap, while the same 32 MB of samples\n split into 16,000 records converted to the same 283 MB CSV without trouble. The\n format allows either layout and says nothing about which to expect.\n\n `full` is a synchronous read of the pending size, so the twenty million rows that\n are not at a boundary cost a comparison rather than a microtask each.\n */\n if (writer.full) await writer.flush();\n }\n await writer.maybeFlush();\n }\n\n recordsDone++;\n }\n\n if (options.onProgress) {\n /*\n A caller's callback is the caller's, and its failures are not the destination's.\n\n This ran inside the same try that turns a stream failure into WRITE_FAILED, so a\n progress callback that threw came back as `Writing to \"out\" failed: caller bug`,\n advising the reader to check a destination that was working perfectly. It is the\n same misattribution the write hints had until 0.4.36, one layer up.\n\n The original is kept as `cause`, so the stack that actually matters survives, and\n the conversion still stops — the callback threw, and carrying on writing into a\n directory whose owner has just failed is not an improvement.\n */\n try {\n options.onProgress({\n recordsDone,\n recordsTotal: endRecord - startRecord,\n bytesWritten: open.reduce((sum, g) => sum + g.writer.charsWritten, 0),\n });\n } catch (cause) {\n throw new ConversionError(\n 'CALLBACK_FAILED',\n `The onProgress callback threw: ${cause instanceof Error ? cause.message : String(cause)}`,\n 'This is the caller\\'s callback, not the recording or the destination. Whatever was ' +\n 'written before it threw is incomplete and should not be used.',\n { cause },\n );\n }\n }\n }\n\n for (const entry of open) {\n await entry.writer.end();\n // With --gzip the writer's stream is the compressor, whose end callback fires when the\n // compressor is done rather than when the file behind it is. Awaiting only that would\n // report success with the tail of the file still in flight.\n await entry.settled;\n }\n return open.map((entry) => ({ name: entry.group.fileName, rows: entry.rows }));\n}\n\n/**\n * The stream rows are written to, plus a promise for the data reaching its destination.\n *\n * Compression sits between the writer and the file as a transform. Failures below it — a\n * full disk, an unwritable path — surface on the file stream, where nothing is listening,\n * so they are forwarded onto the compressor: that is the stream the writer watches, and\n * routing them there keeps one error path rather than two.\n */\nfunction compressed(target: Writable, gzip: boolean): { stream: Writable; settled: Promise<void> } {\n if (!gzip) return { stream: target, settled: Promise.resolve() };\n const compressor = createGzip();\n target.on('error', (error: Error) => compressor.destroy(error));\n\n /*\n pipe() ends its destination when the source ends, and stdout must survive the\n conversion: the writer already refuses to close it, because a closed stdout breaks\n every later write in the process. Nothing waits on stdout either — it is not this\n tool's to finish.\n */\n const toStdout = target === process.stdout;\n compressor.pipe(target, { end: !toStdout });\n if (toStdout) return { stream: compressor, settled: Promise.resolve() };\n\n /*\n A failure under the compressor rejects both this promise and the writer's own end(),\n and end() is the one awaited first. Without a handler attached here that rejection\n belonged to nobody, and Node killed the process over it: `--gzip` into an unwritable\n path printed a raw EISDIR stack trace instead of the ordinary \"Writing to ... failed\"\n message and exit 1, which is what the same path does uncompressed.\n\n Attaching the handler is enough to make it handled. Awaiting `settled` downstream still\n reports the failure in the case where end() happened to succeed.\n */\n const settled = finished(target);\n settled.catch(() => {});\n return { stream: compressor, settled };\n}\n\n/**\n * Write one of the sidecar files, reporting a failure the way the signal writer does.\n *\n * These three used to call `writeFile` bare, so a failure escaped as whatever the\n * filesystem said — `EISDIR: illegal operation on a directory, open '...'` with no hint\n * and, more importantly, no mention that the signal files had already been written. The\n * conversion stopped half-done and the message gave no sign of it.\n */\nasync function writeOutputFile(\n outputDir: string,\n name: string,\n contents: string,\n gzip = false,\n): Promise<void> {\n try {\n // The sidecars are built in memory before being written, so compressing them in memory\n // costs nothing extra. Only the signal tables are large enough to need a stream.\n await writeFile(path.join(outputDir, name), gzip ? gzipSync(contents) : contents, gzip ? undefined : 'utf8');\n } catch (cause) {\n const detail = cause instanceof Error ? cause.message : String(cause);\n throw new ConversionError(\n 'WRITE_FAILED',\n `Writing \"${name}\" to \"${outputDir}\" failed: ${detail}`,\n writeHint(cause),\n );\n }\n}\n\nasync function writeChannelsCsv(\n outputDir: string,\n file: EdfFile,\n plan: ConversionPlan,\n gzip: boolean,\n): Promise<WrittenFile> {\n const includedColumns = new Set(plan.groups.flatMap((g) => g.channels.map((c) => c.signal.index)));\n const fileFor = new Map<number, string>();\n for (const group of plan.groups) {\n for (const channel of group.channels) fileFor.set(channel.signal.index, group.fileName);\n }\n\n const lines = [\n csvRow([\n 'column',\n 'signal_index',\n 'label',\n 'unit',\n 'sampling_rate_hz',\n 'samples_per_record',\n 'physical_min',\n 'physical_max',\n 'digital_min',\n 'digital_max',\n 'transducer',\n 'prefiltering',\n 'output_file',\n 'converted',\n ]),\n ];\n\n for (const signal of file.header.signals) {\n if (signal.isAnnotations) continue;\n const column = plan.columnNames.get(signal.index) ?? `signal_${signal.index}`;\n lines.push(\n csvRow([\n column,\n String(signal.index),\n signal.label,\n signal.physicalDimension,\n String(signal.samplingRate),\n String(signal.samplesPerRecord),\n String(signal.physicalMin),\n String(signal.physicalMax),\n String(signal.digitalMin),\n String(signal.digitalMax),\n signal.transducer,\n signal.prefiltering,\n fileFor.get(signal.index) ?? '',\n includedColumns.has(signal.index) ? 'yes' : 'no',\n ]),\n );\n }\n\n const name = gzip ? 'channels.csv.gz' : 'channels.csv';\n await writeOutputFile(outputDir, name, lines.join('\\n') + '\\n', gzip);\n return { name, rows: lines.length - 1 };\n}\n\n/*\n The bounds an annotation is filtered against: what the caller actually asked for, not the\n window that survived being clamped to the recording.\n\n Filtering by the resolved window meant an unbounded request still lost events. `--end 999h`\n on a three-second file clamps to 3, and `--start 0` gets its end from the recording, so\n both filtered to [0, 3) and dropped the markers at 3.0 and 3.5 that a bare invocation\n keeps — asking for more of a recording returned less of it.\n\n An end the caller did not give is unbounded, not \"the end of the data\": EDF+ lets an\n annotation sit past the last sample, which is exactly where an end-of-recording marker is.\n\n `--duration` is measured from wherever the conversion actually starts. Anchoring it at 0\n instead read the same absent `--start` two ways in two adjacent lines, and on a recording\n that does not begin at zero the two windows did not even overlap: an EDF+D file whose first\n record sits at 30 s converted its samples from [30, 35) while filtering annotations against\n (-inf, 5), so every event inside the converted window was dropped and `annotations.csv` came\n back empty. `resolveRange` has always defaulted the same missing start to the earliest\n record, which is where this now takes it from.\n*/\nfunction requestedAnnotationWindow(\n options: ConvertOptions,\n recordingStart: number,\n): { from: number; to: number } {\n const from = options.start ?? -Infinity;\n const to =\n options.end !== undefined\n ? options.end\n : options.duration !== undefined\n ? (options.start ?? recordingStart) + options.duration\n : Infinity;\n return { from, to };\n}\n\nasync function writeAnnotationsCsv(\n outputDir: string,\n annotations: readonly Annotation[],\n window: { from: number; to: number },\n gzip: boolean,\n): Promise<WrittenFile> {\n const inWindow = annotations\n .filter((a) => a.onset >= window.from && a.onset < window.to)\n .sort((a, b) => a.onset - b.onset || a.recordIndex - b.recordIndex);\n\n const lines = [csvRow(['onset_s', 'duration_s', 'description', 'record_index'])];\n for (const annotation of inWindow) {\n lines.push(\n csvRow([\n String(annotation.onset),\n annotation.duration === null ? '' : String(annotation.duration),\n annotation.text,\n String(annotation.recordIndex),\n ]),\n );\n }\n\n const name = gzip ? 'annotations.csv.gz' : 'annotations.csv';\n await writeOutputFile(outputDir, name, lines.join('\\n') + '\\n', gzip);\n return { name, rows: inWindow.length };\n}\n\n/**\n * What to try next, chosen from what actually went wrong.\n *\n * Every write failure carried the same advice — \"Free up space or choose another destination\n * with --out\" — which fits exactly one errno. A directory sitting where signals.csv belongs\n * came back telling the reader to free up disk space, and so did a read-only volume, a\n * permission denial and a path too long for the filesystem. Wrong advice is worse than none:\n * it sends someone to check `df` on a disk that is fine, and the thing that is actually\n * wrong stays unexamined.\n *\n * The errno is the one piece of the failure that names the cause, so it is what picks the\n * sentence. Anything unrecognised keeps the general form rather than guessing.\n */\nfunction writeHint(cause: unknown, toStdout = false): string {\n /*\n The stdout path writes no files, and --out is the flag its user chose not to pass.\n\n Both halves of this sentence were wrong there: \"the files written so far\" named files\n that do not exist, and \"choose another destination with --out\" is advice for a different\n command — the destination is whatever the shell redirected the stream to. Same class as\n the disk-space hint this function replaced, one flag over.\n */\n const preamble = toStdout\n ? 'What reached stdout before it failed is incomplete and should not be used. '\n : 'The files written so far are incomplete and should not be used. ';\n const elsewhere = toStdout ? 'redirect it somewhere else' : 'choose another with --out';\n const code = (cause as NodeJS.ErrnoException | null)?.code;\n switch (code) {\n case 'ENOSPC':\n return `${preamble}The destination is out of space; free some up or ${elsewhere}.`;\n case 'EDQUOT':\n return `${preamble}You are over your disk quota on this filesystem; ${elsewhere}.`;\n case 'EACCES':\n case 'EPERM':\n return `${preamble}You do not have permission to write there; ${elsewhere}.`;\n case 'EROFS':\n return `${preamble}That filesystem is mounted read-only; ${elsewhere}.`;\n case 'EISDIR':\n return `${preamble}A directory is sitting where that file belongs; remove or rename it, or ${elsewhere}.`;\n case 'ENOENT':\n return `${preamble}Part of that path no longer exists; make sure nothing is removing it while the conversion runs.`;\n case 'ENAMETOOLONG':\n return `${preamble}That path is longer than the filesystem allows; ${toStdout ? 'redirect it somewhere shorter' : 'choose a shorter destination with --out'}.`;\n case 'EMFILE':\n case 'ENFILE':\n return `${preamble}Too many files are open; a recording with many sampling rates opens one output file per rate, so --channels narrows it.`;\n case 'EPIPE':\n return `${preamble}Whatever was reading the output closed it before the conversion finished.`;\n default:\n return `${preamble}Check the destination and run the conversion again.`;\n }\n}\n\n/**\n * Confirms that everything handed to a file-backed stdout actually arrived.\n *\n * `edf2csv rec.edf --stdout > out.csv` onto a volume that the output very nearly fills lost\n * the tail in silence: 94,977 of 102,400 rows on disk, the file ending mid-row, stderr\n * announcing \"Wrote 102,400 rows to stdout.\" and the process exiting 0. The same recording\n * onto the same volume through `--out` fails correctly, which is what gives it away.\n *\n * POSIX `write` returns a short count rather than an error when the disk fills partway\n * through a single call, and only the NEXT write raises ENOSPC. `--out` always has a next\n * write — channels.csv and metadata.json come after — so it always finds out. `--stdout`\n * has nothing after it, and when fd 1 is a regular file Node's stdout is a SyncWriteStream\n * whose `_write` discards the byte count `writeSync` returns, so nothing is raised at all.\n * No error means no `#failure`, so checking that alone would not have caught this.\n *\n * What can be checked is the descriptor: how much it grew against how much it was given.\n * Only for a regular file — a pipe, a terminal or a socket has no size to compare, and on\n * those a short write cannot go unreported this way. Appending (`>>`) is fine, since the\n * starting size is taken before anything is written.\n */\nfunction auditStdout(): { count: (bytes: number) => void; verify: () => void } | null {\n let startSize: number;\n try {\n const info = fstatSync(1);\n if (!info.isFile()) return null;\n startSize = info.size;\n } catch {\n // No usable descriptor to audit; the conversion is not the place to complain about it.\n return null;\n }\n\n let expected = 0;\n return {\n count: (bytes: number): void => {\n expected += bytes;\n },\n verify: (): void => {\n let landed: number;\n try {\n landed = fstatSync(1).size - startSize;\n } catch {\n return;\n }\n if (landed >= expected) return;\n throw new ConversionError(\n 'WRITE_FAILED',\n `Writing to stdout failed: ${expected - landed} of ${expected} bytes did not reach ` +\n `the destination, which stopped accepting them part way through.`,\n 'What is there ends mid-row and should not be used. The destination is almost ' +\n 'certainly out of space — a short write is how a filesystem reports filling up ' +\n 'mid-write, and nothing after it raised an error because there was nothing after it.',\n );\n },\n };\n}\n\n/** Data rows across every signal table, so \"nothing was written\" is one question. */\nfunction rowsIn(written: readonly WrittenFile[]): number {\n return written.reduce((total, file) => total + file.rows, 0);\n}\n\n/**\n * Raised when the conversion had signal tables to fill and put no data rows in any of them.\n *\n * A window can land where there are no samples without being past the end of the recording:\n * between the last sample and the nominal end of the last record, or — on a discontinuous\n * file — inside a gap. `--start 2 --end 10` on a recording whose records sit at 0s, 1s and\n * 10s asks for eight seconds that contain no data at all.\n *\n * What came out was a signals.csv holding its header and nothing else, exit 0, no warning,\n * and `--strict` passing. The closing summary does say \"signals.csv 0 rows\" and --json\n * carries `rows: 0`, so it was not quite invisible — but a header-only file is exactly what\n * a successful extraction of an empty range looks like, and everywhere else that a request\n * produces nothing this tool says so: a --channels term matching nothing is an error, and\n * --annotations-only on a file with no events raises NO_ANNOTATIONS. A warning rather than\n * an error because a batch of five hundred recordings should not stop for one whose gap\n * happens to line up with the window; --strict turns it into a failure for those who want\n * that.\n */\nfunction emptyWindow(range: ConversionPlan['range'], recordCount: number): Diagnostic {\n const asked = !range.isWholeRecording;\n return {\n code: 'EMPTY_WINDOW',\n severity: 'warning',\n message: asked\n ? `No samples fall inside the requested window (${fixed(range.startSeconds, 3)}s to ` +\n `${fixed(range.endSeconds, 3)}s), so the signal files hold their headers and no data.`\n : `This recording's ${recordCount} data records carry no samples in range, so the ` +\n `signal files hold their headers and no data.`,\n hint: asked\n ? 'The window is inside the recording but lands where there is no data — past the ' +\n 'last sample, or inside a gap in a discontinuous file. Run with --info to see where ' +\n 'the records actually sit.'\n : 'Run with --info to see what the header declares.',\n };\n}\n\n/** Raised when the input moved while it was being read. See where it is pushed. */\nfunction inputChanged(hadChecksum: boolean): Diagnostic {\n return {\n code: 'INPUT_CHANGED',\n severity: 'warning',\n message:\n 'The input changed while it was being converted, so this output covers the file as ' +\n 'it was when the conversion started, not as it is now.',\n hint: hadChecksum\n ? 'No checksum was recorded: the bytes that were converted are no longer there to ' +\n 'hash. Convert again once the recording is finished.'\n : 'Convert again once the recording is finished to pick up the rest.',\n };\n}\n\nasync function writeMetadata(\n outputDir: string,\n inputPath: string,\n file: EdfFile,\n plan: ConversionPlan,\n written: readonly WrittenFile[],\n annotationCount: number,\n /** Hash of the bytes that were converted, or null when it could not be vouched for. */\n checksum: string | null,\n): Promise<void> {\n const { header } = file;\n\n /*\n The file as it was when it was opened, not as it is now.\n\n Both of these used to come from re-opening the path once the CSVs were written, which\n describes whatever answers to that name by then rather than what was converted. A\n recording still being written grew from 2,000 records to 3,000 mid-conversion and\n metadata.json recorded `data_records: 2000` — correct, the CSV holds 2,000 — beside the\n byte count and SHA-256 of the 3,000-record file. The two halves of one provenance record\n described two different files, and the checksum covered bytes nobody had converted.\n Replacing the file at that path did the same thing more thoroughly.\n\n `file.fileSize` is the number every record count and window in this output was derived\n from, and the hash is taken over exactly those bytes through the descriptor already open\n on them, so the record describes one file throughout.\n */\n const metadata = {\n tool: { name: 'edf2csv', version: TOOL_VERSION },\n source: {\n path: path.resolve(inputPath),\n bytes: file.fileSize,\n modified: new Date(file.modifiedAtOpenMs).toISOString(),\n sha256: checksum,\n },\n recording: {\n format: describeFormat(header),\n version: header.version,\n patient_id: header.patientId,\n recording_id: header.recordingId,\n // Zone-less on purpose: EDF records local wall-clock digits and no timezone.\n start_datetime_local: formatWallClock(header.startDateTime),\n start_date_raw: header.startDateRaw,\n start_time_raw: header.startTimeRaw,\n data_records: file.recordCount,\n data_records_declared: header.declaredRecordCount,\n record_duration_seconds: header.recordDuration,\n duration_seconds: file.durationSeconds,\n signal_count: header.signalCount,\n annotation_channels: file.annotationSignals.length,\n },\n conversion: {\n converted_at: new Date().toISOString(),\n start_seconds: plan.range.startSeconds,\n end_seconds: plan.range.endSeconds,\n whole_recording: plan.range.isWholeRecording,\n records_converted: [plan.range.startRecord, plan.range.endRecord],\n annotations_written: annotationCount,\n files: written.map((f) => ({ name: f.name, rows: f.rows })),\n rate_groups: plan.groups.map((g) => ({\n file: g.fileName,\n sampling_rate_hz: g.rate,\n channels: g.channels.map((c) => c.column),\n decimals: g.channels.map((c) => c.decimals),\n })),\n },\n notes: [...withoutFileRateWarning(file.diagnostics), ...plan.diagnostics].map((d) => ({\n code: d.code,\n severity: d.severity,\n message: d.message,\n })),\n };\n\n await writeOutputFile(outputDir, 'metadata.json', JSON.stringify(metadata, null, 2) + '\\n');\n}\n\n\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"time-range.js","sourceRoot":"","sources":["../../src/convert/time-range.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,YAAY,GAA2B;IAC3C,CAAC,EAAE,IAAI;IACP,EAAE,EAAE,IAAI;IACR,GAAG,EAAE,IAAI;IACT,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,IAAI;IACX,CAAC,EAAE,EAAE;IACL,GAAG,EAAE,EAAE;IACP,IAAI,EAAE,EAAE;IACR,MAAM,EAAE,EAAE;IACV,OAAO,EAAE,EAAE;IACX,CAAC,EAAE,CAAC;IACJ,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,CAAC;IACV,EAAE,EAAE,KAAK;CACV,CAAC;AAEF,MAAM,KAAK,GAAG,6CAA6C,CAAC;AAC5D,MAAM,UAAU,GAAG,+BAA+B,CAAC;AAEnD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,UAAkB;IAC7D,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACxC,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QAChB,MAAM,IAAI,cAAc,CAAC,GAAG,UAAU,mDAAmD,CAAC,CAAC;IAC7F,CAAC;IAED,6BAA6B;IAC7B,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;IAExF,iCAAiC;IACjC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,OAAO,IAAI,EAAE,IAAI,OAAO,IAAI,EAAE,EAAE,CAAC;YACnC,MAAM,IAAI,cAAc,CACtB,GAAG,UAAU,KAAK,KAAK,iDAAiD,CACzE,CAAC;QACJ,CAAC;QACD,OAAO,YAAY,CAAC,KAAK,GAAG,IAAI,GAAG,OAAO,GAAG,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;IAChF,CAAC;IAED,kCAAkC;IAClC,UAAU,CAAC,SAAS,GAAG,CAAC,CAAC;IACzB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,KAA6B,CAAC;IAClC,qFAAqF;IACrF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAChD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,IAAI,cAAc,CACtB,GAAG,UAAU,KAAK,KAAK,2BAA2B,IAAI,wBAAwB,CAC/E,CAAC;QACJ,CAAC;QAED,iFAAiF;QACjF,qFAAqF;QACrF,qFAAqF;QACrF,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,cAAc,CACtB,GAAG,UAAU,KAAK,KAAK,+BAA+B;gBACpD,sCAAsC,CACzC,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEhB,KAAK,IAAI,MAAM,GAAG,KAAK,CAAC;QACxB,OAAO,EAAE,CAAC;QACV,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,8DAA8D;IAC9D,IAAI,OAAO,KAAK,CAAC,IAAI,QAAQ,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QACnE,MAAM,IAAI,cAAc,CACtB,GAAG,UAAU,KAAK,KAAK,gCAAgC;YACrD,6DAA6D,CAChE,CAAC;IACJ,CAAC;IAED,OAAO,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,YAAY,CAAC,KAAa,EAAE,UAAkB,EAAE,KAAa;IACpE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,cAAc,CAAC,GAAG,UAAU,KAAK,KAAK,qCAAqC,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAmBD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEvC;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,kBAAkB,CAAC;IACrE,OAAO,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,mBAAmB,CACjC,IAAY,EACZ,YAAoB,EACpB,UAAkB,EAClB,YAAoB,kBAAkB;IAEtC,OAAO,IAAI,IAAI,YAAY,GAAG,SAAS,IAAI,IAAI,GAAG,UAAU,GAAG,SAAS,CAAC;AAC3E,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,mBAAmB,CAAC,OAMnC;IACC,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CACrB,CAAC,OAAO,CAAC,YAAY,GAAG,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CACpE,CAAC;IACF,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CACrB,CAAC,OAAO,CAAC,UAAU,GAAG,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAClE,CAAC;IACF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC,CAAC;IACrE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC,CAAC;IACpE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,OAe5B;IACC,4EAA4E;IAC5E,gFAAgF;IAChF,6EAA6E;IAC7E,4EAA4E;IAC5E,2EAA2E;IAC3E,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IAErG,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QAChE,MAAM,IAAI,cAAc,CAAC,2CAA2C,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAC;IAE/C,IAAI,UAAkB,CAAC;IACvB,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS;QAAE,UAAU,GAAG,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC;SAC5E,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS;QAAE,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC;;QACxD,UAAU,GAAG,MAAM,CAAC;IAEzB,IAAI,YAAY,IAAI,MAAM,EAAE,CAAC;QAC3B;;;;;;;;;UASE;QACF,MAAM,IAAI,cAAc;QACtB;;;;;;;;;;;;UAYE;QACF,WAAW,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC,iCAAiC;YACjF,GAAG,cAAc,CAAC,MAAM,CAAC,aAAa,CACzC,CAAC;IACJ,CAAC;IACD,IAAI,UAAU,IAAI,YAAY,EAAE,CAAC;QAC/B,uFAAuF;QACvF,sFAAsF;QACtF,qFAAqF;QACrF,MAAM,QAAQ,GACZ,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;YACxD,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,CAAC;YACrC,CAAC,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAChC,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QAC3D,MAAM,IAAI,cAAc,CACtB,gCAAgC,QAAQ,qCAAqC,UAAU,GAAG,CAC3F,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;IAEpF,OAAO;QACL,YAAY;QACZ,UAAU,EAAE,UAAU;QACtB,WAAW;QACX,SAAS;QACT,gBAAgB,EAAE,YAAY,IAAI,QAAQ,IAAI,UAAU,IAAI,MAAM;QAClE,qBAAqB,EAAE,QAAQ;QAC/B,mBAAmB,EAAE,MAAM;KAC5B,CAAC;AACJ,CAAC;AAED,SAAS,IAAI,CACX,YAA6C,EAC7C,WAAmB,EACnB,cAAsB;IAEtB,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/C,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,cAAc,EAAE,CAAC;IAC/D,CAAC;IACD,IAAI,QAAQ,GAAG,QAAQ,CAAC;IACxB,IAAI,MAAM,GAAG,CAAC,QAAQ,CAAC;IACvB,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QACjC,IAAI,KAAK,GAAG,QAAQ;YAAE,QAAQ,GAAG,KAAK,CAAC;QACvC,IAAI,KAAK,GAAG,cAAc,GAAG,MAAM;YAAE,MAAM,GAAG,KAAK,GAAG,cAAc,CAAC;IACvE,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3D,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,cAAc,EAAE,CAAC;IAC/D,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC9B,CAAC;AAED,sEAAsE;AACtE,SAAS,aAAa,CACpB,OAAwG,EACxG,YAAoB,EACpB,UAAkB;IAElB,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IACpC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;YAC3E,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;SACzF,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC;IAChC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,KAAK,GAAG,OAAO,CAAC,cAAc,GAAG,YAAY,IAAI,KAAK,GAAG,UAAU,EAAE,CAAC;YACxE,IAAI,CAAC,GAAG,KAAK;gBAAE,KAAK,GAAG,CAAC,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI;gBAAE,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IACD,OAAO,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;AACnG,CAAC;AAED;;;;GAIG;AACH,SAAS,MAAM,CAAC,IAAwB,EAAE,OAAe;IACvD,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC;AACnE,CAAC;AAED,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"time-range.js","sourceRoot":"","sources":["../../src/convert/time-range.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Parsing for the time-range options.\n *\n * Researchers write offsets in whatever form is natural for the recording in front\n * of them: seconds for a short ECG strip, `30m` into a sleep study, `01:23:45` when\n * reading off a clock. All three are accepted; anything ambiguous is rejected with\n * a message that shows the forms that work.\n */\n\nimport { formatDuration } from '../format/number.js';\n\nexport class TimeRangeError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'TimeRangeError';\n }\n}\n\nconst UNIT_SECONDS: Record<string, number> = {\n h: 3600,\n hr: 3600,\n hrs: 3600,\n hour: 3600,\n hours: 3600,\n m: 60,\n min: 60,\n mins: 60,\n minute: 60,\n minutes: 60,\n s: 1,\n sec: 1,\n secs: 1,\n second: 1,\n seconds: 1,\n ms: 0.001,\n};\n\nconst CLOCK = /^(?:(\\d+):)?(\\d{1,2}):(\\d{1,2}(?:\\.\\d+)?)$/u;\nconst UNIT_TOKEN = /(\\d+(?:\\.\\d+)?)\\s*([a-z]+)/giu;\n\n/**\n * Parse a duration or offset into seconds.\n *\n * Accepted: `90`, `90s`, `5m`, `1h30m`, `1h 30m 15s`, `00:30:00`, `30:00`, `250ms`.\n */\nexport function parseTimeSpec(input: string, optionName: string): number {\n const text = input.trim().toLowerCase();\n if (text === '') {\n throw new TimeRangeError(`${optionName} is empty. Try a value like 30s, 5m, or 00:30:00.`);\n }\n\n // Bare number means seconds.\n if (/^\\d+(?:\\.\\d+)?$/u.test(text)) return assertFinite(Number(text), optionName, input);\n\n // Clock form: hh:mm:ss or mm:ss.\n const clock = CLOCK.exec(text);\n if (clock) {\n const hours = clock[1] === undefined ? 0 : Number(clock[1]);\n const minutes = Number(clock[2]);\n const seconds = Number(clock[3]);\n if (minutes >= 60 || seconds >= 60) {\n throw new TimeRangeError(\n `${optionName} \"${input}\" has a minutes or seconds field of 60 or more.`,\n );\n }\n return assertFinite(hours * 3600 + minutes * 60 + seconds, optionName, input);\n }\n\n // Unit form: 1h30m, 5 min, 250ms.\n UNIT_TOKEN.lastIndex = 0;\n let total = 0;\n let matched = 0;\n let consumed = 0;\n let match: RegExpExecArray | null;\n // Which units have already been seen, so a repeat can be rejected rather than added.\n const seen = new Set<number>();\n while ((match = UNIT_TOKEN.exec(text)) !== null) {\n const amount = Number(match[1]);\n const unit = match[2] ?? '';\n const scale = UNIT_SECONDS[unit];\n if (scale === undefined) {\n throw new TimeRangeError(\n `${optionName} \"${input}\" uses an unknown unit \"${unit}\". Use h, m, s, or ms.`,\n );\n }\n\n // \"1h1h\" is a typo, not a request for two hours. Summing repeated units silently\n // turned a slip into a plausible window that was quietly the wrong length. Units are\n // keyed by their scale so the aliases collapse together: \"1h30min20m\" is caught too.\n if (seen.has(scale)) {\n throw new TimeRangeError(\n `${optionName} \"${input}\" gives the same unit twice. ` +\n `Combine each unit once, as in 1h30m.`,\n );\n }\n seen.add(scale);\n\n total += amount * scale;\n matched++;\n consumed += match[0].length;\n }\n\n // Reject partially-understood input like \"5x\" or \"1h banana\".\n if (matched === 0 || consumed !== text.replace(/\\s+/gu, '').length) {\n throw new TimeRangeError(\n `${optionName} \"${input}\" is not a time I understand. ` +\n `Try 30s, 5m, 1h30m, 00:30:00, or a plain number of seconds.`,\n );\n }\n\n return assertFinite(total, optionName, input);\n}\n\nfunction assertFinite(value: number, optionName: string, input: string): number {\n if (!Number.isFinite(value) || value < 0) {\n throw new TimeRangeError(`${optionName} \"${input}\" is not a valid non-negative time.`);\n }\n return value;\n}\n\nexport interface ResolvedRange {\n /** Inclusive start, in seconds from the beginning of the recording. */\n startSeconds: number;\n /** Exclusive end, in seconds. */\n endSeconds: number;\n /** First data record touching the window. */\n startRecord: number;\n /** One past the last data record touching the window. */\n endRecord: number;\n /** True when the window covers the whole recording. */\n isWholeRecording: boolean;\n /** Earliest record start, including EDF+D timing gaps. */\n recordingStartSeconds: number;\n /** End of the latest record, including EDF+D timing gaps. */\n recordingEndSeconds: number;\n}\n\n/**\n * Slack for comparisons at sample/window boundaries.\n *\n * A nanosecond is far below any real sampling interval — 20 kHz is 50 microseconds — so it\n * absorbs the arithmetic error in `recordStart + sample / rate` without reaching a\n * neighbouring sample.\n */\nexport const BOUNDARY_TOLERANCE = 1e-9;\n\n/**\n * The slack to use for a channel sampled this often.\n *\n * Never as much as half a sample interval, because slack that reaches the next sample stops\n * being slack. A fixed nanosecond was applied whatever the rate, and the format does not\n * oblige the interval to be larger than it: EDF's record duration is an 8-character field\n * that accepts `1e-9`. A recording of two 1 ns records holding ten samples each wrote ten of\n * its twenty rows — the window ends at 2e-9, the comparison asked for `time < 2e-9 - 1e-9`,\n * and the entire second record failed it. Exit 0, no warning, half the samples gone.\n */\nexport function toleranceFor(rate: number): number {\n if (!(rate > 0) || !Number.isFinite(rate)) return BOUNDARY_TOLERANCE;\n return Math.min(BOUNDARY_TOLERANCE, 1 / rate / 2);\n}\n\n/** Match the exact half-open boundary rules used while writing signal rows. */\nexport function sampleTimeIsInRange(\n time: number,\n startSeconds: number,\n endSeconds: number,\n tolerance: number = BOUNDARY_TOLERANCE,\n): boolean {\n return time >= startSeconds - tolerance && time < endSeconds - tolerance;\n}\n\n/** Count samples from one record that fall inside a half-open requested window. */\nexport function countSamplesInRange(options: {\n recordStart: number;\n rate: number;\n samplesPerRecord: number;\n startSeconds: number;\n endSeconds: number;\n}): number {\n const slack = toleranceFor(options.rate);\n const lower = Math.ceil(\n (options.startSeconds - slack - options.recordStart) * options.rate,\n );\n const upper = Math.ceil(\n (options.endSeconds - slack - options.recordStart) * options.rate,\n );\n const first = Math.max(0, Math.min(options.samplesPerRecord, lower));\n const last = Math.max(0, Math.min(options.samplesPerRecord, upper));\n return Math.max(0, last - first);\n}\n\n/**\n * Turn a requested window into both an exact time span and the record range that\n * contains it. Records are the unit the file can be read in; the exact span is what\n * decides which samples inside those records are actually written.\n */\nexport function resolveRange(options: {\n start?: number | undefined;\n /** The `--start` value exactly as typed, quoted back in the past-the-end error. */\n startText?: string | undefined;\n duration?: number | undefined;\n end?: number | undefined;\n /** The `--end` value exactly as typed, quoted back in the window error. */\n endText?: string | undefined;\n recordDuration: number;\n recordCount: number;\n /**\n * True start time of each data record, for discontinuous files. When absent,\n * records are assumed to sit end to end.\n */\n recordStarts?: Float64Array | null | undefined;\n}): ResolvedRange {\n // For a continuous file the recording spans recordCount * recordDuration. A\n // discontinuous one does not: a 10-second recording with a 95-second gap in the\n // middle still ends at 105 seconds. Deriving the span from the records' real\n // positions is what stops a requested window from being clipped back to the\n // amount of *data* in the file and silently discarding everything past it.\n const { earliest, latest } = span(options.recordStarts, options.recordCount, options.recordDuration);\n\n if (options.duration !== undefined && options.end !== undefined) {\n throw new TimeRangeError('Use either --duration or --end, not both.');\n }\n\n const startSeconds = options.start ?? earliest;\n\n let endSeconds: number;\n if (options.duration !== undefined) endSeconds = startSeconds + options.duration;\n else if (options.end !== undefined) endSeconds = options.end;\n else endSeconds = latest;\n\n if (startSeconds >= latest) {\n /*\n Quote what was typed. Reporting the parsed seconds meant `--start 4h` came back as\n \"--start 14400s is at or past the end\", which reads as a value the user never gave.\n\n In quotation marks, which the parse errors above have always used and this did not.\n Without them the value ran into the sentence: `--start \" 5s \"` printed as\n `--start 5s is at or past the end`, where the value appears to be `5s is` and\n the surrounding spaces — the actual reason a shell-built argument went wrong — are\n invisible.\n */\n throw new TimeRangeError(\n /*\n The recording's length in the same words --info uses for it.\n\n `formatSeconds` renders a bare number of seconds, so this message and the Duration\n line disagreed about one file in one session: --info said \"6m 40s\" and the error said\n \"400s\". On an overnight recording it read \"7950s recording\", leaving the reader to\n divide by 3600 to find out whether their --start was reasonable — which is the one\n question this message exists to answer. cli-reference.md has always documented it\n humanised (\"2h 12m 30s\"), a form no input could produce.\n\n The typed value keeps `quoted`, since that is the user's own text and should come\n back exactly as they wrote it.\n */\n `--start ${quoted(options.startText, startSeconds)} is at or past the end of this ` +\n `${formatDuration(latest)} recording.`,\n );\n }\n if (endSeconds <= startSeconds) {\n // Quote whatever the caller actually gave, for the same reason as the error above. The\n // end is only echoed when --end was passed: with --duration the end is computed here,\n // so there is no typed value to quote and the arithmetic result is the honest thing.\n const endShown =\n options.end !== undefined && options.endText !== undefined\n ? quoted(options.endText, endSeconds)\n : formatSeconds(endSeconds);\n const startShown = quoted(options.startText, startSeconds);\n throw new TimeRangeError(\n `The requested window ends at ${endShown}, which is not after its start at ${startShown}.`,\n );\n }\n\n const clampedEnd = Math.min(endSeconds, latest);\n const { startRecord, endRecord } = selectRecords(options, startSeconds, clampedEnd);\n\n return {\n startSeconds,\n endSeconds: clampedEnd,\n startRecord,\n endRecord,\n isWholeRecording: startSeconds <= earliest && clampedEnd >= latest,\n recordingStartSeconds: earliest,\n recordingEndSeconds: latest,\n };\n}\n\nfunction span(\n recordStarts: Float64Array | null | undefined,\n recordCount: number,\n recordDuration: number,\n): { earliest: number; latest: number } {\n if (!recordStarts || recordStarts.length === 0) {\n return { earliest: 0, latest: recordCount * recordDuration };\n }\n let earliest = Infinity;\n let latest = -Infinity;\n for (const start of recordStarts) {\n if (start < earliest) earliest = start;\n if (start + recordDuration > latest) latest = start + recordDuration;\n }\n if (!Number.isFinite(earliest) || !Number.isFinite(latest)) {\n return { earliest: 0, latest: recordCount * recordDuration };\n }\n return { earliest, latest };\n}\n\n/** Every record whose own time span overlaps the requested window. */\nfunction selectRecords(\n options: { recordDuration: number; recordCount: number; recordStarts?: Float64Array | null | undefined },\n startSeconds: number,\n endSeconds: number,\n): { startRecord: number; endRecord: number } {\n const starts = options.recordStarts;\n if (!starts || starts.length === 0) {\n return {\n startRecord: Math.max(0, Math.floor(startSeconds / options.recordDuration)),\n endRecord: Math.min(options.recordCount, Math.ceil(endSeconds / options.recordDuration)),\n };\n }\n\n let first = options.recordCount;\n let last = 0;\n for (let i = 0; i < starts.length; i++) {\n const begin = starts[i] ?? 0;\n if (begin + options.recordDuration > startSeconds && begin < endSeconds) {\n if (i < first) first = i;\n if (i + 1 > last) last = i + 1;\n }\n }\n return first < last ? { startRecord: first, endRecord: last } : { startRecord: 0, endRecord: 0 };\n}\n\n/**\n * The value as the caller typed it, in quotation marks, or the parsed seconds if they gave\n * none. The marks show where the value begins and ends, which matters most for the values\n * that went wrong because of what surrounds them.\n */\nfunction quoted(text: string | undefined, seconds: number): string {\n return text === undefined ? formatSeconds(seconds) : `\"${text}\"`;\n}\n\nfunction formatSeconds(seconds: number): string {\n return `${Number(seconds.toFixed(3))}s`;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"timing.js","sourceRoot":"","sources":["../../src/convert/timing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"timing.js","sourceRoot":"","sources":["../../src/convert/timing.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Diagnostic } from '../edf/errors.js';\nimport type { EdfFile } from '../edf/reader.js';\n\nexport interface AnnotationTimingData {\n recordStarts: (number | null)[];\n malformed: number;\n /** Unreadable TALs in first position, which carry timing rather than an event. */\n malformedTimekeeping?: number;\n}\n\n/**\n * Resolve the true start time of every data record.\n *\n * Continuous recordings need no table because their record positions are\n * arithmetic. EDF+D recordings carry their positions in the annotation channel;\n * missing or malformed timekeeping entries are reported before falling back.\n */\nexport function deriveRecordStarts(\n file: EdfFile,\n annotationData: AnnotationTimingData,\n): { starts: Float64Array | null; diagnostics: Diagnostic[] } {\n const diagnostics: Diagnostic[] = [];\n\n if (annotationData.malformed > 0) {\n diagnostics.push({\n code: 'ANNOTATION_DECODE_FAILED',\n severity: 'warning',\n message:\n `${annotationData.malformed} annotation entr${annotationData.malformed === 1 ? 'y was' : 'ies were'} ` +\n `unreadable and could not be exported.`,\n hint: 'The rest were exported normally. The file may have been written by a non-conforming tool.',\n });\n }\n\n /*\n A timekeeping TAL is not an event, and saying it \"could not be exported\" describes the\n wrong loss twice over.\n\n These were counted among the annotations, so a file with one unreadable timekeeping TAL\n and three good events announced \"1 annotation entry was unreadable and could not be\n exported\" — while exporting all three. Nothing was missing from annotations.csv; what\n went missing was a record's position in time, which the message never mentioned.\n */\n const lostTimekeeping = annotationData.malformedTimekeeping ?? 0;\n // The EDF+D branch below raises its own, which names the records and is more specific.\n // Saying both would report one problem twice.\n if (lostTimekeeping > 0 && file.header.continuity !== 'EDF+D') {\n const one = lostTimekeeping === 1;\n diagnostics.push({\n code: 'ANNOTATION_DECODE_FAILED',\n severity: 'warning',\n message:\n `${lostTimekeeping} data record${one ? '' : 's'} carr${one ? 'ies' : 'y'} a timekeeping ` +\n `annotation that could not be read, so ${one ? 'it does' : 'they do'} not say where in ` +\n `time ${one ? 'it sits' : 'they sit'}.`,\n hint:\n 'No event was lost — a timekeeping annotation states a record\\'s start time and is ' +\n 'never exported. Times are derived from the records that could be read.',\n });\n }\n\n /*\n A continuous recording's records are contiguous, but the first one need not sit at zero.\n\n EDF+ puts the header's start time and every annotation onset on one origin, and says the\n first data record's timekeeping TAL \"always starts with +0.X\", stating the fraction of a\n second by which that record follows it. Ignoring that fraction timed the samples from 0\n while the events kept their true onsets, so the two ended up on origins half a second\n apart — an event at +0.75 in a 4 Hz recording whose first TAL reads +0.5 landed on sample\n 3 instead of sample 1. The same file marked EDF+D, byte-identical but for the reserved\n field, placed it correctly, which is what gives the omission away.\n\n Records stay contiguous, which is what continuous means: only the origin moves. A first\n TAL of +0 needs no table at all, and that is nearly every file.\n */\n if (file.header.continuity !== 'EDF+D') {\n if (file.header.continuity !== 'EDF+C') return { starts: null, diagnostics };\n\n /*\n The origin comes from whichever record first states one, not from record 0 alone.\n\n Reading only `recordStarts[0]` meant a single unreadable timekeeping TAL threw the\n origin away and timed the whole file from zero — while records 1 and 2, saying plainly\n that they start at 1.5s and 2.5s, went unread. A recording whose records sit at 0.5s,\n 1.5s and 2.5s came out with every sample 0.5s earlier than the file states, against\n annotation onsets that kept their true values. That is precisely the mismatch 0.4.9\n fixed, arriving through the one hole left in it, and the byte-identical EDF+D twin\n timed it correctly, which is what gives it away.\n\n Continuity is what makes this recoverable: record i sits at `origin + i * duration`,\n so any readable record determines the origin for all of them.\n */\n const origin = originOf(annotationData.recordStarts, file.header.recordDuration);\n if (origin === null || origin === 0) return { starts: null, diagnostics };\n\n const contiguous = new Float64Array(file.recordCount);\n for (let i = 0; i < file.recordCount; i++) {\n contiguous[i] = origin + i * file.header.recordDuration;\n }\n\n /*\n A file marked continuous whose own records disagree about it.\n\n Nothing looked at records past the first, so an EDF+C file whose records are in fact\n spread out was timed as though they were contiguous and said nothing. The records are\n being read here anyway, so the contradiction costs nothing to notice — and it is the\n file, not the reader, that has to be wrong for this to fire.\n\n Compared against what the file can express, not for equality. 0.4.41 asked whether the\n two doubles were the same, which they are not: a recording of 0.1s records sitting at\n 0.1, 0.2, 0.3 ... is contiguous by construction, and 0.1 + 2 * 0.1 is\n 0.30000000000000004. Two of its eight records were reported as contradicting\n continuity, on an ordinary file — and under --strict that was a failed run. The\n smallest interval the recording distinguishes is one sample of its fastest channel;\n anything below half of that is arithmetic, not a gap. `canCarry` has already refused\n origins where the double spacing swamps that interval, so the representation error is\n under the tolerance by construction rather than by hope.\n */\n const tolerance = finestInterval(file) / 2;\n const contradicting = annotationData.recordStarts.filter(\n (declared, i) =>\n typeof declared === 'number' && Math.abs(declared - (contiguous[i] as number)) > tolerance,\n ).length;\n if (contradicting > 0) {\n diagnostics.push({\n code: 'DISCONTINUOUS',\n severity: 'warning',\n message:\n `This file is marked continuous (EDF+C), but ${contradicting} of its ` +\n `${file.recordCount} data records say they start somewhere other than where ` +\n `continuity puts them.`,\n hint:\n 'Times are written as if the records were contiguous, which is what EDF+C means. ' +\n 'If the recording really has gaps, the file should have been marked EDF+D.',\n });\n }\n const first = origin;\n const last = contiguous[file.recordCount - 1] ?? first;\n if (!canCarry(last, file)) {\n diagnostics.push(unusableOrigin(first, file));\n return { starts: null, diagnostics };\n }\n return { starts: contiguous, diagnostics };\n }\n\n if (file.annotationSignals.length === 0) {\n diagnostics.push({\n code: 'DISCONTINUOUS',\n severity: 'warning',\n message:\n 'This file is marked discontinuous but has no annotation channel, so where its ' +\n 'records sit in time is not recorded anywhere.',\n hint: 'Times are written as if the records were contiguous. Any gaps are lost.',\n });\n return { starts: null, diagnostics };\n }\n\n /*\n A record with no readable time is placed from the origin the other records establish,\n not from zero.\n\n `i * recordDuration` assumed the recording began at zero, which is the one thing the\n other records are in a position to contradict: a file starting at 0.5s put its\n unreadable record at 0.000 while its neighbours sat at 1.5s and 2.5s. The guess is still\n a guess — a discontinuous file may have a gap exactly there — and it is still reported\n below, but starting it from where the recording actually begins is strictly closer, and\n it makes an EDF+D file agree with its byte-identical EDF+C twin about record 0.\n */\n const base = originOf(annotationData.recordStarts, file.header.recordDuration) ?? 0;\n const starts = new Float64Array(file.recordCount);\n const missing: number[] = [];\n for (let i = 0; i < file.recordCount; i++) {\n const declared = annotationData.recordStarts[i];\n if (declared === null || declared === undefined) {\n missing.push(i);\n starts[i] = base + i * file.header.recordDuration;\n } else {\n starts[i] = declared;\n }\n }\n\n if (missing.length > 0) {\n const shown = missing.slice(0, 5).join(', ');\n diagnostics.push({\n code: 'ANNOTATION_DECODE_FAILED',\n severity: 'warning',\n message:\n `${missing.length} of ${file.recordCount} data records carry no readable timekeeping ` +\n `annotation (record${missing.length === 1 ? '' : 's'} ${shown}` +\n `${missing.length > 5 ? ', …' : ''}), so their true position in time is unknown.`,\n hint: 'Those records are timed as if they were contiguous; treat their timestamps as unreliable.',\n });\n }\n\n let furthest = 0;\n for (const start of starts) if (start > furthest) furthest = start;\n if (!canCarry(furthest, file)) {\n diagnostics.push(unusableOrigin(furthest, file));\n return { starts: null, diagnostics };\n }\n\n let outOfOrder = 0;\n for (let i = 1; i < starts.length; i++) {\n if ((starts[i] as number) < (starts[i - 1] as number)) outOfOrder++;\n }\n if (outOfOrder > 0) {\n diagnostics.push({\n code: 'DISCONTINUOUS',\n severity: 'warning',\n message: `${outOfOrder} data record${outOfOrder === 1 ? '' : 's'} start earlier than the record before it.`,\n hint: 'Rows are written in file order, so the time column will not increase monotonically.',\n });\n }\n\n return { starts, diagnostics };\n}\n\n/**\n * The recording's origin, from the first record that states where it is.\n *\n * Records of a continuous recording sit end to end, so record `i` beginning at `t` puts the\n * origin at `t - i * duration`. Any one readable timekeeping TAL is therefore enough, which\n * is what stops one unreadable entry from costing the whole file its position in time.\n */\nfunction originOf(recordStarts: readonly (number | null)[], recordDuration: number): number | null {\n for (const [index, declared] of recordStarts.entries()) {\n if (typeof declared !== 'number') continue;\n const origin = declared - index * recordDuration;\n return Number.isFinite(origin) ? origin : null;\n }\n return null;\n}\n\n/**\n * Whether times this far out can still tell one sample from the next.\n *\n * A double spaces its values further apart the larger they get: at 1e16 the gap is 2\n * seconds, so `t + 1` is `t`. Past that point a recording's declared origin stops being a\n * position and becomes a wall — the arithmetic that places records and samples returns the\n * origin itself, whatever is added to it.\n *\n * The finest thing that has to survive is the gap between two consecutive samples of the\n * fastest channel, since that is what the time column is made of. If that survives, so does\n * a whole record.\n */\nfunction canCarry(origin: number, file: EdfFile): boolean {\n if (!Number.isFinite(origin)) return false;\n return origin + finestInterval(file) > origin;\n}\n\n/**\n * The shortest span this recording can tell apart: one sample of its fastest channel.\n *\n * The time column is made of these, so nothing below one is a distinction the file is in a\n * position to make — which is what makes it the right size for both the \"can this origin\n * still separate two samples\" question and the \"is this record really somewhere else\"\n * question.\n */\nfunction finestInterval(file: EdfFile): number {\n let interval = file.header.recordDuration;\n for (const signal of file.header.signals) {\n if (signal.isAnnotations || !(signal.samplesPerRecord > 0)) continue;\n const step = file.header.recordDuration / signal.samplesPerRecord;\n if (step > 0 && step < interval) interval = step;\n }\n return interval;\n}\n\n/**\n * An origin the file's own arithmetic cannot express, reported rather than acted on.\n *\n * Two things went wrong when this was taken at face value, both of them quiet. A file whose\n * records all collapsed onto one instant made the recording zero seconds long, and the\n * window resolver — which had no reason to suspect the recording rather than the request —\n * blamed a flag nobody had passed:\n *\n * error: --start 100000000000000000s is at or past the end of this\n * 100000000000000000s recording.\n *\n * Slightly below that, the collapse is partial: `records[i].start + recordDuration` equals\n * the start again, so the test for \"does this record overlap the window\" fails for every\n * record whose neighbour rounded onto it. A twelve-row recording wrote four rows, exit 0,\n * no warning — the eight that vanished looked exactly like a file that never had them.\n *\n * Timing from zero is what the file did before 0.4.9 taught it to honour the first\n * timekeeping TAL, and at this magnitude it is the only column that can hold distinct\n * values. The origin is lost, so this says so.\n */\nfunction unusableOrigin(origin: number, file: EdfFile): Diagnostic {\n return {\n code: 'DISCONTINUOUS',\n severity: 'warning',\n message:\n `This recording's timekeeping annotations place it ${origin}s from its own start ` +\n `date, which is too far out for its ${file.header.recordDuration}s records to be told ` +\n `apart: at that magnitude adding a sample interval leaves the number unchanged.`,\n hint:\n 'Sample times are written from zero instead, so every row is present and the column ' +\n 'increases. Add the onsets in annotations.csv to recover absolute times if you need them.',\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"annotations.js","sourceRoot":"","sources":["../../src/edf/annotations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"annotations.js","sourceRoot":"","sources":["../../src/edf/annotations.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * EDF+ annotation (TAL) decoding.\n *\n * The annotations channel stores UTF-8 text in place of samples. Its bytes are a\n * run of Time-stamped Annotation Lists, each terminated by a NUL, with the rest\n * of the channel NUL-padded:\n *\n * +<onset>[<0x15><duration>]<0x14><text><0x14>...<0x00>\n *\n * The first TAL of every data record must carry that record's start time and no\n * text; that is how an EDF+D file states where each record actually sits in time.\n *\n * +1.25<0x15>0.5<0x14>Seizure onset<0x14><0x00>\n */\n\nimport { decodeUtf8 } from './bytes.js';\n\nconst SEP_TEXT = 0x14; // separates onset/duration from text, and text from text\nconst SEP_DURATION = 0x15; // separates onset from duration\nconst TAL_END = 0x00;\n\nconst TEXT_SEP_CHAR = String.fromCharCode(SEP_TEXT);\nconst DURATION_SEP_CHAR = String.fromCharCode(SEP_DURATION);\n\nexport interface Annotation {\n /** Seconds from the start of the recording. */\n onset: number;\n /** Seconds, or null when the TAL omitted a duration. */\n duration: number | null;\n text: string;\n /** Index of the data record this annotation was stored in. */\n recordIndex: number;\n}\n\nexport interface DecodedRecordAnnotations {\n /** Record start time in seconds, from the leading timekeeping TAL. */\n recordStart: number | null;\n annotations: Annotation[];\n /** Non-empty chunks that were not valid TALs, so the caller can report them. */\n malformed: number;\n /** Unreadable TALs in first position, which carry a record's start time, not an event. */\n malformedTimekeeping: number;\n}\n\n/**\n * Decode one data record's annotation bytes.\n *\n * Malformed TALs are skipped rather than thrown, because a single bad annotation\n * should not cost the user an entire conversion. The count of skipped chunks is\n * returned so the caller can tell the user rather than losing them in silence.\n */\nexport function decodeRecordAnnotations(\n bytes: Uint8Array,\n recordIndex: number,\n): DecodedRecordAnnotations {\n const annotations: Annotation[] = [];\n let recordStart: number | null = null;\n let isFirstTal = true;\n let malformed = 0;\n let malformedTimekeeping = 0;\n\n let start = 0;\n for (let i = 0; i <= bytes.length; i++) {\n if (i !== bytes.length && bytes[i] !== TAL_END) continue;\n\n if (i > start) {\n const chunk = bytes.subarray(start, i);\n const parsed = parseTal(chunk, recordIndex);\n\n // The timekeeping TAL is the one in first POSITION, whether or not it decodes.\n // Clearing this flag only on a successful parse meant that an unreadable first TAL\n // promoted the next ordinary annotation to timekeeping, and its onset silently\n // became the record's start time — shifting every sample in that record. Leaving\n // recordStart null instead is what the caller already handles, with a fallback\n // timestamp and an ANNOTATION_DECODE_FAILED warning naming the record.\n const isTimekeeping = isFirstTal;\n isFirstTal = false;\n\n if (parsed) {\n if (isTimekeeping) recordStart = parsed.onset;\n for (const annotation of parsed.annotations) annotations.push(annotation);\n } else {\n /*\n Counted apart from the events, because losing one is a different loss.\n\n A timekeeping TAL is never exported — it says where the record sits, not what\n happened — so counting it among the entries that \"could not be exported\" both\n overstated what was lost from annotations.csv and said nothing about the thing that\n actually went missing, which is a record's position in time. A file with one\n unreadable timekeeping TAL and three perfectly good events reported \"1 annotation\n entry was unreadable and could not be exported\" while exporting all three.\n */\n if (isTimekeeping) malformedTimekeeping++;\n else malformed++;\n }\n }\n start = i + 1;\n }\n\n return { recordStart, annotations, malformed, malformedTimekeeping };\n}\n\ninterface ParsedTal {\n onset: number;\n annotations: Annotation[];\n}\n\nfunction parseTal(chunk: Uint8Array, recordIndex: number): ParsedTal | null {\n // The onset must be explicitly signed; anything else is not a TAL.\n const first = chunk[0];\n if (first !== 0x2b /* + */ && first !== 0x2d /* - */) return null;\n\n const text = decodeUtf8(chunk);\n const parts = text.split(TEXT_SEP_CHAR);\n const head = parts[0] ?? '';\n\n let onsetText = head;\n let durationText: string | null = null;\n const durationSep = head.indexOf(DURATION_SEP_CHAR);\n if (durationSep >= 0) {\n onsetText = head.slice(0, durationSep);\n durationText = head.slice(durationSep + 1);\n }\n\n const onset = Number(onsetText);\n if (!Number.isFinite(onset)) return null;\n\n let duration: number | null = null;\n if (durationText !== null && durationText !== '') {\n const d = Number(durationText);\n duration = Number.isFinite(d) ? d : null;\n }\n\n const annotations: Annotation[] = [];\n for (const raw of parts.slice(1)) {\n // A trailing separator yields an empty segment; a timekeeping TAL is all empty.\n if (raw === '') continue;\n annotations.push({ onset, duration, text: raw, recordIndex });\n }\n\n return { onset, annotations };\n}\n\nexport { SEP_TEXT, SEP_DURATION, TAL_END };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"bytes.js","sourceRoot":"","sources":["../../src/edf/bytes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAC,KAAiB,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,GAAG,KAAK,CAAC,MAAM;IAC3E,oFAAoF;IACpF,MAAM,KAAK,GAAG,IAAI,CAAC;IACnB,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC;QACxC,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;EASE;AACF,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAE3D,yFAAyF;AACzF,MAAM,UAAU,UAAU,CAAC,KAAiB;IAC1C,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,KAAiB,EAAE,QAAgB;IAC7D,MAAM,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAW,CAAC;IACrC,MAAM,EAAE,GAAG,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAW,CAAC;IACzC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"bytes.js","sourceRoot":"","sources":["../../src/edf/bytes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAC,KAAiB,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,GAAG,KAAK,CAAC,MAAM;IAC3E,oFAAoF;IACpF,MAAM,KAAK,GAAG,IAAI,CAAC;IACnB,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC;QACxC,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;EASE;AACF,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAE3D,yFAAyF;AACzF,MAAM,UAAU,UAAU,CAAC,KAAiB;IAC1C,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,KAAiB,EAAE,QAAgB;IAC7D,MAAM,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAW,CAAC;IACrC,MAAM,EAAE,GAAG,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAW,CAAC;IACzC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAC1C,CAAC","sourcesContent":["/**\n * Byte decoding for the parser, written against `Uint8Array` rather than `Buffer`.\n *\n * The parser used to lean on `Buffer` methods, which put the `Buffer` type into the\n * published `.d.ts` files and forced every TypeScript consumer to have `@types/node`\n * installed to compile. Nothing here needs Node: these are the three operations the\n * EDF reader actually performed on raw bytes.\n */\n\n/**\n * Decode bytes as latin1: each byte becomes the code point of the same value.\n *\n * Written as an explicit loop rather than `TextDecoder('latin1')` because the identity\n * mapping is the property this parser needs, and doing it directly guarantees it rather\n * than inheriting it. The WHATWG Encoding Standard lists `latin1` as a label for\n * windows-1252, which is not an identity map over 0x80-0x9F; Node resolves the label to\n * plain byte identity, so the two agree here, but that is a runtime's behaviour rather\n * than a guarantee to lean on for header bytes.\n *\n * Verified byte-for-byte against `Buffer.toString('latin1')` across all 256 values.\n */\nexport function decodeLatin1(bytes: Uint8Array, start = 0, end = bytes.length): string {\n // Built in chunks so the spread never approaches the engine's argument-count limit.\n const CHUNK = 4096;\n let out = '';\n for (let i = start; i < end; i += CHUNK) {\n out += String.fromCharCode(...bytes.subarray(i, Math.min(i + CHUNK, end)));\n }\n return out;\n}\n\n/*\n `ignoreBOM: true` is the non-obvious part, and it means the opposite of how it reads: it tells the\n decoder to treat a leading U+FEFF as ordinary text rather than as a byte-order mark to strip.\n\n The default (`ignoreBOM: false`) removes a leading EF BB BF, which `Buffer.toString('utf8')` does\n not. That is the single input class where the two disagree — everything else, including every\n malformed sequence, already matches. No EDF file reaches it today, because the only caller guards\n on the first byte being '+' or '-' before decoding a TAL, but this function is written to stand in\n for Buffer's UTF-8 decoding and should not have a silent exception to that.\n*/\nconst UTF8 = new TextDecoder('utf-8', { ignoreBOM: true });\n\n/** Decode bytes as UTF-8, substituting U+FFFD for malformed sequences as Buffer does. */\nexport function decodeUtf8(bytes: Uint8Array): string {\n return UTF8.decode(bytes);\n}\n\n/**\n * Read a signed 16-bit little-endian sample.\n *\n * Plain arithmetic rather than a `DataView`: this runs once per sample, so hundreds of\n * millions of times on a long recording, and allocating or retaining a view per call\n * would show up in the conversion time. Shifting left 16 and back down arithmetically\n * is what sign-extends the result.\n */\nexport function readInt16LE(bytes: Uint8Array, position: number): number {\n const lo = bytes[position] as number;\n const hi = bytes[position + 1] as number;\n return (((lo | (hi << 8)) << 16) >> 16);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/edf/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA4CH;;;GAGG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,IAAI,CAAe;IACnB,IAAI,CAAqB;IAElC,YAAY,IAAkB,EAAE,OAAe,EAAE,IAAa;QAC5D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/edf/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA4CH;;;GAGG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,IAAI,CAAe;IACnB,IAAI,CAAqB;IAElC,YAAY,IAAkB,EAAE,OAAe,EAAE,IAAa;QAC5D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF","sourcesContent":["/**\n * Error and diagnostic types.\n *\n * The distinction that matters here: an EdfError means we cannot produce\n * trustworthy output and must stop. A Diagnostic with severity 'warning' means\n * we can continue, but the user needs to know something about their data that\n * they would not otherwise see.\n */\n\nexport type DiagnosticCode =\n | 'MIXED_SAMPLING_RATES'\n | 'DISCONTINUOUS'\n | 'RECORD_COUNT_UNKNOWN'\n | 'RECORD_COUNT_MISMATCH'\n | 'TRAILING_BYTES'\n | 'DEGENERATE_DIGITAL_RANGE'\n | 'DEGENERATE_PHYSICAL_RANGE'\n | 'UNUSABLE_PHYSICAL_RANGE'\n | 'INVERTED_PHYSICAL_RANGE'\n | 'DUPLICATE_LABEL'\n | 'EMPTY_LABEL'\n | 'NO_ANNOTATIONS'\n | 'ANNOTATION_DECODE_FAILED'\n | 'COMMA_DECIMAL'\n | 'LARGE_OUTPUT'\n | 'NO_SIGNAL_CHANNELS'\n | 'NO_SAMPLES'\n | 'STALE_OUTPUT'\n | 'INPUT_CHANGED'\n | 'EMPTY_WINDOW'\n | 'TIME_RESOLUTION'\n | 'HEADER_BYTES_MISMATCH'\n | 'NONPRINTABLE_LABEL';\n\nexport interface Diagnostic {\n code: DiagnosticCode;\n severity: 'warning' | 'info';\n message: string;\n /** What the user can do about it. Omitted when there is nothing useful to say. */\n hint?: string;\n}\n\nexport type EdfErrorCode =\n | 'FILE_TOO_SMALL'\n | 'BAD_HEADER_FIELD'\n | 'NO_DATA_RECORDS'\n | 'INVALID_SIGNAL_COUNT'\n | 'INVALID_RECORD_DURATION'\n | 'NO_SAMPLES'\n | 'UNREADABLE';\n\n/**\n * A fatal problem with the recording itself. Carries a stable `code` so the CLI\n * can map it to an exit status, and a `hint` so the user is not left guessing.\n */\nexport class EdfError extends Error {\n readonly code: EdfErrorCode;\n readonly hint: string | undefined;\n\n constructor(code: EdfErrorCode, message: string, hint?: string) {\n super(message);\n this.name = 'EdfError';\n this.code = code;\n this.hint = hint;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"header.js","sourceRoot":"","sources":["../../src/edf/header.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"header.js","sourceRoot":"","sources":["../../src/edf/header.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * EDF / EDF+ header parsing.\n *\n * Layout (all fields are ASCII, left-justified, space-padded):\n *\n * fixed header, 256 bytes\n * 0 8 version ('0', or 255 + 'BIOSEMI' for BDF)\n * 8 80 patient identification\n * 88 80 recording identification\n * 168 8 start date dd.mm.yy\n * 176 8 start time hh.mm.ss\n * 184 8 number of bytes in the header record\n * 192 44 reserved ('EDF+C' / 'EDF+D' live here)\n * 236 8 number of data records (-1 if unknown)\n * 244 8 duration of a data record, in seconds (may be fractional)\n * 252 4 number of signals (ns)\n *\n * signal header, ns * 256 bytes, stored FIELD-major rather than signal-major:\n * all ns labels, then all ns transducer types, and so on.\n * ns * 16 label\n * ns * 80 transducer type\n * ns * 8 physical dimension\n * ns * 8 physical minimum\n * ns * 8 physical maximum\n * ns * 8 digital minimum\n * ns * 8 digital maximum\n * ns * 80 prefiltering\n * ns * 8 number of samples in each data record\n * ns * 32 reserved\n */\n\nimport { EdfError } from './errors.js';\nimport type { Diagnostic } from './errors.js';\nimport { listed } from '../format/list.js';\nimport { decodeLatin1 } from './bytes.js';\n\n/** Label the EDF+ spec reserves for the annotations channel. */\nexport const ANNOTATIONS_LABEL = 'EDF Annotations';\n/** BDF+ uses its own spelling for the same channel. */\nexport const BDF_ANNOTATIONS_LABEL = 'BDF Annotations';\n\nexport const FIXED_HEADER_BYTES = 256;\nexport const SIGNAL_HEADER_BYTES = 256;\n\nexport interface EdfSignal {\n /** Position in the file, 0-based. Stable even when labels collide. */\n index: number;\n label: string;\n transducer: string;\n physicalDimension: string;\n physicalMin: number;\n physicalMax: number;\n digitalMin: number;\n digitalMax: number;\n prefiltering: string;\n samplesPerRecord: number;\n reserved: string;\n /** True for the EDF+ 'EDF Annotations' channel, which carries text, not signal. */\n isAnnotations: boolean;\n /** samplesPerRecord / recordDuration, in Hz. */\n samplingRate: number;\n /** Byte offset of this signal's samples within one data record. */\n byteOffsetInRecord: number;\n}\n\nexport interface EdfHeader {\n version: string;\n patientId: string;\n recordingId: string;\n /** Raw 'dd.mm.yy' as written in the file. */\n startDateRaw: string;\n /** Raw 'hh.mm.ss' as written in the file. */\n startTimeRaw: string;\n /** Resolved start instant, or null when the file's date/time fields are unusable. */\n startDateTime: Date | null;\n /**\n * Header size in bytes, computed from the signal count rather than read from the field.\n *\n * Every data record offset is derived from this, so it has to be the one the layout\n * actually uses: 256 for the fixed header plus 256 per signal. A writer that fills the\n * field in carelessly is common enough to have its own warning, HEADER_BYTES_MISMATCH,\n * and trusting the field over the arithmetic would put every sample at the wrong offset.\n */\n headerBytes: number;\n /**\n * What the header's own length field says, which need not be the above.\n *\n * Exposed for the same reason `declaredRecordCount` is: the two disagreeing is a fact\n * about the file, and a caller checking how a recording was written should be able to see\n * what it claimed rather than only what was believed.\n */\n declaredHeaderBytes: number;\n reserved: string;\n isEdfPlus: boolean;\n /** True for BioSemi BDF/BDF+ files, whose samples are 3 bytes rather than 2. */\n isBdf: boolean;\n /** 'EDF+C' continuous, 'EDF+D' discontinuous, or null for plain EDF. */\n continuity: 'EDF+C' | 'EDF+D' | null;\n /** As declared in the header. -1 means \"unknown\", which the spec permits. */\n declaredRecordCount: number;\n recordDuration: number;\n signalCount: number;\n signals: EdfSignal[];\n bytesPerSample: number;\n recordBytes: number;\n}\n\n/** Everything derived by combining the header with the file's real size. */\nexport interface EdfHeaderInfo {\n header: EdfHeader;\n /** Record count implied by the actual file size — the one we trust for reading. */\n recordCount: number;\n /** Bytes after the last complete data record. */\n trailingBytes: number;\n diagnostics: Diagnostic[];\n}\n\n/**\n * A byte the terminal treats as an instruction rather than as text.\n *\n * C0 and C1, plus DEL. Tab is included deliberately: it is harmless to a terminal but it\n * makes a CSV column name that cannot be typed or matched reliably, which is the other half\n * of what this warning is for.\n */\nfunction isControlCharacter(character: string): boolean {\n const code = character.codePointAt(0) as number;\n return code <= 0x1f || (code >= 0x7f && code <= 0x9f);\n}\n\nconst dec = (buf: Uint8Array, start: number, len: number): string =>\n decodeLatin1(buf, start, start + len);\n\n/** EDF fields are space-padded; trailing NULs also occur in files written by sloppy tools. */\nconst trimField = (s: string): string => s.replace(/[\\0\\s]+$/u, '').replace(/^\\s+/u, '');\n\n/**\n * How many signals the fixed header says there are, read exactly as `parseHeader` will.\n *\n * `EdfFile.open` needs this before it can know how much header to read, and it used to work\n * it out with its own `Number(...)` — which was NUL-tolerant but not comma-tolerant, unlike\n * every other numeric field here. A header written with a comma decimal separator, which\n * COMMA_DECIMAL exists to accept and which the documentation lists this field among, was\n * therefore never given its signal headers at all, and the file died on a message that\n * contradicted itself: \"needs a 768-byte header, but the file is only 848 bytes\".\n *\n * Sharing the parse is what keeps the two from disagreeing again about which files are\n * readable. Null means \"not a usable count\", and the caller reads no further header — the\n * real error then comes from `parseHeader`, which is the one place that decides.\n */\nexport function peekSignalCount(fixed: Uint8Array): number | null {\n const count = Number(normaliseNumberField(dec(fixed, 252, 4)).text);\n return Number.isInteger(count) && count > 0 ? count : null;\n}\n\n/** A numeric header field, trimmed and with a comma decimal separator turned into a dot. */\nfunction normaliseNumberField(raw: string): { text: string; sawComma: boolean } {\n const text = trimField(raw);\n // Some writers emit a comma decimal separator despite the spec requiring '.'.\n if (text.includes(',') && !text.includes('.')) {\n return { text: text.replace(',', '.'), sawComma: true };\n }\n return { text, sawComma: false };\n}\n\nfunction parseNumberField(\n raw: string,\n field: string,\n { integer = false, sawComma }: { integer?: boolean; sawComma?: { value: boolean } } = {},\n): number {\n const normalised = normaliseNumberField(raw);\n const text = normalised.text;\n if (normalised.sawComma && sawComma) sawComma.value = true;\n if (text === '') {\n throw new EdfError('BAD_HEADER_FIELD', `Header field \"${field}\" is empty.`);\n }\n const n = Number(text);\n if (!Number.isFinite(n)) {\n throw new EdfError(\n 'BAD_HEADER_FIELD',\n `Header field \"${field}\" is not a number (found ${JSON.stringify(text)}).`,\n 'The file may be truncated, byte-shifted, or not an EDF file at all.',\n );\n }\n if (integer && !Number.isInteger(n)) {\n throw new EdfError(\n 'BAD_HEADER_FIELD',\n `Header field \"${field}\" must be a whole number (found ${JSON.stringify(text)}).`,\n );\n }\n return n;\n}\n\n/**\n * EDF stores a two-digit year. The spec pins the century: 85-99 mean 1985-1999\n * and 00-84 mean 2000-2084. Files outside 1985-2084 cannot express their date.\n */\nfunction resolveStartDateTime(dateRaw: string, timeRaw: string): Date | null {\n const d = /^(\\d{2})[.\\-/](\\d{2})[.\\-/](\\d{2})$/u.exec(trimField(dateRaw));\n const t = /^(\\d{2})[.:\\-](\\d{2})[.:\\-](\\d{2})$/u.exec(trimField(timeRaw));\n if (!d || !t) return null;\n\n const dd = Number(d[1]);\n const mm = Number(d[2]);\n const yy = Number(d[3]);\n const hh = Number(t[1]);\n const mi = Number(t[2]);\n const ss = Number(t[3]);\n\n if (mm < 1 || mm > 12 || dd < 1 || dd > 31 || hh > 23 || mi > 59 || ss > 60) return null;\n\n const year = yy >= 85 ? 1900 + yy : 2000 + yy;\n const date = new Date(Date.UTC(year, mm - 1, dd, hh, mi, Math.min(ss, 59)));\n // Reject dates that rolled over, e.g. 31.02.\n if (date.getUTCMonth() !== mm - 1 || date.getUTCDate() !== dd) return null;\n return date;\n}\n\n/**\n * Parse the fixed 256-byte header plus the per-signal header block.\n *\n * @param buf At least FIXED_HEADER_BYTES + ns * SIGNAL_HEADER_BYTES bytes.\n * @param fileSize Total size of the file on disk, used to derive the real record count.\n */\nexport function parseHeader(buf: Uint8Array, fileSize: number): EdfHeaderInfo {\n const diagnostics: Diagnostic[] = [];\n const sawComma = { value: false };\n\n if (buf.length < FIXED_HEADER_BYTES) {\n throw new EdfError(\n 'FILE_TOO_SMALL',\n `File is ${fileSize} bytes; an EDF header alone needs at least ${FIXED_HEADER_BYTES}.`,\n );\n }\n\n // BDF (BioSemi) marks itself with byte 255 followed by 'BIOSEMI', and stores\n // 3-byte samples instead of 2. Everything else about the layout is identical.\n const isBdf = buf[0] === 0xff && dec(buf, 1, 7) === 'BIOSEMI';\n const version = isBdf ? 'BIOSEMI' : trimField(dec(buf, 0, 8));\n\n const patientId = trimField(dec(buf, 8, 80));\n const recordingId = trimField(dec(buf, 88, 80));\n const startDateRaw = trimField(dec(buf, 168, 8));\n const startTimeRaw = trimField(dec(buf, 176, 8));\n const headerBytes = parseNumberField(dec(buf, 184, 8), 'number of header bytes', {\n integer: true,\n sawComma,\n });\n const reserved = trimField(dec(buf, 192, 44));\n const declaredRecordCount = parseNumberField(dec(buf, 236, 8), 'number of data records', {\n integer: true,\n sawComma,\n });\n const recordDuration = parseNumberField(dec(buf, 244, 8), 'duration of a data record', {\n sawComma,\n });\n const signalCount = parseNumberField(dec(buf, 252, 4), 'number of signals', {\n integer: true,\n sawComma,\n });\n\n if (signalCount <= 0) {\n throw new EdfError(\n 'INVALID_SIGNAL_COUNT',\n `Header declares ${signalCount} signals; expected at least 1.`,\n );\n }\n if (!(recordDuration > 0)) {\n throw new EdfError(\n 'INVALID_RECORD_DURATION',\n `Header declares a data record duration of ${recordDuration}s; expected a positive number.`,\n );\n }\n\n const expectedHeaderBytes = FIXED_HEADER_BYTES + signalCount * SIGNAL_HEADER_BYTES;\n if (buf.length < expectedHeaderBytes) {\n throw new EdfError(\n 'FILE_TOO_SMALL',\n /*\n Which of the two is actually short.\n\n The file size was quoted either way, so a caller that had read too little — the\n signal count parsed one way here and another way there — produced arithmetic that\n refuted itself: \"needs a 768-byte header, but the file is only 848 bytes\". A reader\n following that looks for a truncation that is not there.\n */\n `File declares ${signalCount} signals, which needs a ${expectedHeaderBytes}-byte header, ` +\n (fileSize < expectedHeaderBytes\n ? `but the file is only ${fileSize} bytes.`\n : `but only ${buf.length} bytes of it were handed to the parser.`),\n );\n }\n if (headerBytes !== expectedHeaderBytes) {\n diagnostics.push({\n code: 'HEADER_BYTES_MISMATCH',\n severity: 'warning',\n message:\n `Header says it is ${headerBytes} bytes, but ${signalCount} signals require ` +\n `${expectedHeaderBytes} bytes. Using the value computed from the signal count.`,\n });\n }\n\n // Signal headers are field-major: all labels, then all transducers, and so on.\n const base = FIXED_HEADER_BYTES;\n const readField = (offsetUnits: number, width: number, i: number): string =>\n dec(buf, base + offsetUnits * signalCount + i * width, width);\n\n // EDF+ writes 'EDF+C'/'EDF+D' here; BDF+ writes 'BDF+C'/'BDF+D'. The two mean the\n // same thing, so both are normalised to a single continuity marker.\n const continuityTag = /^(?:EDF|BDF)\\+([CD])/u.exec(reserved);\n const continuity: 'EDF+C' | 'EDF+D' | null =\n continuityTag === null ? null : continuityTag[1] === 'D' ? 'EDF+D' : 'EDF+C';\n\n const signals: EdfSignal[] = [];\n let byteOffsetInRecord = 0;\n const bytesPerSample = isBdf ? 3 : 2;\n const seenLabels = new Map<string, number[]>();\n\n for (let i = 0; i < signalCount; i++) {\n const label = trimField(readField(0, 16, i));\n const transducer = trimField(readField(16, 80, i));\n const physicalDimension = trimField(readField(96, 8, i));\n const physicalMin = parseNumberField(readField(104, 8, i), `physical minimum (signal ${i})`, {\n sawComma,\n });\n const physicalMax = parseNumberField(readField(112, 8, i), `physical maximum (signal ${i})`, {\n sawComma,\n });\n const digitalMin = parseNumberField(readField(120, 8, i), `digital minimum (signal ${i})`, {\n integer: true,\n sawComma,\n });\n const digitalMax = parseNumberField(readField(128, 8, i), `digital maximum (signal ${i})`, {\n integer: true,\n sawComma,\n });\n const prefiltering = trimField(readField(136, 80, i));\n const samplesPerRecord = parseNumberField(\n readField(216, 8, i),\n `samples per record (signal ${i})`,\n { integer: true, sawComma },\n );\n const sigReserved = trimField(readField(224, 32, i));\n\n if (samplesPerRecord < 0) {\n throw new EdfError(\n 'BAD_HEADER_FIELD',\n `Signal ${i} (\"${label}\") declares ${samplesPerRecord} samples per record.`,\n );\n }\n\n const isAnnotations = label === ANNOTATIONS_LABEL || label === BDF_ANNOTATIONS_LABEL;\n\n signals.push({\n index: i,\n label,\n transducer,\n physicalDimension,\n physicalMin,\n physicalMax,\n digitalMin,\n digitalMax,\n prefiltering,\n samplesPerRecord,\n reserved: sigReserved,\n isAnnotations,\n samplingRate: samplesPerRecord / recordDuration,\n byteOffsetInRecord,\n });\n byteOffsetInRecord += samplesPerRecord * bytesPerSample;\n\n if (!isAnnotations) {\n /*\n A label is free text out of the file, and it becomes a column name in signals.csv.\n\n `--info` has escaped control bytes since it was written, because an ANSI escape in a\n header can drive the reader's terminal — `\\x1b[2J` clears the screen. The CSV had no\n such protection and needed none for correctness: quoting makes any byte safe for a\n parser, and this still passes the label through exactly as the file gives it, because\n losing what the header says is not an improvement.\n\n What was missing is the sentence saying so. A recording whose channel is labelled\n `\\x1b[2Jgone` converted with no warning at all, and `cat signals.csv` then cleared\n the terminal — while a script referencing that column by name carried an invisible\n control character in it. NONPRINTABLE_LABEL has been declared and documented as\n reserved since 0.1; this is it doing its job.\n */\n const control = [...label, ...physicalDimension].filter(isControlCharacter);\n if (control.length > 0) {\n const shown = [...new Set(control)]\n .map((c) => `\\\\x${(c.codePointAt(0) as number).toString(16).padStart(2, '0')}`)\n .join(', ');\n diagnostics.push({\n code: 'NONPRINTABLE_LABEL',\n severity: 'warning',\n message:\n `Signal ${i}'s label or unit contains ${control.length} control ` +\n `character${control.length === 1 ? '' : 's'} (${shown}), which will appear in the ` +\n `CSV column name exactly as the header has them.`,\n hint:\n 'Address the channel by position with --channels \"#' +\n `${i}\" rather than by name, since the name cannot be typed. Printing the CSV to a ` +\n 'terminal may do more than print it.',\n });\n }\n\n if (label === '') {\n diagnostics.push({\n code: 'EMPTY_LABEL',\n severity: 'warning',\n message: `Signal ${i} has no label. It will appear as \"signal_${i}\".`,\n });\n } else {\n // Collected rather than reported here: a label repeated five times should\n // produce one warning naming all five, not four near-identical pairs.\n const seen = seenLabels.get(label);\n if (seen) seen.push(i);\n else seenLabels.set(label, [i]);\n }\n\n if (samplesPerRecord === 0) {\n diagnostics.push({\n code: 'NO_SAMPLES',\n severity: 'warning',\n message: `Signal ${i} (\"${label}\") carries no samples at all (0 per data record).`,\n hint: 'It is described in channels.csv but left out of the converted data.',\n });\n }\n\n if (!Number.isFinite(physicalMax - physicalMin)) {\n diagnostics.push({\n code: 'UNUSABLE_PHYSICAL_RANGE',\n severity: 'warning',\n message:\n `Signal ${i} (\"${label}\") declares a physical range from ${physicalMin} to ` +\n `${physicalMax}, whose span is too large to represent, so its values cannot be scaled.`,\n hint: 'Its cells are left empty rather than filled with a value the header cannot justify.',\n });\n } else if (digitalMax === digitalMin) {\n diagnostics.push({\n code: 'DEGENERATE_DIGITAL_RANGE',\n severity: 'warning',\n message:\n `Signal ${i} (\"${label}\") has digital minimum equal to digital maximum ` +\n `(${digitalMin}), so its values cannot be scaled.`,\n hint: 'Its cells are left empty rather than filled with a value the header cannot justify.',\n });\n } else if (physicalMax === physicalMin) {\n diagnostics.push({\n code: 'DEGENERATE_PHYSICAL_RANGE',\n severity: 'warning',\n message:\n `Signal ${i} (\"${label}\") has physical minimum equal to physical maximum ` +\n `(${physicalMin}), so every sample converts to the same value.`,\n });\n } else if ((physicalMax - physicalMin) * (digitalMax - digitalMin) < 0) {\n /*\n Polarity is inverted when the gain is negative, and the gain is\n (physicalMax - physicalMin) / (digitalMax - digitalMin) — so it is the sign of the\n two spans together that matters, not the physical pair alone.\n\n Testing only `physicalMax < physicalMin` was wrong in both directions. A file with\n its DIGITAL bounds reversed is just as inverted and drew no warning at all, handing\n back sign-flipped EEG with nothing to indicate it. A file with BOTH pairs reversed\n has a positive gain and is not inverted, yet was warned about — a message that was\n simply untrue of that recording.\n */\n const reversed =\n physicalMax < physicalMin\n ? `physical minimum ${physicalMin} above physical maximum ${physicalMax}`\n : `digital minimum ${digitalMin} above digital maximum ${digitalMax}`;\n diagnostics.push({\n code: 'INVERTED_PHYSICAL_RANGE',\n severity: 'warning',\n message: `Signal ${i} (\"${label}\") declares ${reversed}, which inverts its polarity.`,\n hint: 'The values are converted exactly as the header specifies, inversion included.',\n });\n }\n }\n }\n\n for (const [label, indices] of seenLabels) {\n if (indices.length < 2) continue;\n diagnostics.push({\n code: 'DUPLICATE_LABEL',\n severity: 'warning',\n message: `${indices.length} signals share the label \"${label}\" (positions ${indices.join(', ')}).`,\n hint: 'Their columns are suffixed with the signal number so they stay distinguishable.',\n });\n }\n\n const recordBytes = byteOffsetInRecord;\n if (recordBytes <= 0) {\n throw new EdfError(\n 'NO_SAMPLES',\n 'No signal in this file carries any samples (every channel declares 0 samples per record).',\n );\n }\n\n if (sawComma.value) {\n diagnostics.push({\n code: 'COMMA_DECIMAL',\n severity: 'warning',\n message: 'Some header numbers use a comma decimal separator, which the EDF spec does not allow.',\n hint: 'They were read as decimal points. Check the values in the channel table.',\n });\n }\n\n const dataBytes = fileSize - expectedHeaderBytes;\n if (dataBytes < 0) {\n throw new EdfError('FILE_TOO_SMALL', `File is smaller than its own header.`);\n }\n const recordCount = Math.floor(dataBytes / recordBytes);\n const trailingBytes = dataBytes - recordCount * recordBytes;\n\n if (recordCount === 0) {\n throw new EdfError(\n 'NO_DATA_RECORDS',\n 'The file contains a header but no complete data record.',\n 'The recording was probably interrupted before any data was written.',\n );\n }\n\n if (declaredRecordCount === -1) {\n diagnostics.push({\n code: 'RECORD_COUNT_UNKNOWN',\n severity: 'warning',\n message:\n `The header does not say how many data records the file has (-1), which the spec allows ` +\n `for recordings still in progress. Using the ${recordCount} records the file actually contains.`,\n });\n } else if (declaredRecordCount !== recordCount) {\n diagnostics.push({\n code: 'RECORD_COUNT_MISMATCH',\n severity: 'warning',\n message:\n `The header declares ${declaredRecordCount} data records but the file contains ` +\n `${recordCount}. Converting the ${recordCount} records that are present.`,\n hint:\n declaredRecordCount > recordCount\n ? 'The recording looks truncated. It may have been cut short or copied incompletely.'\n : 'The file is longer than its header claims.',\n });\n }\n\n if (trailingBytes > 0) {\n diagnostics.push({\n code: 'TRAILING_BYTES',\n severity: 'warning',\n message: `${trailingBytes} bytes after the last complete data record were ignored.`,\n });\n }\n\n const isEdfPlus = continuity !== null;\n if (continuity === 'EDF+D') {\n diagnostics.push({\n code: 'DISCONTINUOUS',\n severity: 'warning',\n message:\n `This is a discontinuous (${isBdf ? 'BDF+D' : 'EDF+D'}) recording: its data records are ` +\n `not contiguous in time.`,\n hint: 'Each row carries its true recording time, so gaps stay visible instead of being closed.',\n });\n }\n\n const dataSignals = signals.filter((s) => !s.isAnnotations);\n if (dataSignals.length === 0) {\n diagnostics.push({\n code: 'NO_SIGNAL_CHANNELS',\n severity: 'warning',\n message: 'This file has no signal channels; it contains only EDF+ annotations.',\n });\n }\n\n // A channel declaring zero samples per record has no sampling rate to speak of — it is\n // reported separately as NO_SAMPLES and no file is written for it. Counting its nominal\n // 0 Hz as a rate made a single-rate recording warn that it used \"2 different sampling\n // rates (4 Hz, 0 Hz)\" and claim it was splitting output it never split.\n const rates = new Set(dataSignals.filter((s) => s.samplesPerRecord > 0).map((s) => s.samplingRate));\n if (rates.size > 1) {\n diagnostics.push({\n code: 'MIXED_SAMPLING_RATES',\n severity: 'warning',\n message:\n `Channels use ${rates.size} different sampling rates ` +\n `(${listed(formatRates([...rates].sort((a, b) => b - a)).map((r) => `${r} Hz`))}).`,\n hint: 'They are written to one file per rate so no channel is resampled.',\n });\n }\n\n return {\n header: {\n version,\n patientId,\n recordingId,\n startDateRaw,\n startTimeRaw,\n startDateTime: resolveStartDateTime(startDateRaw, startTimeRaw),\n headerBytes: expectedHeaderBytes,\n declaredHeaderBytes: headerBytes,\n reserved,\n isEdfPlus,\n isBdf,\n continuity,\n declaredRecordCount,\n recordDuration,\n signalCount,\n signals,\n bytesPerSample,\n recordBytes,\n },\n recordCount,\n trailingBytes,\n diagnostics,\n };\n}\n\n/**\n * The recording start as a zone-less wall clock, \"YYYY-MM-DDTHH:MM:SS\".\n *\n * EDF stores the start time as local wall-clock digits with no timezone anywhere in\n * the format. `startDateTime` is built with Date.UTC purely so those digits survive a\n * round trip unshifted, which makes it a carrier for the wall clock rather than a\n * real instant. Serialising it with `toISOString()` would append a Z and assert UTC,\n * and any reader converting to local time would then shift the recording by their own\n * offset: 13:43:04 in the file becomes 08:43:04 in New York. The Z is omitted because\n * the file genuinely does not say which zone it meant.\n */\nexport function formatWallClock(date: Date | null): string | null {\n if (!date) return null;\n return date.toISOString().slice(0, 19);\n}\n\n/** \"EDF\", \"EDF+ (EDF+D)\", \"BDF\", \"BDF+ (EDF+C)\". */\nexport function describeFormat(header: EdfHeader): string {\n const base = header.isBdf ? 'BDF' : 'EDF';\n if (!header.isEdfPlus) return base;\n return `${base}+ (${header.continuity === 'EDF+D' ? 'discontinuous' : 'continuous'})`;\n}\n\n/** Render a sampling rate without trailing noise: 256, 0.5, 12.5. */\nexport function formatRate(hz: number): string {\n if (Number.isInteger(hz)) return String(hz);\n const rounded = Number(hz.toFixed(6));\n // A rate below 5e-7 rounds away to \"0\", which reads as \"this channel has no sampling\n // rate\" and made the mixed-rate warning contradict itself: it announced two different\n // rates and then printed both as \"0 Hz\". Exponent form keeps a real rate legible, and\n // keeps distinct rates distinct in the channel table and in output filenames.\n if (rounded === 0) return hz.toExponential(3);\n return String(rounded);\n}\n\n/**\n * Renders a group of rates so that rates which differ read as differing.\n *\n * `formatRate` rounds to six decimals, which is what keeps an ordinary rate free of\n * float noise — 30 samples in a 0.1-second record is 299.99999999999994 as a double,\n * and belongs on screen as 300. Two rates separated by less than that round to one\n * string, so a file carrying 1e-6 Hz and 1.25e-6 Hz warned that it used \"2 different\n * sampling rates (0.000001 Hz, 0.000001 Hz)\" and named both files the same thing.\n *\n * That is the contradiction the exponent fallback above already removes for rates that\n * round away to zero; this is the same one a step further out. On a collision every rate\n * in the group switches to its shortest exact form, which is unique for distinct values,\n * rather than only the pair that collided — one column in one notation reads better than\n * two.\n */\nexport function formatRates(rates: readonly number[]): string[] {\n const rounded = rates.map(formatRate);\n const distinct = new Set(rates).size;\n return new Set(rounded).size === distinct ? rounded : rates.map((hz) => String(hz));\n}\n"]}