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 会丢失键级导致化学错误。
延伸资源
- Vina 论文:097《AutoDock Vina 论文精读》;Vina 1.2:098《AutoDock Vina 1.2》;实战:336《用 AutoDock Vina 跑 Docking》;
- Meeko:106《Meeko》;PDBFixer:105《PDBFixer》;GNINA 教程:016《GNINA 教程》。