ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

生物大分子批量仿真开发教程(18):实战二——双抗可开发性与界面筛选流水线

生物大分子批量仿真开发教程(18):实战二——双抗可开发性与界面筛选流水线 生物大分子批量仿真开发教程18实战二——双抗可开发性与界面筛选流水线版本声明块工具/软件Schrödinger Release 2025-4BioLuminate/PIPER、MOE 2024.06Pro:Pro Dock 自本版本起自动选抗体为配体、NetMHCIIpan-4.0、TepiTool语言/环境Python 3.10 pandas PyYAML作业提交复用第 16 篇antibody_pipeline骨架本文目标把第 13/14/15 篇的双抗与可开发性组件装配成一条 YAML 配置驱动、可换后端、可审计的界面筛选流水线。一句话结论双抗筛选比单抗多出界面这一维——流水线必须按格式选择Knobs-into-holesKiH/CrossMab/臂交换→ CH3 突变枚举 → 复合物组装建模 → PIPER 或 Pro:Pro Dock 对接与重排 → 聚集倾向与免疫原性NetMHCIIpan-4.0/TepiTool三域联合排序推进用一份带 SHA-256 哈希的 YAML 固定版本、并行、阈值与权重任何一域单指标都无权淘汰候选。〇、本篇要解决的认知问题双特异性抗体bispecific antibody双抗的 KiH、CrossMab、DuoBody 格式差异在计算流水线里如何选、选了影响什么CH3 异源二聚化界面的突变枚举怎么做组合爆炸怎么剪枝双抗复合物建模与对接复用前面哪几篇的哪些组件界面分数、聚集倾向、免疫原性三域指标如何合成一个可辩护的统一排序为什么这条流水线要用 YAML 配置驱动配置文件里必须有什么一、机制解析1.1 双抗的三张错配税单单抗流水线第 17 篇默认一条重链一条轻链自配自己双抗把这个假设打碎产生三张必须建模的税单税单机制计算后果结构学解法文献锚点重链-重链错配两条不同特异性重链在 CH3 界面随机配对异源二聚体比例低界面打分对象不明KiHKnobs-into-holes 大中小互补Ridgway 1996CrossMab 亦含 CH3 改造轻链错配两条不同轻链随机搭上两臂出现四种组合只一种是要的CrossMab 结构域交换、DuoBody 臂交换Labrijn 2013臂-臂交互两抗原结合域在同一分子内互相干扰表位可达性、聚集热点都变了连接区柔性设计仿真里做界面接触普查格式选择不是生物学口味问题而是流水线分支选 KiH-IgG1 就枚举 CH3 突变、装配异源二聚体 Fc选 CrossMab 还要对轻链-重链配对做约束编码选 DuoBody 类臂交换则重点建 Fab-arm 交换产物。第 15 篇已给单格式的实现本篇把它们变成配置里的可选项。1.2 流水线 DAG 与组件回收YAML 配置(本篇) ─哈希→ 每一步结果行 │ L0 格式决策 ──► L1 CH3 突变枚举(第 15 篇, 剪枝) │ 臂对序列(第 04 篇 ANARCI 编号) ──► L2 复合物组装建模(第 07 篇建模 第 05 篇准备: 二硫/糖基化, 铁律 9) │ L3 对接与重排: maestro→PIPER(BioLuminate, 第 09 篇) / moe→Pro:Pro Dock(第 09 篇) │ └─ 重排: MM-GBSA Residue Scanning(第 15 篇) / Glide 语境见第 10 篇 L4 三域打分: 界面分数 ‖ 聚集/表面(第 13/14 篇) ‖ 免疫原性(NetMHCIIpan-4.0 百分位 TepiTool consensus) │ L5 联合排序: 分位投票 帕累托(Pareto)前沿 → top N 进 MD(第 11 篇) 复核 → 候选清单(第 08 篇入库)两条版本红线MOE 侧 Pro:Pro Dock 自 2024.06 起对含注释的抗体-抗原复合物自动选抗体为配体、抗原为受体且$CDR_H3自动注释——用旧版脚本喂 2024.06 或反过来接口假设就对不上铁律 2Schrödinger 侧 2026-3 发行说明提示 PIPER 新增输出文件解析代码按安装版内 Help 的文件说明写死版本。1.3 联合排序三域各有各的一票否决免疫原性用每个候选在 HLA consensus 面板上预测肽的百分位排名分布如预测到的强结合肽个数/千残基来自 NetMHCIIpan-4.0 与 TepiTool 流水线聚集与表面域沿用第 13/14 篇矩阵。合成规则先各自域内取分位再做帕累托前沿任一候选在三个域上都不被他人全面压制才入前沿前沿内再按可调权重排序——同时任何一域触碰最差 1% 否决线直接出局。这正是铁律 6 的多域版界面亲和力最好但聚集与免疫原性双差的候选恰恰是临床阶段最贵的错误。1.4 为什么必须配置驱动同一份业务代码昨天跑单抗、今天跑双抗、明天换后端如果格式、枚举上限、对接引擎、权重散落在脚本常量里配置漂移会在结果表里留下无法归因的差异。所以YAML 承载全部决策参数版本锁、并行度、阈值、权重、预算文件本身算哈希写进每一行结果铁律 5 的审计版换后端只改docking.backend一行。二、完整代码与逐行剖析代码一bispecific.yaml —— 整条流水线的唯一决策源# bispecific.yaml —— 本文件的 SHA-256 记入结果表每一行配置漂移即无所遁形project:bsab-screen-2026-09versions:# 铁律 2声明并锁定不是注释而是运行前断言schrodinger:2025-4moe:2024.06# Pro:Pro Dock 抗体自动选择自本版本起可用pipeline_pkg:antibody_pipeline0.4.0pairing:arms_csv:data/arms.csv# 列: pair_id,hc_vh,lc_vl,hc2_vh,lc2_vl编号Kabat第 04 篇formats:-name:KiH-IgG1# 重链异构二聚knobs-into-holes 界面ch3_strategy:knobs-into-holeslight_chain:common-vl# 共用轻链免掉轻链错配税单-name:CrossMab-KiHch3_strategy:knobs-into-holeslight_chain:domain-swap# CrossMab 结构域交换防轻链错配enumeration:mutation_table:data/ch3_mutations.csv# 列: chain,resnum,wt,mut——位点与残基号来自第 15 篇设计表max_combo_size:3# 单/双/三突变组合指数爆炸的第一道闸max_combos:200# 枚举总预算次道闸边枚举边截断docking:backend:maestro# maestro→PIPER(BioLuminate); moe→Pro:Pro Dock第 09 篇两实现rescoring:mm-gbsa-residue-scan# MM-GBSA Residue Scanning 重排第 15 篇surface:# 第 13/14 篇指标族metrics:[camsol,a3d,fvcsp_abs,hydro_patch]veto_quantile:0.99# 任何域触最差 1% 出局铁律 6immunogenicity:# 第 14 篇tools:[netmhciipan-4.0,tepi-tool-consensus]# 服务器现状实测 2026-09-04 在线铁律 8strong_bind_per_1k:3# 每千残基强结合肽数阈值超线进否决名单ranking:method:pareto-then-vote# 先帕累托前沿前沿内加权分位权重须与实验组共识weights:{interface:0.4,aggregation:0.35,immunogenicity:0.25}top_n_md:24# 复核名单容量预算在 budget 里封顶budget:{gpu_hours:500,cpus:64}# 第 19 篇调度器据此限流注意versions是数据不是文档驱动脚本启动时逐一断言实际环境对不上就拒绝起跑。rescoring键写的是第 15 篇封装的注册名具体面板参数以安装版内 Help 为准。代码二bsab_pipeline.py —— 配置驱动枚举→组装→对接→重排# bsab_pipeline.py —— 读 YAML 驱动双抗筛选主体对接/表面对外只经 capability 派活importhashlib,itertools,jsonfrompathlibimportPathimportpandasaspd,yamlfromantibody_pipeline.backendsimportget_backend# 第 16 篇唯一容身商业细节的层defload_cfg(pbispecific.yaml):rawPath(p).read_bytes()returnyaml.safe_load(raw.decode(utf-8)),hashlib.sha256(raw).hexdigest()[:12]# 返回配置哈希后面写进每一行结果供第 20 篇平台做审计链defassert_versions(cfg):env{schrodinger:Path(SCHRODINGER_VER).read_text().strip()ifPath(SCHRODINGER_VER).exists()elseabsent,moe:absent}# 实战中向平台查询第 01 篇体检脚本fork,wantincfg[versions].items():# 铁律 2版本不齐不开工ifkinenvandenv[k]!absentandwantnotinenv[k]:raiseRuntimeError(f版本失配{k}: 需要{want}实际{env[k]})defenumerate_ch3(muts_csv,max_size,max_combos):mpd.read_csv(muts_csv)# 残基号沿用第 04 篇固定的 Kabat 编号铁律 1per_site{site:sorted(g[mut])forsite,ginm.groupby([chain,resnum])}# 每位点的候选突变列表combos[]forkinrange(1,max_size1):# 1..3 点组合规模 Π(1候选数) 的截断forsite_pickinitertools.combinations(sorted(per_site),k):formutsinitertools.product(*(per_site[s]forsinsite_pick)):combos.append({f{c}{r}{w}for(c,r),winzip(site_pick,muts)})iflen(combos)max_combos:# 边枚举边截断绝不让组合集先爆炸再剪returncombosreturncombosdefjid_of(pair_id,combo,backend,cfg_sha):hhashlib.sha256()h.update(json.dumps(sorted(combo)).encode())# 参与哈希的必须是影响结果的一切h.update(f{pair_id}|{backend}|{cfg_sha}.encode())# 换后端/改配置 → 新哈希 → 不覆盖旧结果returnh.hexdigest()[:12]defrun():cfg,cshaload_cfg()assert_versions(cfg)beget_backend(cfg[docking][backend])# maestro / moe 在这里才分流第 16 篇ifnotbe.supports(dock):raiseValueError(f后端{be.name}不具备 dock 能力)# capability 护栏早爆ledgerPath(ledger.tsv).open(a,encodingutf-8)# 追加式台账失败也落库铁律 10forfmtincfg[formats]:for_,pinpd.read_csv(cfg[pairing][arms_csv]).iterrows():forcomboinenumerate_ch3(cfg[enumeration][mutation_table],cfg[enumeration][max_combo_size],cfg[enumeration][max_combos]):jidjid_of(f{fmt[name]}|{p[pair_id]},combo,be.name,csha)workPath(runs/bsab)/jidif(work/.done).exists():continue# 幂等续跑第 17 篇漏斗范式work.mkdir(parentsTrue,exist_okTrue)try:complex_maebuild_complex(p,combo,fmt,work)# 复用第 15 篇装配第 05 篇准备dock_and_rescore(complex_mae,work,be,cfg)# 复用第 09 篇批量对接封装(work/.done).write_text(jid)ledger.write(f{jid}\t{p[pair_id]}\t{fmt[name]}\tok\t\t{csha}\n)exceptExceptionase:# 单候选失败绝不断整批分类记进台账ledger.write(f{jid}\t{p[pair_id]}\t{fmt[name]}\tfailed\tf{str(e)[:160]}\t{csha}\n)ledger.close()if__name____main__:run()build_complex与dock_and_rescore是包内函数前者按格式的light_chain策略装配两对轻重链并交第 05 篇准备流程补二硫键与 Fc Asn297 糖型铁律 9后者把复合物交给第 09 篇的 PIPER/Pro:Pro Dock 批量封装再挂上重排。jid_of把后端名也哈希进去意味着换后端重跑不会覆盖旧后端结果两者可在结果库里并排对比——这正是练习 3 的伏笔。代码三joint_rank.py —— 三域联合排序帕累托前沿 域内投票# joint_rank.py —— 界面分数 × 聚集 × 免疫原性三域合成一个可辩护的排名importpandasaspd,yaml cfgyaml.safe_load(open(bispecific.yaml,encodingutf-8))dfpd.read_csv(ledger.tsv,sep\t)dfdf[df.statusok].set_index(jid)# 失败行不参与评选但报告页仍要列出aggpd.read_csv(surface_metrics_bsab.csv).set_index(jid)# 第 13/14 篇导出immpd.read_csv(immuno_metrics.csv).set_index(jid)# 第 14 篇NetMHCIIpan-4.0/TepiToolddf.join(agg[[risk_agg]]).join(imm[[strong_bind_per_1k,immuno_pct]])dompd.DataFrame({interface:1-d[docking_score].rank(pctTrue),# 对接/重排分越高→风险越低aggregation:d[risk_agg].rank(pctTrue),# 已是越大越差的方向immunogenicity:d[immuno_pct].rank(pctTrue),# 强结合肽百分位排名})veto(domcfg[surface][veto_quantile]).any(axis1)# 三域同一条最差 1% 否决线strongd[strong_bind_per_1k]cfg[immunogenicity][strong_bind_per_1k]elig~(veto|strong)# 免疫原性另有绝对阈值线front[]# 帕累托前沿不被任何人在三域全面压制foriindom[elig].index:rdom.loc[i]dominated((dom.loc[elig][[interface,aggregation,immunogenicity]].le(r)dom.loc[elig].ne(r).any(axis1)).any(axis1))ifnotdominated:front.append(i)wpd.Series(cfg[ranking][weights])# 权重是团队共识不是脚本私货ranked(dom.loc[front]*w).sum(axis1).sort_values()# 前沿内加权分位→最终次序outpd.DataFrame({jid:ranked.index,final_rank:range(1,len(ranked)1),top_md:ranked.index[:cfg[ranking][top_n_md]]})out.to_csv(candidates_bsab.csv,indexFalse)print(feligible{elig.sum()}pareto{len(front)}- candidates_bsab.csv)先帕累托后加权的顺序不能反帕累托先把任何一域明显更差的候选剔出竞争权重只在无支配关系的头部小集合里起作用把权重拍脑袋的伤害面积压到最小。免疫原性域额外加了一条绝对阈值强结合肽数/千残基因为它的分位排名在整体都偏低的优质池里区分度不足——阈值数值写进 YAMLstrong_bind_per_1k: 3修改即换哈希历史结果自动隔离。在线工具提交结果一律先缓存落盘再进表服务器可用性按实测日期说话铁律 8。三、常见报错与排查对接打分对格式无感。现象KiH 与 CrossMab 两分支分数几乎同分布。根因复合物装配时把异源二聚体当对称同源建模CH3 界面根本没有突变进去。解法L2 之后加序列层断言——突变集合与产物 FASTA 逐位点核对不符者落库fail_reasonassembly。Pro:Pro Dock 不再自动选抗体为配体。根因MOE ≥2024.06 的自动行为前提是复合物含抗体注释$CDR_H3未注释第 09 篇或用了 2024.06 之前的脚本假设。解法补注释步骤并把 MOE 版本写入配置断言。解析 PIPER 输出偶发 KeyError。根因Schrödinger Release 2026-3 起 PIPER 有新增输出文件解析器按旧版单文件写死。解法解析函数按versions.schrodinger分支缺字段落库而不是崩溃铁律 10。免疫原性批量提交半途失联。现象外呼 NetMHCIIpan-4.0/TepiTool 的后半批超时。根因在线服务限速且服务器状态不可假设长期可用铁律 8本文实测 2026-09-04。解法提交即缓存、断点续提交、必要时降级为仅序列 motif 过滤 标记未评。同一候选在不同运行里名次跳动。根因配置常量散落脚本、或权重在代码里被顺手改过。解法全部参数收回 YAML运行时比对cfg_sha不一致的批次不得进同一张排名表。四、动手练习枚举预算把max_combos从 200 降到 50、max_combo_size保持 3。判定标准台账行数恰好 ≤ 50×臂对数×格式数且枚举在位点组合展开阶段即停止打点计数验证不出现 50 倍内存峰值。后端等价性同一份arms.csv、backend分别设 maestro 与 moe 各跑一遍。判定标准两次jid集合零交集后端名参与哈希、结果库中可按pair_id并排比较两域界面分数Spearman 相关 0.6 为合理量级。否决线守恒构造一条聚集域触 0.99 否决线但界面分数全场第一的假数据。判定标准不出现在candidates_bsab.csv但出现在报告页否决名单表中且注明触线域。五、小结与下一篇预告本篇把双抗的三张错配税单翻译成流水线分支用 YAML 单源配置 配置哈希实现可换后端、可审计、可续跑并以帕累托前沿 → 前沿内加权的三域联合排序守住铁律 6。组件回收清单编号第 04 篇、准备第 05 篇、建模第 07 篇、对接第 09 篇、重排第 10/15 篇、表面与聚集第 13/14 篇、封装第 16 篇、漏斗第 17 篇。两篇实战跑下来瓶颈已经清晰暴露在地基上调度、容错与吞吐。下一篇专讲性能、容错与规模化——作业阵列与并行进程怎么选、失败怎么分类重试、万级变体的机器时怎么估。本篇认知问题回显FAQQ1双抗格式 KiH、CrossMab、DuoBody 在筛选流水线里怎么选A把格式写进 YAML 的 formats 段并映射到装配策略KiH 走 knobs-into-holes 的 CH3 突变枚举CrossMab 追加轻链结构域交换约束臂交换格式重点建交换产物格式决定枚举范围、复合物装配与界面评估对象属流水线分支而非事后过滤。Q2双抗 CH3 界面突变怎么枚举与剪枝A以链/残基号/野生型/突变型四列 CSV 输入按位点分组做 13 点组合枚举用 max_combo_size 和 max_combos 两道闸边枚举边截断并排除 CDR 区与破坏互补电荷对的组合残基号沿用 ANARCI 固定的 Kabat 编号。Q3双抗复合物建模与对接依赖哪些前文组件A建模复用第 07 篇抗体同源建模与第 05 篇结构准备二硫键与 Fc Asn297 糖基化必做对接复用第 09 篇的两条批量路线——Schrödinger BioLuminate 的 PIPER 或 MOE 2024.06 的 Pro:Pro Dock其后重排用 MM-GBSA Residue Scanning。Q4聚集倾向与免疫原性如何与界面分数合成统一排序A三域各自转分位风险秩任何域触最差 1% 否决线出局免疫原性另设每千残基强结合肽数绝对阈值存活者先取三域帕累托前沿前沿内再按 YAML 声明的权重如 0.4/0.35/0.25加权排序。Q5双抗筛选流水线为什么用 YAML 配置驱动A格式、枚举上限、对接后端、指标阈值、权重、预算全部外置于一份 YAML 并计算其 SHA-256 记入每行结果换后端只改一行、配置漂移即被哈希揪出满足版本锁定铁律 2与幂等审计铁律 5。
返回列表