4. 跨批次比较的背景:为什么不同批次的结构数据需要对齐与标准化

做结构比对的人,大多会有一种「强迫症」——希望所有数据都放在一个公平的起跑线上。但现实往往很残酷。你从PDB下载的100个结构,可能来自不同实验室、不同年份、不同分辨率,甚至不同软件包算出来的。直接拿这些结构的坐标去算TM-score?我个人习惯了,绝对不这么干。

举个例子。我几年前做过一个项目,需要比较AlphaFold2预测的2000个人类蛋白结构与对应的实验结构。一开始我偷懒,直接把两个结构的原始坐标丢进TM-score程序里跑。结果出来一堆异常值,有的TM-score只有0.2,但肉眼看着两个结构几乎一模一样。问题出在哪?批次效应。

核心结论:不同批次的结构数据,在坐标原点、旋转方位、原子编号、链命名、残基缺失处理等多个维度上存在系统性偏差。这些偏差不消除,TM-score的可信度就是一句空话。

4.1 什么是“批次”?

这里的“批次”不是一个严格术语。它指的是数据产生的时间、方法或来源差异。常见的有以下几种:

  • 实验批次:不同课题组、不同衍射数据采集条件、不同分辨率范围。
  • 计算批次:不同版本的AlphaFold(v2.0 vs v2.3)、不同模板库、不同GPU精度。
  • 数据库批次:PDB不同release版本之间,部分结构被重新精修过。
  • 时间批次:同一个课题组在不同年份解的同一个蛋白结构。

你想想看,如果把不同批次的数据直接放在一起比较,就像把用米尺量的长度和用游标卡尺量的长度混在一起算平均值。结果能信吗?

4.2 批次效应的具体表现

我用一个真实的例子来说明。下面这段是某个结构比对项目中,两个完全相同序列的蛋白在未对齐前的部分坐标片段:

避坑提醒:我曾经遇到过一种情况——两个结构来自同一篇论文,但一个是X-ray衍射,一个是Cryo-EM。表面上都叫“蛋白A”,实际上坐标原点差了上百个埃格斯特朗。如果不做对齐,TM-score直接归零。

# 结构A(X-ray,2020年)
ATOM      1  CA  MET A   1      10.234   20.567   30.891  1.00 20.00           C
ATOM      2  CA  GLN A   2      12.456   22.789   33.012  1.00 20.00           C
...

# 结构B(AlphaFold2,2023年)
ATOM      1  CA  MET A   1      -5.123   40.987   15.678  1.00 20.00           C
ATOM      2  CA  GLN A   2      -3.456   43.210   17.890  1.00 20.00           C
...

同样的两个CA原子,坐标值差了几十埃格斯特朗。这还不是最严重的。最头疼的是残基编号不一致,比如一个结构把信号肽也算进去,另一个不算。TM-score是依赖残基顺序做sequence alignment的,序号一乱,结果全乱。

4.3 不做对齐的后果

我归纳了一下,直接拿原始坐标跑TM-score会踩到哪些坑:

问题类型 具体表现 影响程度
坐标漂移 全局平移/旋转导致RMSD虚高 严重:TM-score可能被低估0.2-0.5
残基偏移 链命名不同(A vs B)、插入/缺失残基 致命:alignment完全错位
原子缺失 分辨率低的结构缺少部分侧链原子 中等:需决定是否用CA-only比对
模型版本 不同relaxation算法导致局部构象差异 轻微:但会影响置信区间

所以我一直强调:TM-score的计算结果,本质上是一个经过标准化后的相似度指标。标准化的前提,就是先把不同批次的数据拉到同一个“参考系”里。

4.4 对齐与标准化:两个层面

对了,这里得区分两个概念:结构对齐和分数标准化。很多人混为一谈,其实不一样。

  • 结构对齐(Structural Alignment):把一个结构的坐标通过旋转平移,使得它与另一个结构的对应残基在空间上尽可能重叠。这解决的是“坐标不一致”的问题。
  • 分数标准化(Score Normalization):TM-score本身的取值范围受蛋白质长度影响,需要通过理论随机期望值做归一化。这解决的是“长度偏差”的问题。

这两个层面缺一不可。前者是数据预处理,后者是数学后处理。

4.5 统一参考系:最核心的操作

实际工作中,我建议做以下几步标准化:

  1. 重命名链:所有结构的链名统一为单个字母(如'A'),并在PDB文件中保持唯一。
  2. 残基编号对齐:根据序列一致性从1开始重新编号,忽略原始编号。
  3. 原子选择标准化:只保留CA原子或者所有重原子,必须明确声明。
  4. 坐标中心化(可选):将结构的质心移到原点。
  5. 缺失残基填充:统一策略——要么都补成虚拟CA,要么都忽略。

下面是我个人习惯用的一个标准化流程脚本片段:

# 标准化PDB文件:重新编号残基并重命名链
def standardize_pdb(input_pdb, output_pdb, chain_id='A'):
    model = load_structure(input_pdb)
    # 只保留第一个模型
    model = model[0]
    # 重命名所有链
    for chain in model.get_chains():
        chain.id = chain_id
    # 按序列顺序重新编号残基,从1开始
    for i, residue in enumerate(model.get_residues(), start=1):
        residue.id = (' ', i, ' ')
    # 保存标准化后的结构
    save_structure(model, output_pdb)

实用技巧:在做大批量比对时,我习惯把标准化后的中间PDB文件单独存一个目录。这样一旦TM-score结果异常,可以随时回溯看是原始数据的问题还是对齐参数的问题。

4.6 批次对齐的核心逻辑

下面这张图是我自己总结的跨批次比对决策树。说白了,就是让你在动手算TM-score之前,先问自己三个问题:

跨批次比对决策逻辑 两组结构数据(不同批次) Q1: 坐标原点/方位一致吗? 是 否 Q2: 残基编号/链名一致吗? Q3: 缺失原子/残基处理一致吗? 全部确认 → 可靠TM-score比较 核心原则 任何一项为“否”,都需要先做对齐/标准化预处理,否则TM-score结果不能跨批次直接比较

4.7 为什么不能跳过这一步?

说白了,TM-score虽然对全局平移旋转不敏感(因为它会做内部优化),但它的残基配对阶段完全依赖于sequence alignment的正确性。如果残基序号错位,TM-score的初始搜索范围就会偏离真实解。

我遇到过最夸张的情况是这样的:一个结构有301个残基,另一个只有300个。原始文件里第100号残基是Lys,另一个文件里同一个位置却是Gln。不标准化直接跑,TM-score输出0.35,但人工对齐后发现实际相似度超过0.7。整整差了一倍多。这数据你敢往论文里写?

一句话总结:跨批次比较的核心前提,是保证所有输入结构在命名、编号、原子集三个维度上一致。否则TM-score的数学性质再好,也救不了数据本身的混乱。