残基命名与标准氨基酸:三字母代码、单字母代码、非标准残基处理
处理PDB文件,说白了你每天都在跟残基命名打交道。我刚开始接触结构生物学那会儿,就被ATOM记录里的三字母代码搞得晕头转向——明明看着是LYS,心里还想着这是不是赖氨酸,结果库里面写的是LYS,单元里写的是L、Y、S,完全对不上。嗯,今天我们就把这个事情彻底讲清楚。
标准氨基酸的命名体系
PDB格式使用两种残基标识符:三字母代码和单字母代码。前者是PDB文件默认的存储格式,后者常用于序列比对和展示。
这里是我个人习惯的一个对比表,你写脚本的时候直接照着核对就行:
| 氨基酸全名 | 三字母代码 | 单字母代码 | 侧链性质 |
|---|---|---|---|
| 丙氨酸 | ALA | A | 非极性,脂肪族 |
| 精氨酸 | ARG | R | 碱性,带正电 |
| 天冬酰胺 | ASN | N | 极性,不带电 |
| 天冬氨酸 | ASP | D | 酸性,带负电 |
| 半胱氨酸 | CYS | C | 极性,含巯基 |
| 谷氨酰胺 | GLN | Q | 极性,不带电 |
| 谷氨酸 | GLU | E | 酸性,带负电 |
| 甘氨酸 | GLY | G | 非极性,柔性最大 |
| 组氨酸 | HIS | H | 碱性,含咪唑环 |
| 异亮氨酸 | ILE | I | 非极性,支链脂肪族 |
| 亮氨酸 | LEU | L | 非极性,支链脂肪族 |
| 赖氨酸 | LYS | K | 碱性,带正电 |
| 甲硫氨酸 | MET | M | 非极性,含硫 |
| 苯丙氨酸 | PHE | F | 非极性,芳香族 |
| 脯氨酸 | PRO | P | 非极性,亚氨基 |
| 丝氨酸 | SER | S | 极性,含羟基 |
| 苏氨酸 | THR | T | 极性,含羟基 |
| 色氨酸 | TRP | W | 非极性,芳香族 |
| 酪氨酸 | TYR | Y | 极性,含酚羟基 |
| 缬氨酸 | VAL | V | 非极性,支链脂肪族 |
我个人习惯在写解析脚本时,会把三字母到单字母的映射写成一个静态字典,而不是用if-else判断。因为PDB里某些非标准残基也遵循类似的命名规则,你有个字典能更方便地做扩展。
三字母代码的ATOM记录格式
在PDB文件的ATOM或HETATM记录中,残基名称固定占据第18-20列,右对齐。你写解析器的时候,千万别按字符串trim来做,要按字符位置截取。
ATOM 1 N ALA A 1 6.247 18.672 -9.654 1.00 0.00 N
ATOM 2 CA ALA A 1 7.056 17.432 -9.507 1.00 0.00 C
ATOM 3 C ALA A 1 8.566 17.672 -9.473 1.00 0.00 C
# Python示例:截取三字母代码
resname = line[17:20].strip() # 第18-20列,注意索引从0开始
chain_id = line[21] # 第22列,链标识
曾经我在处理一批老旧的PDB文件时,发现某些条目把残基名写在了第17列,导致截取失败。原因是部分早期的X射线结构使用了格式化不严格的记录。所以,稳妥的做法是先检查第17列的字符是否为空格,如果不是,就得用自定义的偏移量做容错。
非标准残基与修饰残基
PDB里不只有20种标准氨基酸。晶体结构解析过程中,经常会遇到修饰残基、配体、水分子、甚至错误建模的残基。你想想看,一个磷酸化的丝氨酸,PDB里写成了SEP,而不是SER。如果你用单纯的三字母到单字母映射去处理,就会丢失这个修饰信息。
常见的非标准残基包括:
- 修饰氨基酸:磷酸化丝氨酸(SEP)、磷酸化苏氨酸(TPO)、磷酸化酪氨酸(PTR)、乙酰化赖氨酸(ALY)
- 非天然氨基酸:正亮氨酸(NLE)、正缬氨酸(NVA)、鸟氨酸(ORN)
- 水分子:HOH或SOL
- 配体与离子:ATP、NAD、ZN、MG等
- 未知或未解析残基:UNK或XXX
我当年在一个蛋白质-配体复合物的项目中,因为没处理好SEP残基,导致后续的力场参数分配全错了——那家伙把磷酸基团当作侧链原子一锅炖,能量最小化直接跑飞。从那以后,我写预处理流程时一定会在PDB解析阶段单独处理非标准残基,并建立一张映射表,把修饰残基还原成标准类型,同时保留修饰标记。
处理策略:统一化还是保留原貌?
这里其实有两种思路,取决于你的下游任务:
- 统一化策略:把非标准残基映射到邻近的标准残基。比如SEP→SER,TPO→THR。这种策略适合做序列比对、保守性分析、机器学习特征提取。
- 保留原貌策略:保留所有修饰标记,把SEP当作独立残基类别。这种策略适合做结合口袋分析、相互作用计算、力场参数分配。
我个人建议用一个YAML配置文件来管理这种映射关系,保持可追踪性。这样下次换一个数据集也不用手动改代码。
# standardize_nonstandard.yaml
# 修饰氨基酸 → 标准氨基酸映射
SEP: SER # 磷酸化丝氨酸 → 丝氨酸
TPO: THR # 磷酸化苏氨酸 → 苏氨酸
PTR: TYR # 磷酸化酪氨酸 → 酪氨酸
ALY: LYS # 乙酰化赖氨酸 → 赖氨酸
CSO: CYS # 巯基氧化半胱氨酸 → 半胱氨酸
MSE: MET # 硒代甲硫氨酸 → 甲硫氨酸
HID: HIS # 质子化组氨酸 → 组氨酸
HIE: HIS # 去质子化组氨酸 → 组氨酸
HIP: HIS # 双质子化组氨酸 → 组氨酸
你解析的时候,可以这样加载:
import yaml
with open("standardize_nonstandard.yaml", "r") as f:
mapping = yaml.safe_load(f)
def standardize_resname(resname):
"""将非标准残基映射为标准残基,如果找不到映射则返回原值。"""
return mapping.get(resname, resname)
特殊案例:组氨酸的质子化状态
组氨酸在PDB中有三种常见的命名变体:HID(δ-质子化)、HIE(ε-质子化)、HIP(双质子化)。这三种构型在静电力学计算中差异很大。你要是直接统一映射成HIS,相当于抹掉了这个关键信息。
我做过一个蛋白质pKa预测的项目,里面有一处关键组氨酸被建模成HID形式,而默认的残基库把它当作标准HIS处理,结果pKa偏移了1.2个单位,整个pH-活性曲线对不上实验数据。所以,如果你的下游分析涉及氢键网络、静电计算或质子化状态,务必保留原始的HID/HIE/HIP标记,至少保留一份元数据副本。
水分子与配体的处理
很多初学者会忽略水分子和配体残基。PDB里水分子统一用HOH或SOL表示(取决于来源),配体则使用HETATM记录。你写预处理流程时,需要根据记录类型来分流:
- ATOM:蛋白质或核酸的主链/侧链原子
- HETATM:非标准残基、水分子、配体、离子
这里有个小技巧:不要只看残基名来区分,因为某些非标准残基(比如SEP)也会出现在ATOM记录中。你要结合record_type和resname两个字段做判断。
def is_protein_atom(record_type, resname):
"""判断原子是否属于蛋白质主链/侧链"""
if record_type != "ATOM":
return False
standard_residues = {
"ALA","ARG","ASN","ASP","CYS","GLN","GLU","GLY",
"HIS","ILE","LEU","LYS","MET","PHE","PRO","SER",
"THR","TRP","TYR","VAL",
# 修饰残基也视为蛋白原子
"SEP","TPO","PTR","ALY","CSO","MSE",
"HID","HIE","HIP"
}
return resname in standard_residues
常见坑点与避坑指南
我整理了几个你一定会遇到的坑:
- 大小写问题:PDB文件里残基名全部大写,但有些第三方库或旧版本PDB会输出小写。解析时最好先做
.upper()。 - 空列填充:残基名不足3字符时,左侧补空格,右侧对齐。比如CYS的C往往会被解析成CY,因为第18列是空格。你截取的时候要用
line[17:20],而不是line.split()[3],因为split会把空格压缩掉。 - 插入残基代码:PDB格式有插入残基(insertion code)的概念,如果两条链在同一位置有不同残基,会用字母后缀区分(如100A、100B)。你在做残基编号映射时,一定要把
resSeq和iCode拼起来作为唯一键。 - 内存残基:某些PDB文件会出现
.(三个点)或UNK作为残基名,通常表示该位置未解析。稳妥的做法是直接跳过或者记录为缺失。
曾经我在解析一个来自EMDB的冷冻电镜结构时,发现某个链在中间位置突然出现了一个残基名为 1(空格空格1)的条目,搞得程序直接崩溃。后来排查发现,这是数据准备阶段的一个残基编号标记错误,原子坐标却是正常的。所以,你一定要对残基名做合法性校验,只通过白名单方式处理。
总结一下核心要点
残基命名这件事,说白了就是:三字母代码是存储格式,单字母代码是计算格式,非标准残基必须单独管理。你按这个思路去设计预处理流程,能省掉不少回头填坑的时间。
我建议你在实际的PDB预处理程序中,把残基命名规范化的模块独立出来做单元测试,特别是针对那些修饰残基、水分子和异常命名,提前写几个边界case的测试用例。如果你刚入门,可以先用PDBbind或PDBbind refine数据集练手,里面既有标准残基也有大量配体,能逼着你做完整的分支处理。