using Pumas
using PumasUtilities
using AlgebraOfGraphics
using CairoMakie
using ColorSchemes
using Random
using CSV
using DataFramesMeta
using Dates
PK06 - One-compartment intravenous plasma/urine II
1 Background
- Structural model - One compartment linear elimination with first order absorption
- Route of administration - Oral and IV given simultaneously
- Dosage Regimen - 12.5 mg IV and 25 mg Oral
- Number of Subjects - 1
2 Objective
In this tutorial, you will learn to build a one compartment model and to simulate the model for different subjects and dosage regimens.
3 Libraries
Call the necessary libraries to get started
4 Model
In this one compartment model, we administer doses both oral and IV on two different occasions.
= @model begin
pk_06 @metadata begin
= "One Compartment Model with Urine Cmt"
desc = u"hr"
timeu end
@param begin
"""
Clearance (L/hr)
"""
∈ RealDomain(lower = 0)
tvcl """
Volume of Distribution (L)
"""
∈ RealDomain(lower = 0)
tvvc """
Fraction of drug excreted in Urine
"""
∈ RealDomain(lower = 0)
tvfe """
Absorption Rate Constant (1/hr)
"""
∈ RealDomain(lower = 0)
tvka """
Lag-time (hr)
"""
∈ RealDomain(lower = 0)
tvlag """
Bioavailability
"""
∈ RealDomain(lower = 0)
tvF ∈ PDiagDomain(6)
Ω """
Proportional RUV
"""
∈ RealDomain(lower = 0)
σ²_prop """
Additive RUV
"""
∈ RealDomain(lower = 0)
σ_add end
@random begin
~ MvNormal(Ω)
η end
@pre begin
= tvcl * exp(η[1])
Cl = tvvc * exp(η[2])
Vc = tvka * exp(η[3])
Ka = tvfe * exp(η[4])
fe end
@dosecontrol begin
= (Depot = tvlag * exp(η[5]),)
lags = (Depot = tvF * exp(η[6]),)
bioav end
@dynamics begin
' = -Ka * Depot
Depot' = Ka * Depot - (Cl / Vc) * Central
Central' = fe * (Cl / Vc) * Central
Urineend
@derived begin
"""
PK06 Plasma Concentration (μg/L)
"""
= @. (Central / Vc)
cp ~ @. Normal(cp, sqrt(cp^2 * σ²_prop))
dv
"""
PK06 Urine Amount (μg)
"""
= @. Urine
ae ~ @. Normal(ae, σ_add)
dv_ae end
end
PumasModel
Parameters: tvcl, tvvc, tvfe, tvka, tvlag, tvF, Ω, σ²_prop, σ_add
Random effects: η
Covariates:
Dynamical system variables: Depot, Central, Urine
Dynamical system type: Matrix exponential
Derived: cp, dv, ae, dv_ae
Observed: cp, dv, ae, dv_ae
5 Parameters
Parameters provided for simulation. Note that tv
represents the typical value for parameters.
Cl
- Clearance (L/hr)Vc
- Volume of Central Compartment (L)Fe
- Fraction of drug excreted in Urinelag
- lag time (hr)Ka
- Absorption rate constant (hr⁻¹)F
- BioavailabilityΩ
- Between Subject Variabilityσ
- Residual error
= (
param = 6.02527,
tvcl = 290.292,
tvvc = 0.0698294,
tvfe = 0.420432,
tvka = 0.311831,
tvlag = 1.13591,
tvF = Diagonal([0.04, 0.04, 0.04, 0.04, 0.04, 0.04]),
Ω = 0.015,
σ²_prop = 3,
σ_add )
6 Dosage Regimen
6.1 For IV
A single subject receives an IV-bolus dose of 12.5 mg or 12500 μg
= DosageRegimen(12500, time = 0, cmt = 2) ev1
Row | time | cmt | amt | evid | ii | addl | rate | duration | ss | route |
---|---|---|---|---|---|---|---|---|---|---|
Float64 | Int64 | Float64 | Int8 | Float64 | Int64 | Float64 | Float64 | Int8 | NCA.Route | |
1 | 0.0 | 2 | 12500.0 | 1 | 0.0 | 0 | 0.0 | 0.0 | 0 | NullRoute |
= Subject(id = "1 - IV", events = ev1) sub1
Subject
ID: 1 - IV
Events: 1
6.2 For Oral
A single subject receives an oral dose of 25 mg or 25000 μg
= DosageRegimen(25000, time = 0, cmt = 1) ev2
Row | time | cmt | amt | evid | ii | addl | rate | duration | ss | route |
---|---|---|---|---|---|---|---|---|---|---|
Float64 | Int64 | Float64 | Int8 | Float64 | Int64 | Float64 | Float64 | Int8 | NCA.Route | |
1 | 0.0 | 1 | 25000.0 | 1 | 0.0 | 0 | 0.0 | 0.0 | 0 | NullRoute |
= Subject(id = "2 - PO", events = ev2) sub2
Subject
ID: 2 - PO
Events: 1
= [sub1, sub2] pop
Population
Subjects: 2
Observations:
7 Simulation
Here, we will learn how to simultaneously simulate plasma concentration and urine amount after IV and oral administration.
Random.seed!(123)
The random effects are zero’ed out since we are simulating means
= zero_randeffs(pk_06, pop, param) zfx
2-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],)
= simobs(pk_06, pop, param, zfx, obstimes = 0.1:0.1:168) sim
Simulated population (Vector{<:Subject})
Simulated subjects: 2
Simulated variables: cp, dv, ae, dv_ae
7.1 For IV
Let’s simulate for plasma concentration and amount excreted unchanged in urine.
The random effects are zero’ed out since we are simulating means
= zero_randeffs(pk_06, sub1, param) zfx
(η = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],)
= simobs(pk_06, sub1, param, zfx, obstimes = 0.1:0.1:168) sim_sub1_iv
SimulatedObservations
Simulated variables: cp, dv, ae, dv_ae
Time: 0.1:0.1:168.0
= DataFrame(sim_sub1_iv)
df_sim_iv first(df_sim_iv, 5)
Row | id | time | cp | dv | ae | dv_ae | evid | lags_Depot | bioav_Depot | amt | cmt | rate | duration | ss | ii | route | η_1 | η_2 | η_3 | η_4 | η_5 | η_6 | Depot | Central | Urine | Cl | Vc | Ka | fe |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
String? | Float64 | Float64? | Float64? | Float64? | Float64? | Int64? | Float64? | Float64? | Float64? | Symbol? | Float64? | Float64? | Int8? | Float64? | NCA.Route? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | |
1 | 1 - IV | 0.0 | missing | missing | missing | missing | 1 | 0.311831 | 1.13591 | 12500.0 | Central | 0.0 | 0.0 | 0 | 0.0 | NullRoute | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | missing | missing | missing | 6.02527 | 290.292 | 0.420432 | 0.0698294 |
2 | 1 - IV | 0.1 | 42.9708 | 29.7989 | 1.80984 | 1.35184 | 0 | missing | missing | missing | missing | missing | missing | missing | missing | missing | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 12474.1 | 1.80984 | 6.02527 | 290.292 | 0.420432 | 0.0698294 |
3 | 1 - IV | 0.2 | 42.8817 | 49.4362 | 3.61592 | 4.59959 | 0 | missing | missing | missing | missing | missing | missing | missing | missing | missing | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 12448.2 | 3.61592 | 6.02527 | 290.292 | 0.420432 | 0.0698294 |
4 | 1 - IV | 0.3 | 42.7928 | 43.5093 | 5.41826 | 6.04342 | 0 | missing | missing | missing | missing | missing | missing | missing | missing | missing | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 12422.4 | 5.41826 | 6.02527 | 290.292 | 0.420432 | 0.0698294 |
5 | 1 - IV | 0.4 | 42.7041 | 39.9175 | 7.21686 | 8.44203 | 0 | missing | missing | missing | missing | missing | missing | missing | missing | missing | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 12396.7 | 7.21686 | 6.02527 | 290.292 | 0.420432 | 0.0698294 |
7.2 For Oral
Let’s simulate the plasma concentration and amount excreted unchanged in urine.
The random effects are zero’ed out since we are simulating means
= zero_randeffs(pk_06, sub2, param) zfx
(η = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],)
= simobs(pk_06, sub2, param, obstimes = 0.1:0.1:168) sim_sub2_oral
SimulatedObservations
Simulated variables: cp, dv, ae, dv_ae
Time: 0.1:0.1:168.0
= DataFrame(sim_sub2_oral)
df_sim_oral first(df_sim_oral, 5)
Row | id | time | cp | dv | ae | dv_ae | evid | lags_Depot | bioav_Depot | amt | cmt | rate | duration | ss | ii | route | η_1 | η_2 | η_3 | η_4 | η_5 | η_6 | Depot | Central | Urine | Cl | Vc | Ka | fe |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
String? | Float64 | Float64? | Float64? | Float64? | Float64? | Int64? | Float64? | Float64? | Float64? | Symbol? | Float64? | Float64? | Int8? | Float64? | NCA.Route? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | Float64? | |
1 | 2 - PO | 0.0 | missing | missing | missing | missing | 1 | 0.319838 | 1.21732 | 25000.0 | Depot | 0.0 | 0.0 | 0 | 0.0 | NullRoute | 0.277793 | 0.0757105 | 0.0962456 | -0.00322968 | 0.0253523 | 0.0692205 | missing | missing | missing | 7.95464 | 313.124 | 0.462908 | 0.0696042 |
2 | 2 - PO | 0.1 | 0.0 | 0.0 | 0.0 | 4.8521 | 0 | missing | missing | missing | missing | missing | missing | missing | missing | missing | 0.277793 | 0.0757105 | 0.0962456 | -0.00322968 | 0.0253523 | 0.0692205 | 0.0 | 0.0 | 0.0 | 7.95464 | 313.124 | 0.462908 | 0.0696042 |
3 | 2 - PO | 0.2 | 0.0 | 0.0 | 0.0 | -2.44076 | 0 | missing | missing | missing | missing | missing | missing | missing | missing | missing | 0.277793 | 0.0757105 | 0.0962456 | -0.00322968 | 0.0253523 | 0.0692205 | 0.0 | 0.0 | 0.0 | 7.95464 | 313.124 | 0.462908 | 0.0696042 |
4 | 2 - PO | 0.3 | 0.0 | 0.0 | 0.0 | 3.24426 | 0 | missing | missing | missing | missing | missing | missing | missing | missing | missing | 0.277793 | 0.0757105 | 0.0962456 | -0.00322968 | 0.0253523 | 0.0692205 | 0.0 | 0.0 | 0.0 | 7.95464 | 313.124 | 0.462908 | 0.0696042 |
5 | 2 - PO | 0.4 | 3.53686 | 3.05311 | 0.0790024 | -2.18722 | 0 | missing | missing | missing | missing | missing | missing | missing | missing | missing | 0.277793 | 0.0757105 | 0.0962456 | -0.00322968 | 0.0253523 | 0.0692205 | 29324.5 | 1107.47 | 0.0790024 | 7.95464 | 313.124 | 0.462908 | 0.0696042 |
@rsubset! df_sim_oral :time > 0.2
8 Visualization
Combined Plot of IV data and Oral data
= [0.3, 0.6, 1, 2, 3, 4, 6, 8, 24, 48, 72, 96, 168]
plasma_times = @rsubset df_sim_iv :time in plasma_times
df_iv_plasma = @rsubset df_sim_oral :time in plasma_times df_oral_plasma
= [24, 48]
urine_times = @rsubset df_sim_iv :time in urine_times
df_iv_urine = @rsubset df_sim_oral :time in urine_times df_oral_urine
= @chain df_sim_iv begin
ivsim_plt @rtransform :Type = "IV Prediction"
dropmissing(:cp)
data(_) *
mapping(
:time => "Time (hours)",
:cp => "Concentration (μg/L) & Amount (μg)",
= :Type,
color *
) visual(Lines, linewidth = 4)
end
= @chain df_iv_plasma begin
iv_plt @rtransform :Type = "IV Observations"
dropmissing(:cp)
data(_) *
mapping(
:time => "Time (hours)",
:cp => "Concentration (μg/L) & Amount (μg)",
= :Type,
color *
) visual(Scatter, color = :blue, markersize = 14)
end
= @chain df_iv_urine begin
ivurine_plt @rtransform :Type = "IV Observations Amount"
dropmissing(:ae)
data(_) *
mapping(
:time => "Time (hours)",
:ae => "Concentration (μg/L) & Amount (μg)",
= :Type,
color *
) visual(ScatterLines, color = :blue, markersize = 14, linewidth = 4)
end
= @chain df_sim_oral begin
oralsim_plt @rtransform :Type = "Oral Prediction"
dropmissing(:cp)
data(_) *
mapping(
:time => "Time (hours)",
:cp => "Concentration (μg/L) & Amount (μg)",
= :Type,
color *
) visual(Lines, linewidth = 4)
end
= @chain df_oral_plasma begin
oral_plt @rtransform :Type = "Oral Observations"
dropmissing(:cp)
data(_) *
mapping(
:time => "Time (hours)",
:cp => "Concentration (μg/L) & Amount (μg)",
= :Type,
color *
) visual(Scatter, markersize = 14)
end
= @chain df_oral_urine begin
oralurine_plt @rtransform :Type = "Oral Observations Amount"
dropmissing(:ae)
data(_) *
mapping(
:time => "Time (hours)",
:ae => "Concentration (μg/L) & Amount (μg)",
= :Type,
color *
) visual(ScatterLines, markersize = 14, linewidth = 4)
end
draw(
+ iv_plt + ivurine_plt + oralsim_plt + oral_plt + oralurine_plt;
ivsim_plt = (;
axis = [0, 20, 40, 60, 80, 100, 120, 140, 160, 180],
xticks = Makie.Symlog10(10),
yscale = [1, 10, 100, 1000, 2000],
yticks = x -> string.(round.(x; digits = 1)),
ytickformat = 3,
ygridwidth = true,
yminorticksvisible = true,
yminorgridvisible = IntervalsBetween(10),
yminorticks = true,
xminorticksvisible = true,
xminorgridvisible = IntervalsBetween(5),
xminorticks
),= (; fontsize = 22),
figure = (position = :bottom, nbanks = 3, tellwidth = true),
legend = (; color = ColorSchemes.tableau_10.colors),
palettes )