using Pumas
using PumasUtilities
using Random
using CairoMakie
using AlgebraOfGraphics
using DataFramesMeta
using CSV
PK51 - Multi-Compartment Drug/Metabolite
1 Learning Outcome
In this tutorial, you will gain a greater appreciation and learn about two compartment parent - metabolite kinetics.
With this modeling exercise, a drug is administered both IV and orally at different occasions to different subjects, and plasma data is collected. The concentrations are obtained for both the drugs and metabolites.
2 Objectives
In this tutorial, you will learn how to build a multi compartment drug/metabolite model and to simulate the model for different subjects and dosage regimens.
3 Background
Before constructing a model, it is important to establish the process the model will follow and a scenario for the simulation.
Below is the scenario for this tutorial:
- Structural model - Multi-Compartment drug/metabolite
- Route of administration - IV administration to one subject and oral administration to another subject
- Dosage Regimen - 5000 mg IV and 8000 mg Oral
- Number of Subjects - 2
This diagram describes how such an administered dose will be handled, which facilitates building the model.
4 Libraries
Call the required libraries to get started.
5 Model
In this two compartment model, we administer the dose to the oral and central compartments on two different occasions.
= @model begin
pk_51 @metadata begin
= "Two Compartment Model with Metabolite Compartment"
desc = u"hr"
timeu end
@param begin
"""
Volume of Central Compartment (L)
"""
∈ RealDomain(lower = 0)
tvvc """
Clearance (L/hr)
"""
∈ RealDomain(lower = 0)
tvcl """
Inter Compartmental Clearance (L/hr)
"""
∈ RealDomain(lower = 0)
tvcld """
Volume of Peripheral Compartment (L)
"""
∈ RealDomain(lower = 0)
tvvt """
Volume of Central Compartment of Metabolite (L)
"""
∈ RealDomain(lower = 0)
tvvcm """
Clearance of metabolite (L/hr)
"""
∈ RealDomain(lower = 0)
tvclm """
Inter Compartmental Clearance of Metabolite (L/hr)
"""
∈ RealDomain(lower = 0)
tvcldm """
Volume of Peripheral Compartment of Metabolite (L)
"""
∈ RealDomain(lower = 0)
tvvtm """
Absorption rate constant (hr⁻¹)
"""
∈ RealDomain(lower = 0)
tvka """
Fraction of drug absorbed
"""
∈ RealDomain(lower = 0)
tvf """
Lag time (hr)
"""
∈ RealDomain(lower = 0)
tvlag ∈ PDiagDomain(7)
Ω """
Proportional RUV - Plasma
"""
∈ RealDomain(lower = 0)
σ²_prop_cp """
Proportional RUV - Metabolite
"""
∈ RealDomain(lower = 0)
σ²_prop_met end
@random begin
~ MvNormal(Ω)
η end
@pre begin
= tvvc * exp(η[1])
Vc = tvcl * exp(η[2])
Cl = tvcld * exp(η[3])
Cld = tvvt * exp(η[4])
Vt = tvvcm
Vcm = tvclm * exp(η[5])
Clm = tvcldm
Cldm = tvvtm * exp(η[6])
Vtm = tvka * exp(η[7])
Ka end
@dosecontrol begin
= (Depot = tvf, Metabolite = (1 - tvf))
bioav = (Depot = tvlag,)
lags end
@dynamics begin
' = -Ka * Depot
Depot' =
Central* Depot - (Cl / Vc) * Central - (Cld / Vc) * Central +
Ka / Vt) * Peripheral
(Cld ' = (Cld / Vc) * Central - (Cld / Vt) * Peripheral
Peripheral' =
Metabolite* Depot + (Cl / Vc) * Central - (Clm / Vcm) * Metabolite -
Ka / Vcm) * Metabolite + (Cldm / Vtm) * PeriMetabolite
(Cldm ' = (Cldm / Vcm) * Metabolite - (Cldm / Vtm) * PeriMetabolite
PeriMetaboliteend
@derived begin
= @. Central / Vc
cp = @. Metabolite / Vcm
met """
Observed Concentration (...)
"""
~ @. Normal(cp, sqrt(cp^2 * σ²_prop_cp))
dv_cp """
Observed Concentration (...)
"""
~ @. Normal(met, sqrt(met^2 * σ²_prop_met))
dv_met end
end
PumasModel
Parameters: tvvc, tvcl, tvcld, tvvt, tvvcm, tvclm, tvcldm, tvvtm, tvka, tvf, tvlag, Ω, σ²_prop_cp, σ²_prop_met
Random effects: η
Covariates:
Dynamical system variables: Depot, Central, Peripheral, Metabolite, PeriMetabolite
Dynamical system type: Matrix exponential
Derived: cp, met, dv_cp, dv_met
Observed: cp, met, dv_cp, dv_met
6 Parameters
The parameters are as given below.
Cl
- Clearance (L/hr)Clm
- Clearance of metabolite (L/hr)Cld
- Inter Compartmental Clearance (L/hr)Cldm
- Inter Compartmental Clearance of metabolite (L/hr)Vc
- Volume of Central Compartment (L)Vcm
- Volume of Central Compartment of Metabolite (L)f
- Fraction of drug absorbedlags
- Lag time (hr)Ka
- Absorption rate constant (hr⁻¹)Vt
- Volume of Peripheral Compartment (L)Vtm
- Volume of Peripheral Compartment of metabolite (L)Ω
- Between Subject Variabilityσ
- Residual error
These are the initial estimates we will be using in this model exercise. Note that tv
represents the typical value for parameters.
= (;
param = 18.7,
tvvc = 0.55,
tvcl = 0.073,
tvcld = 10,
tvvt = 4.9,
tvvcm = 0.08,
tvclm = 0.58,
tvcldm = 55,
tvvtm = 0.03,
tvka = 0.24,
tvf = 21,
tvlag = Diagonal([0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01]),
Ω = 0.015,
σ²_prop_cp = 0.015,
σ²_prop_met )
7 Dosage Regimen
To start the simulation process, the dosing regimen from the background section must be developed first prior to running a simulation.
7.1 IV
A single dose of 5000 mg given as a rapid IV injection.
The dosage regimen is specified as:
= DosageRegimen(5000; 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 | 5000.0 | 1 | 0.0 | 0 | 0.0 | 0.0 | 0 | NullRoute |
This is how to create the single subject undergoing the dosing regimen above.
= Subject(; id = 1, events = ev1) sub1
Subject
ID: 1
Events: 1
7.2 Oral
A single dose of 8000 mg given orally.
The dosage regimen is specified as:
= DosageRegimen(8000; 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 | 8000.0 | 1 | 0.0 | 0 | 0.0 | 0.0 | 0 | NullRoute |
This is how to create the single subject undergoing the dosing regimen above.
= Subject(; id = 2, events = ev2) sub2
Subject
ID: 2
Events: 1
This is how to put both subjects together into a population.
= [sub1, sub2] pop2_sub
Population
Subjects: 2
Observations:
8 Simulation
Simulate using the simobs
function.
Random.seed!()
The Random.seed!
function is included here for purposes of reproducibility of the simulation in this tutorial. Specification of a seed value would not be required in a Pumas workflow that is estimating model parameters.
Random.seed!(123)
= simobs(pk_51, pop2_sub, param, obstimes = 0.1:0.1:1500) sim_pop2_sub
Simulated population (Vector{<:Subject})
Simulated subjects: 2
Simulated variables: cp, met, dv_cp, dv_met
9 Visualization
In the following plots below, we can see the concentration profiles of the parent drug and the metabolite.
@chain DataFrame(sim_pop2_sub) begin
dropmissing(:cp)
data(_) *
mapping(
:time => "Time (hours)",
:cp => "Parent Concentration (-)";
= :id => nonnumeric => "ID",
color *
) visual(Lines; linewidth = 4)
draw(; figure = (; fontsize = 22), axis = (; xticks = 0:150:1500))
end
@chain DataFrame(sim_pop2_sub) begin
dropmissing(:met)
data(_) *
mapping(
:time => "Time (hours)",
:met => "Metabolite Concentration (-)";
= :id => nonnumeric => "ID",
color *
) visual(Lines; linewidth = 4)
draw(; figure = (; fontsize = 22), axis = (; xticks = 0:150:1500))
end
10 Population Simulation
This block updates the parameters of the model to increase intersubject variability in parameters and defines timepoints for prediction of concentrations. The results are written to a CSV file.
Creating a larger population for the simulation and utilizing the following initial estimates for the simulation below:
= (
par = 18.7,
tvvc = 0.55,
tvcl = 0.073,
tvcld = 10,
tvvt = 4.9,
tvvcm = 0.08,
tvclm = 0.58,
tvcldm = 55,
tvvtm = 0.03,
tvka = 0.24,
tvf = 21,
tvlag = Diagonal([0.04, 0.02, 0.02, 0.03, 0.02, 0.04, 0.04]),
Ω = 0.04,
σ²_prop_cp = 0.09,
σ²_prop_met
)
= DosageRegimen(5000, time = 0, cmt = 2)
ev1 = map(i -> Subject(id = i, events = ev1), 1:25)
pop1
= DosageRegimen(8000, time = 0, cmt = 1)
ev2 = map(i -> Subject(id = 1, events = ev2), 26:50) pop2
Simulating the population and obtaining the results.
= [pop1; pop2]
pop
Random.seed!(1234)
= simobs(
sim_pop
pk_51,
pop,
par,= [2, 5, 10, 15, 30, 45, 60, 90, 120, 180, 240, 360, 480, 720, 1440],
obstimes
)sim_plot(sim_pop)
= DataFrame(sim_pop)
df_sim
#CSV.write("pk51.csv", df_sim);
With the CSV.write
function, you can input the name of the dataframe (df_sim
) and the file name of your choice (pk_51.csv
) to save the file to your local directory or repository.
11 Conclusion
Constructing a multi-compartment model involves:
- understanding the process of how the drug and metabolite are passed through the two-compartment system,
- translating processes into ODEs using Pumas, and
- simulating the model in a single patient for evaluation.