2. 蛋白结构预测输出解析
拿到一次结构预测的结果,真正决定后续验证质量的,不是模型本身,而是我们能否把输出文件里的字段读对、读全、读准。AlphaFold2、RoseTTAFold、ESMFold 三类工具的输出格式差异很大:AlphaFold2 以 ranked_*.pdb、model_*.pdb、*_scores.json、pae_*.json 和 plddt_*.json 为主;RoseTTAFold 常给出 model_*.pdb 与 *.npz 置信度数组;ESMFold 则通过 API 或本地脚本返回 PDB 与 pLDDT 数组,通常不提供 PAE。解析工作的核心,是把“坐标”和“置信度”两类信息分别落到正确的字段上,并理解每个字段的工程含义。
一、坐标字段:PDB 与 mmCIF 中的原子级信息
无论哪个工具,最终坐标都落在 PDB 或 mmCIF 的 ATOM / HETATM 记录里。以 PDB 为例,关键列包括:原子序号、原子名、残基名、链 ID、残基序号、x/y/z 坐标、占据率(occupancy)和 B-factor。这里有一个极易被忽略的工程细节:AlphaFold2 与 ESMFold 会把 pLDDT 写入 B-factor 列,而 RoseTTAFold 的 PDB 中 B-factor 常为 0 或占位值,真实置信度需要从 .npz 中读取。因此,解析坐标时不能只看坐标本身,必须同时判断 B-factor 是否承载了置信度语义。
另一个细节是残基编号与链 ID。AlphaFold2 默认输出单链或多链的连续编号,多聚体预测中链 ID 依次为 A、B、C……;ESMFold 对多链输入会保留输入序列的链顺序,但编号可能从 1 重新开始。若后续要做残基级比对或突变位点映射,必须先把“预测编号”与“目标编号”对齐,否则 pLDDT 和 PAE 的索引会整体错位。
二、pLDDT:残基级局部置信度
pLDDT 是 per-residue 的局部置信度,取值 0–100,衡量模型对每个残基局部构象的把握。AlphaFold2 的 plddt_*.json 是一个长度为 L 的数组,顺序与 PDB 中残基顺序一致;ESMFold 返回的 pLDDT 数组同样按残基顺序排列。工程上通常按四档解读:>90 为非常高,70–90 为较高,50–70 为低,<50 为极低。需要强调的是,pLDDT 是局部指标,它高不代表残基之间的相对位置正确,这正是 PAE 存在的意义。
三、PAE:残基对之间的相对位置误差
PAE(Predicted Aligned Error)是 AlphaFold2 引入的成对置信度矩阵,形状为 L×L,单位是 Å。矩阵元素 PAE[i][j] 表示:当以残基 j 为参考对齐时,残基 i 的预测位置与真实位置之间的预期误差。它描述的是相对位置的可信程度,而不是单个残基的局部构象。解读时通常看两个维度:一是对角线附近(局部)应普遍较低;二是不同结构域之间的块状区域,若块内 PAE 低、块间 PAE 高,说明各结构域内部可信,但结构域之间的相对取向不确定。AlphaFold2 的 pae_*.json 中,predicted_aligned_error 是矩阵,max_predicted_aligned_error 是截断上限(通常为 31.75 Å),distance_diff 等字段用于辅助诊断。
四、pTM 与 ipTM:整体与界面置信度
AlphaFold2 的 *_scores.json 中还有两个关键标量:pTM 和 ipTM。pTM 衡量整体拓扑的预测质量,取值 0–1,通常 >0.5 表示整体折叠可信;ipTM 衡量链间界面的预测质量,多聚体预测中尤其重要,>0.6 一般视为界面较可信。这两个字段是“整体级”判断,与残基级的 pLDDT、成对级的 PAE 形成互补。工程上建议把 pTM、ipTM、平均 pLDDT 三者放在一起看:若 pTM 高但 ipTM 低,说明单体折叠可信、复合物界面不可信;若平均 pLDDT 高但 pTM 低,则可能是局部构象好但整体拓扑错误。
五、解析实操:从文件到可分析对象
下面给出一段可直接参考的解析示例,目标是把 AlphaFold2 的 PDB、pLDDT JSON 和 PAE JSON 读入为统一对象,并做索引一致性检查。示例参数为教学假设,实际使用时请替换为真实路径。
import json, numpy as np
from Bio.PDB import PDBParser
pdb_path = "ranked_0.pdb"
plddt_path = "plddt_ranked_0.json"
pae_path = "pae_ranked_0.json"
# 1) 读坐标与 B-factor
structure = PDBParser(QUIET=True).get_structure("m", pdb_path)
residues = [r for r in structure.get_residues() if r.id[0] == " "]
coords = np.array([r["CA"].coord for r in residues if "CA" in r])
bfac = np.array([r["CA"].get_bfactor() for r in residues if "CA" in r])
# 2) 读 pLDDT 数组
with open(plddt_path) as f:
plddt = np.array(json.load(f))
# 3) 读 PAE 矩阵
with open(pae_path) as f:
pae_obj = json.load(f)
pae = np.array(pae_obj["predicted_aligned_error"])
# 4) 索引一致性检查
assert len(plddt) == len(coords), "pLDDT 长度与 CA 数不一致"
assert pae.shape == (len(coords), len(coords)), "PAE 维度与残基数不一致"
assert np.allclose(bfac, plddt, atol=1.0), "B-factor 与 pLDDT 不一致"
print("残基数:", len(coords))
print("平均 pLDDT:", round(plddt.mean(), 2))
print("PAE 全局均值:", round(pae.mean(), 2))
这段代码的关键不在读取本身,而在第 4 步的三条断言。第一条检查 pLDDT 数组长度是否等于 CA 原子数;第二条检查 PAE 是否为方阵且维度匹配;第三条检查 PDB 的 B-factor 是否与 pLDDT 数组一致。任何一条失败,都说明文件版本不匹配或残基筛选逻辑有误,此时不应继续做下游分析。
六、元数据与工程含义
除了数值字段,输出目录中的元数据同样重要。AlphaFold2 的 ranking_debug.json 记录了各模型的 pTM 与排序,msas/ 目录反映 MSA 深度,features.pkl 保存输入特征。MSA 深度直接影响 pLDDT 的可靠性:MSA 浅的靶标,即使 pLDDT 局部较高,也应谨慎对待。ESMFold 不依赖 MSA,其 pLDDT 在低同源序列上可能偏高,需要结合序列长度和复杂度判断。RoseTTAFold 的 .npz 中除 pLDDT 外还可能包含 dist 矩阵,可用于交叉验证 PAE 的合理性。
把上述字段解析清楚后,后续的验证工作才有可靠基础:pLDDT 用于残基级可信度筛选,PAE 用于结构域划分与相对取向判断,pTM/ipTM 用于整体与界面级决策,元数据用于解释置信度来源。下一阶段的结构验证与可信度评估,正是建立在这些字段的正确提取之上。