第 2 章:受体准备 - 缺失原子与非标准残基处理
做分子对接,第一步就是准备受体。这一步要是没弄好,后面所有的对接结果都得打问号。
我自己早期翻过不少跟头——明明对接分数很高,结果一验证就发现配体卡在了蛋白的空腔里,原子间距根本不合理。排查到最后,发现是受体文件里缺了关键原子。嗯,那种感觉,白费了好几天功夫。
这一章咱们就专门聊聊:缺失原子和非标准残基这两个最容易出问题的地方。
核心口诀:原子不全不能跑,残基非标先建模。
2.1 缺失原子的常见情况
先说说缺失原子——这事太常见了。X光晶体结构或冷冻电镜解析出来的PDB文件,并不是完美的。有些原子的电子密度不清晰,结构学家就没法建模。
哪些原子最容易丢?
- 侧链末端原子:比如赖氨酸的NZ原子、谷氨酸的OE原子。这些原子位于残基最外端,溶剂接触多,温度因子高。
- 柔性侧链:精氨酸的NH2、谷氨酰胺的NE2等,在晶体里经常处于无序状态。
- 氢原子:PDB通常不包含氢原子,除非是超高分辨率结构。对接前必须手动加氢。
- 非极性侧链中段:像亮氨酸的CD1和CD2,有时候也会缺失。
我接手过一个项目,目标蛋白是某个激酶。PDB里一个关键的F169残基,侧链的Cβ和Cγ都显示为“未定义”。没补全之前,对接就是妥妥的负分。补全之后,姿势完全变了。
2.2 如何检测缺失原子
最简单的方法——用文本编辑器打开PDB文件,看看ATOM记录行里是不是有奇怪的占位符。
典型异常标志:
| 常见占位符 | 含义 | 处理方式 |
|---|---|---|
-999 |
坐标未确定 | 必须补全或删除该残基 |
0.000 |
坐标缺失或置零 | 需要重建原子坐标 |
ATOM 序列号 重复 |
原子编号冲突 | 重新编号并检查次序 |
HETATM 与 ATOM 混用 |
非标准残基标记错误 | 修正残基类型标记 |
我习惯用脚本批量跑一下。下面这个check_missing_atoms.py是我自己一直在用的,能快速扫描PDB里缺了哪些主链和侧链原子。
import sys
from Bio.PDB import PDBParser
def check_missing( pdb_file ):
parser = PDBParser(QUIET=True)
structure = parser.get_structure("prot", pdb_file)
for model in structure:
for chain in model:
for residue in chain:
std_atoms = {"N", "CA", "C", "O"}
if residue.get_resname() in standard_amino_acids:
missing = std_atoms - { atom.get_id() for atom in residue }
if missing:
print(f"Chain {chain.id} Res {residue.get_resname()} {residue.id[1]}: missing {missing}")
if __name__ == "__main__":
check_missing(sys.argv[1])
小技巧:有些可视化工具也能高亮缺失原子,比如PyMOL里set ignore_pdb_header_warnings, 1之后,用show sticks配合select missing可以快速定位。
2.3 补全缺失原子的常用方法
检测出来缺失以后,该怎么补?我推荐下面这几种方式,按适用场景分好优先级。
- 使用同源建模工具(Modeller / SWISS-MODEL)
- 适合缺失片段较长(比如3个残基以上)的情况
- 能根据同源模板,重建侧链和主链的合理构象
- 缺点是耗时长,需要手动校验
- 用PDB Fixer类工具自动补全
- 比如OpenMM的
pdbfixer,可以一键补全缺失侧链 - 底层逻辑是用Rotamer库来填充缺失原子
- 适合单残基或小侧链缺失
- 比如OpenMM的
- 手动编辑PDB文件,使用PyMOL的
fill missing atoms命令- 快速,适合少量缺失
- 但无法处理主链断裂或大段缺失
一个常见的补全命令示例(PyMOL):
fetch 1abc
fill missing atoms
save 1abc_filled.pdb
注意:补全原子后,务必检查二面角是否有立体化学冲突。我曾在补全一个色氨酸侧链时,没注意χ1角违反了拉氏图,结果对接一直无法收敛。折腾了两天才发现问题。
2.4 非标准残基的处理
非标准残基,指的是不在20种标准氨基酸列表里的残基。比如磷酸化的丝氨酸(SEP)、乙酰化的赖氨酸(ALY)、甲基化的精氨酸等。
这类残基在PDB里被标记为HETATM,而不是ATOM。对接软件默认把HETATM当作小分子配体处理,但事实上它们依然是受体的一部分——这就导致了很多对接失败。
我经历过的真实案例——一个磷酸化位点附近的对接。配体本来应该和SEP侧链的磷酸基团形成盐桥,但AutoDock把SEP当成了小分子配体拿出来单独处理。对接结果完全不对。后来我手动把SEP改成标准残基,再补上磷酸基的原子参数,结果才正常。
2.5 非标准残基的标准化流程
拿到一个非标准残基,我一般走这三步:
- 查看PDB报告——看这个残基有没有完整的原子坐标,有没有对应的化学修饰说明。
- 检查是否为天然修饰——比如磷酸(TPO)、甲基(MLY)、乙酰(ALY)等常见修饰,可以在对接工具里手动添加。
- 手动重建为可对接形式——给该残基分配标准原子命名,导出为MOL2或PDB格式,提供正确的键序和电荷。
下面是一个简单的函数,用来把磷酸化丝氨酸(SEP)还原为标准丝氨酸+磷酸基团,并输出成两段独立的分子对象:
def separate_phosphoserine(het_residue):
# het_residue是Bio.PDB中的Residue对象
std_ser = create_standard_residue("SER", het_residue.id[1])
for atom in het_residue:
if atom.get_name() in ['N', 'CA', 'C', 'O', 'CB', 'OG']:
std_ser.add(atom.copy())
# 剩余P、OP1、OP2、OP3归入磷酸基团
phospho_group = Residue((' ', 1, ' '), 'PO4', '')
for atom in het_residue:
if atom.get_name() not in ['N', 'CA', 'C', 'O', 'CB', 'OG']:
phospho_group.add(atom.copy())
return std_ser, phospho_group
2.6 受体准备中的避坑清单
咱们来总结一下,实操中容易踩的坑。我用列表写清楚,你对照着检查一遍。
- 缺失原子补全前,别忘了加氢——很多工具补全原子时不自动加氢,你得单独加一遍。
- 主链断裂的不能直接补——如果缺失超过3个连续残基,建议还是用同源建模重新建模。直接硬补侧链,主链构象不连续。
- 非标准残基不能全当配体处理——特别是磷酸化、甲基化这种共价修饰,它们依然是受体官能团的延伸。
- PDB里的HETATM不都是小分子——比如血红蛋白里的血红素、酶里的金属离子,这些也是受体结构的一部分。
- 补全后必须做能量最小化——哪怕只是补了一个原子,周围侧链的张力也可能很大。我建议做一轮500步最陡梯度下降。
我的一个习惯:每次补全都跑一遍ProCheck拉氏图检查,看看新加原子的二面角是否合理。比对着结构看感觉要准得多。
2.7 本章知识脉络
下面这张流程图,把受体准备中缺失原子和非标准残基的处理全过程串起来了。你可以先看一眼整体,再回头对照细节。
说白了,受体准备这部分,最大的敌人就是“你以为文件没问题”。很多新手直接网上扒个PDB就开始对接,结果后面到处报错。花10分钟跑一遍缺失原子检测,补全非标残基,再做一轮最小化——对接成功率能翻倍。
最后强调一点:做完上面所有步骤,别忘了加氢。我曾经被一个pH=7.4环境下的组氨酸质子化状态坑过好多次——错过一个氢键,结果整个对接打分差了两个数量级。该用reduce还是用propka,看你的喜好,但这一步省略不得。