信息速览
STAFF III 数据库是 PhysioNet 上的一份十二导联心电库,内容来自 1995 至 1996 年间美国西弗吉尼亚州一家医学中心的导管室。它记录的场合很特殊:患者正躺在导管台上接受择期经皮冠脉腔内成形术,医生把球囊送进将要处理的冠状动脉,充起来,让那支血管暂时断流几分钟,然后再放气。断流的这几分钟正是急性心肌缺血,而心电图上每一个导联都在同步变化。
它收录 104 名患者的记录,对应 152 次主要冠状动脉的闭塞。信号是标准十二导联,采样率 1000 Hz,振幅分辨率 0.625 微伏——后一个数字比多数心电库细得多,因为它最初就是为看清 QRS 波群里的高频成分而采集的,普通诊断心电并不需要这个精度。基线、扩张、扩张后三段都留在同一条记录里,球囊什么时候充盈、什么时候放气,由现场的人在记录上手工标下时刻。
名字里有两处容易读错。STAFF 不是一个技术缩略语,它来自这一系列研究的主导者 Stafford Warren;III 表示这是该系列的第三辑,官方页面没有交代前两辑的构成。这两点决定了它常被误当成某种 ST 分析算法的配套数据集,实际关系不大(§1.2)。一屏速览见下表。
| 维度 | 内容 |
|---|---|
| 官方全名 | STAFF III Database |
| 名称来源 | 取自研究者 Stafford Warren,官方与文献均未给出缩略语展开 |
| 系列位置 | STAFF 研究系列的第三辑,前两辑构成官方未说明 |
| 中文名 | STAFF III 心电数据库 |
| 托管平台 | PhysioNet,Open Access 栏目 |
| 版本 | 1.0.0,2017 年 1 月 31 日上线 |
| DOI | 10.13026/C20P4H |
| 采集地 | 美国西弗吉尼亚州 Charleston,Charleston Area Medical Center |
| 采集年份 | 1995 至 1996 年 |
| 患者数 | 104 名,均为择期球囊冠脉腔内成形术 |
| 闭塞次数 | 152 次,分布于 LAD、RCA、LCX 与左主干 |
| 导联 | 标准十二导联,肢体导联用 Mason-Likar 配置 |
| 采样率 | 1000 Hz |
| 振幅分辨率 | 0.625 微伏 |
| 每段记录 | 基线 5 分钟、扩张段、扩张后 5 分钟三部分 |
| 标注 | 球囊充盈与放气时刻全标,造影剂注射时刻部分标注 |
| 文件 | 每条记录一个头文件、一个数据体、一个事件注释文件 |
| 临床信息 | 另置于 xlsx 与 ods 两份表格 |
| 许可 | Open Data Commons Attribution License v1.0 |
| 引用文献 | Martínez JP 等,Computing in Cardiology 44:266-133,2017 |
§1 它要解决的具体麻烦
1.1 缺血发作的时候,通常没人在旁边记时间
心肌缺血在体表心电图上留下的痕迹,展开得很快:先是 T 波形态变了,接着 ST 段开始偏移,几分钟后 QRS 的形态也跟着改。麻烦在于,自然发作的缺血没人预约。患者在家里、在路上、在睡梦中缺血,等到胸痛难忍被送进急诊、贴上电极,往往只剩一个尾巴。动态心电能守二十四小时,可它守到的发作同样没有准确的起点,只能靠 ST 判据事后回溯,起点定在哪一秒取决于阈值怎么设。
导管室提供了一个别处没有的窗口。球囊充盈的那一刻,血管被机械堵死,缺血从零开始;放气的那一刻,血流恢复,缺血中断。整个过程有人在旁边看着,有压力曲线、有造影、有术者的手在推注射器,时间点被记下来。这就是 STAFF III 的立身之本:它不是等来的缺血,是被安排出来的缺血,有明确的开始、结束,和一段长度可控的中间过程。
这个性质决定了它的用途边界。想要"真实世界里缺血长什么样",它不如动态心电;想要"缺血从第几秒开始、在十二个导联上分别以什么顺序出现",它比任何自然记录都干净。
1.2 三条常见的错误期待
第一条,把它当成一份 ST 段数据库。 名字里的 STAFF 看上去很像 ST 加某个后缀,加上库的内容确实与缺血有关,很容易被归到 ST 段分析那一类。但按 CinC 2017 论文的说法,这个库最初是为了研究急性缺血期间 QRS 的高频成分而采集的,ST 段只是顺带被完整记录下来的副产物。这个出身解释了为什么采样率高达 1000 Hz、振幅分辨率细到 0.625 微伏——ST 段分析用不着这么细。
第二条,把它当成自然发作的缺血。 球囊闭塞是一根导管堵住血管,血管壁没有破,没有斑块破裂,没有血小板聚集,没有血栓,也没有慢性缺血里那套侧支循环逐渐开放的过程。它的缺血是"干净的、突然的、单支的",生理机制比自然发作单纯得多。用它的结论去推断斑块破裂型的急性冠脉综合征,中间隔着一层机制差异。
第三条,把 104 当成整个 STAFF 研究的规模。 104 是 STAFF III 这一辑的纳入人数,官方页面与 CinC 2017 论文口径一致。但 Warren 与 Wagner 2014 年那篇回顾写的是一组 228 名患者的 STAFF 研究,标准与高频心电、核素影像都在其中。两个数字都对,指向的是不同层级的东西(§3.4)。
1.3 它能给到的与给不到的
| 你的需求 | 它给的 | 够不够 |
|---|---|---|
| 缺血起点已知的十二导联数据 | 每次扩张的充盈与放气时刻都被标下 | 够,这是核心价值 |
| 高频 QRS 成分分析 | 1000 Hz 采样、0.625 微伏分辨率 | 够,正是为此而建 |
| 缺血期间 ST 段逐导联演变 | 十二导联全程连续,基线到扩张后不断 | 够,但 ST 偏离要自己算 |
| 缺血与冠脉供血区域的对应 | 每次闭塞的血管有记录,LAD、RCA、LCX、左主干四类 | 够用,但无造影影像 |
| 自然发作缺血的代表性 | 球囊诱发的机械闭塞 | 不够,机制不同 |
| 人群层面的缺血流行病学 | 单中心、择期手术、104 人 | 不够,没有抽样设计 |
| 长期预后与结局研究 | 无随访、无终点事件 | 不够,结构上做不到 |
| 心电与灌注影像配对 | 当年做过核素显像,但未随库提供 | 不够,官方明确不给 |
| 多支病变与侧支循环研究 | 只纳入单支主要冠脉的择期操作 | 不够,入组时已排除 |
| 教学演示缺血的全过程 | 一段记录里基线、缺血、恢复齐全 | 够,且比教科书插图真实 |
1.4 你的处境与它能帮到的事
| 你的处境 | 它能帮你什么 | 下一步该做什么 |
|---|---|---|
| 你在做缺血检测算法,手上只有静态心电图 | 提供同一患者从正常到缺血的连续对照,标签由球囊时刻给定 | 先用基线段做负样本,再用充盈后的一分钟做正样本 |
| 你的模型在动态心电上误报太多 | 给出一批"缺血正在发生但形态改变轻微"的难例 | 取充盈后头三十秒的段做压力测试 |
| 你在研究高频 QRS 与缺血的关系 | 采样率与分辨率都够,且扩张时刻精确 | 按导联分段算高频能量,以充盈时刻为零点对齐 |
| 你在做多导联融合或导联重建 | 十二导联同步、同一患者、同一时刻 | 留出导联做重建,按患者切分训练与测试 |
| 你在验证某个 ST 判据的敏感度 | 缺血起点已知,可以算检出延迟 | 统一采样窗与基线定义,报告延迟秒数 |
| 你在给监护设备做算法验证 | 真实导管室噪声与真实缺血波形 | 保留原始噪声,不要先做理想化滤波 |
| 你想要的是一份能代表门诊人群的心电 | 单中心、择期、术前状态 | 换用有抽样设计的队列资源 |
1.5 一句话判断
它把缺血做成了一个有开关的实验:球囊充盈是开,放气是关,中间那几分钟的十二导联,是别处很难凑齐的干净样本。
1.6 不适合谁:四条边界
不适合当作自然缺血的代表。 库里的缺血全部由机械闭塞产生,血管没有破裂、没有血栓、没有炎症。用它训练出来的检测器,遇到斑块破裂型的急性事件时,面对的是一个机制更复杂、形态更多变的场景。这是设计取向,不是缺陷,但必须在方法段写明。
不适合做长期预后或结局建模。 库里没有随访、没有终点事件、没有出院诊断编码。能建模的只有波形与时刻的关系,不能建模"这样缺血下去会怎样"。
不适合研究多支病变与侧支循环。 入组时就限定了单支主要冠状动脉的择期操作,室性心动过速、急诊手术、采集期间信号丢失的患者都被排除。想研究侧支逐渐开放对 ST 偏移的削弱作用,这个库在设计上就不提供这种对照。
不适合把球囊时刻当成症状发作时刻。 球囊充盈时患者可能毫无感觉,也可能胸痛难忍,库里有麻醉与镇静的背景,官方没有给出症状记录。任何"症状出现与心电改变的时间差"类研究,在这份数据上都缺一环。
§2 数据构成与规格
2.1 波形、注释、表格:三样东西各自为政
这个库的组织方式与多数单目录心电库不同。波形是散装的:每条记录一个头文件、一个数据体,命名是数字加一个小写字母,例如 7c、39c、64b。注释是另一套文件,后缀 .event,只在部分记录上存在。临床信息、扩张次数、分段说明这些"人要看的东西",全部放在两张表里,一张 xlsx、一张 ods,内容相同只是格式不同。
三样东西之间没有内嵌的关联键。表格里有一列专门说明每一行对应哪个记录文件、属于哪种测量类型,波形与注释则靠文件名主体相连。这意味着任何自动化流程的第一步都不是读波形,而是把表格读进来做成索引,再从索引去取文件。
| 层级 | 载体 | 形态 | 说明 |
|---|---|---|---|
| 波形 | .dat |
二进制 | 十二导联按样本交错存放 |
| 描述 | .hea |
纯文本 | 通道数、采样率、增益、样本总数 |
| 事件 | .event |
WFDB 注释二进制 | 充盈、放气、造影剂注射时刻 |
| 临床信息 | .xlsx |
表格 | 每位患者的操作与分段信息 |
| 临床信息副本 | .ods |
表格 | 与 xlsx 同内容,开放格式 |
| 记录名 | 文件名主体 | 数字加小写字母 | 官方未说明字母的含义 |
这套结构有一个直接后果:文件系统里看不出哪条记录属于基线、哪条属于扩张。分段只存在于表格的某一列里,跳过表格直接遍历目录,会得到一堆无法分组的波形(§5.6)。
2.2 字段与记录的完整字典
这个库没有一份正式的字段字典,官方页面用几段散文交代了规格,剩下的要靠表格与头文件拼。下表把能确认的信息项、存放位置与齐全程度并列出来,凡官方未说明的一律标出。
| 信息项 | 存放位置 | 取值或范围 | 是否齐全 |
|---|---|---|---|
| 记录名 | 文件名主体 | 数字加小写字母,如 7c、39c | 全部记录都有 |
| 导联数 | .hea 第一行 |
12 | 全部记录都是十二导联 |
| 采样率 | .hea 第一行 |
1000 Hz | 全库统一 |
| 振幅分辨率 | 官方数据描述 | 0.625 微伏 | 全库统一 |
| 样本总数 | .hea 第一行 |
随记录长度变化 | 全部记录都有 |
| 增益与基线 | .hea 通道行 |
随通道设置 | 全部记录都有 |
| 分段标识 | 临床信息表 | 基线、扩张、扩张后 | 依赖表格 |
| 扩张次数 | 临床信息表 | 每人最多五次 | 依赖表格 |
| 充盈时刻 | .event 与表格 |
相对记录的样本位置 | 部分记录有注释文件 |
| 放气时刻 | .event 与表格 |
相对记录的样本位置 | 部分记录有注释文件 |
| 造影剂注射时刻 | .event |
相对记录的样本位置 | 只标了一部分 |
| 闭塞血管 | 临床信息表 | LAD、RCA、LCX、LM | 全部有 |
| 既往心肌梗死 | 官方数据描述 | 按心电图标准判定,35 名 | 库级统计,非逐条字段 |
| 年龄与性别 | 临床信息表 | 官方未逐项列出 | 需读表确认 |
| 核素灌注影像 | 不提供 | 只对少数患者采集过 | 缺失 |
| 造影影像 | 不提供 | 官方未提及随库分发 | 缺失 |
| 随访与结局 | 不提供 | 无 | 缺失 |
表里最需要留意的是"充盈时刻"与"放气时刻"这两行都写了"部分记录有注释文件"。官方说明注释文件后缀是 .event,并且明确写了"only available for certain recordings"。这意味着时间信息在库内有两份来源:一份是注释文件,一份是表格。两份不一定覆盖同一批记录,做流程时应当以表格为索引、以注释为准,缺注释时回退到表格。
2.3 一条记录的完整解剖
拿 39c 当例子。它是官方特别提到的一条记录:原本表里记着两次扩张,后来整理者按记录长度与扩张时长比对,判断实际发生了三次,第三次被补进注释文件(§4.2)。这条记录因此同时具备"原表口径"与"修订口径"两层信息,正好用来演示这个库的文件长什么样。
头文件的字段顺序是 WFDB 的标准格式,第一行是记录名、通道数、采样率与样本总数,其后每个通道一行,写文件名、存储格式、增益、位分辨率、基线、初值、校验和与通道描述。下面这份是按该顺序写成的结构示意,不是逐字摘录:
39c 12 1000 <样本总数>
39c.dat 16 200.0(0)/mV 16 0 <初值> <校验和> 0 I
39c.dat 16 200.0(0)/mV 16 0 <初值> <校验和> 0 II
39c.dat 16 200.0(0)/mV 16 0 <初值> <校验和> 0 III
#-- 其余九个通道同构,依次为 aVR、aVL、aVF、V1 至 V6
真正读的时候不要手抄这些字段,交给工具:
import wfdb
rec = wfdb.rdrecord('39c', pn_dir='staffiii/1.0.0')
print(rec.record_name, rec.n_sig, rec.fs, rec.sig_len)
print(rec.sig_name[:6], rec.units[:3])
#-- 十二路同步,采样率 1000,长度以样本点计
print(round(rec.sig_len / rec.fs / 60, 2), 'minutes')
读出来的 p_signal 已经是物理量,单位毫伏。十二路的顺序默认与头文件一致,但保险的做法是按 sig_name 建映射再取列,因为不同记录里通道描述的大小写并不完全统一。
一份记录的完整时间结构可以按段切开。基线段是术前静息仰卧的五分钟,扩张段从球囊充盈开始、到放气结束,扩张后段是恢复静息五分钟。三段之间没有文件边界,都在同一个数据体里,靠表格里的分段说明与注释文件里的时刻定位。
| 段 | 官方时长 | 采集条件 | 标注情况 | 典型用途 |
|---|---|---|---|---|
| 基线 | 5 分钟 | 术前静息仰卧,未插入导管,在休息室或导管室或两处都做 | 无事件注释 | 负样本、个体基线校正 |
| 扩张 | 均值 4 分 23 秒,范围 1 分 30 秒至 9 分 54 秒 | 球囊在位并充盈,导管室内连续记录 | 充盈与放气时刻人工标注 | 正样本、缺血演变分析 |
| 扩张后 | 5 分钟 | 静息仰卧,导管室或休息室或两处都做 | 无事件注释 | 恢复过程、复极回退分析 |
2.4 三种记录形态:基线、扩张、扩张后
官方对采集流程的描述里藏着一个容易被忽略的细节:这三段并不总是录在同一条记录里。基线可以在病房休息室录,也可以在导管室录,或者两处都录;扩张段只能在导管室录;扩张后段同样可能在两处之一。这就产生了三种形态的记录——只有基线、含扩张的连续记录、只有扩张后。表格里的分段列就是用来区分它们的。
| 形态 | 内容 | 常见情形 | 使用时要注意 |
|---|---|---|---|
| 纯基线 | 术前五分钟静息心电 | 在休息室单独录一段 | 与扩张段不在同一体位与环境中 |
| 连续扩张 | 从充盈前延续到放气后 | 一次操作内的主记录 | 多数含扩张的记录属于此类 |
| 纯扩张后 | 放气后五分钟静息心电 | 在休息室补录 | 与扩张段的间隔长度不固定 |
| 多次扩张 | 一条记录内串起两到三次闭塞 | 官方点名的少数记录 | 时刻字段的语义在后续扩张中改变 |
第四种形态是这个库最需要小心的地方。官方明确说过,对于第二次及以后的扩张,注释里那个"距扩张的时间"字段并不严格等于距本次扩张的时间,因为该字段把之前的基线、扩张、扩张后各段的时长都算进去了。这一句话会直接改变时间对齐的写法(§4.3)。
2.5 与同类资源的字段差异
把 STAFF III 和库内几份心电资源并排看,字段的取舍差别很大。STAFF III 用十二导联、1000 Hz 换取了空间与频率上的完整,事件标注给到球囊充盈、放气与部分造影剂注射,但没有逐拍标注;LTSTDB 反过来,只用两三条导联、250 Hz,却换来二十一至二十四小时的时长与三级 ST 事件判定,外加人工修正过的逐搏标注;MIT-BIH ST Change 落在中间,一两路 360 Hz、十余分钟到二十余分钟,只有心搏标签;TWADB 则是两三分钟一段、五百赫兹、只标 QRS 时刻。
差别集中在两个维度上:导联数与时间分辨率。STAFF III 的取舍是为了看清一次操作里的细节,LTSTDB 的取舍是为了靠时长去碰自然发作的偶发事件。这不是谁更先进,而是问的问题不同(§6.1)。
§3 它的身份:一次被设计出来的缺血
3.1 谁做的、在哪做的、为什么做
这份数据不是由某个实验室例行采集的数据库项目产出的,它是一次临床研究的副产品。按官方页面,研究协议由 Stafford Warren 与杜克大学医学中心的 Galen Wagner 一起设计,现场采集由当时在瑞典布莱金厄医院工作的 Michael Ringborn 负责。采集地点是西弗吉尼亚州 Charleston 的 Charleston Area Medical Center,时间是 1995 至 1996 年。
那家中心当时采用了与别处不同的操作习惯:用一次时间较长的球囊充盈,替代惯常的一串短充盈。这个习惯在临床上也许有争议,但对数据采集是天赐之物——短充盈只能造出几十秒的缺血,心电改变刚起步就结束了。
采集完成后,数据在多位国际学者手里流转多年,最终由萨拉戈萨大学的 Pablo Laguna 与 Juan Pablo Martínez、隆德大学的 Leif Sörnmo 整理并提交到 PhysioNet。整理工作包括把散落的记录规范成 WFDB 格式、把临床信息汇总成两张表、把事件时刻写成注释文件,以及对若干条记录的扩张次数做修订。
| 角色 | 承担者 | 具体工作 |
|---|---|---|
| 协议设计 | Stafford Warren、Galen Wagner | 确定长时间单次充盈的采集方案与纳入排除标准 |
| 现场采集 | Michael Ringborn | 导管室内记录、事件时刻手工标注 |
| 数据整理 | Pablo Laguna、Juan Pablo Martínez | 格式规范化、注释编写、表格汇总 |
| 平台提交 | Leif Sörnmo | 版本发布、设备与软件归档 |
| 机构 | Charleston Area Medical Center | 提供导管室与患者来源 |
3.2 名字里的 STAFF 与罗马数字
库名的两部分都值得拆开说。STAFF 不是缩略语。官方页面全篇只写 STAFF III 或 STAFF-III,从未给出展开式;Warren 与 Wagner 2014 年那篇回顾把整个系列称作 The STAFF studies,作者署名第一人就是 Stafford Warren。把这几条摆在一起,最稳妥的读法是:STAFF 取自研究者的名,而不是某个由 ST 加若干字母组成的算法名。
III 是系列编号。既然有第三辑,就有第一辑与第二辑,但官方页面没有交代它们的构成、人数与去向。使用者能确认的只有一件事:STAFF III 这一辑是十二导联心电,104 名患者。
| 名字成分 | 常见误读 | 更可能的本义 | 确定性 |
|---|---|---|---|
| STAFF | ST 加某个后缀的算法缩写 | 研究者 Stafford Warren 的名 | 官方未给展开式,属推断 |
| III | 第三个导联或第三次扩张 | 研究系列的第三辑 | 官方标题与文献一致 |
| STAFF studies | 一份数据库的名字 | 一组跨多年研究的统称 | 文献明确使用 |
| 228 | STAFF III 的患者数 | 整个 STAFF 系列累计的患者数 | 文献口径,与官方 104 并存 |
3.3 采集现场:Mason-Likar 与一台定制设备
技术规格里有两处细节,官方写得比别处细,值得单独拎出来。第一处是肢体导联的接法:胸导联按标准位置贴,肢体导联却用了 Mason-Likar 配置,也就是把上肢电极放到锁骨下、下肢电极放到髂前上棘附近,而不是放在手腕与脚踝。这么做是为了压低骨骼肌噪声——导管室里患者紧张、发抖、被搬动,手腕脚踝上的电极最容易拾到肌电。
第二处是采集设备。官方写明用的是 Siemens-Elema AB 在瑞典索尔纳定制的设备,特点是动态输入范围异常宽。这个描述有点含糊,但结合 0.625 微伏的分辨率就好理解了:要同时不削顶地记录毫伏级的 QRS 和微伏级的高频切迹,前端必须有足够宽的动态范围,普通诊断心电机的量程不够。
| 参数 | 取值 | 官方给出的理由 | 后果 |
|---|---|---|---|
| 导联体系 | 标准十二导联 | 覆盖前壁、下壁、侧壁多个方向 | 可做导联间比较与重建 |
| 肢体导联接法 | Mason-Likar | 压低骨骼肌噪声 | 与标准接法的形态略有差别 |
| 胸导联位置 | 标准位置 | 保持与临床诊断的一致性 | 可直接套用常规判读经验 |
| 采样率 | 1000 Hz | 保留 QRS 高频成分 | 数据量约为常规库的四倍 |
| 振幅分辨率 | 0.625 微伏 | 分辨微小的高频波动 | 对噪声与基线漂移更敏感 |
| 采集设备 | Siemens-Elema AB 定制 | 动态输入范围宽 | 型号信息不可得 |
最后一行的后果要记住:高分辨率是一把双刃剑。它能看见别人看不见的东西,也能看见别人不需要的噪声——电极接触的微小抖动、导线的机械振动、工频干扰的残余,在这个精度下都会被放大成可分析的信号。用它做形态学研究时,滤波参数的选择比在 250 Hz 的库上更敏感。
3.4 104 与 228:两个患者数口径
这是这个库里最容易被引用错的一处。官方页面与 CinC 2017 论文都说 104 名患者;Warren 与 Wagner 2014 年的回顾说整个 STAFF 研究纳入 228 名接受择期五分钟球囊闭塞的患者。两个数字之间不存在谁替代谁的问题,它们分别指两件事。
| 口径 | 数字 | 覆盖范围 | 出处 |
|---|---|---|---|
| STAFF III 收录 | 104 名患者 | 以十二导联数字心电形式开放的这一辑 | 官方页面、CinC 2017 论文 |
| STAFF 系列累计 | 228 名患者 | 含标准与高频心电、核素影像的整组研究 | Warren 与 Wagner 2014 年回顾 |
| 冠脉闭塞次数 | 152 次 | STAFF III 这一辑内 | 官方页面、CinC 2017 论文 |
| 既往心肌梗死 | 35 名患者 | 按心电图标准判定 | 官方页面、CinC 2017 论文 |
| 单次扩张平均时长 | 4 分 23 秒 | STAFF III 这一辑 | 官方页面、CinC 2017 论文 |
写论文时的稳妥做法是:正文写 104,脚注或方法段补一句"该库是更大规模 STAFF 研究的一个子集,整组研究共 228 名患者"。这样既忠于官方页面,也不会让读过旧文献的审稿人产生疑问。
3.5 152 次闭塞的血管分布
官方给出的血管分布是四类,合计 152 次。这个分布本身不是抽样得来的,它是择期操作的自然结果——术者按病变位置选择处理哪支血管,没有为研究做过配比。
| 闭塞血管 | 次数 | 供血区域 | 心电上常见表现 |
|---|---|---|---|
| 左前降支(LAD) | 58 | 前壁、前间隔 | 胸前导联 ST 抬高为主 |
| 右冠状动脉(RCA) | 59 | 下壁、右室 | 下壁导联 ST 抬高,常伴镜像压低 |
| 左回旋支(LCX) | 32 | 侧壁、后壁 | 侧壁导联改变,有时不明显 |
| 左主干(LM) | 3 | 前壁加侧壁大范围 | 多导联同时改变 |
左主干只有三次,这个数字在使用时要有意识地处理:想按血管分层做模型评估,左主干这一层样本量过小,任何按血管分组的结论在这一层都站不住。前降支与右冠的次数接近,回旋支少一些,这个比例更接近当年导管室的实际病例构成,而不是研究设计的结果。
入组与排除标准同样影响可外推的范围:
| 类别 | 条件 | 影响 |
|---|---|---|
| 纳入 | 在一支主要冠状动脉接受择期球囊冠脉腔内成形术 | 病变单一,便于归因 |
| 排除 | 室性心动过速 | 心律稳定是分析前提 |
| 排除 | 急诊操作 | 排除不稳定状态与并发用药 |
| 排除 | 采集期间信号丢失 | 保证记录完整 |
| 未限定 | 年龄、性别、合并症 | 官方未给出分层构成 |
§4 它最独特的东西:人为诱发的缺血与秒级标记
4.1 为什么"知道缺血从哪一秒开始"比"缺血有多重"更稀缺
缺血研究里最难的从来不是测量,而是归因。看到一段 ST 压低,你能算出它压了多少毫伏、持续了多少秒,但你算不出它是什么时候开始的——因为记录开始时缺血可能已经在了。动态心电的解决办法是设阈值,把 ST 水平首次越过阈值的那一拍当起点。这个起点是判据的函数,不是生理的函数:阈值改 0.05 毫伏,起点就挪几十秒。
球囊把这件事变成了物理事件。充盈的那一刻血管断流,缺血从零开始,没有模糊地带。这个性质带来的不只是"标签更准",而是整类研究变得可行:你可以算检出延迟、算导联间的出现顺序、算恢复时间常数。这些问题在没有精确零点的数据上只能做得很粗。
4.2 案例:39c 的三次扩张
39c 是官方在注释修订说明里明确点名的一条记录。按原表,这条记录里有两次扩张;整理者在核对时发现记录长度与两次扩张的时长加起来对不上,多出来的部分足以再塞下一次完整的扩张,于是判定实际发生了三次,把第三次补进了注释文件。这条记录因此成了理解这个库标注逻辑的最好样本。
它同时暴露了这个库最微妙的一处语义陷阱。官方说明,注释里那个表示"距扩张的时间"的字段,对第一次扩张而言就是字面意思;但对第二次与第三次扩张,该字段还包含了之前各段基线、扩张、扩张后的时长,所以它不再等于"距本次充盈的时间"。要还原第三次扩张的真实起点,得先从表格里读出各段时长,逐段累加,再从注释字段里减掉。
| 关于 39c 的问题 | 能否确定 | 依据 | 处理建议 |
|---|---|---|---|
| 记录里有几次扩张 | 能,三次 | 官方注释修订说明 | 以修订后的注释为准 |
| 第一次充盈时刻 | 能,字段语义直接 | 注释文件 | 直接读 |
| 第三次充盈时刻 | 需换算 | 注释字段含前序各段时长 | 按表格分段累加后校正 |
| 每次扩张的精确时长 | 部分能 | 充盈与放气两个时刻之差 | 缺放气时刻时不可得 |
| 球囊是否在记录结束前放气 | 未必 | 官方说明部分记录未覆盖放气 | 标注为截断 |
| 三次扩张分别对应哪支血管 | 只能到患者层 | 表格按患者记血管,非按扩张 | 不要按扩张分层归因 |
上表最后一行值得展开。血管信息是按患者记的,不是按每次扩张记的。若一名患者在一次操作里做了三次扩张,官方表格能告诉你这支血管是前降支,未必能告诉你第三次扩张是否仍在同一支。做按血管分层的分析时,把每一次扩张都当成独立的血管事件,会引入无法核实的假设。
关于这条记录还有一层用途:它演示了修订是怎么发生的。整理者用的判据很朴素——记录长度与扩张时长比对。这个判据可靠但不完备:如果某次扩张的时长本身记错了,比对就会失效;如果记录尾部有一段没有标注的空白,比对也会失效。官方在 27c 上就承认了这类不确定:那条记录只标了"距扩张的时间",其后整段被假定为扩张期间,球囊是否提前放气则无从得知。
4.3 标记的三层:充盈、放气、造影剂
库里的时间标记不是一层,而是三层,覆盖程度递减。
| 标记类型 | 覆盖范围 | 粒度 | 可靠性 | 误用后果 |
|---|---|---|---|---|
| 球囊充盈 | 每次扩张 | 单个样本点 | 现场人工标注,官方称全部标出 | 低,语义清晰 |
| 球囊放气 | 多数扩张 | 单个样本点 | 部分记录在结束前未覆盖 | 中,缺放气会把缺血段拉长 |
| 造影剂注射 | 部分注射 | 单个样本点 | 官方明说未标全 | 高,未标的注射会被误读为缺血波动 |
第三层最容易坏事。造影剂注射会造成心电形态的短暂改变,官方因此把注射时刻标注出来,供使用者在分析时剔除或单独看待。但官方同时提醒,并非所有注射都被标注,所以当你在记录里看到一段短暂的、形态上很像注射反应的改变,却没有对应的标记时,不能直接归因为缺血——它可能就是一次没被标下的注射。
这条提醒的实际含义是:这个库的事件标签是"已知事件的清单",不是"全部事件的清单"。把它当负样本的保证来用,会出问题。
4.4 它能支撑的四类实验
| 实验类型 | 需要什么 | 这个库能否支撑 | 关键约束 |
|---|---|---|---|
| 缺血检出延迟评测 | 精确起点与十二导联连续波形 | 能 | 需自定 ST 判据与基线 |
| 导联间演变顺序分析 | 多导联同步、起点已知 | 能 | 需处理各导联噪声差异 |
| 高频 QRS 与缺血程度关联 | 高采样率与高振幅分辨率 | 能,这正是建库初衷 | 需谨慎选择滤波带宽 |
| 缺血恢复过程建模 | 放气时刻与扩张后段 | 部分能 | 部分记录缺放气或扩张后段 |
| 缺血预适应研究 | 同一患者多次扩张的对照 | 部分能 | 多次扩张的记录数量有限 |
| 症状与心电的时序关联 | 症状出现时刻 | 不能 | 库内无主观症状记录 |
第五行值得单说。同一患者多次扩张,天然构成"第一次缺血"与"后续缺血"的对照,这是研究缺血预适应的理想材料——第一次闭塞后的心肌,对第二次闭塞的反应可能更轻。官方没有专门为这个目的设计,但多次扩张的记录确实存在,39c 就是三次。做这类分析时要注意,多次扩张之间的间隔长短不一,间隔本身就是变量。
4.5 边界条件:什么时候它不再适用
| 场景 | 为什么不适用 | 替代思路 |
|---|---|---|
| 自然发作的急性冠脉综合征 | 无斑块破裂、无血栓、无炎症 | 换用带临床结局的队列 |
| 无痛性心肌缺血的筛查 | 无患者症状与动态监测场景 | 换用动态心电资源 |
| 多支血管病变的定位 | 入组限定单支 | 换用带造影与多支记录的资源 |
| 侧支循环研究 | 闭塞时间短,侧支开放窗口不足 | 需更长的闭塞模型 |
| 药物干预效果评估 | 无用药记录与对照设计 | 换用随机对照试验数据 |
| 儿童与特殊人群 | 官方未给出年龄分层 | 不可外推 |
第三行与第四行需要区分。单支限定是为了让缺血区域可归因,好处是干净,坏处是无法观察"一支堵了另一支供血"这种在真实多支病变里极常见的情形。侧支循环的开放通常需要数十秒到数分钟,而这个库的扩张段均值只有四分多钟,窗口不算宽裕,且没有任何侧支血流的测量。
4.6 用事件标记做弱监督
严格说,库里没有"这一拍是缺血"的逐拍标签,只有"这一刻球囊充盈了"。把事件标签变成逐拍标签,需要自己补一层逻辑,而这一层逻辑的选择会实质影响结论。
| 标注策略 | 做法 | 优点 | 风险 |
|---|---|---|---|
| 全段阳性 | 充盈到放气之间全标阳性 | 简单,无参数 | 缺血起步的几十秒形态尚未改变,被强行标阳 |
| 延迟阳性 | 充盈后固定延迟再标阳 | 贴近生理 | 延迟长度是人为参数 |
| 形态门控 | 按 ST 或 T 波判据动态定起点 | 与形态一致 | 判据本身带阈值偏差 |
| 分段软标签 | 按距充盈的时间给权重 | 保留渐变信息 | 权重函数无官方依据 |
四种策略里,第四种在设计上最诚实,也最难在论文里说清。若采用,必须在方法段写明权重函数的形式与理由,否则审稿人无法判断结论是被标签构造带出来的还是数据本身给出的。§4.2 的案例在这里正好派上用场:39c 有三次扩张,若用"全段阳性"策略,三次扩张之间的恢复期也会被标成阳性,而那段恰恰是心肌正在回到基线的时候。
§5 怎么拿到:从数据表到可训练张量
5.1 目录与体积
官方页面给出了文件构成,但没有给出整包体积,也没有给出总时长。体积可以按规格推算:十二导联、1000 Hz、每样本两字节,一秒就是二十四千字节,一分钟约一点四兆字节,十分钟约十四兆字节。一百余条记录、平均十余分钟,整包大致落在两吉字节上下——这个数字是推算,不是官方公布值,规划存储时应留出余量。
| 项 | 官方是否给出 | 数值或推算 | 说明 |
|---|---|---|---|
| 整包体积 | 未给出 | 约两吉字节量级 | 按十二导联与 1000 Hz 推算 |
| 单条记录体积 | 未给出 | 每分钟约 1.4 兆字节 | 同上 |
| 记录条数 | 未给出 | 与患者数同量级 | 官方只给患者数与闭塞数 |
| 总时长 | 未给出 | 未给出 | 需逐条读取头文件相加 |
| 单条时长上界 | 未给出 | 约二十余分钟量级 | 由三段构成推算 |
| 表格文件 | 两份 | xlsx 与 ods | 内容相同 |
第一行与第三行的空白要在方法段老实交代。官方给出的规模数字是患者数与闭塞数,不是文件数与总小时数;把推算值写成官方值,是最常见的一类引用瑕疵。
5.2 批量获取
#-- 方式一:递归抓取整个版本目录
wget -r -N -c -np https://physionet.org/files/staffiii/1.0.0/
#-- 方式二:从公开桶同步,无需账号
aws s3 sync --no-sign-request s3://physionet-open/staffiii/1.0.0/ ./staffiii
#-- 方式三:先只取表格与头文件,建好索引再按需拉数据体
wget -c https://physionet.org/files/staffiii/1.0.0/*.xlsx
wget -c https://physionet.org/files/staffiii/1.0.0/*.ods
第三种方式对这个库特别合适,因为它的记录没有内嵌索引,必须先读表格才知道哪条记录是哪一段。先拿表格与头文件,几百千字节就能建出完整的元数据视图,再决定要拉哪几条波形。
5.3 读表建索引
表格是这个库的入口文件。读进来之后第一件事是确认哪一列把文件名与测量类型对上,通常它是一列类似"文件"或"记录"的字段,值形如 7c 这样的字符串。
import pandas as pd
def load_index(xlsx_path, sheet=0):
df = pd.read_excel(xlsx_path, sheet_name=sheet)
df.columns = [str(c).strip() for c in df.columns]
col = next(c for c in df.columns if 'file' in c.lower() or 'record' in c.lower())
df = df.rename(columns={col: 'record'})
df['record'] = df['record'].astype(str).str.strip()
return df
index = load_index('staffiii_clinical.xlsx')
print(index.shape)
print(index['record'].head(10).tolist())
列名是英文自由文本,不同版本的表可能不同,所以上面用关键词匹配而不是写死列名。拿到 record 列之后,把它与磁盘上的 .hea 文件名做一次交集,就能立刻发现表里有没有、盘上有没有的对不齐——这是清洗这个库必做的第一步。
5.4 读事件注释
.event 是 WFDB 注释格式,用标准读取器即可。注意注释只在部分记录上存在,读之前先判断文件是否存在。
from pathlib import Path
import wfdb
def read_events(rec_name, root='staffiii'):
p = Path(root) / f'{rec_name}.event'
if not p.exists():
return []
ann = wfdb.rdann(str(Path(root) / rec_name), 'event')
return list(zip(ann.sample.tolist(), ann.symbol))
for rec in ['39c', '7c', '27c']:
ev = read_events(rec)
print(rec, len(ev), ev[:2])
读完之后要做一次语义检查,而不是直接当时间用。官方点名的名单可以直接当筛查表用:7c、11c、39d、53c 与 64b 五条事后各判定多出一次扩张,共两次;39c 多出两次,共三次;29c、31c 与 77c 原表已标为两次;27c 只标了距扩张的时间,其后整段被假定为扩张期间,放气时刻不可得。名单之外的记录以单次扩张为主,但仍应按事件个数核对一遍。对多次扩张的记录,第二个及以后的时刻字段需要按分段时长换算(§4.2)。
5.5 切窗与对齐
缺血分析的通用做法是以充盈时刻为零点,向前后各取一段。窗长的选择取决于研究问题:算检出延迟用短窗,看复极回退用长窗。
import numpy as np
def cut_around(rec, onset, pre=60, post=300):
fs = rec.fs
a = max(0, onset - int(pre * fs))
b = min(rec.sig_len, onset + int(post * fs))
x = rec.p_signal[a:b]
t = (np.arange(a, b) - onset) / fs
return x, t
x, t = cut_around(rec, onset=120000, pre=60, post=300)
print(x.shape, t[0], t[-1])
这个函数里唯一需要斟酌的是 pre。基线段的官方定义是术前五分钟静息,但那条五分钟记录未必与扩张段在同一条记录里连续。若记录从充盈前几秒才开始,pre 给到 60 秒就会读到记录起点之前,函数里的 max(0, ...) 会把它截住,返回的窗比预期短。下游若按固定长度堆张量,这种长度不齐会在拼接时报错,所以要么统一截断,要么补齐后打上掩码。
5.6 六个最容易出错的地方
其一,跳过表格直接遍历目录。 拿到一堆无法分段的波形,基线段会被当成缺血段。先读表建索引,再取文件。
其二,把事件字段当绝对时间。 多次扩张的记录里,第二个及以后的时刻整体偏移,正负样本可能错位数分钟。
其三,假设每条记录都含扩张。 纯基线与纯扩张后记录混进来,负样本比例失衡,按分段列过滤即可。
其四,用扩张全段做阳性。 起步与恢复段被判为缺血,模型学到的是"扩张"这个场景,而不是"缺血"这个状态。
其五,忽略造影剂注射时刻。 短暂的形态变化被当成缺血波动,直接推高假阳性。
其六,按固定长度切窗不加掩码。 记录尾部长度不足,拼接时要么报错,要么被静默补零而引入虚假样本。
前两条是这个库特有的坑,其余四条在多数心电库上都会遇到,只是这里的后果更严重——因为这个库的正样本全部依赖事件时刻的准确,时刻一错,整条记录就废了。
5.7 一个能跑通的高频 QRS 检查
建库初衷是高频 QRS,所以最贴合它的一次自检,就是看能否在球囊充盈后测到 QRS 高频能量的变化。做法不复杂:取基线段与充盈后一段,各自带通到高频,算包络均值,比较两者。
import numpy as np
from scipy.signal import butter, sosfiltfilt, hilbert
def hf_energy(x, fs, band=(150, 250)):
sos = butter(4, band, btype='band', fs=fs, output='sos')
y = sosfiltfilt(sos, x)
return float(np.mean(np.abs(hilbert(y))))
base = rec.p_signal[: 60 * rec.fs, 1]
isch = rec.p_signal[130 * rec.fs : 190 * rec.fs, 1]
print(round(hf_energy(base, rec.fs), 6), round(hf_energy(isch, rec.fs), 6))
这段代码只算了一个导联,结论不能推广到十二导联的整体行为。它的用处是确认三件事:数据读得对、采样率用对了、事件时刻落在预期的位置上。三件事都对,再往下做导联间比较才有意义。若两侧能量差异极小甚至反向,先怀疑时刻取错,而不是怀疑生理。
§6 与库内词条的关系
6.1 关系图谱
这份库在库内处在"缺血"这条线的正中,左边是自然发作的动态心电,右边是运动诱发的负荷心电。它与三份同族资源的关系不是替代,而是各自占据缺血研究的一个环节。
| 关系类型 | 相关词条 | 具体关系 |
|---|---|---|
| 同一生理现象 | LTSTDB 缺血与非缺血事件参考集 | 同为心肌缺血,但一个是自然发作、一个是球囊诱发 |
| 同一诱因类型 | MIT-BIH ST Change Database | 都是人为诱发,但一个是运动、一个是机械闭塞 |
| 同一标注对象 | TWADB 微伏级交替库 | 都关注微小电活动,但一个看复极交替、一个看 QRS 高频 |
| 同一平台 | PhysioNet 其它 Open Access 资源 | 同平台、同许可、同取数方式 |
| 同一时代 | 上世纪九十年代的心电采集 | 设备与操作习惯处于同一代际 |
| 同一分析目标 | 缺血检测算法评测 | 三份资源常被并置做跨库验证 |
逐维区隔比关系类型更有用。下面这张表把四份资源放在同一条时间与标注轴上比:
| 维度 | STAFF III | LTSTDB | MIT-BIH ST Change | TWADB |
|---|---|---|---|---|
| 缺血怎么来 | 球囊机械闭塞,术者开关 | 日常生活自然发作 | 运动负荷试验诱发 | 不涉及缺血 |
| 起点是否已知 | 已知,秒级 | 未知,按 ST 判据回溯 | 未知,按试验进程估 | 不适用 |
| 单条时长 | 数分钟至二十余分钟 | 21 至 24 小时 | 约 15 至 25 分钟 | 约 2 分钟 |
| 导联数 | 12 | 2 至 3 | 1 至 2 | 2 至 12 |
| 采样率 | 1000 Hz | 250 Hz | 360 Hz | 500 Hz |
| 标注粒度 | 事件时刻 | 逐搏与三级 ST 事件 | 仅心搏 | 仅 QRS 时刻 |
| 主要用途 | 起点已知的缺血演变 | 长时程缺血负荷统计 | 一过性 ST 改变的形态学 | 复极交替检测 |
七行里最关键的是第二行。LTSTDB 与 MIT-BIH ST Change 的缺血起点都是估出来的:前者靠 ST 水平首次越过阈值,后者靠试验进程与症状。STAFF III 的起点是球囊充盈那一刻,物理上可定义。这一个差别决定了三者的用法不同——要算检出延迟,只能用 STAFF III;要算缺血总负荷,只能用 LTSTDB;要看运动状态下的一过性改变,只能用 MIT-BIH ST Change。
6.2 检索路径
想找"缺血"这个主题的人,从生理信号类目进、按心电信号筛,会同时看到四份资源。此时的分流依据是三个问题:缺血是不是被诱发的、起点是否已知、记录有多长。问"缺血从第几秒开始",走诱发且起点已知那条路,落到 STAFF III;问"一天里缺血发作几次",走长时程自然记录,落到 LTSTDB;问"运动时 ST 怎么变",走负荷试验,落到 MIT-BIH ST Change;问"复极的微伏级波动",走交替专门的 TWADB;问"缺血在十二导联上的空间分布",仍然回到 STAFF III。
其中最后一条最容易走错:TWADB 里的一部分记录确实来自缺血相关的研究,但它的标注对象是 T 波交替,不是缺血本身。想用它做缺血检测,等于用错了标签层。
6.3 与库内心电词条的分工
库内心电词条大多围绕"这一拍是什么"或"这段心律是什么",STAFF III 回答的是另一个问题:这一拍发生的时候,心肌正在缺血,而我们知道缺血是从哪一秒开始的。前者是分类问题,后者是状态与时间的问题。
这个分工带来一个实用推论:做跨库验证时,STAFF III 不该被当成"又一个 ST 数据集"塞进训练集,而应单独作为"起点已知"的测试场景。与 LTSTDB 混在一起训练,模型会同时学到球囊闭塞与自然发作两种形态特征,分开评估才看得出稳定性差异。
§7 质量评估与局限性
7.0 阅读本节前的一个前置校正
在给这份库打分之前,要先校正一个常见的误判:把它当成"缺血数据集"来评。若按数据集的标准衡量,它会被扣得很惨——没有随访、没有结局、没有对照组、人群是单中心择期手术患者、连总时长都没公布。这些评语都对,但都没有解释力,因为它们问的是"这份数据能替代多少别的东西",而不是"这份数据能回答什么别人回答不了的问题"。
把口径换成"实验记录"之后,评价的落点就变了:它的诱发方式是否可控、时刻标注是否可核、规格是否足以支撑它宣称的分析目标。三个问题的答案决定了它适合被当作什么用,也决定了它不该被塞进什么流程。
7.1 五维评分
借用数据交换标准(DAIMS)常被追问的五个维度——可发现、可访问、可互操作、可复用、可追溯——来看,这份库的长短分布得相当清楚。
| 维度 | 评分 | 依据 |
|---|---|---|
| 可发现 | 高 | 有 DOI、有平台收录、有 CinC 论文作为引用锚点 |
| 可访问 | 高 | 无需登录,许可明确,逐文件可取 |
| 可互操作 | 中高 | WFDB 标准格式,但类目信息在表格里,不在波形里 |
| 可复用 | 中高 | 许可宽松,规格清晰,但需自建索引与标签策略 |
| 可追溯 | 中 | 可追到机构、年份与操作,不可追到个体病历 |
DAIMS 关心的核心问题是:这份数据在交换与复用时会不会掉信息。这份库在可发现与可访问上接近满分,因为它挂在被广泛引用的平台上、有独立 DOI、有正式论文;掉分的地方集中在后两项,原因是它的语义没有内嵌在数据里——导联是标准的,但"这段是基线还是扩张"要靠外部表格说。
7.1.1 五个维度里的两条短板
第一块短板是可互操作。WFDB 头文件描述的是波形怎么解码,不描述这段波形属于哪个阶段。同一份数据被两个人拿去,一个按文件名排序,一个按表格分组,得到的正负样本完全不同。这不是格式问题,是元数据位置问题:关键的语义放在了一个需要额外读取、且两份副本可能不同步的表格里。
第二块短板是可追溯。它能追溯到采集机构、采集年份、手术方式与闭塞血管,追溯不到具体病历、具体术者、具体球囊型号与充盈压力。对波形形态研究影响有限,对器械或操作相关的研究则可能是硬缺口。
四条具体表现值得记下:分段信息只存在于表格,建索引时要把它写回每条记录;xlsx 与 ods 两份副本可能不同步,固定用一份并记录下载日期;器械信息完全缺失,只能在方法段声明不确定性;个体病历不可得,只有库级的既往心梗统计,因此不应按个体做临床分层。
7.2 标注的真实覆盖范围
官方对标注的说明分三处,读的时候要合起来看。第一处说,所有与球囊充盈、放气相关的时间点都由人工标注;第二处说,注释文件只对部分记录提供;第三处说,造影剂注射只标注了一部分。
这三句话拼出来的图景是:事件时刻的精度很高,到单个样本点;覆盖并不完整,既不是每条记录都有注释文件,也不是每次注射都被标。把这份标注当成缺血检测的真值来用,等于把一张精度很高但有空白的图纸当成了完整地图。
7.3 已知的、可枚举的偏差
| 偏差 | 表现 | 影响 | 应对 |
|---|---|---|---|
| 机制偏差 | 缺血由机械闭塞产生 | 无斑块破裂、血栓与炎症过程 | 结论限定在闭塞型缺血 |
| 人群偏差 | 单中心择期手术患者 | 不代表急诊与多支病变人群 | 不做流行病学外推 |
| 操作偏差 | 长时间单次充盈的本地习惯 | 缺血时长分布与别处不同 | 写明操作背景 |
| 排除偏差 | 室速、急诊、信号丢失者被排除 | 缺最难的那部分样本 | 承认难度被低估 |
| 时长偏差 | 三段长度不统一 | 固定窗长会截断或补零 | 用掩码处理长度不齐 |
| 语义偏差 | 后续扩张的时刻字段含义不同 | 直接读取会造成整体错位 | 按分段时长换算 |
| 标注偏差 | 造影剂注射未标全 | 短暂形态变化被误判为缺血 | 结合形态与时刻双重判断 |
| 分辨率偏差 | 0.625 微伏放大噪声 | 滤波参数选择影响结论 | 报告滤波设置并做敏感性分析 |
前四条属于采集设计,改不了,只能写在方法段;后四条属于使用层面的坑,可以在流程里处理。写作时最有价值的做法,是把前四条写成"本研究的外推边界",把后四条写成"数据清洗步骤",两者不要混在一起。
7.4 外部验证矩阵
六条验证路径里,四条可行、一条部分可行、一条不可行。与动态心电库对照缺血形态可行,因为同为体表导联,形态可比;与负荷试验库对照诱发差异也可行,机制不同正好做对照;与造影结果对照闭塞位置不可行,库内没有造影影像;与核素灌注对照同样不可行,影像未随库提供;重复测量一致性部分可行,多次扩张的记录可做患者内对照;专家重新判读可行,十二导联可以请医师重判后与算法结果比。
第三条与第五条是这份库相对少见的一处优势与一处劣势并存。多数心电库每位患者只有一段记录,做不了患者内的重复测量;这里有若干条记录含两到三次扩张,天然构成同一患者在不同时刻的重复观测,适合做"同一心肌、不同缺血次数"的对照。反过来,没有影像就没有解剖学真值,任何关于闭塞部位与心电改变对应关系的结论,都只能落在"该患者闭塞的是哪支血管"这一层。
7.5 它为何能持续:一份把缺血钉在秒上的存档
公开库里做缺血的不止一份,但把缺血的起点做成物理事件的,几乎没有第二份。LTSTDB 靠阈值回溯起点,MIT-BIH ST Change 靠试验进程估起点,European ST-T 两者兼有;只有这一份,起点是术者手上那支球囊的动作。这个性质不会因为新数据出现而贬值——新数据同样没有球囊开关。
它能持续存在,靠三点:许可足够宽松,任何人可以下载、改造、再分发;格式足够标准,WFDB 从九十年代用到现在,读取工具没有断代;上下文足够完整,官方页面把协议、纳入排除、采集设备与标注方式都写了下来。再加上 CinC 2017 那篇论文给了它一个可引用的身份,引用链条是通的。
§8 生态位与历史
8.1 历史沿革:从导管室到平台
这段历史可以按三段来分。第一段是 1995 至 1996 年的采集期,地点是西弗吉尼亚的一家医学中心,动机是研究急性缺血期间 QRS 的高频成分,成果陆续发表在心脏病学与心电学刊物上。第二段是流转期,数据在萨拉戈萨、隆德与杜克等机构之间以数字形式传递,被不同团队从不同角度反复分析,用途逐渐超出原始设计。第三段是 2017 年 1 月 31 日上线 PhysioNet,配上 DOI 与正式的数据描述论文,从此有了稳定的引用入口。
第二段最容易被忽略,却最能解释这份库的性格。它在被公开之前,已经在一个小圈子里被用了十几年,方法学论文、临床论文都拿它做过验证。这种"先在小圈子磨合、再公开"的路径,让它的文件组织带着明显的自用痕迹:表格与波形分离、注释只对部分记录提供、记录名用数字加字母。这些在公开库的规范里都算瑕疵,在自用场景里都是效率。
8.2 与后续研究的关系
按官方给出的两篇回顾,这个库在方法学上的影响集中在三块:缺血期间高频 QRS 的测量与解释、ST 段偏移的自动检测与量化、以及更广义的心电信号处理。它被反复用作"真实缺血波形"的样本来源,而不是人群统计的来源。
这个定位带来的后果是:它的引用大多出现在方法段,而不是结果段。方法段引用一份数据,意味着作者需要的是"数据能支撑这个方法",而不是"数据能代表这个人群"。这也解释了为什么一份只有一百余人的库能有这么长的引用寿命。
8.3 生态位:一间可以重放的导管室
用一句话定位:它是一间可以重放的导管室。设备、患者、术者的动作都被压缩成十二条波形与几个时刻;你没法改变当时发生了什么,但你可以把同一分钟看一百遍,每次换一个导联、换一个频带、换一个判据。
这个定位有一个实用推论:使用者应当先确定"我要复现哪一个动作",再取数。想看缺血起点,就取充盈前后各一分钟;想看恢复过程,就取放气前后;想看基线稳定性,就用术前那五分钟。反过来,先下载整库再想问题,通常会在表格与文件名的对应关系上耗掉大半时间。
再补一层:这类"可重放的操作现场"随时间只会更稀缺。新记录更规范、更完整,但球囊长时间闭塞这种操作本身已经少见——支架时代之后,长时间单次充盈的必要性下降了。
8.4 谁在用它,用来做什么
| 使用者类型 | 典型用途 | 需要额外准备 |
|---|---|---|
| 信号处理研究者 | 高频 QRS 测量、ST 偏移量化、去噪 | 自定频带与基线策略 |
| 缺血检测算法开发者 | 起点已知的检出延迟评测 | 统一判据与切窗规则 |
| 临床研究方法学者 | 缺血演变的时间进程分析 | 逐段对齐与清洗 |
| 教学人员 | 演示缺血从正常到异常的全过程 | 挑选形态清晰的记录 |
| 数据平台建设者 | 作为 WFDB 多导联高采样率样例 | 无,工具链现成 |
第三类最容易低估工作量。缺血演变的时间进程分析要把每次扩张的起点对齐、把导联按解剖位置排序、把不同患者的基线差异先扣掉,任何一步偷懒,结论都会变成"平均波形"的堆叠。
§9 使用指引
9.1 三种角色的路径
算法工程师的起点是 §2.2 的字段表与 §5.3 的索引脚本,第一个产出是一份带分段标识的索引,最常见的卡点是跳过表格直接遍历目录。临床研究者的起点是 §4.3 的标注分层,第一个产出是一张按扩张对齐的时间轴,最常见的卡点是把后续扩张的时刻当绝对时间。教学与平台建设者的起点是挑形态清晰的记录,第一个产出是一段可讲解的缺血全过程,最常见的卡点是选到缺放气时刻的记录。
9.2 一条最短的可用流程
从零到一段可用的缺血窗,四步够了。
#-- 第一步:取表格与头文件
wget -r -N -c -np --accept="*.hea,*.xlsx,*.ods,*.event" https://physionet.org/files/staffiii/1.0.0/
#-- 第二步:按记录名补齐数据体
python3 fetch_dat.py --records 39c 7c 29c
import wfdb
from pathlib import Path
rec = wfdb.rdrecord('39c', pn_dir='staffiii/1.0.0')
ann = wfdb.rdann('39c', 'event', pn_dir='staffiii/1.0.0')
onset = int(ann.sample[0])
win = rec.p_signal[max(0, onset - 60 * rec.fs): onset + 300 * rec.fs]
print(win.shape, onset)
第三步是把窗与表格里的分段对上,第四步才是建模。四步里最容易省掉的是第三步,也是最不该省的——没有分段标识,后面所有正负样本的划分都悬空。
9.3 引用方式
| 字段 | 内容 | 用途 |
|---|---|---|
| 数据集 | Martínez JP, Pahlm O, Ringborn M, Warren S, Laguna P, Sörnmo L. The STAFF III Database: ECGs Recorded During Acutely Induced Myocardial Ischemia. Comput Cardiol 44:266-133, 2017 | 官方指定的引用对象 |
| 平台 | PhysioNet as a global platform for biomedical research | 平台引用 |
| 版本 | STAFF III Database v1.0.0 | 精确定位 |
| 标识 | DOI 10.13026/C20P4H | 可解析链接 |
| 许可 | ODC-BY 1.0 | 署名要求 |
引用时要注意两件事。第一,官方指定的引用对象是 CinC 2017 那篇数据描述论文,不是最早的临床论文;写"数据来源"时引它,写"方法背景"时再引 Warren 与 Wagner 2014 的回顾。第二,许可要求署名,商用同样需要,署名内容至少包含数据集名、版本、DOI 与许可名。
9.4 复现一份最小报告的四步检查
第一步查导联数是否为十二,若不是,说明读到了别的目录或头文件被截断。第二步查采样率是否为 1000 Hz,手写 250 或 500 是常见笔误。第三步查事件个数是否与表格记录的扩张次数一致,不一致的大概率是多次扩张的记录。第四步查窗的两端是否都落在记录范围内,超出部分会被静默截断。
四步里第三步最关键,它同时校验表格与注释读得对不对,任何一边出错,事件个数都对不上。
9.5 复现性清单
一篇用到这份库的论文,若想让别人照着重跑,要写清七件事:用了哪些记录名(记录名本身不表意,只写"选取若干条"等于没写)、分段怎么划分(决定正负样本从哪来)、多次扩张怎么处理(时刻字段语义不同)、阳性标签用什么策略(全段、延迟还是门控)、造影剂注射是否剔除(直接影响假阳性率)、滤波与基线怎么设(高分辨率下影响显著)、下载日期是哪天(表格可能修订)。
七项里最容易被忽略的是最后一项。版本号自 2017 年上线以来没有变过,但表格作为独立文件是可以被替换的;写清下载日期,成本极低,收益是别人复现时不会因为读到另一份表格而与你的结论打架。
§10 AI 使用声明
| 项目 | 内容 |
|---|---|
| 写作方式 | 由人工智能辅助撰写,人工校核事实与表述 |
| 事实来源 | 官方项目页、CinC 2017 数据描述论文、Warren 与 Wagner 2014 年回顾、欧洲 PMC 检索结果 |
| 未使用的手段 | 未下载全量数据做分布统计,未做频次、空位率或逐条样本明细分析 |
| 数字口径 | 官方页面与论文给出什么就写什么,不推断不补全 |
| 不确定项处理 | 标注"官方未说明"或"属推断",不写成事实 |
| 换算值 | 体积与时长量级明确标注为按规格推算 |
| 封面图 | 由生成模型按风格提示词产出,不含真实数据 |
| 更新责任 | 若官方页面修订,以官方为准,本页随之更新 |
常见误读(避坑清单)
| 说法 | 实际 | 证据 |
|---|---|---|
| STAFF 是 ST 分析的算法缩写 | 取自研究者 Stafford Warren,官方未给展开式 | 官方标题与 2014 年回顾署名 |
| 这是一份 ST 段数据库 | 建库初衷是 QRS 高频成分,ST 只是副产品 | CinC 2017 论文引言 |
| 缺血是患者自然发作的 | 全部由球囊机械闭塞诱发 | 官方数据描述 |
| 患者数是 228 | 104 是 STAFF III 的纳入数,228 是整个系列 | 官方页面与 2014 年回顾 |
| 每条记录都含一次扩张 | 存在纯基线、纯扩张后与多次扩张的记录 | 官方分段说明与注释修订 |
| 事件时刻可直接当绝对时间 | 第二次及以后的扩张字段含前序各段时长 | 官方注释说明 |
| 所有造影剂注射都被标注 | 官方明说只标注了一部分 | 官方数据描述 |
| 有核素灌注影像可下载 | 只对少数患者采集过,未随库提供 | 官方数据描述 |
| 采样率与常规心电库相同 | 1000 Hz,约为常规库的四倍 | 官方数据描述 |
| 可直接用于人群层面的推断 | 单中心择期手术,无抽样设计 | 纳入排除标准 |
FAQ
问:STAFF 到底指什么?
答:官方页面与文献都只写 STAFF studies,没有给出缩略语展开。这一系列研究由 Stafford Warren 主导设计,Warren 与 Wagner 2014 年的回顾即以 The STAFF studies 为题,因此最稳妥的读法是取自研究者的名,而不是某个技术缩写的首字母组合(§3.2)。
问:为什么患者数有 104 和 228 两个说法?
答:104 是 STAFF III 这一辑的纳入人数,官方页面与 CinC 2017 论文口径一致。228 出自 Warren 与 Wagner 2014 年对整组 STAFF 研究的回顾,指整个系列累计的患者数。引用时写清说的是哪一层即可(§3.4)。
问:它和动态心电里自然发作的缺血有什么不同?
答:最大不同是起点已知。球囊充盈的那一刻就是缺血开始,现场有人标注时间;动态心电记录里的缺血要靠 ST 判据事后回溯,起点只能估。代价是这里的缺血由机械闭塞造成,没有斑块破裂与血栓(§6.1)。
问:能直接训练 ST 段偏离检测器吗?
答:可以,但要用对标注。库里标的是球囊时刻,不是逐拍 ST 真值;把充盈后的整段都当阳性,会把缺血刚起步、形态尚未改变的秒也标成阳性。更稳的做法是自己算 ST 水平曲线,再用球囊时刻做区间约束(§4.6)。
问:多次扩张的记录该怎么处理?
答:先确认它属于官方点名的名单,再按表格里的分段时长对时刻字段做换算。39c 是最典型的一条,表里记两次、实际三次,第三个时刻必须换算后才可用(§4.2 的案例)。
问:核素影像能拿到吗?
答:拿不到。官方说明当年确实做过灌注显像,但只有少数患者有,因此没有随库提供下载。想要影像与心电配对的研究,这份库给不了。
问:基线段一定和扩张段在同一条记录里吗?
答:不一定。官方说基线可以在病房休息室录,也可以在导管室录,或者两处都录;扩张段只能在导管室录。因此存在纯基线记录、纯扩张后记录与连续记录三种形态(§2.4)。
问:许可允许商用吗?
答:允许。ODC-BY 1.0 允许包括商业用途在内的使用与再分发,条件是署名。署名应包含数据集名、版本、DOI 与许可名,并同时引用 CinC 2017 那篇数据描述论文。
问:和库里的 LTSTDB 怎么选?
答:看你的问题里"缺血起点"是不是关键变量。要算检出延迟、要算导联出现顺序,用这一份;要算一天里的缺血总负荷、要看自然发作的来去,用 LTSTDB(§6.1)。
问:记录名里的字母有意义吗?
答:官方没有说明。可以观察到同一编号会带不同字母,例如 39c 与 39d 同时存在,因此字母更像同一位患者操作中的连续记录编号,而不是扩张次数;这一条属于推断,引用时须注明。§4.2 的案例里,39c 含三次扩张而字母只有一个,正好说明字母不表示扩张序号。
术语表
| 术语 | 英文 | 在本库中的含义 |
|---|---|---|
| 球囊冠脉腔内成形术 | PTCA | 用球囊扩张狭窄冠脉的介入操作 |
| 球囊充盈 | balloon inflation | 球囊充气堵住血管、造成短暂断流的动作 |
| 球囊放气 | balloon deflation | 球囊排气、恢复血流的动作 |
| 闭塞 | occlusion | 血管被完全阻断的状态 |
| 扩张次数 | inflation count | 一次操作中球囊充盈的次数,最多五次 |
| 基线心电 | baseline ECG | 术前静息仰卧记录的五分钟心电 |
| 扩张后心电 | post-inflation ECG | 放气后静息记录的五分钟心电 |
| 前降支 | LAD | 左前降支,供血前壁与前间隔 |
| 右冠状动脉 | RCA | 供血下壁与右室 |
| 左回旋支 | LCX | 供血侧壁与后壁 |
| 左主干 | LM | 左冠脉主干,闭塞影响范围大 |
| 高频 QRS | high-frequency QRS | QRS 波群中的高频成分,建库初衷 |
| Mason-Likar 配置 | Mason-Likar | 肢体电极改置于躯干的十二导联接法 |
| 振幅分辨率 | amplitude resolution | 可分辨的最小电压差,本库 0.625 微伏 |
| 造影剂注射 | contrast injection | 造影时注入对比剂,可短暂改变心电形态 |
| 事件注释 | event annotation | 记录时刻的注释文件,后缀 event |
| 分段标识 | segment label | 标记记录属于基线、扩张或扩张后 |
| 缺血预适应 | ischemic preconditioning | 前次短暂缺血使心肌对后续缺血更耐受 |
| 侧支循环 | collateral circulation | 阻塞血管周围的替代供血通路 |
| 核素灌注显像 | perfusion imaging | 用放射性示踪剂显示心肌血流分布 |
| 检出延迟 | detection delay | 从缺血开始到算法报警的时间 |
附录 A:核心数字核对表
| 项 | 值 | 来源 | 来源层级 |
|---|---|---|---|
| 患者数 | 104 | 官方页面与 CinC 2017 | 官方 |
| 冠脉闭塞次数 | 152 | 官方页面与 CinC 2017 | 官方 |
| 前降支闭塞 | 58 次 | 官方数据描述 | 官方 |
| 右冠闭塞 | 59 次 | 官方数据描述 | 官方 |
| 回旋支闭塞 | 32 次 | 官方数据描述 | 官方 |
| 左主干闭塞 | 3 次 | 官方数据描述 | 官方 |
| 既往心肌梗死 | 35 名 | 官方数据描述 | 官方 |
| 导联数 | 12 | 官方数据描述 | 官方 |
| 采样率 | 1000 Hz | 官方数据描述 | 官方 |
| 振幅分辨率 | 0.625 微伏 | 官方数据描述 | 官方 |
| 基线段时长 | 5 分钟 | 官方数据描述 | 官方 |
| 扩张后段时长 | 5 分钟 | 官方数据描述 | 官方 |
| 单次扩张平均时长 | 4 分 23 秒 | 官方数据描述 | 官方 |
| 扩张时长范围 | 1 分 30 秒至 9 分 54 秒 | 官方数据描述 | 官方 |
| 系列累计患者数 | 228 | Warren 与 Wagner 2014 | 论文 |
| DOI | 10.13026/C20P4H | 官方页面 | 官方 |
附录 B:数字的来源分层
| 层级 | 含义 | 本页涉及的数字 |
|---|---|---|
| 官方页面 | PhysioNet 项目页直接给出 | 患者数、闭塞次数、血管分布、采样率、分辨率、版本、DOI、许可 |
| 论文摘要 | CinC 2017 与 2014 年回顾 | 库的定位、228 名系列患者、方法学用途 |
| 官方数据描述 | 采集流程段落 | 段时长、扩张时长范围、充盈延后、排除标准 |
| 推导 | 由官方规格换算 | 单条与整包体积量级、单条时长上界 |
| 工作假设 | 依据文件名提出、官方未确认 | 记录名中字母的含义 |
前三层可直接引用;推导层可复算,写论文时若要引用应自行计算;工作假设必须写明是推断,不能写成官方说明。
附录 C:完整参考文献
| 序号 | 文献 | 用途 |
|---|---|---|
| 1 | Martínez JP, Pahlm O, Ringborn M, Warren S, Laguna P, Sörnmo L. The STAFF III Database: ECGs Recorded During Acutely Induced Myocardial Ischemia. Comput Cardiol 44:266-133, 2017. | 官方指定的数据描述论文 |
| 2 | Warren SG, Wagner GS. The STAFF studies of the first 5 minutes of percutaneous coronary angioplasty balloon occlusion in man. J Electrocardiol 47(4):402-407, 2014. | 系列研究的回顾与 228 名口径 |
| 3 | Laguna P, Sörnmo L. The STAFF III ECG database and its significance in methodological development evaluation. J Electrocardiol 47:408-417, 2014. | 方法学影响的综述 |
| 4 | Pettersson J 等. Spatial, individual and temporal variation of the high frequency QRS amplitudes in the 12 standard electrocardiographic leads. Am Heart J 139(2):352-358, 2000. | 建库初衷对应的首篇研究 |
| 5 | PhysioNet. STAFF III Database v1.0.0. 2017-01-31. DOI 10.13026/C20P4H. | 官方数据页 |
| 6 | Open Data Commons. Attribution License v1.0. | 许可文本 |
附录 D:任务代码
一段把表格、头文件与事件注释合到一张索引表里的脚本。
import re
from pathlib import Path
import pandas as pd
import wfdb
def header_info(path):
h = wfdb.rdheader(str(path.with_suffix('')))
return {'record': path.stem, 'n_sig': h.n_sig, 'fs': h.fs, 'sig_len': h.sig_len}
def events(rec_path):
p = rec_path.with_suffix('.event')
if not p.exists():
return -1, []
ann = wfdb.rdann(str(rec_path.with_suffix('')), 'event')
return len(ann.sample), ann.sample.tolist()
def build(root='staffiii'):
root = Path(root)
rows = []
for hea in sorted(root.glob('*.hea')):
r = header_info(hea)
n_ev, ev = events(hea)
r['n_events'] = n_ev
r['first_event'] = ev[0] if ev else -1
r['minutes'] = round(r['sig_len'] / r['fs'] / 60, 2)
rows.append(r)
return pd.DataFrame(rows)
df = build()
print(df.shape, df['minutes'].min(), df['minutes'].max())
脚本刻意做了两件事。第一,注释文件缺失时返回 -1 而不是抛异常,因为这个库里没有注释文件的记录是常态而非异常。第二,把记录时长也算进索引,因为官方没有公布总时长,任何按小时计的规划都只能从这张表里自己加。
跑完之后,n_events 这一列就是筛查多次扩张记录的第一道筛子:大于一的行,需要回表格核对官方名单,再决定是否做时刻换算。
附录 E:如果只记五件事
一,STAFF 取自研究者 Stafford Warren,不是 ST 类算法缩写,III 是系列第三辑。二,104 名患者、152 次闭塞,十二导联 1000 Hz,为高频 QRS 而建。三,缺血由球囊机械闭塞诱发,起点是物理事件而非判据回溯,这是它不可替代之处。四,事件时刻需换算:第二次及以后的扩张,注释字段含前序各段时长。五,分段信息只在表格里,不做索引就开始切窗,正负样本一定错。
编辑说明
本页按 v4 编辑纪律撰写:只写规模、结构、边界三类数字,不做分布统计;官方存在两个口径处并列呈现,不判对错。体积、时长上界与记录名字母含义均标注为推算或推断。若 PhysioNet 页面修订,以官方为准。
相关数据集导航
以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:
- fantasia — 共享标签:生理信号 / 心电信号 / 心血管疾病 / 时序数据
- bpssrat — 共享标签:生理信号 / 心血管疾病 / 时序数据
- ptb-xl — 共享标签:生理信号 / 心电信号 / 心血管疾病 / 时序数据
- code-15 — 共享标签:生理信号 / 心电信号 / 心血管疾病 / 时序数据
- cinc-2015 — 共享标签:生理信号 / 心电信号 / 心血管疾病 / 时序数据
- ptb-xl-plus — 共享标签:生理信号 / 心电信号 / 心血管疾病 / 时序数据
- bp-graphene-bioimpedance — 共享标签:生理信号 / 心血管疾病 / 时序数据
- wctecgdb — 共享标签:生理信号 / 心电信号 / 心血管疾病
- ahadb — 共享标签:生理信号 / 心电信号 / 心血管疾病
- chfdb — 共享标签:生理信号 / 心电信号 / 心血管疾病
导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

