using PumasUtilities
using Random
using Pumas
using CairoMakie
using AlgebraOfGraphics
using CSV
using DataFramesMeta
using Dates
PK12 - Intravenous and oral dosing
1 Background
To determine (oral) bioavailability, the drug is administered by both oral and intravenous routes. The administration is generally done in a crossover manner at different times, separated by a washout period. But if the drug follows a time-dependent clearance (and if the washout period is long), then it may affect the results. To avoid this situation, the doses can be administered semi-simultaneously, separated by a small time up to 1 hour.
In the current study, the test drug was administered orally, followed by a constant rate infusion (reference) for 15 minutes at 60 minutes.
- Structural model - Two compartment model with first order absorption and elimination
- Route of administration - Oral and IV given simultaneously
- Dosage Regimen - 2.5 mg Oral and 0.5 mg IV infusion for 15 minutes
- Number of Subjects - 1
2 Learning Outcomes
This exercise demonstrates the bioavailability of a compound administered semi-simultaneously by oral and intravenous routes.
3 Objectives
- To build a two-compartment model for semi-simultaneous oral and intravenous administration
- To design a semi-simultaneous dosage regimen
- To simulate and plot a single subject with predefined time points.
4 Libraries
Load the necessary libraries.
5 Model definition
Note the expression of the model parameters with helpful comments. The model is expressed with differential equations. Residual variability is a proportional error model.
A two compartment model with oral absorption is built for a semi-simultaneous administration of an oral dose followed by intravenous infusion.
= @model begin
pk_12 @metadata begin
= "Two Compartment Model"
desc = u"minute"
timeu end
@param begin
"""
Absorption Rate Constant (min⁻¹)
"""
∈ RealDomain(lower = 0)
tvka """
Clearance (L/min/kg)
"""
∈ RealDomain(lower = 0)
tvcl """
Inter-compartmental distribution (L/kg)
"""
∈ RealDomain(lower = 0)
tvq """
Volume of Central Compartment (L/kg)
"""
∈ RealDomain(lower = 0)
tvvc """
Volume of Peripheral Compartment (L/kg)
"""
∈ RealDomain(lower = 0)
tvvp """
Lag time (min)
"""
∈ RealDomain(lower = 0)
tvlag """
Bioavailability
"""
∈ RealDomain(lower = 0)
tvF ∈ RealDomain(lower = 0.0001)
Ω_ka ∈ RealDomain(lower = 0.0001)
Ω_cl ∈ RealDomain(lower = 0.0001)
Ω_q ∈ RealDomain(lower = 0.0001)
Ω_vc ∈ RealDomain(lower = 0.0001)
Ω_vp ∈ RealDomain(lower = 0.0001)
Ω_lag ∈ RealDomain(lower = 0.0001)
Ω_F """
Proportional RUV
"""
∈ RealDomain(lower = 0)
σ²_prop end
@random begin
~ Normal(0, sqrt(Ω_ka))
η_ka ~ Normal(0, sqrt(Ω_cl))
η_cl ~ Normal(0, sqrt(Ω_q))
η_q ~ Normal(0, sqrt(Ω_vc))
η_vc ~ Normal(0, sqrt(Ω_vp))
η_vp ~ Normal(0, sqrt(Ω_lag))
η_lag ~ Normal(0, sqrt(Ω_F))
η_F end
@pre begin
= tvcl * exp(η_cl)
CL = tvq * exp(η_q)
Q = tvvc * exp(η_vc)
Vc = tvvp * exp(η_vp)
Vp = tvka * exp(η_ka)
Ka end
@dosecontrol begin
= (Depot = tvlag * exp(η_lag),)
lags = (Depot = tvF * exp(η_F),)
bioav end
@dynamics Depots1Central1Periph1
@derived begin
= @. 1000 * (Central / Vc)
cp """
Observed Concentrations (μg/L)
"""
~ @. Normal(cp, sqrt(cp^2 * σ²_prop))
dv end
end
PumasModel
Parameters: tvka, tvcl, tvq, tvvc, tvvp, tvlag, tvF, Ω_ka, Ω_cl, Ω_q, Ω_vc, Ω_vp, Ω_lag, Ω_F, σ²_prop
Random effects: η_ka, η_cl, η_q, η_vc, η_vp, η_lag, η_F
Covariates:
Dynamical system variables: Depot, Central, Peripheral
Dynamical system type: Closed form
Derived: cp, dv
Observed: cp, dv
6 Initial Estimates of Model Parameters
The model parameters for simulation are the following. Note that tv
represents the typical value for parameters.
Ka
- Absorption Rate Constant (min⁻¹)Cl
- Clearance (L/min/kg)Q
- Inter-compartmental distribution (L/kg)Vc
- Volume of Central Compartment (L/kg)Vp
- Volume of Peripheral Compartment (L/kg)lag
- Lag time (min)F
- Bioavailabilityσ
- Residual Error
= (
param = 0.103,
tvka = 0.015,
tvcl = 0.021,
tvq = 0.121,
tvvc = 0.276,
tvvp = 4.68,
tvlag = 0.046,
tvF = 0.01,
Ω_ka = 0.01,
Ω_cl = 0.01,
Ω_q = 0.01,
Ω_vc = 0.01,
Ω_vp = 0.01,
Ω_lag = 0.01,
Ω_F = 0.04,
σ²_prop )
7 Dosage Regimen
Dosage Regimen - 2.5 mg/kg orally followed by a 15 minute intravenous infusion of 0.5 mg/kg starting 60 minutes after oral dosing, administered to a single subject (sub1
).
= DosageRegimen(2.5, time = 0, cmt = 1) ev_oral
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 | 2.5 | 1 | 0.0 | 0 | 0.0 | 0.0 | 0 | NullRoute |
= DosageRegimen(0.5, time = 60, cmt = 2, duration = 15) ev_inf
Row | time | cmt | amt | evid | ii | addl | rate | duration | ss | route |
---|---|---|---|---|---|---|---|---|---|---|
Float64 | Int64 | Float64 | Int8 | Float64 | Int64 | Float64 | Float64 | Int8 | NCA.Route | |
1 | 60.0 | 2 | 0.5 | 1 | 0.0 | 0 | 0.0333333 | 15.0 | 0 | NullRoute |
= DosageRegimen(ev_oral, ev_inf) 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 | 1 | 2.5 | 1 | 0.0 | 0 | 0.0 | 0.0 | 0 | NullRoute |
2 | 60.0 | 2 | 0.5 | 1 | 0.0 | 0 | 0.0333333 | 15.0 | 0 | NullRoute |
8 Single-individual that receives the defined dose
= Subject(id = 1, events = ev1, observations = (cp = nothing,)) sub1
Subject
ID: 1
Events: 2
Observations: cp: (n=0)
9 Single-Subject Simulation
Simulate plasma concentrations with specific observation time points
Initialize the random number generator with a seed for reproducibility of the simulation.
Random.seed!(123)
Define the timepoints at which concentration values will be simulated.
= simobs(
sim_s1
pk_12,
sub1,
param,= [6, 10, 15, 20, 30, 45, 60, 63, 66, 75, 80, 90, 107, 119, 134, 150],
obstimes )
SimulatedObservations
Simulated variables: cp, dv
Time: [6, 10, 15, 20, 30, 45, 60, 63, 66, 75, 80, 90, 107, 119, 134, 150]
10 Visualize Results
@chain DataFrame(sim_s1) begin
dropmissing(:cp)
data(_) *
mapping(:time => "Time (minutes)", :cp => "Concentration (μg/L)") *
visual(Lines; linewidth = 4)
draw(;
= (; fontsize = 22),
figure = (;
axis = Makie.pseudolog10,
yscale = map(i -> 10^i, 1:0.5:3),
yticks = x -> string.(round.(x; digits = 1)),
ytickformat = 0:20:160,
xticks
),
)end
11 Perform a Population Simulation
We perform a population simulation with 40 participants.
This code demonstrates how to write the simulated concentrations to a comma separated file (.csv
).
= (
par = 0.103,
tvka = 0.015,
tvcl = 0.021,
tvq = 0.121,
tvvc = 0.276,
tvvp = 4.68,
tvlag = 0.046,
tvF = 0.0625,
Ω_ka = 0.0016,
Ω_cl = 0.0169,
Ω_q = 0.0064,
Ω_vc = 0.0121,
Ω_vp = 0.0144,
Ω_lag = 0.0144,
Ω_F = 0.04,
σ²_prop
)
= DosageRegimen([2.5, 0.5], time = [0, 60], cmt = [1, 2], duration = [0, 15])
ev1 = map(i -> Subject(id = i, events = ev1), 1:40)
pop
Random.seed!(1234)
= simobs(pk_12, pop, par, obstimes = 0:1:150)
pop_sim = DataFrame(pop_sim)
pkdata_12_sim #CSV.write("pk_12_sim.csv", pkdata_12_sim)
12 Conclusion
This tutorial showed how to build a two-compartment model for semi-simultaneous oral and intravenous administration and perform a single subject and population simulation.