第4章 分子结构文件格式:PDB、Mol2、XYZ 简介

做计算化学,打交道最多的东西,除了原子,就是这些文件。

你从实验拿到晶体结构,从数据库下载参考构象,或者自己建个模型——最终都得落在一个文件里。

而这些文件的格式,决定了你能读出什么,读出的东西对不对。

嗯,这章我就以手里最常见的三种格式:PDB、Mol2、XYZ 为例子,跟你聊聊里面的门道。我个人习惯是,包里永远备着这三类文件的解析器,因为你永远不知道合作方会扔给你什么格式。


4.1 PDB 格式:蛋白晶体学的“通用语言”

PDB,全称 Protein Data Bank。它不是一种存储格式,它几乎就是结构生物学的标准语言。

我在项目里拿到的大部分晶体结构,甚至冷冻电镜的模型,源头都是 PDB 文件。你随便去 RCSB 网站下载一个 .pdb 文件,打开看看,会发现它其实是纯文本——说白了,就是一串固定长度的字符行。

4.1.1 核心结构:ATOM 记录

PDB 文件最核心的行,是 ATOM 开头的记录。每行固定 80 个字符,用列位置来分割信息。

我曾经为了在一个老旧脚本里硬解析 PDB,忘了列偏移,结果把原子序号和坐标读串了,折腾了一下午。所以,记住下面这个列位图,很有用。

COLUMNS        DATA  TYPE    FIELD          DEFINITION
-------------------------------------------------------------
 1 -  6        Record name   "ATOM  "
 7 - 11        Integer       serial         Atom serial number
13 - 16        Atom          name           Atom name
18 - 20        Residue name  resName        Residue name
22             Character     chainID        Chain identifier
23 - 26        Integer       resSeq         Residue sequence number
31 - 38        Real(8.3)     x              Orthogonal coordinates for X
39 - 46        Real(8.3)     y              Orthogonal coordinates for Y
47 - 54        Real(8.3)     z              Orthogonal coordinates for Z
55 - 60        Real(6.2)     occupancy      Occupancy
61 - 66        Real(6.2)     tempFactor     Temperature factor
77 - 78        LString(2)    element        Element symbol, right-justified
79 - 80        LString(2)    charge         Charge on the atom

这里有个坑:原子名(Atom name) 的对齐方式。你回想一下,主链的 Cα 原子,它写的是 " CA ",前后有空格的;而钙离子也是 "CA ",但位置不同。如果你按字符串直接对比,很容易匹配错。我建议直接用列区间取子串,别偷懒用 split()。

注意:不是所有 PDB 文件都严格遵循 80 列。有些软件生成的 PDB,在 79-80 列塞了多余信息,甚至把坐标扩展到 6 位小数。解析时最好做容错处理,或者用专业库(如 Biopython)读。

4.1.2 PDB 中的 RMSD 计算要点

用 PDB 做 RMSD 对齐时,我个人只关心 ATOM 记录。HETATM(配体、水分子)要不要对齐,取决于你的目标。

如果你是在对比蛋白骨架,那就只取 CA 原子。方法很简单:筛选出 ATOM 开头,且原子名为 CA 的行。

# Python 伪代码:从PDB提取CA坐标
for line in pdb_lines:
    if line.startswith("ATOM") and line[12:16].strip() == "CA":
        x = float(line[30:38])
        y = float(line[38:46])
        z = float(line[46:54])
        coordinates.append([x, y, z])

提取后,你就得到了一份只含主链骨架的坐标集,用来算 RMSD,又快又稳。


4.2 Mol2 格式:Sybyl 时代的“富容器”

Mol2 格式来自 Tripos 公司的 Sybyl 软件。它不像 PDB 那样纯线性,而是按块划分。每个块用 @<TRIPOS>XXXXXX 标识。

我记得第一次做小分子配体对接时,输出结果就是 Mol2 格式。里面不但有原子坐标,还能带上原子类型、形式电荷、键连接,甚至残基名称。

4.2.1 关键块结构

一个典型的 Mol2 文件,包含以下几个主要块。我建议你只关注 @<TRIPOS>MOLECULE、ATOM、BOND 这三个,其他如 SUBSTRUCTURE 对结构对齐没太大用处。

块标识内容重要性
@<TRIPOS>MOLECULE分子名、原子数、键数、类型必读
@<TRIPOS>ATOM原子序号、坐标、原子类型、残基名必读(核心)
@<TRIPOS>BOND键连接关系与键级推荐读
@<TRIPOS>SUBSTRUCTURE子结构定义与根原子可选

看一个 ATOM 块的示例。每行依次是:原子序号、x y z 坐标、原子类型、残基编号、残基名、形式电荷。

@<TRIPOS>ATOM
      1 C1         1.234   2.345   3.456 C.3        1 LIG     0.0000
      2 C2         2.345   3.456   4.567 C.2        1 LIG     0.0000
      3 N1         3.456   4.567   5.678 N.4        1 LIG     0.0000

实战经验:Mol2 的原子类型(如 C.3、C.2、N.4)比 PDB 的元素符号更精细。它直接告诉你杂化状态。做势能参数化或电荷分配时,这个信息比坐标本身还珍贵。我习惯把原子类型作为辅助字段写入自定义数据结构。

4.2.2 对齐前需要考虑的问题

Mol2 格式虽然信息丰富,但也有头痛的地方。不同分子里的原子序号不一定连续,而且残基名可能带不同前缀。你在做 RMSD 对齐前,最好是按原子序号或原子类型做一个映射,别直接按行号对比。


4.3 XYZ 格式:极简主义的“坐标快照”

如果你觉得 PDB 太啰嗦,Mol2 太复杂,那 XYZ 就是一股清流。

它啥也没有——就是原子符号和坐标。第一行是原子数,第二行是注释,后面行列式排开。说白了,就是一个列表。

4.3.1 标准格式

3
water molecule example
O  0.000   0.000   0.000
H  0.757   0.000   0.000
H -0.757   0.000   0.000

就这些,没了。

为什么会有人喜欢这个格式?因为它的 IO 开销最小。我在跑大规模构象搜索(比如用 CREST 或 xTB 扫上千个构象)时,生成 XYZ 文件几乎是瞬间的事。写脚本解析它也极其简单。

def read_xyz(filepath):
    with open(filepath) as f:
        lines = f.readlines()
    n_atoms = int(lines[0].strip())
    comment = lines[1].strip()
    atoms = []
    coords = []
    for i in range(2, 2 + n_atoms):
        parts = lines[i].split()
        atoms.append(parts[0])
        coords.append([float(x) for x in parts[1:4]])
    return atoms, coords, comment

简单归简单,它也有致命伤。

警告:XYZ 文件不记录键连接信息,也不记录电荷、多重度、原子类型。如果你想用 XYZ 做精准的 RMSD 对位,必须自己维护一套映射逻辑。我曾经用 XYZ 做轨迹分析,结果发现不同帧里原子顺序写错了,跑的 RMSD 全乱套了。

4.3.2 什么时候用 XYZ?

我的建议是:

  • 做轨迹对齐、批量构象比较时,优先用 XYZ。解析快,不占地方。
  • 需要保留键合信息或原子类型时,绝对别用 XYZ。请回头用 PDB 或 Mol2。

4.4 三种格式的对比与选择

你会问,这么多格式,到底用哪个?

我的建议是:以你最终 RMSD 对齐的目标来决定。下表供你快速决策。

特性PDBMol2XYZ
文件大小(同类复杂分子)大中小
是否记录键连接部分(CONECT)有(BOND)无
原子类型元素符号Sybyl 类型元素符号
形式电荷无(仅 PQR 扩展有)有无
残基/链信息完整残基名无
解析难度中(列对齐)中(块结构,行分割)低
RMSD 对齐适用场景蛋白-蛋白、蛋白-配体小分子比对、对接输出轨迹帧、批量构象

嗯,这些说完,我再给你看一张我整理的结构关系图。它能帮你快速回忆起什么时候该用哪种文件。

分子结构文件格式:起源、编码与核心属性 PDB 蛋白晶体学标准 Mol2 Sybyl 对接格式 XYZ 极简坐标快照 列对齐(ATC 格式) 固定 80 字符 / 行 列位 = 字段含义 块结构(Block) @<TRIPOS> 块分割 块内按行解析 行列式(Flat) 首行原子数,次行注释 后续行:符号 + 坐标 残基+链信息 蛋白骨架比对 原子类型+电荷 配体对接/优化 纯坐标 轨迹/构象批量比较 对应 RMSD 应用:蛋白-蛋白 → PDB;小分子对位 → Mol2;轨迹分析 → XYZ

这张图从左到右,你可以看到三个格式的出身、编码方式和在 RMSD 计算中的典型用法。我个人觉得,把这三种格式理解透了,你手里的分子结构文件,就再也不会出现格式信息丢失导致的 RMSD 偏差了。


总结性建议:

  • 如果你在做蛋白-蛋白、蛋白-配体复合物的结构比对:用 PDB,靠列取子串解析。
  • 如果你在操作小分子、对接后处理、或者需要原子类型和电荷信息:用 Mol2,按块读取。
  • 如果你在做构象搜索、轨迹后处理或高频 IO 批量对齐:用 XYZ,解析简单,速度快。
  • 在任何一种格式里,都留一手元数据映射——比如把 PDB 的 CA 原子编号、Mol2 的原子类型、XYZ 的原子顺序,跟你的目标 RMSD 参考构象先对齐一次,确认无误再跑。