using Random
using Pumas
using PumasUtilities
using AlgebraOfGraphics
using CairoMakie
using CSV
using DataFramesMeta
using Dates
PK27 - Allometry - Elementary & Complex Dedrick plot
1 Background
- Structural model - Target Mediated Drug Disposition Model (TMDD)
- Route of administration - IV-Bolus
- Dosage Regimen - 1.5, 5, 15, 45 mg/kg administered after a complete washout
- Number of Subjects - 4
2 Learning Outcome
- To fit a full TMDD model with data from only ligand, ligand and target, target and ligand-target complex
- Write a differential equation for a full TMDD model
3 Objective
The objective of this exercise is to simulate from a TMDD model
4 Libraries
Call the necessary libraries to get started
5 Model
= @model begin
pk_27 @metadata begin
= "Target Mediated Drug Disposition Model"
desc = u"hr"
timeu end
@param begin
"""
Clearance of central compartment (L/kg/hr)
"""
∈ RealDomain(lower = 0)
tvcl """
Second order on rate of ligand (L/mg/hr)
"""
∈ RealDomain(lower = 0)
tvkon """
First order off rate of ligand (1/hr)
"""
∈ RealDomain(lower = 0)
tvkoff """
Volume of Peripheral Compartment (L/kg)
"""
∈ RealDomain(lower = 0)
tvvp """
Inter-compartmental clearance (L/kg/hr)
"""
∈ RealDomain(lower = 0)
tvq """
Zero order receptor synthesis process (mg/L/hr)
"""
∈ RealDomain(lower = 0)
tvkin """
First order receptor degeneration process (1/hr)
"""
∈ RealDomain(lower = 0)
tvkout """
First order elimination of complex (1/hr)
"""
∈ RealDomain(lower = 0)
tvkerl """
Volume of Central Compartment (L/kg)
"""
∈ RealDomain(lower = 0)
tvvc ∈ PDiagDomain(9)
Ω """
Proportional RUV - Plasma
"""
∈ RealDomain(lower = 0)
σ²_prop_cp """
Proportional RUV - Receptor
"""
∈ RealDomain(lower = 0)
σ²_prop_rec """
Proportional RUV - Complex
"""
∈ RealDomain(lower = 0)
σ²_prop_com end
@random begin
~ MvNormal(Ω)
η end
@pre begin
= tvcl * exp(η[1])
Cl = tvkon * exp(η[2])
Kon = tvkoff * exp(η[3])
Koff = tvvp * exp(η[4])
Vp = tvq * exp(η[5])
Q = tvkin * exp(η[6])
Kin = tvkout * exp(η[7])
Kout = tvkerl * exp(η[8])
Kerl = tvvc * exp(η[9])
Vc end
@dosecontrol begin
= tvvc * exp(η[9])
Vc_ = (Central = 1 / Vc_,)
bioav end
@init begin
= Kin / Kout
Receptor end
@dynamics begin
' =
Central-(Cl / Vc) * Central - (Q / Vc) * Central + (Q / Vp) * Peripheral -
* Receptor * Central + Koff * Complex
Kon ' = (Q / Vc) * Central - (Q / Vp) * Peripheral
Peripheral' = Kin - Kout * Receptor - Kon * Receptor * Central + Koff * Complex
Receptor' = Kon * Receptor * Central - Koff * Complex - Kerl * Complex
Complexend
@derived begin
= @. Central
cp """
Observed Concentration - Plasma (mg/L)
"""
= @. Normal(cp, sqrt(cp^2 * σ²_prop_cp))
dv_cp = @. Receptor
rec """
Observed Concentration - Receptor (mg/L)
"""
= @. Normal(rec, sqrt(rec^2 * σ²_prop_rec))
dv_rec = @. Complex
com """
Observed Concentration - Complex (mg/L)
"""
= @. Normal(com, sqrt(com^2 * σ²_prop_com))
dv_com end
end
PumasModel
Parameters: tvcl, tvkon, tvkoff, tvvp, tvq, tvkin, tvkout, tvkerl, tvvc, Ω, σ²_prop_cp, σ²_prop_rec, σ²_prop_com
Random effects: η
Covariates:
Dynamical system variables: Central, Peripheral, Receptor, Complex
Dynamical system type: Nonlinear ODE
Derived: cp, dv_cp, rec, dv_rec, com, dv_com
Observed: cp, dv_cp, rec, dv_rec, com, dv_com
6 Parameters
The parameters are as given below. tv represents the typical value for parameters.
Cl
- Clearance of central compartment (L/kg/hr)Kon
- Second order on rate of ligand (L/mg/hr)Koff
- First order off rate of ligand (1/hr)Vp
- Volume of Peripheral Compartment (L/kg)Q
- Inter-compartmental clearance (L/kg/hr)Kin
- Zero order receptor synthesis process (mg/L/hr)Kout
- First order receptor degeneration process (1/hr)Kerl
- First order elimination of complex (1/hr)Vc
- Volume of Central Compartment (L/kg)
= (
param = 0.001,
tvcl = 0.096,
tvkon = 0.001,
tvkoff = 0.100,
tvvp = 0.003,
tvq = 0.11,
tvkin = 0.0089,
tvkout = 0.003,
tvkerl = 0.05,
tvvc = Diagonal([0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04]),
Ω = 0.02,
σ²_prop_cp = 0.012,
σ²_prop_rec = 0.015,
σ²_prop_com )
7 Dosage Regimen
- Single dose of 1.5 mg/kg was administered as IV-Bolus at
time=0
- Single dose of 5 mg/kg was administered as IV-Bolus at
time=0
- Single dose of 15 mg/kg was administered as IV-Bolus at
time=0
- Single dose of 45 mg/kg was administered as IV-Bolus at
time=0
= [1.5, 5, 15, 45] dose
= ["1.5 mg/kg", "5 mg/kg", "15 mg/kg", "45 mg/kg"] ids
dose_ind(x) = DosageRegimen(dose[x], time = 0, cmt = 1)
= map(
pop4_sub -> Subject(
i = ids[i],
id = dose_ind(i),
events = (cp = nothing, rec = nothing, com = nothing),
observations
),1:length(ids),
)
Population
Subjects: 4
Observations: cp, rec, com
8 Simulation
Random.seed!(123)
The random effects are zero’ed out since we are simulating means
= zero_randeffs(pk_27, pop4_sub, param) zfx
4-element Vector{NamedTuple{(:η,), Tuple{Vector{Float64}}}}:
(η = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],)
(η = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],)
(η = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],)
(η = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],)
= simobs(pk_27, pop4_sub, param, zfx, obstimes = 0.1:1:500) sim_pop4
Simulated population (Vector{<:Subject})
Simulated subjects: 4
Simulated variables: cp, dv_cp, rec, dv_rec, com, dv_com
9 Visualization
= @chain DataFrame(sim_pop4) begin
df27 dropmissing([:cp, :rec, :com])
end
= Figure(; fontsize = 32, resolution = (1200, 1200))
fig ytickformater(ticks) = @. string(round(ticks; digits = 1))
= fig[1, 1]
gridpos =
plt1 data(df27) *
mapping(
:time => "Time (days)",
:cp => "PK27 Concentrations (mg/L)",
= :id => nonnumeric => "Doses",
color *
) visual(Lines, linewidth = 6)
draw!(
gridpos,
plt1;= (;
axis = "Ligand",
title = log10,
yscale = map(i -> 10.0^i, -2:2),
yticks = ytickformater,
ytickformat = 0:100:500,
xticks
),
)
= fig[1, 2]
gridpos =
plt2 data(df27) *
mapping(
:time => "Time (days)",
:rec => "PK27 Concentrations (mg/L)",
= :id => nonnumeric => "Doses",
color *
) visual(Lines, linewidth = 6)
draw!(
gridpos,
plt2;= (;
axis = "Receptor",
title = log10,
yscale = map(i -> 10.0^i, -2:1),
yticks = ytickformater,
ytickformat = 0:100:500,
xticks
),
)
= fig[2, 1]
gridpos =
plt3 data(df27) *
mapping(
:time => "Time (days)",
:com => "PK27 Concentrations (mg/L)",
= :id => nonnumeric => "Doses",
color *
) visual(Lines, linewidth = 6)
= draw!(
p3
gridpos,
plt3;= (;
axis = "Complex",
title = log10,
yscale = map(i -> 10.0^i, 0.6:0.2:1.4),
yticks = ytickformater,
ytickformat = 0:100:500,
xticks
),
)
= fig[2, 2]
gridpos legend!(
gridpos,
p3;= 8,
linewidth = false,
tellwidth = :right,
halign = :center,
valign = (10, 10, 10, 10),
margin
) fig
10 Population simulation
= (
par = 0.001,
tvcl = 0.096,
tvkon = 0.001,
tvkoff = 0.100,
tvvp = 0.003,
tvq = 0.11,
tvkin = 0.0089,
tvkout = 0.003,
tvkerl = 0.05,
tvvc = Diagonal([0.09, 0.04, 0.0125, 0.04, 0.0326, 0.0525, 0.0124, 0.0111, 0.0234]),
Ω = 0.025,
σ²_prop_cp = 0.03,
σ²_prop_rec = 0.04,
σ²_prop_com
)
= DosageRegimen(1.5, cmt = 1, time = 0)
ev1 = map(i -> Subject(id = i, events = ev1), 1:20)
pop1 = DosageRegimen(5, cmt = 1, time = 0)
ev2 = map(i -> Subject(id = i, events = ev2), 21:40)
pop2 = DosageRegimen(15, cmt = 1, time = 0)
ev3 = map(i -> Subject(id = i, events = ev3), 41:60)
pop3 = DosageRegimen(45, cmt = 1, time = 0)
ev4 = map(i -> Subject(id = i, events = ev4), 61:80)
pop4 = [pop1; pop2; pop3; pop4]
pop
## Simulation
Random.seed!(1234)
= simobs(pk_27, pop, par, obstimes = [0.1, 1, 10, 24, 72, 120, 168, 240, 360, 499])
sim_pop sim_plot(sim_pop)
= DataFrame(sim_pop);
df_sim
#CSV.write("pk_27.csv", df_sim)