Meeko 是 AutoDock 团队开发的 Python 工具,用于把配体和受体转换成 PDBQT 格式。它取代了依赖 Python 2 的老旧 MGLTools 脚本,是现在 Vina/AutoDock 流程的标准准备工具。
PDBQT 格式:为什么需要它
# PDBQT = PDB + Q(部分电荷)+ T(原子类型)
#
# 它比 PDB 多了两类信息:
# 1) 每个原子的部分电荷(Gasteiger 电荷)
# 2) AutoDock 的原子类型(区分芳香碳、氢键供受体等)
#
# 还多了柔性定义:
# ROOT / BRANCH / ENDBRANCH / TORSDOF
# → 定义了哪些键可以旋转,以及旋转的树状结构
#
# 这就是为什么不能简单用 OpenBabel 转格式:
# OpenBabel 能生成 PDBQT,但柔性树的定义
# 和原子类型分配可能与 AutoDock 的预期不一致
# → 建议用 Meeko(见 107 的对比)
#
# 注意:
# PDBQT 中氢原子被合并(非极性氢并入重原子)
# → 这是 AutoDock 的「united atom」处理
# → 只保留极性氢(连在 N、O 上的)
配体准备
pip install meeko
# 命令行:从 SDF(必须已含三维坐标与氢)
mk_prepare_ligand.py -i ligand.sdf -o ligand.pdbqt
# 批量处理多分子 SDF
mk_prepare_ligand.py -i ligands.sdf --multimol_outdir pdbqt_out/
# 大环化合物(见 098)
mk_prepare_ligand.py -i macrocycle.sdf -o out.pdbqt --macrocycle
# 保留特定键为刚性
mk_prepare_ligand.py -i lig.sdf -o out.pdbqt --rigid_macrocycles
# Python API(推荐用于流程集成)
from rdkit import Chem
from rdkit.Chem import AllChem
from meeko import MoleculePreparation, PDBQTWriterLegacy
mol = Chem.MolFromSmiles("CC(=O)Nc1ccc(O)cc1")
mol = Chem.AddHs(mol)
params = AllChem.ETKDGv3()
params.randomSeed = 0xf00d
AllChem.EmbedMolecule(mol, params)
AllChem.MMFFOptimizeMolecule(mol)
prep = MoleculePreparation()
setups = prep.prepare(mol)
for setup in setups:
pdbqt_string, ok, err = PDBQTWriterLegacy.write_string(setup)
if ok:
with open("ligand.pdbqt", "w") as f:
f.write(pdbqt_string)
else:
print("失败:", err)
准备配体时最容易犯的错
- 忘记生成三维坐标:Meeko 不做构象生成,输入必须已有三维坐标。从 SMILES 直接转会失败或给出平面结构;
- 忘记加氢:必须先
Chem.AddHs()再嵌入三维坐标,顺序反了会导致氢的位置错误; - 质子化态错误:Meeko 不改变输入的质子化态。羧酸应该是去质子的(COO⁻),碱性胺应该是质子化的(NH₃⁺)——这需要在准备 SDF 时用 Dimorphite-DL 等工具处理(见 046《分子标准化》);
- 立体化学丢失:从 SMILES 到三维时,未指定的手性中心会随机分配。应该明确指定或枚举所有立体异构体;
- 互变异构体:不同互变异构体的氢键供受体角色不同,会影响对接结果。
受体准备
# 新版 Meeko 提供受体准备工具
mk_prepare_receptor.py \
--read_pdb receptor_fixed.pdb \
-o receptor \
-p \
--box_center 11.2 23.4 -5.7 \
--box_size 22 22 22
# 参数说明:
# -p 输出 PDBQT
# --box_center 对接盒子中心
# --box_size 盒子尺寸(Å)
# → 同时生成 receptor.box.txt(Vina 配置文件)
# 用参考配体自动定盒子
mk_prepare_receptor.py \
--read_pdb receptor.pdb -o receptor -p \
--box_enveloping reference_ligand.sdf \
--padding 5.0
# 重要前提:
# 输入的 PDB 必须已经修复过(见 105)
# Meeko 不做补缺失残基、加氢等工作
#
# 标准流程:
# PDB 下载 → PDBFixer 修复 → PROPKA 定质子化态
# → Reduce 优化氢 → Meeko 转 PDBQT
柔性侧链
# 指定受体的某些侧链为柔性
mk_prepare_receptor.py \
--read_pdb receptor.pdb -o receptor -p \
--flexres "A:TYR:123,A:LEU:145"
# 输出两个文件:
# receptor_rigid.pdbqt 刚性部分
# receptor_flex.pdbqt 柔性侧链
# 对接时:
vina --receptor receptor_rigid.pdbqt \
--flex receptor_flex.pdbqt \
--ligand ligand.pdbqt ...
# 什么时候需要柔性侧链:
# - 已知某些残基在配体结合时会改变构象
# - 不同共晶结构中该侧链取向差异大
# - 口袋入口有「门控」残基
#
# 代价:
# 每个柔性侧链增加搜索空间
# → 通常最多指定 3~5 个,且要增大 exhaustiveness
# → 超过这个数量,搜索质量会明显下降
#
# 替代方案:
# 用多个受体构象做集合对接(ensemble docking)
# 构象来自不同的晶体结构或 MD 快照
# → 通常比柔性侧链更可靠
从 PDBQT 转回可用格式
# 对接结果是 PDBQT,需要转回 SDF 才能用 RDKit 分析
#
# 关键:直接用 OpenBabel 转会丢失键级信息
# (PDBQT 不含键级)
# → 芳香性、双键位置可能错误
#
# Meeko 的正确做法:用原始分子的模板恢复
from meeko import PDBQTMolecule, RDKitMolCreate
pdbqt_mol = PDBQTMolecule.from_file("docked.pdbqt", skip_typing=True)
rdkit_mols = RDKitMolCreate.from_pdbqt_mol(pdbqt_mol)
from rdkit import Chem
w = Chem.SDWriter("docked.sdf")
for m in rdkit_mols:
if m is not None:
w.write(m)
w.close()
# 命令行版本:
# mk_export.py docked.pdbqt -o docked.sdf
#
# 这一步很重要 —— 用错工具会得到化学上错误的分子
完整流程小结
| 步骤 | 工具 |
|---|---|
| 1. 修复蛋白 | PDBFixer(见 105《PDBFixer》) |
| 2. 质子化态 | PROPKA / PDB2PQR / Reduce |
| 3. 受体转 PDBQT | mk_prepare_receptor.py |
| 4. 配体标准化与质子化 | RDKit + Dimorphite-DL(见 046《分子标准化》) |
| 5. 生成三维构象 | RDKit ETKDG(见 279《OpenEye Omega》) |
| 6. 配体转 PDBQT | mk_prepare_ligand.py |
| 7. 对接 | Vina / GNINA |
| 8. 结果转 SDF | mk_export.py |
关键要点
- 必须先 AddHs 再生成三维坐标,顺序反了氢的位置会错;
- Meeko 不改变质子化态——羧酸/胺的电离状态要在准备 SDF 时处理好;
- 大环化合物必须加
--macrocycle,否则环的柔性被完全忽略; - 结果转回 SDF 要用 mk_export,用 OpenBabel 会丢失键级导致化学错误。
延伸资源
- PDBFixer:105《PDBFixer》;OpenBabel:107《OpenBabel 转格式》;
- Vina 1.2:098《AutoDock Vina 1.2》;实战:336《用 AutoDock Vina 跑 Docking》;构象生成:279《OpenEye Omega》。