Indirect Response Models (IRM)¶
Mechanism-based PD models where drug affects the production (Kin) or elimination (Kout) of a response variable, rather than directly modulating the response.
Model Overview¶
graph LR
subgraph "Turnover System"
K1[Kin<br/>Production] --> R[Response R]
R --> K2[Kout<br/>Elimination]
end
C[Drug<br/>Concentration] -.->|Inhibits or<br/>Stimulates| K1
C -.->|Inhibits or<br/>Stimulates| K2
The Four IRM Types¶
| Model | Target | Direction | Effect on R |
|---|---|---|---|
| IRM-I | Kin (production) | Inhibition | Decreases R |
| IRM-II | Kin (production) | Stimulation | Increases R |
| IRM-III | Kout (elimination) | Inhibition | Increases R |
| IRM-IV | Kout (elimination) | Stimulation | Decreases R |
Clinical Applications¶
| IRM Type | Example Applications |
|---|---|
| IRM-I | Corticosteroids (cortisol), Statins (cholesterol), Warfarin (clotting factors) |
| IRM-II | EPO (RBC production), G-CSF (neutrophils), Growth factors |
| IRM-III | Diuretics (renal function), Thyroid hormones (metabolism) |
| IRM-IV | Laxatives (bowel motility), Some immunosuppressants |
Mathematical Formulation¶
Baseline Turnover¶
At baseline (no drug):
\[\frac{dR}{dt} = K_{in} - K_{out} \cdot R = 0\]
Therefore: \(R_0 = K_{in} / K_{out}\)
Drug Functions¶
Inhibition function (for IRM-I, IRM-III):
\[I(C) = \frac{I_{max} \cdot C}{IC_{50} + C}\]
Stimulation function (for IRM-II, IRM-IV):
\[S(C) = \frac{S_{max} \cdot C}{SC_{50} + C}\]
IRM Equations¶
| Model | Differential Equation |
|---|---|
| IRM-I | \(\frac{dR}{dt} = K_{in} \cdot (1 - I(C)) - K_{out} \cdot R\) |
| IRM-II | \(\frac{dR}{dt} = K_{in} \cdot (1 + S(C)) - K_{out} \cdot R\) |
| IRM-III | \(\frac{dR}{dt} = K_{in} - K_{out} \cdot (1 - I(C)) \cdot R\) |
| IRM-IV | \(\frac{dR}{dt} = K_{in} - K_{out} \cdot (1 + S(C)) \cdot R\) |
Parameters¶
Common Parameters¶
| Parameter | Symbol | Units | Description | Constraints |
|---|---|---|---|---|
| Production rate | Kin | units/h | Zero-order production | Kin > 0 |
| Elimination rate | Kout | 1/h | First-order elimination | Kout > 0 |
| Baseline response | R0 | units | Steady-state baseline | R0 = Kin/Kout |
Inhibition Parameters (IRM-I, IRM-III)¶
| Parameter | Symbol | Units | Description | Constraints |
|---|---|---|---|---|
| Maximum inhibition | Imax | - | Fraction at saturation | 0 < Imax ≤ 1 |
| Inhibition potency | IC50 | mg/L | Concentration for 50% Imax | IC50 > 0 |
Stimulation Parameters (IRM-II, IRM-IV)¶
| Parameter | Symbol | Units | Description | Constraints |
|---|---|---|---|---|
| Maximum stimulation | Smax | - | Fold-increase at saturation | Smax > 0 |
| Stimulation potency | SC50 | mg/L | Concentration for 50% Smax | SC50 > 0 |
Julia API¶
Type Definitions¶
# IRM-I: Inhibition of Kin
struct IndirectResponseIRM1 <: PDModelKind end
struct IndirectResponseIRM1Params
Kin::Float64 # Production rate
Kout::Float64 # Elimination rate constant
R0::Float64 # Baseline response
Imax::Float64 # Maximum inhibition [0, 1]
IC50::Float64 # Inhibition potency
end
# IRM-II: Stimulation of Kin
struct IndirectResponseIRM2 <: PDModelKind end
struct IndirectResponseIRM2Params
Kin::Float64
Kout::Float64
R0::Float64
Smax::Float64 # Maximum stimulation (can exceed 1)
SC50::Float64 # Stimulation potency
end
# IRM-III: Inhibition of Kout (also known as IndirectResponseTurnover)
struct IndirectResponseTurnover <: PDModelKind end
struct IndirectResponseTurnoverParams
Kin::Float64
Kout::Float64
R0::Float64
Imax::Float64
IC50::Float64
end
# IRM-IV: Stimulation of Kout
struct IndirectResponseIRM4 <: PDModelKind end
struct IndirectResponseIRM4Params
Kin::Float64
Kout::Float64
R0::Float64
Smax::Float64
SC50::Float64
end
IRM-I: Inhibition of Production¶
Mechanism¶
Drug inhibits the production of the response variable.
\[\frac{dR}{dt} = K_{in} \cdot \left(1 - \frac{I_{max} \cdot C}{IC_{50} + C}\right) - K_{out} \cdot R\]
Clinical Example: Corticosteroid Effect on Cortisol¶
using NeoPKPD
# Cortisol dynamics
# Baseline cortisol: 15 mcg/dL
# Turnover half-life: ~1.5 hours
Kout = log(2) / 1.5 # 0.46/h
R0 = 15.0
Kin = Kout * R0 # 6.9 mcg/dL/h
# Corticosteroid effect
pd_params = IndirectResponseIRM1Params(
Kin,
Kout,
R0,
0.9, # Imax: 90% suppression possible
0.01 # IC50: 0.01 mg/L (very potent)
)
# Validate
spec = PDSpec(IndirectResponseIRM1(), "cortisol", pd_params)
validate(spec)
println("Baseline cortisol: $(R0) mcg/dL")
println("Turnover t1/2: $(round(log(2)/Kout, digits=2)) h")
Response Profile¶
# PK: Single oral dose
pk_params = OneCompOralFirstOrderParams(1.5, 2.0, 50.0)
doses = [DoseEvent(0.0, 10.0)] # 10 mg dose
pk_spec = ModelSpec(OneCompOralFirstOrder(), "steroid", pk_params, doses)
grid = SimGrid(0.0, 48.0, collect(0.0:0.25:48.0))
solver = SolverSpec(:Tsit5, 1e-10, 1e-12, 10_000_000)
# Simulate coupled PKPD
result = simulate_pkpd(pk_spec, spec, grid, solver)
# Key features of IRM-I:
# - Effect is delayed relative to concentration
# - Maximum suppression occurs AFTER Cmax
# - Slow return to baseline (governed by Kout)
IRM-II: Stimulation of Production¶
Mechanism¶
Drug increases the production rate.
\[\frac{dR}{dt} = K_{in} \cdot \left(1 + \frac{S_{max} \cdot C}{SC_{50} + C}\right) - K_{out} \cdot R\]
Clinical Example: EPO on Red Blood Cells¶
using NeoPKPD
# RBC dynamics
# Baseline RBC: 5 million/mcL
# Turnover half-life: ~30 days
Kout = log(2) / (30 * 24) # 0.001/h
R0 = 5.0 # million/mcL
Kin = Kout * R0
# EPO stimulation
pd_params = IndirectResponseIRM2Params(
Kin,
Kout,
R0,
3.0, # Smax: up to 4× production
0.1 # SC50: 0.1 mIU/mL
)
spec = PDSpec(IndirectResponseIRM2(), "rbc", pd_params)
# Maximum possible response at infinite C:
# R_max = Kin × (1 + Smax) / Kout = R0 × (1 + Smax) = 20 million/mcL
println("Maximum possible RBC: $(R0 * (1 + pd_params.Smax)) million/mcL")
IRM-III: Inhibition of Elimination¶
Mechanism¶
Drug inhibits the elimination of the response variable.
\[\frac{dR}{dt} = K_{in} - K_{out} \cdot \left(1 - \frac{I_{max} \cdot C}{IC_{50} + C}\right) \cdot R\]
Clinical Example: Warfarin Effect on Clotting Factors¶
using NeoPKPD
# Clotting factor dynamics
# Baseline: 100% of normal
# Turnover half-life: ~36 hours
Kout = log(2) / 36.0
R0 = 100.0 # % of normal
Kin = Kout * R0
# Warfarin effect (inhibits synthesis, modeled as IRM-III)
pd_params = IndirectResponseTurnoverParams(
Kin,
Kout,
R0,
0.95, # Imax: 95% inhibition possible
1.5 # IC50: 1.5 mg/L
)
spec = PDSpec(IndirectResponseTurnover(), "clotting", pd_params)
# Minimum possible response (at complete inhibition):
# When I(C) → Imax, Kout_eff → Kout × (1 - Imax)
# New steady state: R_min = Kin / (Kout × (1 - Imax))
# For Imax = 0.95: R_min = R0 / 0.05 = 2000 (unrealistic)
# In practice, Imax < 1 ensures R remains finite
println("With complete inhibition, R could increase to: ",
round(R0 / (1 - pd_params.Imax), digits=1), "%")
IRM-IV: Stimulation of Elimination¶
Mechanism¶
Drug increases the elimination rate.
\[\frac{dR}{dt} = K_{in} - K_{out} \cdot \left(1 + \frac{S_{max} \cdot C}{SC_{50} + C}\right) \cdot R\]
Clinical Example: Laxative Effect¶
using NeoPKPD
# Bowel content dynamics
Kout = log(2) / 12.0 # ~12 hour transit
R0 = 100.0 # arbitrary units
Kin = Kout * R0
# Laxative stimulates elimination
pd_params = IndirectResponseIRM4Params(
Kin,
Kout,
R0,
5.0, # Smax: up to 6× elimination rate
0.5 # SC50
)
spec = PDSpec(IndirectResponseIRM4(), "bowel", pd_params)
# Minimum response at high drug concentration:
# R_min = Kin / (Kout × (1 + Smax)) = R0 / (1 + Smax)
println("Minimum response: $(round(R0 / (1 + pd_params.Smax), digits=1)) units")
Comparing IRM Types¶
using NeoPKPD
# Same baseline and turnover for all
Kout = 0.1 # 1/h
R0 = 100.0
Kin = Kout * R0
# Same drug concentration profile
pk_params = OneCompIVBolusParams(2.0, 20.0)
doses = [DoseEvent(0.0, 100.0)]
pk_spec = ModelSpec(OneCompIVBolus(), "drug", pk_params, doses)
grid = SimGrid(0.0, 48.0, collect(0.0:0.25:48.0))
solver = SolverSpec(:Tsit5, 1e-10, 1e-12, 10_000_000)
pk_result = simulate(pk_spec, grid, solver)
# IRM-I and IRM-IV: Response DECREASES
params_irm1 = IndirectResponseIRM1Params(Kin, Kout, R0, 0.8, 2.0)
params_irm4 = IndirectResponseIRM4Params(Kin, Kout, R0, 4.0, 2.0)
# IRM-II and IRM-III: Response INCREASES
params_irm2 = IndirectResponseIRM2Params(Kin, Kout, R0, 3.0, 2.0)
params_irm3 = IndirectResponseTurnoverParams(Kin, Kout, R0, 0.8, 2.0)
println("At high drug concentrations:")
println(" IRM-I (inhib Kin): R decreases toward $(R0 * (1 - 0.8))")
println(" IRM-II (stim Kin): R increases toward $(R0 * (1 + 3.0))")
println(" IRM-III (inhib Kout): R increases (limited by Imax < 1)")
println(" IRM-IV (stim Kout): R decreases toward $(round(R0 / (1 + 4.0), digits=1))")
Response Dynamics¶
Time to Maximum/Minimum Effect¶
Unlike direct effect models, IRM effects are delayed:
| Factor | Effect on Delay |
|---|---|
| Lower Kout | Longer delay (slower turnover) |
| Higher IC50/SC50 | Longer time at effective concentration |
| Longer drug exposure | Greater effect accumulation |
Return to Baseline¶
After drug washout:
\[t_{90\%\ recovery} \approx \frac{2.3}{K_{out}}\]
Population Simulation¶
using NeoPKPD
# Typical IRM-I parameters
typical_params = IndirectResponseIRM1Params(10.0, 0.1, 100.0, 0.8, 2.0)
# IIV on turnover and potency
omega = OmegaMatrix([
0.09 0.0 0.0; # ω²_Kout (30% CV on turnover)
0.0 0.16 0.0; # ω²_Imax (40% CV on max effect)
0.0 0.0 0.25 # ω²_IC50 (50% CV on potency)
])
# Note: R0 and Kin are usually fixed or derived
# since R0 = Kin/Kout at baseline
base_spec = PDSpec(IndirectResponseIRM1(), "pop_irm", typical_params)
pop_spec = PopulationSpec(base_spec, 50, omega, 12345)
Model Selection Guide¶
| Observation | Suggested Model |
|---|---|
| Drug decreases biomarker | IRM-I or IRM-IV |
| Drug increases biomarker | IRM-II or IRM-III |
| Effect persists after drug washout | Any IRM (vs direct effect) |
| Biomarker is a production rate | IRM-I (inhibit) or IRM-II (stimulate) |
| Biomarker is eliminated/degraded | IRM-III (inhibit) or IRM-IV (stimulate) |
| Known mechanism of action | Select based on biology |
Equations Summary¶
| Model | dR/dt | Steady State at High C |
|---|---|---|
| IRM-I | \(K_{in}(1-I(C)) - K_{out}R\) | \(R_0(1-I_{max})\) |
| IRM-II | \(K_{in}(1+S(C)) - K_{out}R\) | \(R_0(1+S_{max})\) |
| IRM-III | \(K_{in} - K_{out}(1-I(C))R\) | \(R_0/(1-I_{max})\) |
| IRM-IV | \(K_{in} - K_{out}(1+S(C))R\) | \(R_0/(1+S_{max})\) |
Common to all: - Baseline: \(R_0 = K_{in}/K_{out}\) - Recovery t1/2: \(\ln(2)/K_{out}\)
See Also¶
- Direct Emax Model - Simpler, no delay
- Sigmoid Emax Model - Variable steepness
- Effect Compartment Model - Temporal delay
- Population Modeling - Population PKPD