using PumasUtilities
using Pumas
using Random
using CairoMakie
using AlgebraOfGraphics
using CSV
using DataFramesMeta
using Dates
PK04 (Part 1) - One-compartment oral dosing
1 Background
- Structural model - One compartment linear elimination with first order absorption.
- Route of administration - Oral, Multiple dosing
- Dosage Regimen - 352.3 μg
- Number of Subjects - 1

We recommend reading our introductory tutorial on PK02 - One-compartment oral dosing for comparison.
2 Learning Outcome
This exercise demonstrates simulating multiple oral dosing kinetics from a one compartment model. In the exercise PK04, four models are compared.
- Model 1 - One compartment model without lag-time, distinct parameters Ka and K
- Model 2 - One compartment model with lag time, distinct parameters Ka and K
- Model 3 - One compartment model without lag time, Ka = K = K¹
- Model 4 - One compartment model with lag time, Ka = K = K¹
Models 1 and 2 are included in this tutorial, while models 3 and 4 are included in the second part of this tutorial.
3 Objectives
To build a one-compartment model, simulate the model for a single subject given a multiple oral dosing, and subsequently perform a simulation for a population.
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.
In this one compartment model, we administer multiple doses orally.
pk_04_1_2 = @model begin
@metadata begin
desc = "One Compartment Model"
timeu = u"hr"
end
@param begin
"""
Absorption Rate constant (1/hr)
"""
tvka ∈ RealDomain(lower = 0)
"""
Elimination Rate Constant (1/hr)
"""
tvk ∈ RealDomain(lower = 0)
"""
Volume of Distribution (L)
"""
tvvc ∈ RealDomain(lower = 0)
"""
Lag-time (hr)
"""
tvlag ∈ RealDomain(lower = 0)
Ω ∈ PDiagDomain(3)
"""
Proportional RUV
"""
σ²_prop ∈ RealDomain(lower = 0)
end
@random begin
η ~ MvNormal(Ω)
end
@pre begin
Ka = tvka * exp(η[1])
K = tvk * exp(η[2])
Vc = tvvc * exp(η[3])
end
@dosecontrol begin
lags = (Depot = tvlag,)
end
@dynamics begin
Depot' = -Ka * Depot
Central' = Ka * Depot - K * Central
end
@derived begin
"""
PK04 Concentration (μg/L)
"""
cp = @. Central / Vc
"""
PK04 Concentration (μg/L)
"""
dv ~ @. Normal(cp, sqrt(cp^2 * σ²_prop))
end
endPumasModel
Parameters: tvka, tvk, tvvc, tvlag, Ω, σ²_prop
Random effects: η
Covariates:
Dynamical system variables: Depot, Central
Dynamical system type: Matrix exponential
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 (hr⁻¹),K- Elimination Rate Constant (hr⁻¹),Vc- Volume of Central Compartment(L),Ω- Between Subject Variability,σ- Residual error
A vector of model parameter values is defined.
param = [
(
tvka = 0.14,
tvk = 0.14,
tvvc = 56.6,
tvlag = 0.00,
Ω = Diagonal([0.01, 0.01, 0.01]),
σ²_prop = 0.015,
),
(
tvka = 0.20,
tvk = 0.12,
tvvc = 64.9,
tvlag = 3.0,
Ω = Diagonal([0.01, 0.01, 0.01]),
σ²_prop = 0.01,
),
]7 Dosage Regimen
Dosage Regimen - 352.3 μg of oral dose once a day for 10 days.
ev1 = DosageRegimen(352.3, time = 0, ii = 24, addl = 9, cmt = 1)| 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 | 352.3 | 1 | 24.0 | 9 | 0.0 | 0.0 | 0 | NullRoute |
8 Define a single-individual that receives the defined dose
pop = map(
i -> Subject(id = i, events = ev1, observations = (cp = nothing,)),
["1: No Lag", "1: With Lag"],
)Population
Subjects: 2
Observations: cp
9 Simulation
Simulate the plasma concentration of the drug after multiple oral dosing.
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.
sim = map(zip(pop, param)) do (subj, p)
return simobs(pk_04_1_2, subj, p, obstimes = 0:0.1:240)
endSimulated population (Vector{<:Subject})
Simulated subjects: 2
Simulated variables: cp, dv
10 Visualize Results
@chain DataFrame(sim) begin
dropmissing(:cp)
data(_) *
mapping(
:time => "Time (hours)",
:cp => "PK04 Concentration (μg/L)",
color = :id => "",
) *
visual(Lines, linewidth = 4)
draw(; axis = (; xticks = 0:24:240,), figure = (; fontsize = 22))
end11 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).
par2 = (
tvka = 0.20,
tvk = 0.12,
tvvc = 64.9,
tvlag = 3.0,
Ω = Diagonal([0.0326, 0.048, 0.096]),
σ²_prop = 0.019,
)
ev1 = DosageRegimen(352.3, time = 0, ii = 24, addl = 9, cmt = 1)
pop = map(i -> Subject(id = 1, events = ev1), 1:40)
Random.seed!(1234)
pop_sim = simobs(pk_04_1_2, pop, par2, obstimes = 0:1:240)
pkdata_04_1_2_sim = DataFrame(pop_sim)
#CSV.write("pk_04_1_2_sim.csv", pkdata_04_1_2_sim)12 Conclusion
This tutorial showed how to build a one compartement model with and without lag time and performing a single subject and population simulation.