七个男人的心磁网格 — Kiel Cardio 心磁图库

7 人 / 200 个测点 / 6.8 GB 原始与预处理

来源 https://physionet.org/content/kiel-cardio/1.0.0/发布时间: 2026-10-28最后更新: 2026-10-28 阅读 13
七个男人的心磁网格 — Kiel Cardio 心磁图库

信息速览

数据集名称七个男人的心磁网格 — Kiel Cardio 心磁图库
数据类型时序信号,波形,元数据,原始数据链接
规模7 名健康男性志愿者 / 350 条记录
接入方式https://physionet.org/content/kiel-cardio/1.0.0/
AI 就绪度

心电图问世一百多年,一直是心脏病学最常用的工具。它的磁学孪生兄弟心磁图却始终停在小众:测的同样是心脏电活动,只是把体表电位换成体表磁场,量级落在皮特斯拉这一档,比地磁场弱好几个数量级。测它需要超导器件加液氦,或者光泵磁力仪加磁屏蔽室,设备贵、场地贵,能稳定产出数据的实验室一直不多。Kiel Cardio Database 就是在这一背景下公开的:基尔大学把自家屏蔽室里测到的第一批心磁数据放上 PhysioNet,让没有设备的课题组也能摸到这种信号。

它规模很小——七名健康男性,每人 25 次一分钟测量,胸前共 200 个测点。结构却相当特殊:四只光泵磁力仪组成小阵列,靠人工移动夹具逐格覆盖胸前,每一格都留下坐标。拿到数据的人不只是得到一段波形,还得到一张可以重建的空间网格。心磁研究里最难复制的往往不是信号本身,而是"在哪个位置测的",这个库把它写进了头文件。

需要说清的边界:没有心电图同步,没有磁共振,没有任何注释,受试者全部健康且为男性,第一版也只有心磁一个模态。它适合练手、验证算法、评估传感器,不适合直接训练诊断模型。换个说法,它提供的是"看得到心磁"这件事本身,而不是关于心脏的任何结论。一屏速览见下表。

维度 内容
全名 Kiel Cardio Database
发布方 PhysioNet(托管);数据由基尔大学采集
作者 Erik Engelhardt、Norbert Frey、Gerhard Schmidt
首次上线 2023 年 12 月 15 日,版本 1.0.0
规模 7 名受试者 × 25 次测量 = 350 条清单记录
每人测点数 200 个胸前位置
单次时长 一分钟
通道数 8 路(四只探头,各一至两个方向)
采样率 200 Hz
物理量 磁场,单位为皮特斯拉
传感器 QuSpin QZFM Gen 1 光泵磁力仪,四只
采集场景 磁屏蔽室,受试者仰卧,静息
受试者 7 名健康男性,22–50 岁,2022 年采集
注释 无(官方明确本版不提供)
文件格式 WFDB:.hea / .dat,raw 与 preprocessed 两套
体积 未压缩 6.8 GB,ZIP 压缩包 6.5 GB
许可 CC BY-SA 4.0,免注册

§1 它要解决的具体麻烦

1.1 心磁的瓶颈不在算法,在能不能测到

心电图的采集门槛极低:一副电极、一片前端、一台电脑就能录。心磁图不行。心脏电活动在体表产生的磁场是皮特斯拉量级,大约只有地磁场的百万分之一,没有屏蔽的环境里会被环境磁噪声整个淹没。要测到它,要么用必须泡在液氦里的超导量子干涉器件,要么用同样离不开屏蔽室的光泵磁力仪。两条路都指向同一件事:你得先有一间磁屏蔽室。

这解释了一个长期失衡:心电的公开数据数以百万计,心磁的公开数据用"个"来数。官方在背景一节直接点名 PhysioNet 上此前没有任何其它心磁数据库;文献综述里也只数出一份公开可得的心磁参考数据,含五名 25 至 35 岁男性,用 304 通道超导系统采集,其余提到建库的文章多数没有给出可下载的入口。

所以这个库要解决的麻烦与其说在算法层,不如说在准入层:让没有屏蔽室的人也能拿到真实心磁波形,先把方法做起来。官方摘要说得很直白,目的是让这种昂贵的方法对没有相应设备的研究者也可用。

1.2 三条常见的错误期待

第一条,期待它是一份心电数据。 这是名字造成的误读。Kiel Cardio Database 里的 cardio 指心血管,不指心电图;第一版里的全部内容都是磁场,单位皮特斯拉,没有一路是毫伏级的体表电位。心电的常见处理链路——基线校正、QRS 检测、心率变异性——很多能借,但没有一条可以直接照搬而不重新标定。

第二条,期待它有病理标签。 七名受试者都是健康男性。本版没有心搏标注、没有节律标注、没有诊断结论,也没有任何解读意见。官方在用法说明里点明,拿它做分割或检测类评测之前,必须先完成人工标注。

第三条,期待它是多模态的。 官方确实说了未来版本会补入心电、磁共振与注释,但那是计划,不是现状。当前版本只有心磁,也没有与任何其它模态配对的同步记录。想做心磁与心电的联合分析,得自己另找来源或另采。

1.3 它能给到的与给不到的

你的需求 它给的 够不够
真实心磁波形作方法预研 7 人各 25 次、每次 8 路的真实信号 够,这是主业
胸前网格上的磁场分布 200 个测点,每点带三维坐标 够,坐标写在头文件
传感器或阵列的性能评估 四只光泵磁力仪的双轴原始输出 够,原始与滤波都在
原始与预处理链路的对照 raw 与 preprocessed 两套并行 够,可直接比滤波代价
心搏或节律标注 无 不够,需自行标注
心磁与心电的同步分析 本版无心电 不够,等后续或另采
患者与健康人的判别 全部健康男性 不够,没有对照组
人群层面的统计推断 7 人 不够,样本量不允许

1.4 你的处境与它能帮到的事

你的处境 它能帮你什么 下一步该做什么
你的组刚拿到一只光泵磁力仪,还没有屏蔽室,想先看看真实信号长什么样 提供同型号探头(QuSpin QZFM Gen 1)在屏蔽室内的真实输出,可直接当作基线形态参考 先跑 §5.3 的读取,把 raw 与 preprocessed 各画一遍,再决定预处理链
你在做心磁去噪,缺带真值的干净段作参考 提供未经滤波的原始电压,与官方滤波版成对,可当作"输入—目标"的近似配对 注意官方滤波版不等于真值,见 §7.2
你想验证一个心磁源定位或等值线重建算法 200 个带坐标的测点构成不规则网格,正好做插值与重建 用 §2.3 的坐标解析把网格画出来,先确认覆盖形状
你在做心电算法向心磁迁移的可行性判断 同一套分割思路能否用在磁信号上,可以用它做小样本试跑 先自己做少数几个心搏的标注,再算迁移后的错检率
你在评估不同心磁设备的差异 提供光泵磁力仪这一条技术路线下的公开参照 与超导系统的公开数据对比,注意量级与噪声底不同
你在写综述,需要说清公开心磁数据有多稀缺 PhysioNet 上唯一的同类数据,可作为稀缺性的直接证据 引用时同时给出 DOI 与官方页面的背景一节

1.5 一句话判断

它是一份"让你在没有屏蔽室的情况下也能摸到心磁"的样本:七个人、两百个点、一分钟一段,足以看清心磁长什么样、够不够干净,却不足以支撑任何关于人的结论。

1.6 不适合谁:四条边界

不适合做人群层面的研究。 七个人、全是健康男性、都在同一间屏蔽室、用同一套设备、在同一年完成。任何一个维度都不具备外推的条件。想用它讨论年龄、性别、体型与心磁形态的关系,样本量在第一步就会把结论压成轶事。

不适合做监督学习。 没有标签,没有对照,没有健康与患病的切分。它连一个可以当作二分类目标的字段都不具备。想用它做监督任务,得先自己标注,而标注完的类别也仍然只有"健康"一类。

不适合做多模态融合。 本版只有心磁。官方确实规划了心电与磁共振,但在它们落地之前,任何"心磁+心电"的联合研究都必须另外解决配对问题,而这个库帮不上。

不适合当作跨机构泛化基准。 只有一家机构、一间屏蔽室、一套探头。它可以告诉你某种方法在这个条件下有效,不能告诉你它在另一间屏蔽室里还灵不灵。

§2 数据构成与规格

2.1 一套文件,两个版本,七乘二十五

目录结构极其扁平。所有记录都放在 data 目录下,文件名由三段拼成:受试者编号、版本名、测次编号。受试者从 1 数到 7,测次从 01 数到 25,版本有两个取值:raw 表示原始,preprocessed 表示经过官方预处理的版本。于是每个受试者对应 50 个记录,全库共 350 条,记录清单 RECORDS 逐行列出这 350 条,一行一条,不带扩展名。

值得注意的是 RECORDS 只列了 preprocessed 一套。原记录名同样存在,文件也在同一目录,只是没有进清单。所以按清单下载只能拿到一半数据,要做 raw 与 preprocessed 的对照,得自己把文件名里的版本段替换掉。这一点在写批量脚本时必须提前处理,否则会以为"下载完了",实际上原始数据一份没拿到。

层级 命名 取值 含义
目录 data/ 单一目录 全部记录平铺,无二级子目录
受试者段 subject<N>_ 1 至 7 受试者编号
版本段 _raw_ 或 _preprocessed_ 两个取值 原始电压或预处理后的磁场
测次段 trial<NN> 01 至 25 第几次移动夹具
头文件 .hea 与记录同名 文本,声明通道与注释
信号文件 .dat 与记录同名 二进制,8 路交错
辅助目录 images/ 七张图 示意图与四条示例波形

images 目录里是文档配图,不参与分析:夹具照片、屏蔽室总览、坐标示意图、标记位置图,另有四张示例波形。这四张图命名用 patient_N,数据文件用 subjectN,两套叫法并存,检索时容易搜错。

2.2 字段与记录的完整字典

这个库的"字段"分三处:文件名、头文件正文、头文件末尾的注释行。没有独立的元数据表,唯一的结构化表格是根目录下的 subject-info.csv,只有三列。

信息项 所在位置 取值形态 含义 使用注意
受试者编号 文件名首段 subject1–subject7 受试者标识 只有 7 个取值
版本标识 文件名中段 raw / preprocessed 是否经官方滤波 两者不可混入同一训练集
测次编号 文件名末段 trial01–trial25 第几次移动夹具 序号越大位置越靠网格另一端
信号条数 .hea 首行第 2 字段 8 八路通道 不是八个测点,见 §2.3
采样率 .hea 首行第 3 字段 200 每秒采样点 与心电常见的 500 不同
采样点数 .hea 首行第 4 字段 约一万三千至一万七千 单次总长 约合 65 至 87 秒
存储格式 信号行第 2 字段 212 WFDB 的 12 位打包格式 需用 wfdb 读取,不要按 int16 直读
增益 信号行第 3 字段 每通道不同 换算到物理单位 raw 为伏,preprocessed 为皮特斯拉
位分辨率 信号行第 4 字段 12 有效位数 落在 16 位容器低 12 位
ADC 零值 信号行第 5 字段 0 零电平对应整数 换算时无需额外偏移
初始值 信号行第 6 字段 逐通道不同 首采样点整数 可用于核验读取
校验和 信号行第 7 字段 逐通道不同 采样点累加和 与 SHA256SUMS.txt 互补
信号名 信号行第 9 与 10 字段 Sensor 0 至 Sensor 3 加方向 哪只探头、哪个方向 同一探头可能出现两次
年龄 .hea 注释行 整数 采集时年龄 本版只出现 26 至 35 岁
性别 .hea 注释行 m 采集时性别 本版全为 m
采集年份 .hea 注释行 2022 年份 全部一致
传感器坐标 .hea 注释行 三个整数,单位厘米 四只探头各自位置 受试者坐标系
出生年份 subject-info.csv 整数 用于推年龄 与头文件年龄互相校验
诊断 全库 无 — 任何位置都没有
注释 全库 无 — 没有 .atr 或同等文件

subject-info.csv 三列:编号、性别、出生年。七行性别全为 m,出生年从 1971 到 2000 不等。头文件年龄是 2022 年采集时的年龄,与出生年推得的一致。七人实际跨度为二十六到三十五岁,是官方"22 到 50 岁"招募条件落在实际入组里的更窄区间。

"信号条数等于 8"这一行最容易被误读。做过十二导联心电的人看到 8,会条件反射地当成八导联。这里不是:八路来自四只探头,其中两只各记录一个方向,两只各记录两个方向,而且同一只探头在不同测次里记录的方向还可能不同。换句话说,通道编号固定,通道对应的方向不固定。任何想把第 k 路当作固定解剖位置的写法,都会在跨测次时出错。

2.3 一条记录的完整解剖

以 subject1_preprocessed_trial01 为例。头文件由 1 行摘要、8 行信号声明、10 行注释组成:

subject1_preprocessed_trial01 8 200 13964
subject1_preprocessed_trial01.dat 212 54.355288498234756(24)/pT 12 0 -2047 23303 0 Sensor 0  -Y
subject1_preprocessed_trial01.dat 212 57.28832847443557(937)/pT 12 0 -2047 62697 0 Sensor 0  Z
subject1_preprocessed_trial01.dat 212 48.27115581743158(87)/pT 12 0 -2047 46325 0 Sensor 1  -Y
subject1_preprocessed_trial01.dat 212 42.96730083937927(895)/pT 12 0 -2047 10916 0 Sensor 1  Z
subject1_preprocessed_trial01.dat 212 44.01762233691774(-73)/pT 12 0 -2047 52496 0 Sensor 2  -Y
subject1_preprocessed_trial01.dat 212 44.55874730282193(353)/pT 12 0 -2047 14965 0 Sensor 2  X
subject1_preprocessed_trial01.dat 212 48.32806856627415(49)/pT 12 0 -2047 42822 0 Sensor 3  -Y
subject1_preprocessed_trial01.dat 212 43.26390256684903(571)/pT 12 0 -2036 25093 0 Sensor 3  X
#-- <age>: 26
#-- <sex>: m
#-- <year of recording>: 2022
#-- <position sensor 0 [cm]>: [-11  17 -14]
#-- <position sensor 1 [cm]>: [-14  17 -11]
#-- <position sensor 2 [cm]>: [-14  17 -14]
#-- <position sensor 3 [cm]>: [-11  17 -11]

首行四个字段:记录名、八路信号、200 Hz、13964 个采样点。13964 除以 200 是 69.82 秒,比官方的"一分钟"多出近十秒;同一受试者第二次测量是 13856 点,约 69.3 秒。可见每次实际长度都略长于六十秒,一分钟是约数,固定按 12000 点切会丢掉末尾近十秒。

信号行的增益逐通道不同,54.355288498234756(24)/pT 表示浮点增益后跟括号内基线值,单位皮特斯拉。八路增益无一相同,因为对应的是不同物理通道,灵敏度各异。raw 版单位是 V,增益为几千到近万的分数量级。

注释行里的四个坐标值得单独看。sensor 0 的 [-11 17 -14] 表示 x 为 −11、y 为 17、z 为 −14,单位厘米。y 恒为 17,因为 y 轴从后背指向前胸,体位固定时夹具进深不变;变的是 x 与 z,构成胸前平面上的移动。

坐标的来源官方写得很清楚:夹具内四只探头相对位置固定,初始位置由第一次测量给出,此后 24 次各有一个偏移量,x 与 z 各取 0、3、6、9、12 五档,五乘五共 25 种组合,对应 25 次测量。夹具内相对位置是 sensor 0 在原点、sensor 1 在左后上、sensor 2 在左后、sensor 3 在正后下方。

夹具内探头 X(厘米) Y(厘米) Z(厘米) 相对位置描述
Sensor 0 0 0 0 原点,夹具尖端中心
Sensor 1 −3 0 3 左侧偏上
Sensor 2 −3 0 0 左侧同高
Sensor 3 0 0 −3 同列偏下

把两张表叠起来就能得到每次测量的四组绝对坐标:初始位置加上夹具内相对位置,再加上该次的偏移量。这也解释了为什么 25 次乘以 4 只探头等于 100 个探头位置,而官方说 200 个——因为其中两只探头各记录两个方向,每个探头位置贡献两个测点,于是 100 个探头位置展开成 200 个测点。这个换算关系官方没有逐句推导,但两张表把它固定住了。

读取这条记录的标准写法:

import wfdb
import numpy as np

base = "https://physionet.org/files/kiel-cardio/1.0.0"
rec = wfdb.rdrecord(f"{base}/data/subject1_preprocessed_trial01", physical=True)

print(rec.fs, rec.sig_len, len(rec.sig_name))
#-- 200 13964 8
print([n.strip() for n in rec.sig_name])
#-- ['Sensor 0  -Y', 'Sensor 0  Z', 'Sensor 1  -Y', 'Sensor 1  Z',
#--  'Sensor 2  -Y', 'Sensor 2  X', 'Sensor 3  -Y', 'Sensor 3  X']
print(rec.units)
#-- 全部为 'pT'
print(rec.p_signal.shape, round(rec.p_signal[:, 0].std(), 3))
#-- (13964, 8) 以及第一路的皮特斯拉标准差
print(rec.comments[:2])
#-- ['<age>: 26', '<sex>: m']

用 physical=True 读出的 p_signal 已经是皮特斯拉,增益与基线已经在读取时算进去了。如果读 raw 版,同一段代码给出的单位是伏,数值量级会差出好几个数量级,画图时如果不看 units 就会以为是信号坏了。

2.4 三本账:人数、记录数与体积

规模有三个口径,官方页面、记录清单与文件系统各说一部分,合起来才完整,并不矛盾。

口径 数值 出处 回答的问题
受试者 7 官方摘要与 subject-info.csv 有多少人
每人测次 25 官方方法节与文件名 每人被移动了几次夹具
每人测点 200 官方摘要 胸前被覆盖了多少格
清单记录数 350 RECORDS 行数 有多少条可下载记录
实际记录组数 700 目录内 .hea 计数 加上 raw 之后的总量
单次通道数 8 头文件首行 一条记录里几路信号
单次采样点 约一万四千 头文件首行 一条记录有多长
单次时长 略多于一分钟 采样点除以 200 实际时长
每人累计时长 约 29 分钟 25 次之和 每人被记录的总时长
全库累计时长 约 3.4 小时 7 人之和 总量级
未压缩体积 6.8 GB 官方文件区 需要多少磁盘
压缩包体积 6.5 GB 官方下载按钮 需要多少带宽

最容易出偏差的是清单记录数与实际组数两行。RECORDS 只列预处理版,不是笔误,原始版确实在目录里。只数清单会得出"齐了"的结论,而磁盘上应有七百组、一千四百个文件。体积上,6.8 GB 摊到七百组每组约 9.7 MB,原始版占大头;对心电来说这个量级很大,对心磁却合理,因为每个测点都要在胸前挪一次。

2.5 与同类资源的字段差异

对比项 Kiel Cardio Koch 参考集 通用心电库 心磁无屏蔽研究
物理量 磁场 磁场 体表电位 磁场
传感器 光泵磁力仪 超导量子干涉器件 电极 因研究而异
通道数 8 304 1 至 12 数十
受试者 7 5 数百至数万 数十至数百
是否公开下载 是 是 是 多数否
空间网格 200 个测点 固定阵列一次覆盖 不适用 取决于阵列
是否需屏蔽 是 是 否 部分否
附带心电 否(计划中) 是 是 部分有
注释 无 因库而异 多有 少见

关键是两列形状的差异:Koch 的参考集用 304 通道一次覆盖胸前,采一次得一张完整场图;本库用 8 通道分 25 次拼图。前者空间分辨率高但时间上只有一瞬间,后者每一格都有一分钟时程。两种设计回答的问题不同,不存在谁更先进。

官方背景一节还列了几项建了库但未公开的工作:36 个位置测 125 人做缺血性心脏病预测、64 通道测数百人做心磁统计、无屏蔽心磁识别缺血性心脏病、以及一项胎儿心磁库的链接已于 2023 年 10 月不可达。这说明心磁数据总量不小,缺的是可下载的入口。真正要在选型时区分的是空间与时间这两条轴:如果你的问题需要一张覆盖完整胸前的场图,就该去找阵列式数据;如果需要看某一点在几十秒里的连续形态,本库的逐格记录才合适。两者叠加使用时要注意,本库的 8 通道不能假装成阵列式的 304 通道,通道路数与空间覆盖不是一回事。

§3 这台设备是怎么搭起来的

3.1 四只光泵磁力仪与一间屏蔽室

核心硬件是四只 QuSpin QZFM Gen 1 光泵磁力仪,原理是让激光穿过碱金属蒸气,外部极微弱磁场会改变原子自旋与光的耦合状态,测透射光即可反推磁场。相比超导器件,它室温工作、不需液氦,但同样对磁噪声敏感,仍然离不开屏蔽。

四只传感器装在一个夹具里,固定在检查床上方。受试者仰卧不动,操作员在两次测量之间手动移动夹具——官方原文说得很朴素:受试者始终躺在床上,操作员在测量之间移动传感器阵列。整个 200 点网格由此是 25 次人工挪动拼出来的,空间精度取决于操作员每次都把夹具放到标记位置的手艺。

采集在基尔大学工程学院的磁屏蔽室内完成。屏蔽室是这类测量的前提:没有它,地磁场与工频干扰会把这些皮特斯拉级信号整个盖住。这也直接抬高了复现门槛——没有同等级屏蔽环境的课题组,很难判断自己采到的信号与这里是不是同一回事。

3.2 采集软件与坐标系统

传感器由课题组自研的实时软件 KiRAT 控制和回读,这个软件出自同一院系的数字信号处理与系统理论组,名字是 “Kiel Real-time Application Toolkit” 的缩写。它在官方引用列表里作为一套软件被单独列出,说明数据的采集过程与这套软件是绑定的,复现采集链路时需要一并考虑。

坐标系统有两套。第一套是受试者坐标系,原点在检查床上脊柱与肩线水平线的交点,x 轴从左到右略高于肩,y 轴从背到前,z 轴沿脊柱从脚到头。第二套是传感器阵列坐标系,轴方向相同,原点在 sensor 0 尖端中心。头文件里的四组坐标用的是第一套。

坐标轴 方向 说明
x 左到右,略高于肩 胸前横向
y 后背到前胸 进深,本库所有测量恒为 17 厘米
z 脚到头,沿脊柱 纵向,覆盖胸骨上下
原点 脊柱与肩线的交点 位于床面

y 轴恒为 17 这一点很重要。它说明夹具与受试者后背的距离是固定的,测量平面与胸廓保持恒定间距。如果这个值在不同测次间变化,那么相邻格点之间的差异里会混入距离效应,做等值线重建时就得先校正。官方把距离固定住了,等于替使用者消掉了这一项混杂。

3.3 五乘五的位移表

25 次测量的位置不是随机的,而是一张五乘五的表。x 方向取 0、3、6、9、12 厘米五档,z 方向同样取五档,组合出 25 个偏移。表里编号从 1 编到 25,编号的排法是以左下角为起点先沿 x 走、再换 z 行。

z 偏移 \ x 偏移 0 厘米 3 厘米 6 厘米 9 厘米 12 厘米
0 厘米 1 2 3 4 5
3 厘米 6 7 8 9 10
6 厘米 11 12 13 14 15
9 厘米 16 17 18 19 20
12 厘米 21 22 23 24 25

这张表把"第 25 次测量在大网格的哪个位置"这件事完全确定下来:编号除以 5 得行、取余得列,没有随机成分。也正因如此,任何以"测次编号"为特征输入的模型都会间接学到空间位置,而不是学到生理信息。这一点在 §7.3 还会再提。

网格的步长是 3 厘米,覆盖范围是 12 厘米见方。四只探头的固定间距也是 3 厘米,与网格步长一致。这个设计不是巧合:步长与探头间距对齐,意味着相邻两次测量之间,探头恰好移到上一只探头的位置,整个网格的采样密度因此是均匀的,不会出现某些区域密、某些区域疏的情况。

把夹具内偏移与位移表叠加,subject1_preprocessed_trial02 的坐标就是 [-8 17 -14]、[-11 17 -11]、[-11 17 -14]、[-8 17 -11],与第一次的 [-11 17 -14] 那一组相比,x 整体加了 3 厘米,正是表里从 1 号挪到 2 号的结果。这两个头文件可以用来交叉验证坐标推导,§4.2 的案例就是从这里起的。

3.4 信号的两条路径

每条记录都提供两个版本,文件名里以 raw 与 preprocessed 区分。两者是同一次采集的两种保存形态,不是两次采集。

特征 raw 版 preprocessed 版
物理单位 伏 皮特斯拉
是否滤波 否 是,三段滤波加缩放
单次采样点 约三百三十万 约一万四千
单次体积 约 6.5 MB 约 28 KB
用途 自建预处理、研究噪声 直接看形态、快速起跑
是否在清单内 否 是

采样点差了两个数量级,这是有原因的:raw 的采样率实际高于 200 Hz,而预处理时做了抽取,连同滤波一起降到 200 Hz。官方把预处理描述为四步——按光泵磁力仪的灵敏度缩放、100 Hz 低通、1 Hz 高通、50 Hz 带阻——但没写抽取这一步,而两条记录的首行采样点数摆在那里,说明确实发生了重采样。

这个细节对使用者的实际影响很直接:raw 的时间轴与 preprocessed 的时间轴不是同一个刻度,做两者逐点对比时必须先重采样,不能直接相减。§4.2 的案例会用这两个文件做演示。

§4 它最独特的东西:每格一分钟、每格一个坐标

4.1 为什么"逐格测量"比"一次成像"更少见

心磁的商用系统多数是阵列式的:几十上百个通道排成一个面,一次覆盖整个胸前,采一次就得到一张完整的场图。这种做法空间分辨率高、采集快,但代价是通道数多、设备贵。Kiel 走的是另一条路:只用四只探头,靠移动夹具来扩大覆盖范围,每次仍然只测一小块区域,但每一块都能连续记录一分钟。

这个选择的后果是双向的。好处是硬件便宜得多,四只光泵磁力仪加一套移动机构,成本远低于上百通道的阵列;且每次记录一分钟,任何一个测点都能看到完整的心动周期序列,而不是阵列系统那种"一次只抓一个瞬间"的快照。坏处是相邻测点时间不同步——第 1 格与第 2 格之间隔着操作员挪动夹具的几十秒,心脏已跳了几十次。想要一张真正同步的场图,只能假设各格形态在时间上可对齐,而这个假设本身要检验。

公开心磁数据里,逐格测量的比阵列成像的少:阵列式看起来更像一张图,容易套图像处理方法;逐格数据更像一堆时间序列,要先插值对齐才能成图。这份数据的设计者显然更关心后者,否则不会把 25 次测量的坐标写得这么完整。

4.2 案例:subject1 的 trial01 与 trial02

选 subject1 的前两次测量作贯穿案例,是因为这两个文件可以同时说明三件事:坐标偏移怎么叠、raw 与 preprocessed 怎么对应、通道方向为什么不能当固定导联。两次测量在头文件里都能完整读到,不需要下载信号文件。

import re
import wfdb
import numpy as np

base = "https://physionet.org/files/kiel-cardio/1.0.0/data"

def head(name):
    r = wfdb.rdheader(f"{base}/{name}")
    meta = dict(re.findall(r"<(age|sex|year of recording)>: (.+)", "\n".join(r.comments)))
    pos = {int(k): v for k, v in re.findall(
        r"<position sensor (\d) \[cm\]>: \[([^\]]+)\]", "\n".join(r.comments))}
    return r.fs, r.sig_len, r.sig_name, meta, pos

for tag in ("trial01", "trial02"):
    fs, n, names, meta, pos = head(f"subject1_preprocessed_{tag}")
    print(tag, fs, n, round(n / fs, 2), "秒")
    print("  年龄", meta["age"], "位置", pos)
    print("  通道", [s.strip() for s in names])

跑出来的结果就是 §2.3 给出的那两行:trial01 的 sensor 0 在 x 为 −11,trial02 的 sensor 0 在 x 为 −8,差正好是 3 厘米,与 §3.3 的位移表对上。两位小数之后的时长都在 69 秒上下,比一分钟长约十秒。

再看 raw 与 preprocessed 的对应:

import wfdb

base = "https://physionet.org/files/kiel-cardio/1.0.0/data"
raw = wfdb.rdheader(f"{base}/subject1_raw_trial01")
pre = wfdb.rdheader(f"{base}/subject1_preprocessed_trial01")

print("raw 采样率与点数", raw.fs, raw.sig_len)
print("pre 采样率与点数", pre.fs, pre.sig_len)
print("raw 单位", set(raw.units))
print("pre 单位", set(pre.units))
print("两条记录时长比", round(raw.sig_len / raw.fs, 3),
      round(pre.sig_len / pre.fs, 3))

两个头点数相差两个数量级,单位一为伏一为皮特斯拉,但换算出的总时长一致,说明预处理是在时间轴不动的前提下做的抽取。§1.4 表里"原始与预处理链路对照"这一行,能做的就只有这类时长与频谱对照,逐点相减需先重采样。

通道方向这一层,两次测量并排看最清楚:trial01 的八路依次是 sensor 0 的 −Y 与 Z、sensor 1 的 −Y 与 Z、sensor 2 的 −Y 与 X、sensor 3 的 −Y 与 X,trial02 顺序与方向组合都相同。这两次之间映射稳定,但官方没承诺它在全部 25 次里不变——方向按夹具配置定,不按通道号定。要确认某一测次的方向,只能读头文件。

4.3 时间对齐的三种做法

同一个测点上的信号是连续的,跨测点之间却是分离的,要把它们拼成一张场图,得先解决"不同格的哪一时刻算同一时刻"。公开文献里的做法大致有三种:以每次记录内自行检测到的心搏为锚点做叠加平均,这是最严谨也最费力的一种,前提是先有可靠的心搏检测;直接取每次记录的第 n 个采样点对齐,最省事,但把每次采集起跳时的相位差全忽略了,拼出来的图会有明显接缝;把 200 个测点当散点做空间插值,这是空间层面的处理,与时间对齐正交,可以与前两种叠加使用。§4.2 的案例给出的是每一格的原始波形,正好可以作为三种做法的共同输入。

4.4 它支撑的四类实验

实验 设计 它能给的 结论强度
波形形态学 单测点一分钟内的形态统计 8 通道连续记录 中,7 人不足以推广
传感器评估 比较四只探头的一致性 同一次记录内的四路并行 中,同一夹具、同一环境
噪声与滤波研究 raw 与 preprocessed 对照 同一采集的两个版本 较高,可控条件最全
空间场重建 200 个带坐标的测点做插值 完整网格 中,需自行对齐时间

第三类结论强度最高,因为这一项完全在数据内部完成,不涉及人,也不涉及跨测点的时间假设:一份 raw 加一份 preprocessed,就能回答官方那条滤波链做了什么、丢掉了什么。其余三类都要跨出数据本身。

§5 怎么拿到:从清单到一张胸前场图

5.1 目录与体积

全库解压 6.8 GB,压缩包 6.5 GB。根目录下 RECORDS 约 10 KB、README.md 约 11 KB、LICENSE.txt 约 16 KB、SHA256SUMS.txt 约 69 KB,subject-info.csv 只有 98 字节;data 目录里预处理版的头文件约 1 KB、信号约 28 KB,原始版的头文件同样约 1 KB、信号约 6.5 MB;images 目录七张文档配图合计约 10 MB。页面上给了三种取法:网页下载 ZIP、用 wget 递归、用 AWS 命令行同步公开桶。考虑到原始版单条就有 6.5 MB,全量下载对磁盘与带宽都有要求,先只取预处理版是更常见的做法。

5.2 批量获取

#-- 只拉清单与受试者表,先看清结构
base=https://physionet.org/files/kiel-cardio/1.0.0
curl -sL "$base/RECORDS" -o RECORDS
curl -sL "$base/subject-info.csv" -o subject-info.csv
wc -l RECORDS

#-- 按清单下载预处理版(清单里就是这一套)
mkdir -p data
while IFS= read -r rel; do
  for ext in hea dat; do
    curl -sL --max-time 60 "$base/${rel}.${ext}" -o "data/$(basename "$rel").${ext}"
  done
done < RECORDS

#-- 只取一条 raw 试通链路:把版本段换掉即可
one=subject1_preprocessed_trial01
curl -sL --max-time 180 "$base/${one/_preprocessed_/_raw_}.hea" -o data/subject1_raw_trial01.hea

#-- 核对:预处理版应有 350 个 hea
ls data/*preprocessed*.hea | wc -l

第二段用 ${one/_preprocessed_/_raw_} 做字符串替换,把版本段换掉即可拼出原始版的路径——清单里没有 raw,但文件名规则是稳定的。先按这个方法取一条 raw 查时间,再决定要不要全量。全量下载需要考虑时间:七百组文件里,三百五十个原始信号合计约 6.5 GB,按普通网络速度要跑一段时间,§2.4 的三本账就是为这个决定准备的。

5.3 建立测点索引

绝大多数实验的第一步是把坐标整理成一张表。头文件里的坐标藏在一行注释里,用正则抽出来即可:

import os
import re
import pandas as pd

ROOT = "data"
pat_pos = re.compile(r"<position sensor (\d) \[cm\]>: \[([^\]]+)\]")
pat_meta = re.compile(r"<(age|sex|year of recording)>: (.+)")

rows = []
for fn in sorted(os.listdir(ROOT)):
    if not fn.endswith(".hea"):
        continue
    stem = fn[:-4]
    m = re.match(r"subject(\d)_(raw|preprocessed)_trial(\d+)", stem)
    if not m:
        continue
    text = open(os.path.join(ROOT, fn), encoding="utf-8").read()
    meta = dict(pat_meta.findall(text))
    for sid, xyz in pat_pos.findall(text):
        x, y, z = [int(v) for v in xyz.split()]
        rows.append({
            "subject": int(m.group(1)),
            "stage": m.group(2),
            "trial": int(m.group(3)),
            "sensor": int(sid),
            "x": x, "y": y, "z": z,
            "age": int(meta["age"]),
        })
grid = pd.DataFrame(rows)
print(grid.shape)
print(grid.groupby("stage")["trial"].nunique())
print(grid[grid["stage"] == "preprocessed"]["sensor"].value_counts())

这段代码只读头文件,不碰信号,跑一遍只要几十秒。输出的 grid 每行是"某个受试者的某次测量里的某只探头",预处理版应有 350 乘 4 共 1400 行,raw 版同样一千四百行。sensor 的计数应当四只各占四分之一,如果某一只有缺,说明该测次记录不全。

坐标抽取时有一个坑:头文件里坐标写作 [-11 17 -14],负数前有空格,三位数字之间是双空格。用 split() 而不是按单空格切分就不会出错;若按 str.split(" ") 写,会出现空串再转整数时报错。

5.4 从测点到场图

坐标有了,剩下的工作是把 200 个测点的某一段信号投影到胸前平面上。最简单的一种做法是取每个测点在固定时间窗内的峰峰值,画成散点再插值:

import numpy as np
import pandas as pd
import wfdb
from scipy.interpolate import griddata

base = "https://physionet.org/files/kiel-cardio/1.0.0/data"
sid, stage = 1, "preprocessed"
tiles = []

for t in range(1, 26):
    name = f"subject{sid}_{stage}_trial{t:02d}"
    r = wfdb.rdrecord(f"{base}/{name}", physical=True)
    chunk = r.p_signal[:12000]                       #-- 取前 60 秒
    amp = chunk.max(axis=0) - chunk.min(axis=0)      #-- 每路峰峰值
    tiles.append((name, amp))

g = pd.read_parquet("grid.parquet")
g = g[(g.subject == sid) & (g.stage == stage)]

#-- 每个测点方向的峰峰值挂到该测次的传感器坐标上
pts, val = [], []
for t, (name, amp) in enumerate(tiles, start=1):
    sub = g[g.trial == t].sort_values("sensor")
    for k, s in enumerate(sub.itertuples()):
        pts.append((s.x, s.z))
        val.append(amp[k])
pts = np.array(pts, float)
val = np.array(val, float)

xi = np.linspace(pts[:, 0].min(), pts[:, 0].max(), 120)
zi = np.linspace(pts[:, 1].min(), pts[:, 1].max(), 120)
X, Z = np.meshgrid(xi, zi)
V = griddata(pts, val, (X, Z), method="cubic")
print(V.shape, float(np.nanmax(V)))

这段代码演示的是"把逐格数据拼成一张图"的最小路径,重点在流程本身,不在结果好不好看。有一个隐含的近似必须写进方法节:八路通道与四只探头并非一一对应,其中两路是同一探头的第二方向,上面的写法把它们都挂到探头坐标上,等于把两个方向的幅度放在同一张图里比较,量纲与物理含义都不严格。正式分析时应当按方向分开画两张图。

5.5 三种常见起跑姿势

推荐的第一步是只看形态:读一条 preprocessed,把八路波形画出来,花几分钟就能判断这份信号到底有没有心动周期、噪声底厚不厚。如果连形态都看不出周期,后面的工作都不会顺。第二步是做对照,取同名的 raw 与 preprocessed,比较两者的时长与频谱,这一步不需要全量下载,一条记录的两个版本就够,十几分钟能跑完。第三步才是建网格,跑 §5.3 的测点索引,再画 §5.4 的场图,需要较多下载与计算,适合已经确定要用这份数据做正式分析的人。

这三步的顺序不能颠倒,原因很实际:心磁的原始信号里,心动周期与噪声的幅度可能相差不大,如果在没有确认形态之前就投入建网格,很可能花了两小时下载与插值,最后发现某几个测次根本看不出周期。先看一条、再比两条、最后铺全市,是最省返工的走法。

5.6 六个最容易出错的地方

位置 错误写法 后果 正确做法
数据集定位 当作心电库套用心电流程 单位与量级全错 先确认单位是皮特斯拉
下载 只按清单取 只拿到一半,原始版缺失 把版本段换成 _raw_ 再补一遍
通道理解 当八导联做解剖映射 跨测次方向错位 每次读头文件的信号名
时长假设 假定每条正好 60 秒 切窗丢末尾十秒 用实际采样点除以采样率
raw 对照 直接与 preprocessed 相减 时间轴未对齐,结果无意义 先重采样到同一刻度
坐标解析 按单空格切分 空串导致整型转换报错 用 split() 不加参数

第五行最隐蔽:两个版本时长一致,点数却差两个数量级,先入为主地以为"同一次采集直接减就行",减出来的只是两条不同分辨率上的抽样,既不是噪声也不是误差。

§6 与库内条目的关系

6.1 关系图谱

在心电与生理信号这一类资源里,它的位置不在"规模"轴,也不在"任务"轴,而在"模态"轴。库内相关词条测的都是电位,只有它测的是磁场。

资源 模态 与 Kiel Cardio 的关系
ECG-ID 单导联心电 同源异模态:电极测电位,光泵测磁场
MIT-BIH 心律失常库 双导联心电 任务完全不同,仅共享 WFDB 读写工具
INCART 十二导联库 十二导联心电 通道数相反,它是宽覆盖,本库是窄阵列
PTB-XL 与 PTB-XL+ 十二导联诊断 人群相反,它是患者,本库是健康志愿者
MIMIC-IV 波形库 多参数床旁监护 同一格式家族,不同采集场景
adfecgdb 腹壁与直接胎心电 同属小众模态,都受采集条件高度限制定
chfdb 心衰长程心电 用途互补,它给病理时长,本库给空间分布

真正有参照价值的是第一行与第六行。与 ECG-ID 是"同源异模态":都记录心脏电活动,一个记电位一个记磁场,处理链路可以互相借,但单位、噪声结构与传感器响应完全不同。与 adfecgdb 是"同为受采集条件限制的小众模态":都是几十条记录、都需要专门设备,都适合方法验证而非统计。

6.2 检索路径

你要找的东西 检索词 会落到哪里
心磁的公开数据 magnetocardiography dataset、MCG database §8.1 与 §6.1
光泵磁力仪的研究用数据 OPM MCG、optically pumped magnetometer §3.1
心电算法向心磁迁移 ECG delineation MCG §4.4 与 §7.4
磁场与电位的关系 BSPM、body surface potential mapping §2.5 的对照列
许可与署名义务 CC BY-SA 4.0、ShareAlike §9.3
心电同源参考 ECG database、WFDB §6.1 表

6.3 与其他库的分工判据

任务 主粮仓该用什么 本库的位置 原因
心电诊断模型训练 带诊断标签的大规模心电库 不参与 无标签、无患者
心磁方法预研 心磁公开数据 主力 PhysioNet 上唯一的同类
传感器与阵列评估 设备厂商数据或自采 可用作参照 四只同型号探头并行
磁场反演与源定位 阵列式心磁数据 有条件可用 逐格测量需自行对齐
心电与心磁联合分析 配对采集的数据 不适用 本版无心电
教学演示磁与电的差别 两类数据各一份 适合 同一平台、同一格式,便于并排

第二行与最后一行是它真正的落点。作为方法预研的起点,它的稀缺性几乎无法替代——没有第二份公开的心磁数据可换。作为教学的对照,它与心电库同用 WFDB 格式,学生可以在同一套代码里读两种模态,直接看到单位与波形的差异。真正的分工判据可以压缩成一句话:凡是需要"人多、有标签、有同步心电"的任务,它都不在候选名单里;凡是需要"真实心磁、带坐标、可比较滤波链路"的任务,它几乎没有替代品。

§7 质量评估与局限性

7.0 阅读本节前的一个前置校正

评价这份数据时最容易犯的误判,是拿它和心电库比规模,然后得出"七个人太少"的结论。这个比较的坐标轴本身选错了。心电采集的成本主要落在人身上——找受试者、排班、贴电极;心磁的成本主要落在设备和场地上——屏蔽室、探头、操作员。两者的瓶颈不在同一处,所以可公开的样本量天然差好几个数量级。

换成正确的坐标轴之后,评分才读得准。对心磁来说,七个人已是相当可观的一份公开数据。它的短板不在人数,而在没有任何标注、只有单一模态这两处,而这两处恰好都能由后续版本补上。

还需做一次口径区分:官方写受试者 22 到 50 岁,而 subject-info.csv 与头文件推出的实际年龄是 26 到 35 岁。前者是招募条件,后者是实际入组,写论文时应引实际数据。

7.1 五维评分

按 DAIMS 的常用维度打分,每项 1 到 5 分,锚定在"作为心磁方法研究数据"这个用途上:

维度 分数 理由
数据规模 3 七人在心磁里不算小,但绝对量仍偏低
标注质量 1 本版完全没有注释,官方明确说明
任务适配 4 逐格加坐标的结构独有,覆盖多种方法学需求
文档完整 4 方法、坐标、位移表、伦理与致谢都写全了
可获取性 4 免注册、CC BY-SA,但 6.5 GB 不是随手能下

合计 16 分(满分 25)。适配性与文档撑起一半,标注把总分拖下来。标注给 1 分是按本版事实给分,官方在用法说明里已写明本版不提供注释、定量评价须先人工标注。可获取性给 4 分是因为体积:免注册、许可清晰、下载方式齐全,但 6.5 GB 的压缩包不是"先下下来看看"的量级,需要先规划存储。

7.2 预处理链路的真实含义

官方的预处理写了四步:按灵敏度缩放、100 Hz 低通、1 Hz 高通、50 Hz 带阻。这四步决定了 preprocessed 版能用来做什么、不能用来做什么。

步骤 作用 可能损失 建议
灵敏度缩放 把电压换成皮特斯拉 无损失 直接用
100 Hz 低通 抑制高频噪声 高于 100 Hz 的成分不可恢复 研究高频成分时改用 raw
1 Hz 高通 去掉基线漂移 低于 1 Hz 的慢变化被削 研究慢波时改用 raw
50 Hz 带阻 抑制工频干扰 50 Hz 附近成分被挖空 做频谱分析时注意缺口

这四步不是"把信号洗干净",而是"把某段频带之外的成分删掉"。采样率 200 Hz,按奈奎斯特上限 100 Hz 正是能保留的最高频率,低通因此没有额外损失;真正有损失的是高通与带阻,1 Hz 以下与 50 Hz 附近被移除,而心磁的低频成分在源定位与慢波分析里是有意义的。

这也解释了 raw 版为何必须提供:官方把两个版本都放出来,等于把"要不要滤波、滤多狠"的决定交回使用者,§4.2 的案例正是为这个决定提供依据。对做源定位的人,这意味着一个具体的取舍:用 preprocessed 版省事,但 1 Hz 以下的慢变化已经被削掉,反演出来的源深度会偏;用 raw 版则要自己承担从电压到皮特斯拉的换算与全部噪声。两条路都能走通,差别在于你在论文里能不能说清自己删掉了哪一段频带。

7.3 已知的、可枚举的偏差

偏差 表现 影响
性别单一 七人全为男性 无法讨论性别差异
年龄集中 实际 26 到 35 岁 无法讨论年龄效应
健康人群 全部健康志愿者 无病理对照
单一机构 一间屏蔽室、一套探头 无法做跨中心验证
单一模态 本版只有心磁 无法做模态间联合
无标注 没有心搏或节律文件 无法直接做监督任务
时间不同步 相邻测点间隔数十秒 场图重建需自行对齐
位置离散 200 个测点来自五乘五网格 网格分辨率受位移表限制
清单不全 RECORDS 只列预处理版 只按清单下载会漏一半

影响最大的不是"人少",而是"无标注"与"时间不同步"这两行。人少是显性限制,写论文的人都会承认;时间不同步是隐性限制,它不出现在任何一句官方描述里,只在位移表与"操作员移动夹具"这句话里透出来,没注意到的使用者会把 200 个测点当成同一时刻的场图,结果在物理上不成立。「清单不全」是操作层面的坑:RECORDS 一直是预处理版清单,把版本段当可替换字段而非相信清单的完备性,就能避开。位置上还有一个容易被忽略的偏差:五乘五网格的步长固定为 3 厘米,网格边界以外的磁场分布完全没有数据。若心脏的某个源恰好落在覆盖范围之外,插值会外推出一片看着合理、实际没有依据的区域。画场图时应把网格边界画出来,边界外的部分留白而不是补满。

7.4 外部验证矩阵

先要说清"外部验证"在这个库上意味着什么。它体量小、无标注、单机构,任何以它为训练集再在别处测试的研究都还不存在;目前能谈的只是别人拿它做什么,而不是它验证了别人什么。这层区分在评估这类小库时尤其重要,否则容易把"有人引用"误读成"已经通过外部检验"。

以 Europe PMC 检索,匹配到的工作只有一项,讨论强噪声下的心磁去噪:作者用本库的干净段作参照,构造基线漂移、1/f 噪声与白噪声合成的复合噪声,训练对抗式网络降噪。这恰好落在本库最有把握的位置上——提供干净的真实信号,而不是标注或诊断。

验证角色 典型做法 讲得通的地方 风险
去噪算法的参照源 用干净段作目标,合成噪声作输入 信号真实、条件可控 干净段的"干净"是相对于本库的采集环境
分割算法的迁移试跑 自己标注几个心搏后跑心电模型 同源异模态,形态可比 无官方标注,结果不可跨研究比较
传感器评估 比较四只探头的噪声与灵敏度 同一次采集内条件一致 只有一种型号
场图重建 200 个测点做插值 网格完整、坐标清晰 时间不同步被忽略时会失真

第一行是目前唯一有公开证据的用法,也最自然。第二行说得通但可比性差,各组自标的几个心搏标准不会一致。第三行的价值在于把设备层面的问题变得可讨论:同型号探头之间的差异在任何心磁实验里都存在,一份公开的同环境对照总是有用的。

7.5 它为何能持续:稀缺的是设备,不是意愿

它从 2023 年底上线至今没有新版,却仍有被引用的理由:PhysioNet 上第一份心磁数据。想做心磁又没有屏蔽室的人几乎只能从这里开始。这个位置不是靠采得好拿到的,而是靠"别人做不了"拿到的。

生存逻辑还有一层时间维度:官方说后续版本会补心电、磁共振与注释,所以当前版本更像一块地基而非成品。地基的价值在于它先立住了,后来者往上加东西时有个参照。只要心磁的设备门槛还在,这块地基就有存在的理由。

§8 生态位与历史

8.1 历史沿革

心磁的历史几乎与心电图一样长:上世纪六十年代首次在屏蔽室内测到人体心脏磁场,七十年代超导器件成熟后进入实验室常规手段,此后主战场一直是可以承担超导成本的少数中心,应用集中在胎儿心磁、心肌缺血与心律失常灶定位。根源始终同一处:设备贵、场地贵,能做的机构少。

基尔大学走的是传感器替代路线。他们所在的协作研究中心 CRC 1261 专注磁电传感器,主题是把复合材料的磁电效应用于生物磁诊断。光泵磁力仪在这条路线里是折中:比超导便宜、比磁电传感器成熟。用四只探头拼网格,本质上是在设备成本与覆盖范围之间找平衡,这个选择的痕迹留在每一个头文件里。

8.2 时间线

时间 事件 意义
2022 年 七名受试者完成采集 全部记录的实际年份
2023-08 RECORDS 与 subject-info.csv 定型 目录结构的最后形态
2023-11 README.md 定稿 说明文字不再变动
2023-12-09 LICENSE.txt 落位 许可确定
2023-12-15 以 1.0.0 版上线 PhysioNet 获得 DOI,进入可引用状态
待定 计划补入心电、磁共振与注释 官方声明,尚未发布

几个时间点都集中在 2023 年下半年,说明采集完成后整理上线用了约一年。版本号只有 1.0.0,发布说明只有一行"初始版本",没有修订记录,这对使用者是好事:没有版本漂移。也不必有"等新版本再动手"的想法,因为官方没有给出任何时间表;更稳妥的做法是现在就按 1.0.0 定下实验协议,若日后真有 1.1,再把它当作独立的第二份数据来复制同一套流程,而不是在同一份结果里混着两个版本。

8.3 生态位:唯一的一格

位置 代表 本库的角色
心电大数据 各类十二导联库与监护库 完全不同的模态,无竞争
心磁阵列数据 超导系统的一次成像 互补:它给空间分辨率,本库给时间序列
心磁单通道数据 零星发表的案例 本库覆盖更完整、可下载
心磁方法基准 此前没有公开基准 本库占据这一格

它的位置简单到一句话能说完:在公开可下载的心磁数据里,它是唯一一个既完整又带坐标的。这个"唯一"既是价值,也是风险——没有第二份可以对照,任何在它上面得到的结论都无法用它自己来验证。

8.4 谁在用它,用来做什么

使用者大致三类:信号处理研究者把它当干净参照,验证降噪或分割算法能否处理皮特斯拉级信号;设备与传感器研究者把它当同型号探头在屏蔽室内的性能标本,判断自家系统噪声底是否合理;研究者与学生把它当入门材料,理解磁与电的关系。

最小众的是第二类,但它恰好用到了最不可复制的部分:四只同型号探头、同一间屏蔽室、同一批受试者。三类人面对同一组限制——没有标注、没有心电、只有七个人,所以结论都要收窄到"这间屏蔽室、这套探头、这批健康男性",不能顺口写成"心磁的普遍规律"。这份数据规模小、条件干净,最容易让人产生"我看到的就是全部"的错觉。

§9 使用指引

9.1 三种角色的路径

角色 第一天 第一周 注意事项
信号处理研究者 读一条 preprocessed,画出八路波形 取同名 raw,比较滤波前后的频谱 时间轴需重采样后再对齐
设备与传感器研究者 取一条记录,看四只探头的噪声底 跨测次比较同一探头的稳定性 通道方向需每次从头部确认
教学人员 用 §4.2 的案例,两次测量的坐标并排 把心磁与心电库各取一条并排演示 强调单位是皮特斯拉

9.2 最短可用流程(第一步:取清单)

#-- 1. 取清单与受试者表
base=https://physionet.org/files/kiel-cardio/1.0.0
curl -sL "$base/RECORDS" -o RECORDS
curl -sL "$base/subject-info.csv" -o subject-info.csv
head -3 RECORDS

9.3 最短可用流程(第二步:读一条记录)

import wfdb

base = "https://physionet.org/files/kiel-cardio/1.0.0/data"
name = "subject1_preprocessed_trial01"
rec = wfdb.rdrecord(f"{base}/{name}", physical=True)

print(rec.fs, rec.sig_len, rec.units[0])
#-- 200 13964 pT
for i in range(4):
    print(rec.sig_name[2 * i].strip(),
          round(float(rec.p_signal[:, 2 * i].std()), 3))
#-- 四只探头的主方向标准差,逐行打印

按探头两两分组打印标准差是最直观的第一步;要看波形再画图,横轴用采样点除以 fs 换算成秒即可。若某一路形态明显不同于同组另一路,先确认这一路的方向,同一只探头的两个方向本来就可能形态不同。

9.4 引用方式

引用对象 内容 何时需要
数据集本体 Engelhardt E, Frey N, Schmidt G. Kiel Cardio Database (version 1.0.0). PhysioNet. 2023. DOI 10.13026/q6r2-zz68 使用数据时必须
平台综述 PhysioNet 平台论文,按官方页面惯例一并引用 按平台要求
资助 德国研究基金会(DFG)协作研究中心 CRC 1261 说明数据来源时可写
许可 CC BY-SA 4.0,署名且同许可共享 再分发衍生数据时必须

署名之外还有一条容易被忽略的义务:ShareAlike。如果把这份数据加工成新的数据集并公开,新数据集必须用同一许可发布。这一点与很多 PhysioNet 库的 ODC-BY 不同,后者只要求署名,不要求传染。做衍生数据集之前要把许可想清楚,尤其是打算申请专利或走闭源路线的情况。还有一处细节值得在方法节里写明:受试者已按 GDPR 去标识,官方声明取得了在公共仓库共享去标识数据的明确知情同意,所以引用时不涉及额外的伦理审批,但涉及人体的部分仍应在方法节交代伦理批件编号。

§10 AI 使用声明

项目 声明
文本生成 本文由 AI 辅助撰写,结构与事实由编辑把关
数字来源 规模、结构、边界三类数字来自官方页面、README.md、RECORDS 与头文件
文件核验 逐个取回了 RECORDS、README.md、LICENSE.txt、subject-info.csv,并读取多条头文件原文
头文件核验 subject1 的 trial01 与 trial02 两个头文件逐行核对,用于坐标与位移表的交叉验证
未核验内容 未下载 data 目录下的信号文件做逐条统计,采样点与时长以头文件声明的数值为准
论文信息 Europe PMC 检索仅匹配到一篇引用本库的去噪研究,未获得官方独立论文
差异披露 官方写受试者 22–50 岁,subject-info.csv 推出 26–35 岁,两者分别对应招募条件与实际入组
图像 无配图;封面为生成式提示词,不含真实心磁波形
免责 本文不构成临床建议;数据使用须遵守 CC BY-SA 4.0 的署名与同许可条款

常见误读(避坑清单)

说法 实际 证据
「这是一个心电数据库」 存的是心磁图,单位皮特斯拉 头文件信号行单位写作 /pT,raw 版为 /V
「每人是 25 个测点」 25 次测量,共 200 个测点 官方摘要写 200 个位置,位移表为五乘五
「八通道就是八个测点」 八路来自四只探头,其中两只有第二方向 头文件信号名为 Sensor 0 至 Sensor 3 加方向
「它就是 200 Hz 采的」 预处理版 200 Hz,raw 版采样点约三百三十万 两个头文件首行点数差两个数量级
「每条记录正好一分钟」 采样点除以采样率约 69 秒 13964 除以 200 得 69.82
「清单里的记录就是全部」 RECORDS 只列预处理版,raw 版另有 350 条 清单文件名统一含 _preprocessed_
「它带心电和磁共振」 本版只有心磁,其余是官方计划 官方摘要写"未来版本将纳入"
「它可以用来自动分割心搏」 无任何注释文件 官方用法说明要求先做人工标注
「四只探头位置每次都一样」 夹具内相对位置固定,绝对位置随测次变 位移表五乘五,x 与 z 各五档
「CC BY-SA 与 ODC-BY 差不多」 多一条同许可扩散义务 LICENSE.txt 为 CC BY-SA 4.0 全文

FAQ

Q1:Kiel Cardio Database 是心电数据库吗?
不是。它存的是心磁图,用光泵磁力仪测心脏电活动产生的微弱磁场,单位是皮特斯拉,测量必须在磁屏蔽室内完成。它与心电图同源但不同模态:心电测体表电位差,心磁测体表磁场。

Q2:只有七个人,这个库还有用吗?
有用,但用途限定在方法与设备层面。心磁设备昂贵、需要屏蔽室,公开数据极少,所以它在心磁里的稀缺性远高于同等规模的心电库。它能支撑波形形态、噪声处理、等值线重建与传感器评估,但撑不起人群统计或诊断模型。

Q3:每人 25 次测量、200 个位置是怎么算出来的?
四只探头装在夹具里,夹具被操作员移动 25 次,位置由五乘五的偏移表决定。其中两只探头各记录两个方向,于是 25 次乘以 4 只探头得到 100 个探头位置,再乘以方向展开成 200 个测点。

Q4:能不能直接做心搏分类或心律失常检测?
不能。本版没有任何注释,官方在用法说明里明确写到做检测评测前必须先人工标注。受试者全是健康男性,即便标注完也没有病理类别可用。

Q5:raw 版与 preprocessed 版有什么区别?
raw 是原始电压、未滤波、采样点约三百三十万;preprocessed 是按灵敏度缩放为皮特斯拉并做 100 Hz 低通、1 Hz 高通、50 Hz 带阻后的版本,采样点约一万四千。两者时长一致,分辨率不同。

Q6:为什么清单里只有 350 条,目录里却有 700 组记录?
RECORDS 只列预处理版,原始版文件实际存在但不在清单里。要拿 raw 版,把文件名中的 _preprocessed_ 换成 _raw_ 即可。

Q7:这份数据能不能和心电做联合分析?
本版做不到。官方声明未来版本会补入心电与磁共振,但当前版本只有心磁,也没有任何配对信息。想做联合分析需另找来源或自行同步采集。

Q8:200 个测点是同一时刻的场图吗?
不是。每一次测量是一分钟独立记录,相邻测点之间隔着操作员挪动夹具的时间。要把它们拼成场图,必须先做时间对齐,取平均或以心搏为锚点叠加是常见做法。

Q9:这份数据允许商用吗?
允许,CC BY-SA 4.0 覆盖商业用途。条件是署名,且若把数据加工成衍生数据集再公开,衍生数据集须以同一许可发布。

Q10:它会不会有后续版本?
官方明确说计划补入心电、磁共振与注释,但没有给时间表。截至 1.0.0,版本说明只有一行初始发布。

Q11:受试者年龄到底是 22 到 50 岁还是 26 到 35 岁?
两个数字都对,含义不同。官方的 22 到 50 岁是招募条件,subject-info.csv 与头文件里的出生年推出的是实际入组的七个人,落在 26 到 35 岁之间。

Q12:为什么没有一篇正式的数据论文?
官方页面的引用栏直接指向 PhysioNet 上的数据集本身,DOI 是本库的版本 DOI,没有列出配套的期刊论文。相关的方法背景可以参考 CRC 1261 名下关于磁电传感器与心磁电流密度估计的几篇会议与期刊文章。

术语表

术语 解释
心磁图(MCG) 测量心脏电活动产生的体表磁场,单位皮特斯拉
光泵磁力仪(OPM) 利用激光与碱金属蒸气测量极弱磁场的传感器,室温工作
超导量子干涉器件(SQUID) 另一种高灵敏度磁传感器,需液氦冷却
磁屏蔽室 用高磁导率材料包围的空间,隔绝地磁与环境磁噪声
皮特斯拉(pT) 磁感应强度单位,一万亿分之一特斯拉
磁电传感器 利用磁致伸缩与压电效应测磁场的器件,CRC 1261 的研究主题
夹具 固定四只探头、保持相对位置不变的支架
测次(trial) 一次一分钟的测量,夹具在测次之间被移动
测点 一只探头在一个位置上的一个测量方向
位移表 五乘五的偏移组合,决定 25 次测量的平面位置
WFDB PhysioNet 的波形数据库格式,含头文件与信号文件
格式 212 WFDB 的 12 位打包存储格式
增益 每个整数单位对应的物理量,逐通道不同
基线 头文件增益后括号内的值,换算时的零点
带阻滤波 挖掉指定窄频段的滤波,本库用于 50 Hz 工频
等值线重建 由离散测点插值出连续场分布
时相叠加 以心搏为锚点把多段信号平均,用于观察形态
DAIMS 数据管理与分析框架,用于五维评分
CRC 1261 德国研究基金会资助的协作研究中心,主题为磁电传感器
KiRAT 课题组自研的实时采集软件
CC BY-SA 4.0 署名且同许可共享的国际知识共享许可

附录 A:核心数字核对表

项 值 来源 来源层级
受试者数 7 官方摘要;subject-info.csv 行数 官方页面
每人测次 25 官方方法节;文件名 官方页面
每人测点数 200 官方摘要 官方页面
清单记录数 350 RECORDS 行数 官方文件
实际记录组数 700 目录内 .hea 计数 官方文件
单次通道数 8 头文件首行 官方文件
采样率 200 Hz 官方页面;头文件首行 官方页面
单次采样点 约一万四千 头文件首行 官方文件
单次时长 约 69 秒 采样点除以采样率 官方文件派生
年龄(实际) 26 至 35 岁 subject-info.csv 出生年 官方文件派生
年龄(招募) 22 至 50 岁 官方方法节 官方页面
性别 全部男性 subject-info.csv;头文件 官方文件
采集年份 2022 官方方法节;头文件注释 官方页面
传感器型号 QuSpin QZFM Gen 1 官方方法节 官方页面
传感器数量 4 官方方法节 官方页面
网格步长 3 厘米 位移表;官方方法节 官方页面
未压缩体积 6.8 GB 官方文件区 官方页面
压缩包体积 6.5 GB 官方下载按钮 官方页面
许可 CC BY-SA 4.0 官方页面;LICENSE.txt 官方页面
上线日期 2023-12-15 官方页面 官方页面
DOI 10.13026/q6r2-zz68 官方页面 官方页面

附录 B:数字的来源分层

第一层:官方页面与官方文件。 受试者人数、每人测次与测点数、传感器型号与数量、采集场景、坐标定义、位移表、预处理步骤、许可、日期与 DOI,都来自项目主页、README.md、LICENSE.txt 与头文件原文。记录清单的行数、目录内文件数量、subject-info.csv 的三列内容,是直接读取文件得到的。

第二层:官方文件的直接派生。 单次时长由采样点除以采样率得到,约 69 秒;全库累计时长由 25 次乘 7 人得到;网格步长由位移表的相邻差值得到;受试者实际年龄由 subject-info.csv 的出生年与采集年份相减得到。这些数字不是官方单独列出的,而是从官方数据算出来的,口径已在正文说明。

第三层:未核实。 信号文件逐条的实际采样点总量、四只探头在各测次的具体方向配置是否完全一致、raw 与 preprocessed 之间的精确重采样比例、受试者来源与招募方式、官方所称"后续版本"的时间表。这些官方未逐项公布,正文中标为未说明或计划。

附录 C:完整参考文献

编号 文献 链接 用途
1 Kiel Cardio Database v1.0.0 https://physionet.org/content/kiel-cardio/1.0.0/ 规模、结构、边界数据来源
2 该库的 PhysioNet 文件目录 https://physionet.org/files/kiel-cardio/1.0.0/ RECORDS、README.md、头文件
3 数据集 DOI https://doi.org/10.13026/q6r2-zz68 引用与版本定位
4 数据集官网 https://biomagnetic-sensing.de/index.php/data-bases/datasets/kiel-cardio-database 官方声明的更新版本入口
5 PhysioNet 平台综述 https://doi.org/10.1038/s44360-026-00096-z 托管模式与引用规范
6 Engelhardt E 等,磁电传感器心肌电流密度估计 Current Directions in Biomedical Engineering, 2023 §8.1 的技术背景
7 Engelhardt E 等,心磁传感器系统质量分级 Current Directions in Biomedical Engineering, 2022 §7.2 的滤波与质量讨论
8 LG-BiTCN 心磁去噪研究 https://doi.org/10.1088/2057-1976/ae34b3 §7.4 的外部用法
9 Koch H 等,心电生理模型验证的参考数据集 Biomedical Engineering Online, 2011 §2.5 的同类对照
10 ECG-ID 数据库(库内对照) https://physionet.org/content/[ecgiddb](https://www.qianfanghub.com/ai-ready-dataset/ecgiddb/1488)/1.0.0/ §6.1 的同源异模态对比

附录 D:任务代码

任务一:按受试者做留一交叉验证的数据打包

import os
import re
import numpy as np
import pandas as pd
import wfdb

DATA = "https://physionet.org/files/kiel-cardio/1.0.0/data"

def load_subject(sid, stage="preprocessed", win=12000):
    rows = [wfdb.rdrecord(f"{DATA}/subject{sid}_{stage}_trial{t:02d}",
                          physical=True).p_signal[:win].astype("float32")
            for t in range(1, 26)]
    #-- 25 次测量的通道顺序一致,可直接堆成 (25, 8, win)
    return np.stack([r.T for r in rows])

for sid in range(1, 8):
    arr = load_subject(sid)
    print(sid, arr.shape, float(arr.std()))

这段代码把每个受试者的 25 次测量堆成一个三维数组,形状是测次乘通道乘采样点。用固定长度 win 截断,是为了让 25 次能对齐;截断到一万二千点即前六十秒,丢掉的末尾十秒不属于同一段时相,不截反而更难处理。

任务二:四只探头的一致性检查

import numpy as np
import pandas as pd
import wfdb

DATA = "https://physionet.org/files/kiel-cardio/1.0.0/data"
rows = []
for t in range(1, 26):
    r = wfdb.rdrecord(f"{DATA}/subject1_preprocessed_trial{t:02d}", physical=True)
    names = [s.strip().split() for s in r.sig_name]
    for k, (sensor, axis) in enumerate(names):
        seg = r.p_signal[:12000, k]
        rows.append({
            "trial": t, "sensor": int(sensor[1]), "axis": axis,
            "std_pT": float(seg.std()),
        })
df = pd.DataFrame(rows)
print(df.groupby(["sensor", "axis"])["std_pT"].describe().round(3))

第二段代码回答的是"四只探头是不是同一水位"这个问题。同一只探头在不同测次里的标准差若出现数量级跳变,通常不是信号问题,而是那一次测量时探头没贴稳或者夹具移位没到位。这类检查在任何传感器阵列数据上都是第一步。

附录 E:如果只记五件事

序号 记住什么 为什么
1 它是心磁,不是心电,单位皮特斯拉 这一条决定了后面所有流程能不能照搬
2 七个人、两百个测点、每次一分钟 三个数字定住了它的规模上限
3 25 次测量来自五乘五位移表 空间网格是设计出来的,不是随机的
4 本版没有任何标注,也没有心电 想训练监督模型,得先自己标
5 清单只列预处理版,raw 需换名字补下 只按清单下载会漏掉一半数据

编辑说明

核对于 2026 年 10 月 28 日完成。核对方式为直接访问 PhysioNet 项目页与文件目录,取回 RECORDS、README.md、LICENSE.txt、subject-info.csv 全文,并逐行读取 subject1 的 raw 与 preprocessed 头文件、trial02 头文件与 subject7 首末测次头文件,用于交叉核对坐标、采样点与时长。未下载 data 下的信号文件做逐条统计,单时长与总时长均由头文件声明的采样点与采样率推算,属于对官方文件的派生。论文侧只做了 Europe PMC 检索,仅匹配到一篇引用本库的降噪研究,未获得官方独立数据论文。未覆盖的内容包括:四只探头在全部测次的完整方向配置、raw 与 preprocessed 的精确重采样比例、受试者的招募方式、以及官方所称后续版本的时间表。这些均标为未说明或计划。


相关数据集导航

以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:

  • eye-tracking-ecg — 共享标签:生理信号 / 心电信号 / 多模态
  • ephnogram — 共享标签:生理信号 / 心电信号 / 多模态
  • deepfake-ecg — 共享标签:生理信号 / 心电信号 / 多模态
  • ecg-spider-clip — 共享标签:生理信号 / 心电信号 / 多模态
  • ninfea — 共享标签:生理信号 / 心电信号 / 多模态
  • ucddb — 共享标签:生理信号 / 多模态
  • qol-stress — 共享标签:生理信号 / 心电信号 / 多模态
  • dreamer — 共享标签:生理信号 / 心电信号 / 多模态
  • heartcycle — 共享标签:生理信号 / 心电信号 / 多模态
  • vitaldb-arrhythmia — 共享标签:生理信号 / 多模态

导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

返回 AI-Ready 数据集