017

AutoDock Vina 教程:免费 Docking 工具的核心用法

AutoDock Vina 是最常用的免费对接工具。这篇给出从零开始的完整流程与关键参数。

AutoDock Vina 是使用最广泛的免费对接软件。它的核心用法并不复杂——但真正决定结果质量的是准备工作与验证,而非对接本身。这篇按实际流程给出完整的操作路径。

完整流程概览

步骤 工具 耗时占比
1. 蛋白结构修复 PDBFixer(见 105《PDBFixer》
2. 质子化态确定 PROPKA / Reduce
3. 受体转 PDBQT Meeko(见 106《Meeko》
4. 配体准备 RDKit + Dimorphite-DL
5. 配体转 PDBQT Meeko
6. 重对接验证 Vina 必做
7. 对接 Vina 取决于规模
8. 结果转回 SDF Meeko mk_export
9. 后处理与验证 PoseBusters、PLIP

注意时间分配:真正跑 Vina 的时间可能只占 10%,准备与验证占大部分。新手常常低估这一点。

准备工作

# ---- 安装 ----
pip install vina meeko pdbfixer
# 或 conda install -c conda-forge vina meeko

# ---- 1) 蛋白修复 ----
from pdbfixer import PDBFixer
from openmm.app import PDBFile

fixer = PDBFixer(filename="4xyz.pdb")
fixer.findMissingResidues()
# 【删除末端缺失,只补中间的 loop】
chains = list(fixer.topology.chains())
for key in list(fixer.missingResidues.keys()):
    chain = chains[key[0]]
    if key[1] == 0 or key[1] == len(list(chain.residues())):
        del fixer.missingResidues[key]

fixer.findNonstandardResidues()
fixer.replaceNonstandardResidues()
fixer.removeHeterogens(keepWater=False)   # 【注意:可能需要保留关键水】
fixer.findMissingAtoms()
fixer.addMissingAtoms()
fixer.addMissingHydrogens(pH=7.4)
PDBFile.writeFile(fixer.topology, fixer.positions,
                  open("receptor_fixed.pdb", "w"))

# ---- 2) 受体转 PDBQT ----
# mk_prepare_receptor.py --read_pdb receptor_fixed.pdb \
#   -o receptor -p --box_enveloping crystal_ligand.sdf --padding 5

# ---- 3) 配体准备(【最容易出错的部分】)----
from rdkit import Chem
from rdkit.Chem import AllChem
from meeko import MoleculePreparation, PDBQTWriterLegacy

def prepare_ligand(smiles, out_path, seed=0xf00d):
    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:
        return False
    AllChem.MMFFOptimizeMolecule(mol)

    prep = MoleculePreparation()
    for setup in prep.prepare(mol):
        pdbqt, ok, err = PDBQTWriterLegacy.write_string(setup)
        if ok:
            open(out_path, "w").write(pdbqt)
            return True
    return False

# 【配体准备的检查清单】:
#   □ 质子化态正确吗?(羧酸去质子、胺质子化)
#     → 用 Dimorphite-DL 处理
#   □ 立体化学指定了吗?未指定的会随机分配
#   □ 互变异构体考虑了吗?
#   □ 三维构象生成成功了吗?
#   □ 大环化合物加了 --macrocycle 吗?

重对接验证:必做的第一步

# 【在对新分子做对接之前,必须先验证流程】

from vina import Vina
from rdkit import Chem
from rdkit.Chem import rdMolAlign

v = Vina(sf_name="vina", cpu=8, seed=42)
v.set_receptor("receptor.pdbqt")
v.compute_vina_maps(center=[11.2, 23.4, -5.7], box_size=[22, 22, 22])

v.set_ligand_from_file("crystal_ligand.pdbqt")
v.dock(exhaustiveness=32, n_poses=9)
v.write_poses("redock.pdbqt", n_poses=9, overwrite=True)

# 转回 SDF 并算 RMSD
# mk_export.py redock.pdbqt -o redock.sdf

ref = Chem.RemoveHs(Chem.SDMolSupplier("crystal_ligand.sdf")[0])
for i, mol in enumerate(Chem.SDMolSupplier("redock.sdf")):
    if mol:
        print(f"姿势 {i+1}: RMSD = "
              f"{rdMolAlign.CalcRMS(Chem.RemoveHs(mol), ref):.2f} Å")

# 【判据】:top-1 RMSD ≤ 2 Å
#
# 【失败时的排查顺序】:
#   1) 盒子是否覆盖整个结合位点?(先放大试试)
#   2) 质子化态对吗?尤其 His(见 105)
#   3) 删掉了必要的辅因子、金属或关键水吗?
#   4) 配体的立体化学与互变异构体对吗?
#   5) exhaustiveness 够大吗?(试 64)
#   6) 这个口袋是否高度柔性?(考虑集合对接)

批量对接(Python API)

from vina import Vina
import glob, os, json

v = Vina(sf_name="vina", cpu=8, seed=42, verbosity=0)
v.set_receptor("receptor.pdbqt")

# 【关键优化:格点只算一次,所有配体复用】
v.compute_vina_maps(center=[11.2, 23.4, -5.7], box_size=[22, 22, 22])

results = []
for path in sorted(glob.glob("ligands_pdbqt/*.pdbqt")):
    name = os.path.basename(path)[:-6]
    try:
        v.set_ligand_from_file(path)
        v.dock(exhaustiveness=16, n_poses=5)
        energies = v.energies()
        results.append({"name": name, "score": float(energies[0][0])})
        v.write_poses(f"out/{name}.pdbqt", n_poses=3, overwrite=True)
    except Exception as e:
        results.append({"name": name, "score": None, "error": str(e)})

json.dump(results, open("results.json", "w"), indent=2)

# 【为什么用 API 而非命令行】:
#   命令行每次调用都重算格点
#   → 十万级筛选时差异很可观(见 098)

关键参数与常见问题

参数/问题 说明
exhaustiveness 筛选 8~16,精确 32~64;线性影响耗时
盒子尺寸 覆盖口袋 + 配体最大尺寸;太大搜索效率降低
seed 必须固定,否则结果不可复现
打分函数 vina / vinardo / ad4——在自家体系上比较后选
分数偏好大分子 用配体高效性纠正(见 095《Docking Score》
配体准备失败 检查立体化学、大环、异常价态
结果转 SDF 用 mk_export,不要用 OpenBabel(会丢键级)

结果的正确解读

  • Vina 分数不是亲和力:它是经验拟合的值,与实测活性的相关性有限(见 095《Docking Score》);
  • 对接是筛子不是尺子:擅长把十万缩到几百,不擅长告诉你哪个更强;
  • 必须用配体高效性比较不同大小的分子LE = -score / 重原子数
  • 姿势比分数更有信息量:看它是否复现了关键相互作用(见 108《PLIP》);
  • 后处理不可省:PoseBusters 检查 + 相互作用核对 + 人工审查。

关键要点

  • 准备与验证占大部分时间,真正跑 Vina 只占很小一部分;
  • 重对接验证(RMSD ≤ 2 Å)是使用前的必做步骤
  • 用 Python API 复用格点,批量筛选时能省大量时间;
  • 结果转回 SDF 必须用 mk_export——OpenBabel 会丢失键级导致化学错误。

延伸资源