Lesson 8 of 12 · 11 min
Scoring Functions and Binding Affinity
Every pose that AutoDock Vina reports comes with a single number in kcal/mol called the predicted binding affinity. That number is produced by Vina's empirical scoring function, a weighted sum of physics-inspired terms whose weights were fitted against a training set of protein-ligand complexes with known structures and measured affinities. Knowing what feeds into it tells you exactly how much to trust it.
Anatomy of the Score
The score adds up a handful of pairwise atom-atom terms, each evaluated on the surface distance between a ligand atom and a receptor atom rather than the raw center-to-center distance. Two Gaussian terms reward close but non-clashing contact and stand in for attractive van der Waals forces, while a repulsion term penalizes atoms that overlap. A hydrophobic term rewards nonpolar atoms resting against each other, and a hydrogen-bond term rewards donor-acceptor pairs sitting at bonding distance.
# Vina intermolecular score: weighted sum over atom pairs
# d = surface distance = r - Ri - Rj (r = center distance, R = atom radii)
c_inter = -0.0356 * Gauss1(d) # attractive vdW, sharp well
-0.00516 * Gauss2(d) # attractive vdW, broad well
+0.840 * Repulsion(d) # steric clash penalty (raises score)
-0.0351 * Hydrophobic(d) # nonpolar contact bonus
-0.587 * HBond(d) # hydrogen-bond bonus
# torsional entropy penalty divides the sum by a rotatable-bond term
affinity = c_inter / (1 + 0.0585 * N_rot) # reported in kcal/molBecause the van der Waals, hydrophobic, and hydrogen-bond weights are negative, favorable interactions pull the total downward, so a more negative affinity means stronger predicted binding. The intermolecular sum is then divided by a term that grows with the number of active rotatable bonds, which is Vina's torsional entropy penalty: a floppy ligand must freeze several bonds to bind, and that costs it. This is why an otherwise well-fitting pose of a very flexible molecule can still land at a modest score.
Reading the Vina Log
# Vina 1.2 removed the --log flag, so send stdout to a file with tee
vina \
--receptor receptor.pdbqt \
--ligand ligand.pdbqt \
--center_x 15.0 --center_y 53.5 --center_z 12.0 \
--size_x 22 --size_y 22 --size_z 22 \
--exhaustiveness 8 \
--out docked.pdbqt | tee vina_log.txtAutoDock Vina v1.2.5
Scoring function : vina
Rigid receptor: receptor.pdbqt
Ligand: ligand.pdbqt
Grid center: X 15 Y 53.5 Z 12
Grid size : X 22 Y 22 Z 22
Grid space : 0.375
Exhaustiveness: 8
CPU: 0
Verbosity: 1
Computing Vina grid ... done.
Performing docking (random seed: 1274908391) ...
0% 10 20 30 40 50 60 70 80 90 100%
|----|----|----|----|----|----|----|----|----|----|
***************************************************
mode | affinity | dist from best mode
| (kcal/mol) | rmsd l.b.| rmsd u.b.
-----+------------+----------+----------
1 -9.234 0 0
2 -8.719 2.015 3.128
3 -8.507 1.876 2.442
4 -7.892 3.045 5.211
5 -7.634 2.333 3.874
Vina sorts poses from best to worst, so mode 1 always carries the lowest, most negative affinity, and the affinity column is the one you read. As a rough guide, scores near -6 kcal/mol are weak, -7 to -9 is typical for a genuine hit, and values past -10 are strong but worth double-checking for grid-box or protonation artifacts. Treat the gap between mode 1 and the runner-up as a hint of how confident the search is in its top pose.
# Pull just mode number and affinity out of the log
awk '/^-----/{seen=1; next} seen && $1 ~ /^[0-9]+$/ {print "pose "$1" "$2" kcal/mol"}' vina_log.txtpose 1 -9.234 kcal/mol
pose 2 -8.719 kcal/mol
pose 3 -8.507 kcal/mol
pose 4 -7.892 kcal/mol
pose 5 -7.634 kcal/mol
Warning: Vina's absolute affinities are approximate. Benchmark error is commonly 2 to 3 kcal/mol, and because a tenfold change in binding constant is only about 1.4 kcal/mol at room temperature, one reported number can be off by orders of magnitude in Kd. Trust the ranking far more than the value: use the scores to compare poses of one ligand or to rank a compound library, not to claim a real dissociation constant.