第3章 分子文件格式转换概述:SDF、MOL2、PDB、PDBQT的差异及转换原则
做计算化学的人,手里最常打交道的就是这些分子文件。我自己折腾过的项目不下上百个,遇到过最头疼的事——明明是同一个分子,换了个格式读进去,原子对不上了,电荷跑偏了,键序也没了。嗯,说白了,格式之间那点“隐藏规则”,才是坑的地方。
这一章我先带你快速扫一遍SDF、MOL2、PDB、PDBQT四种格式长什么样,各自记什么、不记什么。然后再聊转换时的基本规则——怎么把数据搬过去还能保持物理意义不变。
格式差异:它们到底存了什么?
你想象一下,每个分子文件就是一张卡片。有些卡片画了键,有些只标了坐标;有些写了原子类型,有些留空。我列了一张对比表,核心差异一目了然。
| 特性 | SDF | MOL2 | PDB | PDBQT |
|---|---|---|---|---|
| 原子坐标 | 3D / 2D | 3D | 3D(Å) | 3D(Å) |
| 键信息 | 完整键表 + 键序 | 完整键表 + 键类型 | 无(可推算残基连接) | 无(使用AutoDock内置键搜索) |
| 原子类型 | 元素符号 | Sybyl原子类型 | 元素符号 + 残基名 | AutoDock类型 + 部分电荷 |
| 电荷 | 可选(字段内) | 每个原子带部分电荷 | 无 | 每个原子带Gasteiger电荷 |
| 可旋转键标记 | 无 | 无 | 无 | 有(ROT表) |
| 官能团/残基 | 无 | 无 | 残基名 + 链号 | 无 |
我的经验:SDF 和 MOL2 是配体转换的“好上游”,因为键信息完整。PDB 更适合蛋白骨架,PQR 格式才带电荷,PDBQT 是 AutoDock 的“特供”,少了键表但多了可旋转键标记。
光看表还不够。我拿一个苯环举个例子,看看同一个分子在不同格式下怎么写。
SDF 格式:带键表的瑞士军刀
SDF(Structure Data File)其实是 mol 文件的“增强版”——核心是一个 mol 块,后面可以跟自定义数据字段。mol 块里面原子块和键块是分开写的。我个人习惯用SDF做配体存储,因为它能同时保留下坐标、键序、还有库里的额外信息(比如名字、SMILES)。
Molfile block example for benzene (C6H6)
-OEChem-01302023003D
6 6 0 0 0 0 0 0 0999 V2000
1.3983 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.6991 1.2103 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-0.6991 1.2103 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-1.3983 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
-0.6991 -1.2103 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.6991 -1.2103 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1 2 2 0 0 0 0
2 3 1 0 0 0 0
3 4 2 0 0 0 0
4 5 1 0 0 0 0
5 6 2 0 0 0 0
6 1 1 0 0 0 0
M END
注意那个键块里第三列的数字:2代表双键,1代表单键。这在后面转成PDBQT时,AutoDock需要根据键序推断哪些单键可旋转。
MOL2 格式:自带原子类型和部分电荷
MOL2 是 Sybyl 软件的老格式。它把原子、键、以及每个原子的类型写在一起。一个很大的好处是——它明确表达了原子杂化状态。举个例子,sp² 碳和 sp³ 碳在 MOL2 里是不同的类型(C.2 vs C.3)。
@<TRIPOS>MOLECULE
benzene
6 6 1 0 0
SMALL
GASTEIGER
@<TRIPOS>ATOM
1 C1 1.3983 0.0000 0.0000 C.2 1 BENZENE 0.0000
2 C2 0.6991 1.2103 0.0000 C.2 1 BENZENE 0.0000
3 C3 -0.6991 1.2103 0.0000 C.2 1 BENZENE 0.0000
4 C4 -1.3983 0.0000 0.0000 C.2 1 BENZENE 0.0000
5 C5 -0.6991 -1.2103 0.0000 C.2 1 BENZENE 0.0000
6 C6 0.6991 -1.2103 0.0000 C.2 1 BENZENE 0.0000
@<TRIPOS>BOND
1 1 2 ar
2 2 3 ar
3 3 4 ar
4 4 5 ar
5 5 6 ar
6 6 1 ar
最后一列“0.0000”是部分电荷(这里用的是 Gasteiger 电荷)。你看,它的键类型用“ar”表示芳香键——这个信息在转换时很有用,因为 AutoDock 需要区分芳香碳和脂肪碳。
我曾经把一个MOL2文件的Gasteiger电荷直接复制到PDBQT,结果对接能量差了一大截。后来才发现MOL2里默认电荷单位是原子单位,PDBQT需要按e⁻(电子电荷)来写——其实是一样的,但精度差两位小数就会让对接结果乱跳。一定要用整数化后的电荷(乘1000取整)。
PDB 格式:蛋白世界的通用语言
PDB 当初是为蛋白质晶体结构设计的,所以它的世界观是“残基 + 原子名”。一个配体分子在PDB里通常写成HETATM记录。PDB格式最大的缺陷:它不记键,不记电荷,甚至氢原子都常常缺失。
HETATM 1 C1 LIG 1 1.398 0.000 0.000 1.00 0.00 C
HETATM 2 C2 LIG 1 0.699 1.210 0.000 1.00 0.00 C
HETATM 3 C3 LIG 1 -0.699 1.210 0.000 1.00 0.00 C
HETATM 4 C4 LIG 1 -1.398 0.000 0.000 1.00 0.00 C
HETATM 5 C5 LIG 1 -0.699 -1.210 0.000 1.00 0.00 C
HETATM 6 C6 LIG 1 0.699 -1.210 0.000 1.00 0.00 C
END
做对接的时候,很多工具拿PDB读配体——但缺失键信息,就得依赖原子间距离去“猜”键。有时距离阈值设错,苯环的六个碳会连成一条线。所以我的建议是:尽量别直接从PDB转PDBQT,除非你清楚知道编辑器已经补了键。
PDBQT 格式:AutoDock 的专属名片
PDBQT 全称 Protein Data Bank, Partial Charge (Q) & Atom Type (T)。它继承PDB的行格式,但加了两个新列:原子类型(比如C、A、HD、OA等)和部分电荷(整数化后写的,单位是千分之一电子电荷)。另外在文件末尾用ROTATABLE BONDS区块记录哪些单键可旋转。
HETATM 1 C1 LIG 1 1.398 0.000 0.000 0.000 0.00 0.0000 0.0000 0.0000 C 0
HETATM 2 C2 LIG 1 0.699 1.210 0.000 0.000 0.00 0.0000 0.0000 0.0000 C 0
HETATM 3 C3 LIG 1 -0.699 1.210 0.000 0.000 0.00 0.0000 0.0000 0.0000 C 0
HETATM 4 C4 LIG 1 -1.398 0.000 0.000 0.000 0.00 0.0000 0.0000 0.0000 C 0
HETATM 5 C5 LIG 1 -0.699 -1.210 0.000 0.000 0.00 0.0000 0.0000 0.0000 C 0
HETATM 6 C6 LIG 1 0.699 -1.210 0.000 0.000 0.00 0.0000 0.0000 0.0000 C 0
END
ROTATABLE BONDS
BRANCH 1 2
BRANCH 2 1
BRANCH 3 4
BRANCH 4 3
BRANCH 5 6
BRANCH 6 5
ENDROT
你仔细看——PDBQT里没有键表,但AutoDock在运行时收到文件后会做一套自己的键等价划分。所以PDBQT转换最关键的一步是:正确分配原子类型。比如一个sp²碳应该写成C(芳香碳),而不是A(脂肪碳)。我曾经因为把苯环碳标成了A,对接时程序把它当成可旋转的烷基链,自由度算错了一大堆。
转换原则:怎么搬才不翻车?
不管从哪种格式转到PDBQT,有几个原则你最好刻在脑子里。我把它们总结成五条。
- 原子类型映射:SDF/MOL2里的元素符号要映射到AutoDock的原子类型(C、A、N、O、S、H、HD、HA等)。芳香碳是A,脂肪碳是C,这部分我自己会写一个查表脚本。
- 电荷计算与整数化:PDBQT要求电荷写成千分之一电子电荷单位的整数。Gasteiger电荷是最常用的方法,但要注意MOL2自带的部分电荷可能已经是半经验值,不能直接照搬。
- 键信息重建:如果源文件没有键表(比如PDB),需要根据距离+元素类型+可能的手性推算。这步最容易出错。
- 可旋转键的确定:对于配体,主链上只含单键且非环的非末端键才可旋转。AutoDock的算法会把键分成ROT与ROT-Free,你需要确保ROTATABLE BONDS区域正确。
- 加氢处理:PDBQT里的配体一般要有氢原子。SDF/MOL2可能自带氢,也可能没有。别忘了加氢,否则对接时有些氢键位点会丢失。
避坑指南:我最开始做转换时,总以为把SDF读入Open Babel直接输出PDBQT就完事了。结果有次对接一个含手性中心的配体,发现镜像构象的能量反而更低——后来排查发现,Open Babel在加氢时默认加了极性H但没加非极性H,导致手性中心附近的立体化学信息丢失。从那以后我养成了一个习惯:先用保立体的工具(如RDKit)加氢,再转PDBQT。
知识结构图:四种格式的转换关系
下面这张SVG图帮你把四种格式之间的转换方向、关键步骤和注意点画在一个图里。本质上讲,转换是“信息增减”的过程——你从信息丰富的格式(SDF/MOL2)向信息精简的格式(PDBQT)走时,必须自己补上缺失的信息。
转换路线图:实际项目中怎么走?
我按经验给一条最稳的流程。你拿到一个SDF配体文件,想做成PDBQT做分子对接——不走弯路。
- 输入检查:看看SDF里有没有氢原子。没有?先加氢(立体化学正确)。
- 读取键表:从mol块里提取所有键序。注意芳香键通常被写成4或5,要转换成AutoDock能识别的状态。
- 分配原子类型:写一个查表字典,比如sp²碳→A,sp³碳→C,羟基氧→OA,等等。这一步我一般用Open Babel的
obabel命令,但需要后处理校验。 - 电荷计算:用Gasteiger电荷。推荐用RDKit的
rdkit.Chem.AllChem.ComputeGasteigerCharges,结果乘以1000取整。保存到PDBQT的charge列。 - 确定可旋转键:遍历键表,排除环内键、双键、三键、末端的单键(比如甲基上的C-H键)。剩下的就是可旋转键。
- 生成PDBQT文件:按标准格式写ATOM/HETATM记录,然后在文件末尾写ROTATABLE BONDS表。
一个小窍门:如果你只是做快速批量转换,用meeko(一个专门配体准备的工具)自动生成PDBQT,它会处理电荷和可旋转键。但手动控制场景(比如特定原子类型修正),还是写脚本更可控。