4. 盒子(Box)设置:grid中心与尺寸确定、Autodock Tools与脚本方法
盒子设置这一步,说白了就是画一个虚拟的“搜索笼子”。
Vina只会在你指定的这个三维空间里寻找配体的结合姿势。笼子画歪了、画小了,哪怕你的蛋白质结构再准、对接参数再牛,结果也基本是废的。我早期做虚拟筛选时,就因为盒子偏了2 Å,导致一整个批次的阳性化合物全都没对接上——那次教训挺深刻的。
4.1 盒子的核心参数:中心坐标与尺寸
盒子由两组参数决定:center_x, center_y, center_z(中心坐标)和 size_x, size_y, size_z(边长,单位Å)。Vina会在以中心为球心、各边半长为半径的立方体区域内采样。
| 参数 | 含义 | 典型取值范围 |
|---|---|---|
| center_x/y/z | 盒子几何中心的笛卡尔坐标 | 取决于受体在PDB文件中的位置 |
| size_x/y/z | 盒子各轴向的边长(Å) | 15~30(刚性对接)或覆盖整个活性位点 |
4.2 用AutoDock Tools (ADT) 可视化设置盒子
对于单个体系,ADT是最直观的方式。你想想看,鼠标点几下就能看到盒子框在哪,心里踏实很多。
- 启动ADT,加载受体PDB文件:
File → Read Molecule。 - 加氢、合并非极性氢(虽然Vina不需要ADT的pdbqt,但为了可视化,这一步建议做)。
- 找到配体或已知共晶配体,用它来定位盒子中心。
- 点击
Grid → Macromolecule → Choose,选择受体。 - 再点击
Grid → Set Grid,弹出盒子参数面板。 - 在面板里,直接拖动盒子边缘的彩色箭头,或者手动输入 Spacing (Å) 和 Number of points。
这里有个换算关系要记住:
size_Å = (number_of_points - 1) × spacing
默认 spacing 是 1.0 Å,Number 默认是 40,算出来 size = 39 Å。这个尺寸偏大,对大多数活性位点来说足够了,但跑起来会慢。我一般会把 spacing 改成 0.375 Å(接近Vina默认格点间距),然后把 Number 调成使 size 在 20~25 Å之间。
4.3 从ADT导出盒子配置(GPF文件)
ADT能把盒子参数保存为Grid Parameter File(.gpf)。
操作路径:Grid → File → Save GPF
生成的 .gpf 长这样:
npts 40 40 40
gridfld 1abc_receptor.maps.fld
spacing 1.0
receptor_types A C HD N OA
ligand_types A C HD N OA P SA
receptor 1abc_receptor.pdbqt
gridcenter 12.345 67.890 34.567
smooth 0.5
map 1abc_receptor.A.map
map 1abc_receptor.C.map
map 1abc_receptor.HD.map
map 1abc_receptor.N.map
map 1abc_receptor.OA.map
map 1abc_receptor.P.map
map 1abc_receptor.SA.map
elecmap 1abc_receptor.e.map
dielectric -0.1465
注意 gridcenter 那行,就是我们要的中心坐标。Vina 的 center_x/y/z 直接从这个字段读取就行。
4.4 用脚本方法批量计算盒子参数
我目前做高吞吐量筛选时,已经完全放弃GUI了。全流程脚本化,盒子参数也从已知共晶配体的坐标直接算出来。下面是Python伪代码的思路,你可以套用到自己的数据上。
import re
import numpy as np
def parse_ligand_coords(pdb_file):
"""
读取配体的所有原子坐标,返回N×3数组。
"""
atoms = []
with open(pdb_file, 'r') as f:
for line in f:
if line.startswith('ATOM') or line.startswith('HETATM'):
x = float(line[30:38])
y = float(line[38:46])
z = float(line[46:54])
atoms.append([x, y, z])
return np.array(atoms)
def compute_box_center(coords):
"""
几何中心 = 各轴最小最大值的中间点。
为什么要这样?因为配体可能不在原点附近。
"""
min_xyz = coords.min(axis=0)
max_xyz = coords.max(axis=0)
center = (min_xyz + max_xyz) / 2.0
return center
def compute_box_size(coords, margin=4.0):
"""
基于配体范围+余量,算出size。
margin 是各边额外加的Å,保证盒子覆盖整个活性位点边缘。
"""
min_xyz = coords.min(axis=0)
max_xyz = coords.max(axis=0)
size = (max_xyz - min_xyz) + 2 * margin
return size
# 使用示例
coords = parse_ligand_coords('ligand.pdb')
center = compute_box_center(coords)
size = compute_box_size(coords, margin=4.0)
print(f"Box center: {center[0]:.3f} {center[1]:.3f} {center[2]:.3f}")
print(f"Box size: {size[0]:.1f} {size[1]:.1f} {size[2]:.1f}")
这段代码输出后,直接塞进Vina的配置文件里:
receptor = receptor.pdbqt
ligand = ligand.pdbqt
center_x = 12.345
center_y = 67.890
center_z = 34.567
size_x = 20.0
size_y = 20.0
size_z = 20.0
exhaustiveness = 8
num_modes = 5
out = output.pdbqt
4.5 盒子中心确定的两条实用原则
- 已知共晶配体法:如果有共晶结构,直接用配体的质心作为盒子中心。这是最可靠的做法,因为共晶配体的位置就是实验验证的结合位点。
- 残基中心法:没有共晶配体?从文献或保守性分析推断几个关键残基,手动指定它们的几何中心。我一般取2~3个关键残基的Cα坐标,算平均值当盒子中心。
为什么会有人用盲对接(whole-protein docking)?说白了是不知道活性位点在哪。但盲对接盒子要覆盖整个蛋白,size 可能超过100 Å,运行时间和内存开销都暴涨。我的建议是:先通过序列比对或保守位点分析缩小范围,再用残基中心法确定盒子,最后用已知抑制剂验证一下。这样命中率比纯盲搜高太多了。
4.6 本章知识体系
下面这张图概括了盒子设置的决策流程:从输入受体/配体到最后生成Vina配置文件。核心逻辑是用已知结构或计算手段确定一个合理的搜索空间边界。
4.7 避坑指南
- 盒子太大不是好事:size超过30 Å后,搜索空间体积按立方增长,Vina需要更多时间采样。网格点数超过40×40×40时,内存占用也翻倍。我控制在20~25 Å是最平衡的。
- 中心不要落在蛋白质量心:除非你做盲对接,否则别把盒子中心设在整个蛋白的质心。不然盒子可能包住了蛋白但完全没覆盖活性位点。
- 多次对接的一致性:批次筛选时,所有化合物必须用完全相同的盒子参数。我习惯把box参数写进模板配置文件,然后每个配体单独生成作业时只改ligand和out路径。
4.8 小结
盒子设置看似简单,但在高通量筛选时,一个小小的坐标偏差就可能让整批次结果报废。我的习惯是:始终把盒子配置单独写成conf文件,然后对每个配体只替换ligand和out路径。这样不仅不易出错,而且方便批量提交作业。用ADT做可视化验证,用脚本做批量计算——两条腿走路,哪条都不能瘸。