Pharmacodynamics: Dose–Response
Pharmacodynamics (PD) is what the drug does to the body — the quantitative relationship between drug concentration and the size of its effect. Where pharmacokinetics tells us the concentration over time, PD converts that concentration into an effect, and for antimicrobials the “effect” is the rate at which bacteria are killed.
(Hill) dose–response curves for increasing Hill coefficients." />
The model
Almost every dose–response relationship saturates: doubling the concentration does not double the effect once receptors approach full occupancy. The workhorse model captures this with a rectangular hyperbola:
Here is the baseline effect with no drug, is the maximal drug-induced effect (efficacy), and is the concentration producing half of (potency). As the effect approaches , and at it sits exactly halfway.
The sigmoid (Hill) model
Many systems respond more steeply than a simple hyperbola because of cooperativity or multi-step binding. Adding a Hill coefficient produces the sigmoid model (writing the baseline as zero for clarity):
The exponent controls steepness: recovers the plain hyperbola, gives a switch-like S-curve, and a shallow one. Plotted against — the natural axis for dose–response, since concentrations span orders of magnitude — the curve is a symmetric sigmoid centered on , a shape you may recognize from functions and graphs and from the logistic curve.
Solving for a target effect
Because the Hill equation is invertible, we can find the concentration producing any fractional effect. Setting and solving,
so the concentration for 90% of maximal effect is . When this means is nine times ; a steep curve with large narrows that gap dramatically.
Worked example
Suppose an antibiotic has (maximal kill rate), , and Hill coefficient .
At a concentration the effect is
i.e. 80% of the maximal kill rate. The concentration for 90% of maximum is
Because , tripling the concentration from takes the effect from 50% to 90% — steeper than the ninefold factor a hyperbola would require.
In code
We plot the Hill curve and then recover its parameters by nonlinear least squares from noisy data — the estimation problem at the heart of optimization.
R
Emax <- 4; EC50 <- 2; h <- 2
hill <- function(C, Emax, EC50, h) Emax * C^h / (EC50^h + C^h)
set.seed(1)
C <- c(0.25, 0.5, 1, 2, 4, 8, 16)
y <- hill(C, Emax, EC50, h) + rnorm(length(C), 0, 0.1)
fit <- nls(y ~ Emax * C^h / (EC50^h + C^h),
start = list(Emax = 3, EC50 = 1, h = 1))
coef(fit) # ~ Emax 4, EC50 2, h 2
hill(4, Emax, EC50, h) # 3.2 : effect at C = 4
Python
import numpy as np
from scipy.optimize import curve_fit
Emax, EC50, h = 4.0, 2.0, 2.0
hill = lambda C, Emax, EC50, h: Emax * C**h / (EC50**h + C**h)
rng = np.random.default_rng(1)
C = np.array([0.25, 0.5, 1, 2, 4, 8, 16])
y = hill(C, Emax, EC50, h) + rng.normal(0, 0.1, C.size)
p, _ = curve_fit(hill, C, y, p0=[3, 1, 1])
print(p) # ~ [4, 2, 2]
print(hill(4, *p)) # ~3.2 : effect at C = 4
[4.02057431 2.02736333 1.98503466]
3.1921646202469307
Julia
using LsqFit
Emax, EC50, h = 4.0, 2.0, 2.0
hill(C, p) = @. p[1] * C^p[3] / (p[2]^p[3] + C^p[3])
C = [0.25, 0.5, 1, 2, 4, 8, 16]
y = hill(C, [Emax, EC50, h]) .+ 0.1 .* randn(length(C))
fit = curve_fit(hill, C, y, [3.0, 1.0, 1.0])
fit.param # ~ [4, 2, 2]
hill([4.0], [Emax, EC50, h])[1] # 3.2 : effect at C = 4
Why it matters
The Hill curve is the bridge from a measured concentration to a predicted bacterial kill rate, and its two key numbers have direct clinical meaning: says how good a drug can be, says how much you need. Coupling this dose–response with the time-varying concentration from pharmacokinetics is precisely what defines the PK/PD indices used to design antibiotic regimens.
Related
- Pharmacokinetics: Compartment Models
- Antimicrobial PK/PD
- Functions and Graphs — the sigmoid shape
- Logistic Growth — the same S-curve algebra
- Optimization — least-squares curve fitting
- Quantitative Methods