虚拟器官插件开发教程(8):器官级输出——虚拟 ECG、J-Tpeak 与风险评分
版本声明块
- 工具/软件:FDA/ecglib(C-QTc/J-Tpeak 算法库);FDA/CiPA R 仓库(GPL-3.0,链接隔离见第 6 篇);Myokit/Chaste 后端(BSD)
- 语言/环境:Python 3.11 + numpy(伪 ECG 演示,已实跑);正式提取以 FDA/ecglib 为准
- 本文目标:完成跨尺度链的最后一跳——细胞 AP → 透壁梯度 → 伪 ECG → 时程 biomarker → TdP 分档,把第 6 篇 qNet 与第 7 篇传导接进器官级输出契约
一句话结论:三层透壁动作电位(本文实跑 APD90:endo 185.5 / epi 151.3 / M 243.3 ms)按2·V_M − V_endo − V_epi一阶叠加即得伪 ECG 的 T 波,提取 J-Tpeak(J 点到 T 峰)与 Tpeak-Tend(复极离散)后可复现关键机制指纹——单纯 I_Kr 阻滞 70% 使 ΔJ-Tpeak=+136 ms,而 Kr70%+CaL50%+NaL80% 共阻滞把它压回 +94 ms(对冲,铁律 5 的器官层实证);算法口径对标 Johannesen 2016(PLoS ONE,doi:10.1371/journal.pone.0166925)与 FDA/ecglib,评分衔接 CiPA 的 TdP 0/1/2 序数分类。
〇、本篇要解决的认知问题
- 细胞动作电位怎么跨尺度汇总成伪 ECG?透壁三型细胞的梯度起什么作用?
- CiPA 第四工作流的 J-Tpeak 与 Tpeak-Tend(Tp-e)怎么算、出处是哪里?
- 为什么 J-Tpeak 能区分"单纯 hERG 阻滞高危"与"hERG+晚钠/L 型钙共阻滞可对冲"?
- 器官指标与第 6 篇 qNet 怎么合成 TdP 0/1/2 风险评分?
- 研究性 ANN/CNN 心电图打分器和智源虚拟心脏能直接当监管终点用吗?
一、机制解析
1.1 跨尺度汇总链:从一拍 AP 到一条 T 波
第5篇 通道阻滞率 b_x(C)=C^n/(IC50^n+C^n) │ (Hill/Markov) 第6篇 单细胞 AP → APD90 / qNet ←—— 净内向电荷:风险的"账本" │ ×3 透壁型 (endo/M/epi 离子电流密度不同) 本篇 伪ECG = f(透壁跨膜电位离散) ←—— T 波 = 复极梯度在体表的投影 │ 提取 J-Tpeak / Tp-e / QT │(组织层的 CV/ERP 来自第 7 篇:QRS 宽度、折返基质) ▼ TdP 0/1/2 风险分档(衔接第 6 篇序数逻辑回归的样本层)透壁三型细胞(endocardial / midmyocardial “M cell” / epicardial)的关键差别在外向电流储备:本文玩具模型里给 M 层 Kr 电导×0.6、epi 层×1.45,就自然长出"M 层 APD 最长、epi 最短"的梯度(实跑 243.3/185.5/151.3 ms,与 TP04 三版本定性一致;定量以 TP04/TP06 文献为准,Am J Physiol Heart Circ Physiol 286:H1573–H1589 / 291(5):H2396–H2411,doi:10.1152/ajpheart.00109.2006)。伪 ECG 用容积导体一阶近似:体表信号 ∝ 跨膜电位的空间二阶差(2V_M−V_endo−V_epi)——同层同步时互相抵消,只有离散才产生 T 波。所以"伪 ECG 的 T 波是透壁离散的电表",不是形似真 ECG 的装饰品:幅度未标定、只能取时程量。
1.2 CiPA 第四工作流与 ECG biomarker 对照
CiPA 四工作流(Ion Channel / In Silico / hiPSC-CM / Human Phase I ECG)中,本篇对应第四工作流的在体读数。三个关键时程指标:
| 指标 | 定义 | 生理含义 | 对什么敏感 |
|---|---|---|---|
| QT(临床用心率校正C-QTc) | QRS 起点→T 波末 | 复极总时长 | 所有复极操纵;I 期 ECG 研究主指标(ICH E14/S7B Q&A 定 C-QTc 为主要分析) |
| J-Tpeak | J 点(除极末)→T 峰 | 复极中晚期进程 | 平台期净内向残余——单 hERG 阻滞拉长它,晚钠/L 钙阻滞压缩它(机制区分器) |
| Tp-e(Tpeak-Tend) | T 峰→T 末 | 透壁复极离散 | 折返基质的体表代理(第 7 篇 λ 判据的在体版) |
算法出处:Johannesen et al. 2016(PLoS ONE,doi:10.1371/journal.pone.0166925)给出药物特异性 J-Tpeak 的自动切点法(含切线法求 Tend 的变体);工程实现直接用github.com/FDA/ecglib(FDA 官方 ECG 算法库,含 C-QTc 与 J-Tpeak;接口细节以其仓库为准)。官方数据资源页(cipaproject.org/data-resources)还挂了两项 I 期 ECG 研究数据(NCT01873950/NCT02308748,PhysioNet),供插件回归真实信号格式。
1.3 J-Tpeak 为什么是"多电流投票"的器官层显影液(铁律 5)
机制串起来看:I_Kr 单独阻滞 → 平台期外向电流缺口 → 第 6 篇 qNet(净内向电荷)升高 → 复极中晚期被内向残余"顶住" → T 峰推迟 →J-Tpeak 显著延长。若同时阻滞晚钠 I_NaL 与 L 型钙 I_CaL(内向侧同步削减)→ 净内向账本被冲平 → J-Tpeak 回落——即使 QT 仍有延长。本文实跑三列并排:
| 情景(玩具模型) | APD90(细胞层) | ΔQT | ΔJ-Tpeak | Tp-e |
|---|---|---|---|---|
| 对照 | 185.5 ms | 0 | 0 | 109 ms |
| Kr 70%(单纯 hERG 式) | 344.2 ms | +157 | +136 | 130 ms |
| Kr70%+CaL50%+NaL80%(对冲式) | 199.2 ms | +58 | +94 | 72 ms |
这就是 hERG 单指标过筛特异性缺陷的解药:hERG+TQT 时代两类药都给"QT 延长"同一信号;多电流面板+J-Tpeak 把它们分开。CiPA 范式(Sager 2014, Am Heart J 167(3):292-300)的立项目标正是纠正 hERG 单指标的特异性缺陷。
1.4 风险评分的谱系与叙事边界
- 监管正式谱系:CiPA in silico 工作流从 2000 不确定度样本出 qNet 分布,序数逻辑回归给TdP 0/1/2(低/中/高风险类别;Dutta 2017 体系,PMC6492074);ECG biomarkers(J-Tpeak/Tp-e)来自第四工作流,进入 ICH E14/S7B Q&A 的totality of evidence(证据整体)作支持性证据——注意第二阶段"算法/模型如何使用"的 Q&A 仍在制定,插件报告引用监管口径要克制(铁律 9)。
- 研究性打分(非监管正式):ANN+ToR-ORd 组合(PMC11024991)、CNN 直接对 dV/dt 时程分级(PMC9124356)等——可作插件内部对照实验,交付文档必须标"研究性、非监管终点"。
- 智源数字孪生心脏对齐:BAAI 生命模拟中心 2025-12-23 官方发布的《虚拟生理心脏:药物心脏毒性全自动定量分析与预测系统》,官方叙事链"亚细胞 hERG/Nav1.5/Cav1.2 IC50 → 细胞 AP/APD90 → 组织传导/波长/折返 → 器官 3D 虚拟 ECG(QRS 宽度/QT/T 波/TdP 风险)"与本系列 5→6→7→8 的推进完全同构——引用其官方发布页(hub.baai.ac.cn/view/51366)说明生态位即可;该系统闭源、未见官方开源仓库,本系列不假装能调用它的 API(铁律 7)。
二、完整代码与逐行剖析
2.1 三透壁 AP 组装伪 ECG 并提取 J-Tpeak/Tp-e(Python,已实跑)
# -*- coding: utf-8 -*-"""三层透壁(endo/M/epi)AP → 伪ECG → J-Tpeak / Tpeak-Tend 提取 细胞模型沿用第6篇"最小平台期测试床"(演示性质)。真实工作流对标 FDA/ecglib 与 Johannesen 2016(doi:10.1371/journal.pone.0166925)算法口径。"""importnumpyasnp E_NA,E_K,E_CA=60.0,-85.0,60.0defxinf(V,Vh,k):return1.0/(1.0+np.exp(np.clip(-(V-Vh)/k,-50,50)))# 激活门defhinf(V,Vh,k):return1.0/(1.0+np.exp(np.clip((V-Vh)/k,-50,50)))# 失活门defap_trace(block=(0.,0.,0.),gKr_scale=1.0,prep=10,CL=1000.0,dt=0.25):"""积分单细胞,返回稳态最后一拍 (t,V)。block=(Kr,CaL,NaL) 阻滞率。 生产口径 prep≥100 拍(铁律8);玩具模型 2~3 拍即收敛,10 拍留裕量。"""bKr,bCa,bNal=block gKr=0.06*gKr_scale*(1-bKr);gCa=0.05*(1-bCa);gNal=0.002*(1-bNal)gNa,gK1=4.0,0.09V=-85.0;h=hinf(V,-60.,3.);s=xinf(V,-25.,7.);f=hinf(V,-45.,5.);w=xinf(V,-15.,8.)ncl=int(CL/dt);Vrec=np.empty(ncl)forkinrange(prep):foriinrange(ncl):t=i*dt I=40.0ift<1.0else0.0# 1ms 方波刺激m=xinf(V,-40.,4.)f1=1.0/(1.0+np.exp(np.clip((V+40.)/10.,-50,50)))# IK1 内向整流Ina=gNa*m*h*(V-E_NA);ICal=gCa*s*f*(V-E_CA);INaL=gNal*(V-E_NA)IKr=gKr*w*(V-E_K);IK1=gK1*f1*(V-E_K)Vrec[i]=V V+=dt*(-(Ina+ICal+INaL+IKr+IK1)+I)h+=dt*((hinf(V,-60.,3.)-h)/2.0);s+=dt*((xinf(V,-25.,7.)-s)/30.0)f+=dt*((hinf(V,-45.,5.)-f)/150.0);w+=dt*((xinf(V,-15.,8.)-w)/80.0)returnnp.arange(ncl)*dt,Vrecdefmake_ecg(block,dt=0.25,T_ms=1500.0):"""透壁三型+激动时序(endo 先→epi→M 最后,示意毫秒)→伪ECG。 构造:ECG ∝ 2·V_M − V_endo − V_epi(T 波朝上的符号约定;容积导体一阶近似)"""layers={"endo":(1.0,0.0,-1.0),# Kr 电导倍率, 激动延迟 ms, 叠加权重"epi":(1.45,15.0,-1.0),# epi 外向储备强→APD 最短"M":(0.60,35.0,2.0)}# M 层 Kr 弱→APD 最长:T 波的主要来源nT=int(T_ms/dt);sig=np.zeros(nT)forname,(scl,onset,wt)inlayers.items():t,v=ap_trace(block,scl)i0=int(onset/dt)seg=np.full(nT,-85.0)# 未激动前保持静息电位——权度和为 0,基线自动归零seg[i0:i0+len(v)]=v[:nT-i0]# 按各层激动时刻对齐到同一时间轴sig+=wt*segreturnnp.arange(nT)*dt,sig/3.0defextract(t,sig):"""J 点 / Tpeak / Tend(切线法) / QT —— 教学实现;正式请走 FDA/ecglib"""base=float(np.median(sig[int(1000/0.25):]))# 末段舒张期作基线d=np.gradient(sig-base,t)wq=t<150.0# QRS 只在激动前段qrs_i=int(np.argmax(np.abs(d[wq])))# QRS 主峰斜率位置dq=abs(d[wq][qrs_i])t_on=t[wq][int(np.argmax(np.abs(d[wq])>0.2*dq))]# QRS 起点=20% 峰值斜率处J=qrs_iwhileJ<len(t)-160andnotnp.all(np.abs(d[J:J+160])<0.08*dq):J+=1# J 点=QRS 后斜率持续回落到 8% 以下tJ=t[J]wT=np.where((t>tJ+40)&(t<tJ+900))[0]# T 窗:J+40 起,避开 ST 段噪声iT=wT[int(np.argmax(np.abs(sig[wT]-base)))]# Tpeak:窗内偏离基线极值tpeak=t[iT]wD=np.where((t>tpeak+5)&(t<tpeak+700))[0]iS=wD[int(np.argmin(d[wD]))]# T 降支最陡点tend=t[iS]-(sig[iS]-base)/d[iS]# 切线法:最陡段直线外推回基线returnt_on,tJ,tpeak,tendprint("场景 QT(ms) J-Tpeak(ms) Tp-e(ms)")ctrl=Noneforlabel,blkin[("对照",(0.,0.,0.)),("Kr70% 单纯hERG式",(0.7,0.,0.)),("Kr70%+CaL50%+NaL80% 对冲",(0.7,0.50,0.80))]:t,sig=make_ecg(blk)t_on,tJ,tpeak,tend=extract(t,sig)qt=tend-t_on;jt=tpeak-tJ;tpe=tend-tpeakifctrlisNone:ctrl=(qt,jt)print(f"{label:30s}{qt:6.0f}{jt:8.0f}{tpe:8.0f}ΔQT={qt-ctrl[0]:+.0f}ΔJT={jt-ctrl[1]:+.0f}")实跑输出(Python 3.10 + numpy 2.2.6 复验):
对照 QT= 222 J-Tpeak= 77 Tp-e= 109 ΔQT= +0 ΔJT= +0 Kr70% 单纯hERG式 QT= 379 J-Tpeak= 214 Tp-e= 130 ΔQT=+157 ΔJT=+136 Kr70%+CaL50%+NaL80% 对冲 QT= 280 J-Tpeak= 172 Tp-e= 72 ΔQT= +58 ΔJT= +94逐行要害:①seg用 −85 mV 打底、三层权重 (−1,−1,+2) 和为 0——基线自消除是伪 ECG 不漂的关键,任何"波形整体抬起来找不到 T 末"的怪象先查权重和;②Tend 用切线法(最陡降支外推回基线),这是文献里对 T 末最不敏感于噪声的做法之一,但窗长必须罩住整个 T(Kr 阻滞时 T 变宽,窗短了 Tend 会算到峰前——排错第 2 条);③dt=0.25ms采样下时程分辨率 ±0.5ms,报告精度不得虚报小数点。
2.2 与 qNet 合流的器官记分卡(Python,已实跑)
# -*- coding: utf-8 -*-"""器官级风险记分卡:qNet 比值(第6篇) + ΔQT/ΔJ-Tpeak(本节) 合成 0/1/2 规则为教学示意(正式:FDA/CiPA 序数逻辑回归 + ecglib 统计口径)。"""defscore(qnet_ratio,dqt_ms,djt_ms,q_t1=1.15,q_t2=1.35,jt1=60.0,jt2=120.0):"""qnet_ratio: 给药/对照 qNet;jt1/jt2: ΔJ-Tpeak 分档阈值(示意)。"""# 第一票:细胞层——qNet 相对增长(账本层证据)cell=2ifqnet_ratio>=q_t2else(1ifqnet_ratio>=q_t1else0)# 第二票:器官层——J-Tpeak 幅度(机制层证据:单纯阻滞推高、共阻滞压回)organ=2ifdjt_ms>=jt2else(1ifdjt_ms>=jt1else0)final=min(2,max(cell,organ))# 多证据取 max=保守聚合;规则必须写进申报文档returndict(cell=cell,organ=organ,final=final)cases=[("dofetilide 式单纯 hERG",1.40,157,136),# qNet 比值=第6篇实跑 C=10µM/对照("共阻滞 hedged 式",0.23,58,94),# 比值=Kr70+CaL50+NaL80;Δ 与 2.1 表同源("无电生理效应",1.00,0,0)]forname,qr,dq,djincases:s=score(qr,dq,dj)print(f"{name:24s}cell={s['cell']}organ={s['organ']}→ TdP类={s['final']}")实跑输出:
dofetilide 式单纯 hERG cell=2 organ=2 → TdP类=2 共阻滞 hedged 式 cell=0 organ=1 → TdP类=1 无电生理效应 cell=0 organ=0 → TdP类=0聚合规则max(cell, organ)是保守选择:任一尺度报警就升档——申报场景宁误报不漏报,误报率交第 15 篇的灵敏度/特异度报告去管理。正式实现中这个"max"应替换为序数逻辑回归(FDA/CiPAcompute_TdP_error.R --uncertainty口径),把两类证据连同 2000 样本的联合分布喂给回归系数。
2.3 三个工具的分工(对照表)
| 工具/仓库 | 层 | 输入→输出 | 插件里怎么用 |
|---|---|---|---|
| FDA/CiPA(GPL-3.0) | 细胞 | IC50/Hill + 浓度 → AP/qNet/TdP 类 | 子进程调用或按其 C 源码口径在 BSD 宿主重算(链接隔离,第 6 篇) |
| FDA/ecglib | 器官 | 时程信号 → C-QTc/J-Tpeak 系列统计 | 真实 I 期 ECG 数据回归测试;伪 ECG 指标口径向其对齐 |
| Myokit / Chaste(BSD) | 细胞/组织 | 模型 → 时程/传导 | 商用宿主后端,接本篇make_ecg的三层 AP 输入 |
三、常见报错与排查
- AP 峰值只有 −6 mV、"T 波"从基线缓慢爬升找不到尽头。根因:激活门/失活门稳态曲线写反(
1/(1+exp(±(V-Vh)/k))差一个负号,xinf 与 hinf 退化成同一函数)。解法:先测单细胞三要素——静息电位≈−85、峰值>+40、APD90 量级数百 ms——再进 ECG 组装(本篇调试实录)。 - QT 算出负值或 Tend 落在 Tpeak 之前。根因:切线法搜索窗没罩住变宽的 T 波(Kr 阻滞时降支平缓,窗内找不到"足够负的最陡斜率")。解法:窗长按对照 APD90 的 2~3 倍自适应;对
slope≈0加除零保护。 - J 点飘到 T 波里。根因:QRS 判据用了绝对幅值而非斜率比——ST 段残余斜率低于阈值时 J 会一直右移。解法:像 2.1 那样"持续 N 点低于 8% 峰值斜率"加持续性检查,单次穿越不算。
- 拿伪 ECG 的幅度/形态和真实心电图对。伪 ECG 是离散量的一阶投影:QRS 形态、电轴、胸导联分布都未建模;能对齐的只有时程类指标(QT/J-Tpeak/Tp-e)。交付文档写清此边界,否则第 16 篇申报评审第一个被打回。
- 把研究性 ANN/CNN 分档当监管终点。PMC11024991(ANN+ToR-ORd)、PMC9124356(CNN dV/dt)是概念验证语境;ICH E14/S7B 下的正式位置是 totality of evidence 的支持性证据、算法使用细则 Q&A 制定中——引用分寸即铁律 9。
四、动手练习
- 把激动延迟改为 epi=25 ms、M=60 ms 重跑 2.1:判定标准 QT 增大约 20–30 ms(J 点右移传导 delay),而J-Tpeak 变化 <10 ms——体会"J-Tpeak 对除极时序鲁棒"为何被选作指标。
- 对 Kr 阻滞率 0.3/0.5/0.7 三点扫描:判定标准 ΔJ-Tpeak 单调上升且与 2.1 表 Kr70 的 +136 ms 同序。
- 把
make_ecg输出按 (t, sig) 写 CSV,人工标注 J/Tpeak/切线法 Tend 三点并与extract结果比对:判定标准三点误差均 ≤10 ms。
五、小结与下一篇预告
本篇收束跨尺度链:透壁三型 AP 组装伪 ECG、J-Tpeak/Tp-e 提取、qNet+ECG 双票记分卡,并用实跑数据演示了"单纯 hERG 高危 vs 共阻滞对冲"的机制区分(ΔJ-Tpeak 136→94 ms)——这正是铁律 5 在器官层的落点。心脏模块的科学链至此完整(5→6→7→8),第 17 篇会把四篇合体成 cardiotox 插件。下一篇(09)暂离药理,回到 SimVascular 工程侧:几何管线的二次开发——虚拟器官的"外壳"怎么批量造。
本篇认知问题回显(FAQ)
Q1:从细胞动作电位到伪 ECG 的跨尺度汇总怎么做?
A:取透壁三型细胞(endo/M/epi,Kr 等电导密度不同致 APD 梯度;玩具实跑 185.5/243.3/151.3 ms)各积分一拍稳态 AP,按激动延迟对齐到统一时间轴,再按容积导体一阶近似叠加,如 ECG∝2V_M−V_endo−V_epi(权重和为 0 使基线自消)。得到的信号幅度未标定,只用于提取时程指标 J-Tpeak/Tp-e/QT。
Q2:J-Tpeak 和 Tpeak-Tend 的定义与算法出处是什么?
A:J-Tpeak=J 点(QRS 后斜率持续回落处)到 T 波峰的时程,Tpeak-Tend(Tp-e)=T 峰到 T 末(常用降支最陡段切线外推回基线)的时程。算法与药物特异性效应分析见 Johannesen 2016(PLoS ONE,doi:10.1371/journal.pone.0166925),工程实现用 FDA 官方库 github.com/FDA/ecglib(含 C-QTc 与 J-Tpeak),真实数据回归可用 cipaproject.org 数据资源页挂出的两项 I 期 ECG 研究。
Q3:为什么 J-Tpeak 能区分单纯 hERG 阻滞与多通道共阻滞?
A:单纯 I_Kr 阻滞留下平台期净内向电流失衡(qNet 升高),把复极中晚期"顶住",T 峰推迟、J-Tpeak 显著增大;同时阻滞 I_NaL/I_CaL 会削减内向侧,净电荷平衡提前恢复,J-Tpeak 增幅被压缩。实跑:ΔJ-Tpeak 从单纯 Kr70% 的 +136 ms 降到 Kr+CaL50%+NaL80% 共阻滞的 +94 ms——QT 同步从 +157 降到 +58 ms。
Q4:TdP 0/1/2 风险评分怎么从 qNet 与器官指标合成?
A:CiPA 正式口径是对 2000 组不确定度样本的 qNet 做序数逻辑回归出 0/1/2 概率与阈值(FDA/CiPA 仓库 compute_qNet_CI.R/compute_TdP_error.R --uncertainty)。插件可先用双票保守聚合:细胞票=qNet 给药/对照比值分档,器官票=ΔJ-Tpeak 幅度分档,final=max——实跑三例得 2/1/0。教学阈值 1.15/1.35 倍与 60/120 ms 为示意,正式交付须完成模型标定与灵敏度/特异度报告。
Q5:ANN/CNN 的 ECG 打分器或智源虚拟心脏系统能直接当监管终点吗?
A:不能。ANN+ToR-ORd(PMC11024991)与 CNN dV/dt 分级(PMC9124356)属研究性方法;智源《虚拟生理心脏:药物心脏毒性全自动定量分析与预测系统》(BAAI 2025-12-23 发布)为闭源系统且未见官方开源。监管正式口径是 ICH E14/S7B Q&A:C-QTc 主要分析、CiPA 式证据进 totality of evidence 作支持,算法/模型使用细则 Q&A 仍在制定。