3. PDB数据结构与字段含义

PDB格式,说白了就是蛋白质结构的“通用语言”。我在刚接触这个领域时,最先面对的就是那堆密密麻麻的文本行。不弄清楚每一列是什么,后续工作根本无从谈起。

这一章我们来拆解PDB文件中最重要的两类记录:ATOM和HETATM,以及残基命名规则、字段含义和粒度层次。

3.1 PDB文件的基本框架

一个PDB文件是由多条记录按顺序组成的。每条记录都有固定的列偏移,早期标准每列都有专属用途。

下面是一个简化版的PDB文件片段——只看结构层次:

HEADER    EXTRACELLULAR MATRIX                    29-JAN-98   1A3I
TITLE     STRUCTURE OF THE INTEGRIN BINDING PROTEIN DELAFIN
COMPND    MOL_ID: 1; MOLECULE: DELAFIN; CHAIN: A, B
ATOM      1  N   ALA A  23      10.525  37.119  11.579  1.00 19.59           N
ATOM      2  CA  ALA A  23      10.419  36.740  10.159  1.00 18.30           C
ATOM      3  C   ALA A  23       9.221  35.817   9.936  1.00 16.50           C
HETATM  200  O   HOH A  45      11.200  38.500  12.000  1.00 20.00           O
TER      400      ALA A  23
END

嗯,这里要注意:ATOM 记录的是标准氨基酸的原子,HETATM 则用于非标准分子。我遇到过不少新手把这个搞混,导致对接计算时出了大问题。

3.2 ATOM记录——核心中的核心

一条 ATOM 记录共 12 个固定字段。我习惯用一张对照表来记忆它们的位置:

字段列位置描述示例
记录类型1-6固定为「ATOM」或「HETATM」ATOM
序号7-11原子编号,按出现顺序计数1
原子名称13-16原子名称,如 CA、CB、NN
残基名称18-20三字母氨基酸代码ALA
链标识22单字母链 IDA
残基号23-26在链内的序列编号23
X 坐标31-38埃格斯特朗单位10.525
Y 坐标39-46同上37.119
Z 坐标47-54同上11.579
占位因子55-60位置占有率(0~1)1.00
温度因子61-66B factor,热运动参数19.59
元素符号77-78元素周期表符号N

那这六列坐标都记录了什么呢?其实就是该原子在三维空间中的精确位置。我做对接时经常遇到 占位因子 不等于 1.0 的情况——这意味着该原子在晶体中有两种可能位置。

个人习惯:解析时我从不依赖空格分割,而是按固定列截取字符串。原因是有些字段是左对齐、有些是右对齐,split 后很容易错位。

3.3 HETATM 与残基命名

有一次我在筛选 PDB 文件时,发现一个蛋白结构里竟然有 200 多个水分子。这些水就属于 HETATM 记录。两者基本一模一样,就差在记录名称上。

HETATM 适用于:

  • 水分子(HOH)
  • 配体(如 ATP、NAD、抑制剂)
  • 金属离子(如 Zn²⁺、Mg²⁺)
  • 修饰过的残基(如 MSE)

残基命名同样有讲究:

类型示例说明
标准氨基酸ALA, GLY, LYS20 种常见氨基酸的三字母缩写
非标准残基MSE, CSD修饰氨基酸,常见于晶体学衍生
DNA/RNADA, DC, U, A核酸碱基,D 前缀表示 DNA
配体/小分子ATP, NAD, HOHPDB 组分字典定义的代码

你想想看:如果把一个 MSE(硒代甲硫氨酸)当作标准 MET 处理,你的能量计算就会完全跑偏。我早期就吃过这个亏,后来学乖了,先在处理流程中加入残基类型白名单检查。

3.4 原子名称与字段细节

原子名称的规则其实藏着大学问。比如 CA 可能是 Cα(主链碳),也可能是钙离子。怎么区别?看记录类型就知道了——钙离子的记录一定是 HETATM,而不是 ATOM。

常见原子名称格式:

  • N, CA, C, O —— 主链四大件
  • CB, CG, CD1 —— 侧链原子
  • OXT —— C 端氧原子
  • 1H, 2H —— 氢原子(多用数字前缀区分)

坑点:我曾经在对接时把 HETATM 里的金属离子坐标直接拼进蛋白结构,结果计算出的结合自由能全是 NaN。后来发现是元素符号字段被截断——Zn 只取了 Z,影响了原子半径查找。

记住:元素符号 在 77-78 列,如果只有 1 个字符,第 78 列一定是空格。

3.5 知识框架图

下面这张 SVG 图展示了本章核心知识点之间的层级关系:

PDB数据记录结构层次 PDB 结构文件 ATOM 记录 HETATM 记录 原子坐标 xyz 残基名 占位/B因子 水/溶剂 配体分子 金属离子 ⚠ 区分依据 :ATOM → 标准残基原子 HETATM → 水、配体、非标残基 命名规则延伸 残基名三字母 → wwPDB 组分字典 | 原子名称左对齐四位 | 链标识区分不同链

3.6 解析实操

你写 Python 脚本时怎么解析?记住两点:一是用 line[12:16].strip() 这种切片方式取原子名,二是用 line[17:20].strip() 取残基名。别偷懒用 split()。

下面是一段我日常用的解析核心代码:

def parse_atom_line(line):
    if not (line.startswith("ATOM") or line.startswith("HETATM")):
        return None
    rec = line[0:6].strip()
    atom_serial = int(line[6:11].strip())
    atom_name   = line[12:16].strip()
    alt_loc     = line[16].strip()
    res_name    = line[17:20].strip()
    chain_id    = line[21].strip()
    res_seq     = int(line[22:26].strip())
    x = float(line[30:38].strip())
    y = float(line[38:46].strip())
    z = float(line[46:54].strip())
    occupancy   = float(line[54:60].strip())
    b_factor    = float(line[60:66].strip())
    element     = line[76:78].strip()
    return {
        "record": rec,
        "serial": atom_serial,
        "name": atom_name,
        "alt_loc": alt_loc,
        "res_name": res_name,
        "chain": chain_id,
        "res_seq": res_seq,
        "x": x, "y": y, "z": z,
        "occupancy": occupancy,
        "b_factor": b_factor,
        "element": element
    }

关键提醒:残基号可能带插入码(如 23A),那时 line[22:26] 里含有字母。遇到这种情况,序列号要用 line[22:27].strip(),并单独提取字母部分做排序用。

3.7 记录类型对照总结

下面这个表就是日常区分 ATOM 和 HETATM 的快速参考:

特征ATOMHETATM
记录类型字符串ATOMHETATM
包含的分子标准 20 种氨基酸、核酸主链水、配体、非标准残基、离子
异常处理建议缺少时优先补全(后续章节讲)缺失时通常直接丢弃或单独处理
占位因子范围通常为 1.0可能出现 0.3~1.0 的位置无序
在解析中的角色组成蛋白主链、侧链外部小分子、环境

个人技巧:处理前先把所有 HETATM 中的水行单独列出来,将它们转存到 WATER 组里,能大幅减少后续对接时的计算量。

这一章的要点就是这些。记牢字段的列偏移和命名规则,你解析 PDB 文件就不再是靠感觉胡乱切字符串了。