4. Python 调用 Vina:subprocess 与 meeko 的基本用法
说实话,很多人刚开始做分子对接,习惯手工敲命令行。一个一个跑,一次一次等。我一开始也是这么干的,直到有一天我需要跑 200 个配体……嗯,从那天起,我就再也没手动敲过 Vina 命令行。
这一章,我们就聊聊怎么用 Python 把 Vina 管起来。你想想看,自动化之后,参数调试的效率完全不一样。
4.1 subprocess:最直接的调用方式
Python 的 subprocess 模块,说白了就是让你能在 Python 里执行外部命令。Vina 本身就是个命令行工具,所以这个组合特别自然。
先看一个最基本的例子:
import subprocess
cmd = [
"vina",
"--receptor", "receptor.pdbqt",
"--ligand", "ligand.pdbqt",
"--out", "output.pdbqt",
"--center_x", "0.0",
"--center_y", "0.0",
"--center_z", "0.0",
"--size_x", "20",
"--size_y", "20",
"--size_z", "20",
"--exhaustiveness", "8"
]
result = subprocess.run(cmd, capture_output=True, text=True)
print(result.stdout)
4.2 捕获输出与解析结果
跑完对接,结果怎么拿?Vina 会把对接结果打印到标准输出,同时也写入输出文件。两种方式我都用过,但实际项目里我更推荐解析输出文件。
为什么?
# 来看看标准输出长什么样
result = subprocess.run(cmd, capture_output=True, text=True)
print(result.stderr) # Vina 的进度信息在这里
print(result.stdout) # 最终打分信息在这里
但 stdout 的格式不太稳定。不同版本的 Vina 输出格式可能微调。所以我一般这么做:
def parse_vina_score(pdbqt_file):
"""从 Vina 输出 PDBQT 中提取打分"""
scores = []
with open(pdbqt_file, 'r') as f:
for line in f:
if line.startswith('REMARK VINA RESULT:'):
parts = line.split()
# 格式: REMARK VINA RESULT: -9.5 0.0 0.0
score = float(parts[3])
scores.append(score)
return scores
REMARK VINA RESULT: 行可能有多个(多构象)。解析时记得循环全部找出来,别只读第一行。
4.3 批量处理的思路
单个文件没问题了,批量就好办了。我在项目中遇到过需要跑 1000+ 配体的场景,那时我是这样组织的:
import glob
ligands = glob.glob("ligands/*.pdbqt")
results = []
for lig in ligands:
out_file = f"results/{lig.split('/')[-1]}"
cmd = [
"vina",
"--receptor", "receptor.pdbqt",
"--ligand", lig,
"--out", out_file,
# ... 其他参数
]
subprocess.run(cmd, check=True)
scores = parse_vina_score(out_file)
results.append((lig, scores[0] if scores else None))
你想想看,这样一遍跑下来,所有打分都收集好了。再配个 pandas 导出 CSV,汇报数据直接就能用。
4.4 meeko 库:更优雅的配体准备
subprocess 虽然直接,但有个麻烦——配体得先转成 PDBQT。Vina 自带的 prepare_ligand4.py 脚本跑起来有点慢,而且对 SDF 格式支持不够好。
meeko 库就是来解决这个问题的。我第一次用 meeko 的时候,最惊艳的是它可以直接从 SDF 文件生成带构象的 PDBQT。省了 MGLTools 那套流程。
4.5 meeko 的基本用法
安装很简单:
pip install meeko
核心用法分三步:
from meeko import MoleculeSetup
# 1. 加载配体
setup = MoleculeSetup.from_sdf("ligand.sdf")
# 2. 生成可旋转键和构象
setup.expand_protonation_states()
setup.generate_conformers(n_conformers=10)
# 3. 写出 PDBQT
pdbqt_string = setup.write_pdbqt_string("ligand_output.pdbqt")
n_conformers 设 10-20 个就够了。太多反而增加对接时间,打分提升不明显。
4.6 meeko 与 Vina 的整合
meeko 最有价值的地方,是它内置了对接调用的高层接口。你可以直接这么用:
from meeko_docking import MeekoDocking
docking = MeekoDocking(
receptor="receptor.pdbqt",
center=(0.0, 0.0, 0.0),
box_size=(20, 20, 20),
exhaustiveness=8
)
results = docking.dock_from_sdf("ligands.sdf")
for res in results:
print(f"Ligand: {res.ligand_name}, Score: {res.score}")
嗯,这里要说明一下,meeko_docking 的接口还在迭代。我建议你还是以官方文档为准,但基本原理就是这样——它帮我们把 subprocess 那套流程封装了。
4.7 subprocess vs meeko:怎么选?
做一个简单对比,方便你选:
| 维度 | subprocess | meeko |
|---|---|---|
| 输入格式 | 需要 PDBQT | 直接支持 SDF/SMI |
| 配体准备 | 自己额外处理 | 内置 |
| 批量处理 | 灵活,自由控制 | 方便,但自由度稍低 |
| 参数调试 | 完全手动控制 | 通过参数对象控制 |
| 学习成本 | 低 | 中(需了解 meeko 内部逻辑) |
我个人的建议是:如果只是简单测试两个配体,subprocess 完全够用。但如果要做批量筛选、参数优化,meeko 能省不少代码。
4.8 实际项目中的避坑指南
最后分享几个我踩过的坑:
- 路径问题:Vina 执行路径最好用绝对路径,或者确保在 PATH 里。我曾经被相对路径坑过一次,脚本在 IDE 里能跑,部署到服务器就找不到了。
- 资源限制:并行跑 Vina 时注意 CPU 核数。subprocess 不会自动限流,我建议用
multiprocessing.Pool控制并发数,避免把服务器跑挂。 - meeko 版本兼容:meeko 更新较快,不同版本 API 可能有变化。建议在项目里固定版本号,比如
meeko==0.3.1。 - 大文件处理:如果配体 SDF 文件特别大(上万分子),不要一次全部读进内存。用 meeko 的生成器模式
docking.dock_from_sdf_generator(),按批次处理。
核心要点:
- subprocess 适合简单直接的单次或小批量调用
- meeko 更适合大批量、复杂配体处理的场景
- 解析结果时,文件解析比 stdout 解析更稳定
- 批量处理一定要加并发控制,别让进程数超过 CPU 核心数
说白了,工具是死的,用活才是关键。subprocess 和 meeko 各有所长,理解了它们的原理,你就能根据项目需求灵活搭配。我自己做参数调试的时候,经常是 meeko 准备配体、subprocess 做精细控制,两者配合着用。