341

用 Meeko 准备 Docking 文件:PDBQT 文件怎么生成

Meeko 把配体与受体转成 Vina 所需的 PDBQT。这篇给出完整命令与 API 用法,以及配体准备中最容易出错的化学细节。

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;金属酶注意保留并正确设置金属离子。

延伸资源