PDBQT 是 AutoDock 系列专用的格式,包含原子类型、部分电荷和可旋转键定义。Meeko(见 214《Meeko》)负责这个转换。它只做格式转换——不生成构象、不修复结构、不判断质子化态,这些都要你事先做对。
安装
pip install meeko rdkit
mk_prepare_ligand.py --help
mk_prepare_receptor.py --help
mk_export.py --help
配体准备:完整链路
from rdkit import Chem
from rdkit.Chem import AllChem
def smiles_to_3d_sdf(smiles, out_path, seed=0xf00d):
"""SMILES → 3D SDF,这是 Meeko 的输入"""
mol = Chem.MolFromSmiles(smiles)
if mol is None:
return False
mol = Chem.AddHs(mol)
params = AllChem.ETKDGv3()
params.randomSeed = seed # 固定种子保证可复现
if AllChem.EmbedMolecule(mol, params) != 0:
# 嵌入失败时放宽条件重试
params.useRandomCoords = True
if AllChem.EmbedMolecule(mol, params) != 0:
return False
AllChem.MMFFOptimizeMolecule(mol, maxIters=2000)
Chem.MolToMolFile(mol, out_path)
return True
smiles_to_3d_sdf("CC(=O)Nc1ccc(O)cc1", "ligand.sdf")
# 转 PDBQT
mk_prepare_ligand.py -i ligand.sdf -o ligand.pdbqt
# 批量:多分子 SDF 拆成多个 PDBQT
mk_prepare_ligand.py -i library.sdf --multimol_outdir pdbqt/
# 大环柔性(对接大环化合物时必须开)
mk_prepare_ligand.py -i macrocycle.sdf -o out.pdbqt --macrocycle
Python API:适合嵌进批量流程
from meeko import MoleculePreparation, PDBQTWriterLegacy
from rdkit import Chem
from rdkit.Chem import AllChem
import os
def prepare_ligand(smiles, name, outdir="pdbqt", seed=0xf00d):
os.makedirs(outdir, exist_ok=True)
mol = Chem.MolFromSmiles(smiles)
if mol is None:
return None, "parse_failed"
mol = Chem.AddHs(mol)
p = AllChem.ETKDGv3(); p.randomSeed = seed
if AllChem.EmbedMolecule(mol, p) != 0:
return None, "embed_failed"
AllChem.MMFFOptimizeMolecule(mol)
prep = MoleculePreparation(rigid_macrocycles=False)
setups = prep.prepare(mol)
if not setups:
return None, "prep_failed"
pdbqt, ok, err = PDBQTWriterLegacy.write_string(setups[0])
if not ok:
return None, f"write_failed:{err}"
path = os.path.join(outdir, f"{name}.pdbqt")
open(path, "w").write(pdbqt)
return path, None
# 批量处理并统计失败
from collections import Counter
fails = Counter()
for i, (smi, name) in enumerate(zip(df["smiles"], df["name"])):
path, err = prepare_ligand(smi, name)
if err:
fails[err] += 1
print("失败统计:", fails)
受体准备
# 先用 PDBFixer 修复(见 340),再转 PDBQT
mk_prepare_receptor.py -i receptor_fixed.pdb -o receptor -p \
--box_center 11.2 23.4 -5.7 --box_size 22 22 22
# 输出 receptor.pdbqt 及可选的盒子配置文件
结果回读:不要跳过这一步
# PDBQT 格式丢失了键级信息!
# 直接用对接输出的 PDBQT 做后续分析会出错
mk_export.py docking_out.pdbqt -s docked.sdf
# 或在 Python 中
from meeko import PDBQTMolecule, RDKitMolCreate
pdbqt_mol = PDBQTMolecule.from_file("docking_out.pdbqt", skip_typing=True)
rdkit_mols = RDKitMolCreate.from_pdbqt_mol(pdbqt_mol)
for m in rdkit_mols:
print(Chem.MolToSmiles(m)) # 键级正确还原
这一步经常被忽略但很重要:PDBQT 不含键级信息,直接拿它做相互作用分析、MD 或绘图,芳香性和键级判断都会出错。用 mk_export 借助原始分子的化学信息还原成 SDF,才能安全进入下游。
最容易出错的化学细节
| 问题 | 后果 | 解决 |
|---|---|---|
| 质子化态错误 | 静电互补完全错误 | 用 Dimorphite-DL 等按 pH 7.4 预处理 |
| 互变异构体 | 氢键供受体模式改变 | 事先枚举并决定用哪个 |
| 立体化学缺失 | 构象与参数分配出错 | SMILES 中写明手性 |
| 大环当刚性处理 | 低估柔性,姿势错误 | 加 --macrocycle |
| 从 PDB 读小分子 | 键级推断错误 | 始终用 SDF 或 SMILES |
| 金属离子丢失 | 金属酶对接完全失真 | 受体中保留并正确设置类型 |
质子化态预处理
# Dimorphite-DL:按 pH 枚举质子化状态
pip install dimorphite-dl
from dimorphite_dl import DimorphiteDL
dim = DimorphiteDL(min_ph=6.4, max_ph=8.4, pka_precision=1.0)
for smi in ["CC(=O)O", "CCN", "c1cc[nH]c1"]:
states = dim.protonate(smi)
print(smi, "→", states)
# 输出可能有多个状态。策略:
# - 取主导状态(多数情况)
# - 或全部对接,取最优(更严谨但成本高)
常见坑与提示
- Meeko 只做格式转换——构象、质子化态、立体化学都要事先做对;
- 输入用 SDF/SMILES 而非 PDB,保证键级明确;
- 对接完务必用
mk_export转回 SDF,PDBQT 丢了键级信息; - 大环加
--macrocycle;金属酶注意保留并正确设置金属离子。