从 OPM、SQUID、EEG 原始数据到 BIDS:一个多模态脑磁数据处理项目实践

1. 背景:我是做什么工作的

我目前的研究方向是基于原子磁力仪(OPM)的脑磁图(MEG)研究。

组里有两份远古时期传承下来的数据,一份做出来,一份没做出来。数据格式是txt,内里只有数据,命名诡异,其他无任何说明 🤤
大量时间都花在搞清楚这个设备参数、实验范式和整理数据上了

不同设备导出的数据格式各异,元数据散落在实验记录本里,后续如果想用 MNE-Python 等标准工具链进行分析,往往需要写大量的“胶水代码”来适配。

  • 因此,先把数据组织成可复现、可验证、可继续分析的工程项目,这很重要。

有一天拷打在AI,无意中看到了珍贵的多模态脑数据,涵盖了 SQUID-MEG、OPM-MEG,以及和 SQUID 同步采集的 EEG 数据。

image
OPM-MEG, SQUID-MEG, and EEG (OSE) dataset

根据 MNE 官方推荐解决方案,可将所有原始数据统一转换为 BIDS(Brain Imaging Data Structure)标准格式。

2. 原始数据长什么样

本次项目共包含 5 名被试:002、005、006、093、095
每位被试在一次实验中通常包含以下几类数据:

  • EEG:脑电图
  • SQUID:传统低温超导 MEG
  • OPM:可穿戴光泵磁力仪 MEG
  • Empty:空房间环境噪声记录
  • T1:结构磁共振成像(用于后续源定位)
    实验任务包含四个范式:auditory(听觉)、motor(运动)、rest(静息态)、somatosensory(体感)。

原始数据的格式不统一:

  • EEG 使用 BrainVision 格式(三件套 .vhdr/.vmrk/.eeg)。
  • OPM 导出为 MATLAB .mat 文件,包含数据矩阵、传感器位置、方向和 trigger。
  • SQUID 使用 Ricoh/KIT 系统的 .con 格式。
    如果不做标准化,这三份数据不好入手。

3. BIDS 长什么样

BIDS 不仅仅是一个目录命名规范,它强制你保留数据的上下文。把数据转成 BIDS 的工程收益包括:

  1. 统一入口:后续所有分析只需通过 mne-bids 读取,不用关心底层是 .eeg 还是 .con
  2. 元数据保留:通道信息、事件信息、坐标系等以 .tsv.json 标准化保存,人机可读。
  3. 无缝衔接 Pipeline:转成 BIDS 后,可以直接接入 mne-bids-pipeline 等自动化流程,极大提升复现性。
    转换后的 BIDS 目录结构如下:
bids_dataset/
  sub-002/
    ses-01/
      eeg/
        sub-002_ses-01_task-auditory_eeg.vhdr
        sub-002_ses-01_task-auditory_eeg.vmrk
        sub-002_ses-01_task-auditory_eeg.eeg
        sub-002_ses-01_task-auditory_eeg.json
        sub-002_ses-01_task-auditory_channels.tsv
        sub-002_ses-01_task-auditory_events.tsv
        sub-002_ses-01_task-auditory_electrodes.tsv
        sub-002_ses-01_task-auditory_coordsystem.json
      meg/
        sub-002_ses-01_task-auditory_meg.con
        sub-002_ses-01_task-auditory_channels.tsv
        ...
  sub-emptyroom/
    ses-01/
      meg/
        sub-emptyroom_ses-01_task-noise_meg.con
吐槽一下,我觉得这个结构似乎不是给人类准备的

4. 三种设备的转换差异(核心踩坑记录)

这是整个项目中最耗时的部分,不同设备的转换逻辑差异巨大,以下是各类设备处理的核心思路:

:)我现在有[OPM-MEG, SQUID-MEG, and EEG (OSE) dataset],在文件夹内,请你将它们依次规整成BIDS格式

OPM: MAT 文件解析重构

OPM 数据是 .mat 文件,虽然官方提供了Reading data for different recording systems,但是因为程序处理字段是写死的,不一致就会有报错

比如这里 KeyError: 'data' 在这个.mat文件中数据字段是 bexp 🌞

image

这里我选择古法炮制数据——将.mat文件拆开再填充进新建RAW对象,胃,这真的很酷,不是吗 😎

提取数据矩阵、采样率、通道名称、传感器位置和朝向(坐标转换矩阵) 以及 trigger 通道

这里的传感器位置很重要,后续的降噪处理比如 HFC 会用到,需要写入进loc数组中

注意到探头型号是 Quspin (数据文档也有标明)

FIFFV_COIL_QUSPIN_ZFOPM_MAG 是 Z 轴 OPM,其线圈坐标系中敏感轴是 z 轴,即 [0,0,1]

MNE 将 loc[3:12] 解释为 3×3 旋转矩阵的三列:

loc[3:6]  = ex  ← 线圈局部坐标系 x 轴在 head 坐标下的方向
loc[6:9]  = ey
loc[9:12] = ez  ← 线圈 z 轴 = 敏感轴,在 head 坐标下的方向

compute_proj_hfc 计算各传感器法向量时,执行的是 R @ [0,0,1] = loc[9:12]
你的代码把 pick_ori[i](敏感轴)写进了 loc[3:6],而 loc[9:12] 全为零 → HFC 看到的所有法向量都是零向量 → 投影矩阵退化,校正完全无效。

然后,使用 MNE 的 mne.io.RawArray 构造 Raw 对象,转成 fif,最后统一通过 mne-bids 写入标准的 FIF 和 BIDS sidecar 文件。

以上是摸索,下面使用了 GPT5.5 一步到位,简直爽歪歪

EEG: BrainVision 格式整理

BrainVision 格式相对友好,mne-bids 原生支持较好。这里的工程重点在于修正内部文件引用(确保 .vhdr 内部指向正确的 .eeg.vmrk),并确保手动补全标准的 channels.tsv(标记 EOG/ECG 等额外通道)、events.tsv(提取 trigger 转为事件)以及 electrodes.tsvcoordsystem.json(写入标准 10-10 系统电极坐标)。

SQUID: Ricoh/KIT .con 格式映射问题

SQUID 数据使用 Ricoh/KIT 系统的 .con 格式。这里遇到了一个硬坑:MNE 在读取特定型号(如 PQ1400R)的 .con 文件时,对 planar gradiometer(平面梯度计)的通道映射不完整,导致通道类型识别错误。
解决办法:通过运行时兼容映射(runtime compatibility mapping),强行将 .con 转换为标准的 FIF 文件,再手动写入 MEGGRADAXIAL(轴向梯度计)和 MEGGRADPLANAR(平面梯度计)
即可。这种方式比逐个填充通道参数(Info)更加优雅且不易出错。

from mne.io.constants import FIFF
from mne.io.kit import constants as kit_constants

kit_constants.KIT.CH_TO_FIFF_COIL[
    kit_constants.KIT.CHANNEL_PLANAR_GRADIOMETER
] = FIFF.FIFFV_COIL_KIT_GRAD

以上只是麻烦些,手动对齐颗粒度即可,遇到问题记得及时拷打AI 🤛

5. 我要验 BIDS 没有问题

我说写完 BIDS 一定要验证,不然还是感觉乱七八糟

以OPM为例

每个 OPM FIF 能否被 MNE 读取
channels.tsv 行数是否匹配 raw channel 数
meg.json 是否存在
coordsystem.json 是否存在
events.tsv 是否存在
保证每种设备本身是完整的、可读的、元数据基本一致
VALIDATORS = [
    ("EEG", "validate_eeg_bids.py"),
    ("OPM-MEG", "validate_opm_bids.py"),
    ("SQUID-MEG", "validate_squid_bids.py"),
    ("MNE-BIDS read", "validate_mne_bids_read.py"),
]
通道类型是否正确?
采样率是否一致?
事件是否能用于 epoch?
MNE-BIDS 是否能按 BIDSPath 逐个读取?
保证 MNE-BIDS pipeline 能跑起来
from mne_bids import BIDSPath, read_raw_bids

bids_path = BIDSPath(
    root="bids_dataset",
    subject="002",
    session="01",
    task="auditory",
    acquisition="squid",
    run="01",
    datatype="meg",
    suffix="meg",
    extension=".fif",
)

raw = read_raw_bids(bids_path=bids_path)
print(raw)

反正就是跑 + 输出参数,肉眼丁真一下看看有没有问题

前面仅对 RAW 对象填充字段和数据,加上AI审查生成,基本不会填充错误

不会很难,理顺就好

6. 第一版 auditory QC 结果

数据整理完毕后,不是我 GPT 跑了第一版听觉任务的质量控制分析。处理流程非常基础:

  1. 带通滤波 1-40 Hz
  2. 提取 Epoch 并进行 Baseline 校正
  3. 计算 Evoked 响应
  4. 计算 GFP(Global Field Power)和 RMS(Root Mean Square)
  5. 评估 SNR 和峰值潜伏期

group_auditory_gfp_by_acq

当前阶段的统计结果如下:

[Auditory Evoked Response QC]
EEG:    平均 SNR 6.89, 峰值潜伏期 176 ms
OPM:    平均 SNR 3.10, 峰值潜伏期 132.5 ms
SQUID:  平均 SNR 6.09, 峰值潜伏期 133.6 ms

特别声明:这只是第一版 QC(质量控制)数据。当前 OPM 的 SNR 偏低是预期的,因为我还啥也没做诶。这组数据目前的作用是证明“数据流转链路已完全打通”。

7. 下一步计划

有了可验证的 BIDS 数据集,接下来的工程化路线就非常清晰了:

总结:完善的BIDS结构数据集来喽

posted @ 2026-06-22 22:11  胡诌八扯  阅读(2)  评论(0)    收藏  举报