using Random
using Pumas
using PumasUtilities
using CairoMakie
using AlgebraOfGraphics
using DataFramesMeta
using CSV
using Dates
PK41 - Multiple Intravenous Infusions: NCA vs Regression
1 Background
- Structural Model - One compartment model with non-linear elimination.
- Route of administration - IV infusion
- Dosage Regimen - 310 μg, 520 μg, and 780 μg
- Number of Subjects - 3
2 Learning Outcome
This is a one compartment model with capacity limited elimination. The concentration time profile was obtained for three subjects administered with three different dosage regimens.
3 Objectives
In this tutorial, you will learn how to build a one compartment model with non-linear elimination.
4 Libraries
Call the necessary libraries to get started.
5 Model
The following model describes the parameters and the differential equation for a one-compartment model with capacity limited elimination
= @model begin
pk_41 @metadata begin
= "One Compartment Model"
desc = u"hr"
timeu end
@param begin
"""
Maximum Metabolic Rate (μg/kg/hr)
"""
∈ RealDomain(lower = 0)
tvvmax """
Michaelis Menten Constant (μg/kg/L)
"""
∈ RealDomain(lower = 0)
tvkm """
Volume of Central Compartment (L/kg)
"""
∈ RealDomain(lower = 0)
tvvc ∈ PDiagDomain(3)
Ω """
Proportional RUV
"""
∈ RealDomain(lower = 0)
σ²_prop end
@random begin
~ MvNormal(Ω)
η end
@pre begin
= tvvmax * exp(η[1])
Vmax = tvkm * exp(η[2])
Km = tvvc * exp(η[3])
Vc end
@dynamics begin
' = -(Vmax * (Central / Vc) / (Km + (Central / Vc)))
Centralend
@derived begin
= @. Central / Vc
cp """
Observed Concentrations (μg/L)
"""
~ @. Normal(cp, sqrt(cp^2 * σ²_prop))
dv end
@observed begin
= Central / Vc
conc := @nca conc
nca = NCA.cl(nca)
cl end
end
PumasModel
Parameters: tvvmax, tvkm, tvvc, Ω, σ²_prop
Random effects: η
Covariates:
Dynamical system variables: Central
Dynamical system type: Nonlinear ODE
Derived: cp, dv
Observed: cp, dv, conc, cl
6 Parameters
The parameters are as given below. Note that tv
represents the typical value for parameters.
Vmax
- Maximum Metabolic Rate (μg/kg/hr)Km
- Michaelis Menten Constant (μg/kg/L)Vc
- Volume of Central compartment (L/kg)
= (
param = 180.311,
tvvmax = 79.8382,
tvkm = 1.80036,
tvvc = Diagonal([0.04, 0.04, 0.04, 0.04, 0.04]),
Ω = 0.015,
σ²_prop )
7 Dosage Regimen
All subjects receive an IV infusion over 5 hours with the following doses:
- Subject 1 receives a dose of 310 μg
- Subject 2 receives a dose of 520 μg
- Subject 3 receives a dose of 780 μg
= [310, 520, 780] dose
= [62, 104, 156] rate_ind
= ["310 μg.kg-1", "520 μg.kg-1", "780 μg.kg-1"] ids
ev(x) =
DosageRegimen(dose[x], cmt = 1, time = 0, rate = rate_ind[x], route = NCA.IVInfusion)
ev (generic function with 1 method)
= map(i -> Subject(id = ids[i], events = ev(i)), 1:length(ids)) pop3_sub
Population
Subjects: 3
Observations:
8 Simulation
Simulate the plasma concentration of the drug for all the subjects
Random.seed!(123)
The random effects are zero’ed out since we are simulating a single subject
= zero_randeffs(pk_41, pop3_sub, param) zfx
3-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.1:0.01:10
time_values = simobs(pk_41, pop3_sub, param, zfx, obstimes = time_values) sim_pop3_sub
Simulated population (Vector{<:Subject})
Simulated subjects: 3
Simulated variables: cp, dv, conc, cl
9 Visualization
We will build a DataFrame
to facilitate plotting
= [i.observations.cp for i in sim_pop3_sub]
cp_values = [
df_subs DataFrame(:cp => cp_values[i], :id => ids[i], :time => time_values) for
in eachindex(ids)
i
]= vcat(df_subs...) df_plot
@chain df_plot begin
dropmissing(:cp)
data(_) *
mapping(:time => "Time (hours)", :cp => "Concentration (μg/L)", color = :id => "Dose") *
visual(Lines; linewidth = 4)
draw(;
= (; fontsize = 22),
figure = (;
axis = 0:10,
xticks = log10,
yscale = i -> (@. string(round(i; digits = 1))),
ytickformat
),= (; position = :bottom),
legend
)end
= reduce(vcat, map(sim_pop3_sub) do subj
df_41 = DataFrame(id = subj.subject.id, cl = subj.observations.cl)
subdf end)
@chain df_41 begin
dropmissing!(:cl)
unique([:id, :cl])
data(_) *
mapping(:id => nonnumeric => "Dose", :cl => "Cl (L/hr/kg)") *
visual(ScatterLines, linewidth = 4, markersize = 22)
draw(axis = (; yticks = 0.8:0.2:1.8,), figure = (; fontsize = 22))
end
10 Simulating a Population
= (
par = 180.311,
tvvmax = 79.8382,
tvkm = 1.80036,
tvvc = Diagonal([0.0462, 0.0628, 0.0156, 0.0321, 0.0126]),
Ω = 0.0234,
σ²_prop
)
= DosageRegimen(310, cmt = 1, time = 0, rate = 62, route = NCA.IVInfusion)
ev1 = map(i -> Subject(id = i, events = ev1), 1:20)
pop1 = DosageRegimen(520, cmt = 1, time = 0, rate = 104, route = NCA.IVInfusion)
ev2 = map(i -> Subject(id = i, events = ev2), 21:40)
pop2 = DosageRegimen(780, cmt = 1, time = 0, rate = 156, route = NCA.IVInfusion)
ev3 = map(i -> Subject(id = i, events = ev3), 41:60)
pop3 = [pop1; pop2; pop3]
pop
Random.seed!(1234)
= simobs(pk_41, pop, par, obstimes = [0, 0.1, 2, 5, 6, 8, 10])
sim_pop
= reduce(
df_sim
vcat,map(sim_pop) do subj
= DataFrame(
subdf = subj.subject.id,
id = subj.time,
time = subj.observations.cp,
cp = subj.observations.cl,
cl
)end,
);
#CSV.write("pk_41.csv", df_sim)