1. 认识PDB文件格式:一个结构生物学家的老朋友

说起PDB格式,它绝对是结构生物学里最“古老”的数据格式之一。我本科那会儿第一次打开一个PDB文件,满屏的数字和字母看得我头皮发麻——这玩意儿怎么读?后来做了几年结构数据清洗,才发现这位“老朋友”虽然年纪大了点,但真的很有内涵。

PDB格式是Protein Data Bank的缩写,诞生于上世纪70年代。说白了,它就是一套描述生物大分子三维结构的“标准语法”。我们做数据清洗,第一步就得读懂这套语法。

1.1 一个真实的PDB文件长什么样

先别急着看密密麻麻的规范文档。咱们直接打开一个真实的PDB文件看看。我习惯用胰岛素的一段记录当例子,它特别能说明问题:

HEADER    HORMONE                               01-JAN-98   1INS
ATOM      1  N   ALA A   1       5.123   3.456   2.789  1.00 16.00           N
ATOM      2  CA  ALA A   1       6.234   4.567   3.890  1.00 17.00           C
ATOM      3  C   ALA A   1       7.345   5.678   4.901  1.00 18.00           C
ATOM      4  O   ALA A   1       8.456   6.789   5.012  1.00 19.00           O
ATOM      5  CB  ALA A   1       5.678   4.890   2.345  1.00 15.00           C
TER
HETATM   10  O   HOH A 101       9.012   7.890   6.123  1.00 20.00           O
END

嗯,是不是看着有点眼花?我来拆开讲,你马上就能看懂。

1.2 原子记录格式:别被80列吓到

早期的PDB格式规定每行必须严格80列。为什么?因为那时候用的还是打孔纸带和宽行打印机。现在虽然不强制了,但绝大多数PDB文件还沿用这个传统。我个人觉得,这反而让格式更整齐,解析起来也简单。

原子记录主要分两种:ATOM和HETATM。ATOM记录标准氨基酸/核酸的原子,HETATM记录配体、水分子等“非标”东西。它们的字段位置完全一样:

列位置 字段名 说明 示例
1-6 记录类型 ATOM 或 HETATM ATOM
7-11 原子编号 整数,建议连续 5
13-16 原子名称 左侧留空格,右侧对齐 CB
17-17 备选位置 有空位异构时用A/B/C
18-20 残基名称 三字母代码 ALA
22-22 链标识 单字母A-Z A
23-26 残基编号 整数,可用负值 1
27-27 插入码 如晶体制备时插入的残基
31-38 X坐标 浮点数,单位埃 5.678
39-46 Y坐标 浮点数,单位埃 4.890
47-54 Z坐标 浮点数,单位埃 2.345
55-60 占据率 0.00-1.00 1.00
61-66 温度因子 也叫B因子,单位平方埃 15.00
77-78 元素符号 靠右对齐 C

核心提示:解析PDB时我推荐用固定列宽截取,而不是用空格split。因为原子名称和残基名称可能连在一起。用split碰到"CA"和" A"的区别,你会头大的。

1.3 坐标数据:从XYZ到实际应用

坐标数据是PDB的核心,三个浮点数定义了原子在三维空间的位置。单位都是埃(Å),1Å = 0.1纳米。做数据处理时,我见过最多的问题就是单位搞混了——有人把坐标当纳米处理,计算出来的键长全是错的。

占据率这个字段,新手容易忽略。它表示这个原子在晶体里的“出现概率”。理想情况下是1.00,但侧链柔性大的残基,或者配体结合不明确的地方,可能会出现0.50甚至更低。我个人习惯,做能量计算前会把占据率低于0.50的原子去掉,否则结果偏差很大。

温度因子(也叫B因子)更有意思。它反映的是原子的运动幅度。B因子越大,原子越“抖”。我曾经帮一个课题组清理数据,他们发现某个活性位点的配体B因子特别高——后来证明那个配体根本没结合好,是晶体打包时硬塞进去的。

小技巧:做结构比对前,先看看B因子。残基的B因子如果超过80,它的坐标基本不可信。这是我从无数失败的叠加里总结出来的。

1.4 注解字段:藏在文件里的“剧情简介”

PDB文件不只是原子坐标。文件头部的HEADER、TITLE、COMPND、SOURCE这些注解字段,记录了实验信息、分子来源、功能描述。做数据清洗时,千万别忽略它们。

举个真实的例子。有一次我批量处理冗余的PDB结构,发现两条记录一个标的是“人胰岛素”,另一个标的是“猪胰岛素”,但坐标对得严丝合缝。查了SOURCE记录才知道:后者虽然标的猪,但表达系统是人源细胞,测出来构象一模一样。如果光对坐标,我会直接删掉一个,就漏掉这条重要信息了。

几个常用的注解字段:

  • HEADER:分子类型,比如HORMONE、TRANSPORT PROTEIN
  • TITLE:实验的简短描述,常包含突变信息和配体信息
  • COMPND:分子名称,包括链的命名
  • SOURCE:表达系统,对理解翻译后修饰很重要
  • KEYWDS:关键词,方便检索和分类
  • REMARK 2:分辨率信息,这是质量评价的第一道门槛

1.5 PDB格式的两大“坑”

讲了这么多好的,也得说说坑。我花了至少两个月才彻底搞明白这两个问题:

避坑指南1:链标识不是唯一的

不同的PDB文件,同样的链可能叫A,也可能叫B,还可能同一个链在不同模型中用不同的字母。做跨文件比对时,绝对不能只靠链字母对应。我建议自己重新编号,按连续残基顺序标链。

避坑指南2:原子名称的对齐规则

标准氨基酸的原子名称放在13-16列,是“右侧对齐左侧留空”的。比如Cα写为" CA",不是"CA "。而水分子氧原子写为" O "。用split(' ')拆分时,空字符串能把你逼疯。我统一用固定列宽截取,再也不纠结。

1.6 知识结构总览

在你开始实战解析前,先看看PDB格式的整体骨架。下面这张图总结了我们刚才讲的核心内容:

PDB文件格式知识结构图 PDB文件格式知识结构总览 PDB文件 文件头 HEADER 原子坐标与参数 注解与元数据 TITLE / COMPND SOURCE / KEYWDS XYZ坐标(Å) 占据率 温度因子 REMARK 2分辨率 实验方法 解析时:ATOM vs HETATM / 固定80列 / 原子名称对齐规则

1.7 实战准备:用Python读一行PDB

理论讲完,还是得动手。这是我写的第一版PDB解析函数的简化版,留给你当模板:

def parse_atom_line(line):
    """
    解析单行ATOM/HETATM记录
    返回字典,失败返回None
    """
    # 检查记录类型
    rec_type = line[0:6].strip()
    if rec_type not in ("ATOM", "HETATM"):
        return None

    record = {
        "type": rec_type,
        "serial": int(line[6:11].strip()),
        "name": line[12:16].strip(),
        "alt_loc": line[16:17].strip(),
        "res_name": line[17:20].strip(),
        "chain": line[21:22].strip(),
        "res_seq": int(line[22:26].strip()),
        "i_code": line[26:27].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

注意,我这里用的全是固定列宽截取。你可以自己试试,如果换成line.split(),原子名为" CA"时split的结果会多一个空串,这个bug能让你debug到怀疑人生。

好了,PDB文件的基本骨架你已经摸清了。下一阶段我们会深入到格式变种和异常处理——相信我,PDB文件里的“妖怪”比你想象的多。