对EDF/BDF格式的几点想法

如果你在脑电(EEG)或者睡眠监测(PSG)领域工作,大概率听过 EDF 格式,也可能听说过它的升级版 EDF+ 或 BDF。这些格式在科研里用得非常广泛,是研究人员存储和分享数据的“通用语言”。

我之前写过一个 EDF 与其他格式互转的工具(https://github.com/eegdb/eeg_convert),但今天我不打算讲怎么用 EDF,而是想聊聊一个问题:在现代 EEG 设备里,EDF/BDF 还能跟上高采样、多导联和实时性需求吗?

EDF资料

https://www.edfplus.info/specs/edf.html

实时写入

EDF最初是为数据共享和存储设计的,它的核心思想很简单:把数据分块存储,每块叫做一个 record。每个 record 的时长固定,由 8 个 ASCII 字节表示。这样做的好处是结构清晰、解析方便,但对实时写入来说就有些力不从心了。 现在很多 EEG 设备都用无线传输,这就带来两个问题:

  • 数据顺序:无线可能乱序,蓝牙\TCP等协议也有重传机制。

  • 数据传输过程中意外丢失。

所以,想实时把 EEG 数据写进 EDF,就必须额外维护缓存(buffer),处理这些异常情况。 示例图片

多模态、多导联的支持

EDF 对多导联、多模态信号的支持有限。举个例子:

假设系统里有两个采集芯片:

  • 芯片 A:25 Hz

  • 芯片 B:250 Hz

如果要把它们写进同一个 EDF 文件,就要面对 record 时长选择的问题:

  • record 太短 → 分块太多,性能差

  • record 太长 → 单块数据太大,也影响性能

简单分析一下采样周期:

  • 25 Hz → 每个采样 0.04 s

  • 250 Hz → 每个采样 0.004 s

公共采样周期 → 0.04 s

也就是说,最小 record 时长就是 0.04 s,否则 EDF 结构不允许。另一种方法是写两个 EDF 文件,现实中有人使用多个EDF来记录一个数据么?我不清楚。

时间:

EDF 的时间概念很粗糙:Header 里有开始时间,但精度只到秒。

在一些 ERP 或事件相关实验中,秒级精度显然不够。工程上通常会在 EDF 文件里额外加字段来记录更精确的时间: 示例图片

查询

  • 连续数据:可以直接按文件偏移跳到对应时间位置。

  • 不连续数据:非连续数据的查询及其糟糕。只能在每一个record里记录相对开始时间的offset。时间查询时可能需要先把所有 record 的 offset 载入内存,再开始查询,也就是说我们需要把整个EDF文件都读一遍。

对于不连续的数据,为了加速查询,我们需要额外建立一个索引表。