第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 对齐的目标来决定。下表供你快速决策。
| 特性 | PDB | Mol2 | XYZ |
|---|---|---|---|
| 文件大小(同类复杂分子) | 大 | 中 | 小 |
| 是否记录键连接 | 部分(CONECT) | 有(BOND) | 无 |
| 原子类型 | 元素符号 | Sybyl 类型 | 元素符号 |
| 形式电荷 | 无(仅 PQR 扩展有) | 有 | 无 |
| 残基/链信息 | 完整 | 残基名 | 无 |
| 解析难度 | 中(列对齐) | 中(块结构,行分割) | 低 |
| RMSD 对齐适用场景 | 蛋白-蛋白、蛋白-配体 | 小分子比对、对接输出 | 轨迹帧、批量构象 |
嗯,这些说完,我再给你看一张我整理的结构关系图。它能帮你快速回忆起什么时候该用哪种文件。
这张图从左到右,你可以看到三个格式的出身、编码方式和在 RMSD 计算中的典型用法。我个人觉得,把这三种格式理解透了,你手里的分子结构文件,就再也不会出现格式信息丢失导致的 RMSD 偏差了。
总结性建议:
- 如果你在做蛋白-蛋白、蛋白-配体复合物的结构比对:用 PDB,靠列取子串解析。
- 如果你在操作小分子、对接后处理、或者需要原子类型和电荷信息:用 Mol2,按块读取。
- 如果你在做构象搜索、轨迹后处理或高频 IO 批量对齐:用 XYZ,解析简单,速度快。
- 在任何一种格式里,都留一手元数据映射——比如把 PDB 的 CA 原子编号、Mol2 的原子类型、XYZ 的原子顺序,跟你的目标 RMSD 参考构象先对齐一次,确认无误再跑。