using Random
using Pumas
using PumasUtilities
using CairoMakie
using AlgebraOfGraphics
using DataFramesMeta
using CSV
using Dates
PK48 - One-compartment Michaelis-Menten kinetics - Drug and metabolite in urine
1 Background
- Structural model - One Compartment Michaelis Menten Kinetics, Drug and metabolite in Urine
- Route of administration - IV bolus
- Dosage Regimen - 500 μmol IV
- Number of Subjects - 1
2 Learning Outcome
In this model, you will learn
- To build a one compartment model for the drug given Intravenous Bolus dosage, following Michaelis Menten Kinetics.
- To apply differential equations in the model as per the compartment model.
3 Objectives
In this tutorial, you will learn how to build a one compartment Michaelis Menten Kinetics model, with drug and metabolite in urine.
4 Libraries
Call the necessary libraries to get started
5 Model
In this one compartment model, we administer the dose on the Central compartment.
= @model begin
pk_48 @metadata begin
= "One Compartment Michaelis Menten Kinetics Model"
desc = u"hr"
timeu end
@param begin
"""
Maximum rate of metabolism (μM/hr)
"""
∈ RealDomain(lower = 0)
tvvmax """
Michaelis Menten Constant (μM)
"""
∈ RealDomain(lower = 0)
tvkm """
Renal Clearance (L/hr)
"""
∈ RealDomain(lower = 0)
tvclr """
Central Volume of Distribution (L)
"""
∈ RealDomain(lower = 0)
tvvc ∈ PDiagDomain(4)
Ω """
Proportional RUV
"""
∈ RealDomain(lower = 0)
σ²_prop end
@random begin
~ MvNormal(Ω)
η end
@pre begin
= tvvmax * exp(η[1])
Vmax = tvkm * exp(η[2])
Km = tvclr * exp(η[3])
Clr = tvvc * exp(η[4])
Vc end
@vars begin
:= Vmax * (Central / Vc) / (Km + (Central / Vc))
VMKM end
@dynamics begin
' = -VMKM - (Clr / Vc) * Central
Central' = (Clr / Vc) * Central
UrineP' = VMKM
UrineMend
@derived begin
= @. Central / Vc
cp = @. UrineP
ae_p = @. UrineM
ae_m """
Observed Concentration (μmol/L)
"""
~ @. Normal(cp, sqrt(cp^2 * σ²_prop))
dv """
Observed Amount (μmol)
"""
~ @. Normal(ae_p, sqrt(cp^2 * σ²_prop))
dv_aep """
Observed Amount (μmol)
"""
~ @. Normal(ae_m, sqrt(cp^2 * σ²_prop))
dv_aem end
end
PumasModel
Parameters: tvvmax, tvkm, tvclr, tvvc, Ω, σ²_prop
Random effects: η
Covariates:
Dynamical system variables: Central, UrineP, UrineM
Dynamical system type: Nonlinear ODE
Derived: cp, ae_p, ae_m, dv, dv_aep, dv_aem
Observed: cp, ae_p, ae_m, dv, dv_aep, dv_aem
6 Parameters
The parameters are as given below. Note that tv
represents the typical value for parameters.
Vmax
- Maximum rate of metabolism (μM/hr)Km
- Michaelis Menten Constant (μM)Clr
- Renal Clearance (L/hr)Vc
- Central Volume of Distribution (L)Ω
- Between Subject Variabilityσ
- Residual error
= (;
param = 51.4061,
tvvmax = 5.30997,
tvkm = 2.46764,
tvclr = 24.5279,
tvvc = Diagonal([0.04, 0.04, 0.04, 0.04]),
Ω = 0.02,
σ²_prop )
7 Dosage Regimen
Intravenous bolus dosing of 500 μmol to a single subject at time=0
.
= DosageRegimen(500, cmt = 1, time = 0) ev1
1×10 DataFrame
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 | 500.0 | 1 | 0.0 | 0 | 0.0 | 0.0 | 0 | NullRoute |
= Subject(id = 1, events = ev1) sub1
Subject
ID: 1
Events: 1
8 Simulation
Let’s simulate for plasma concentration with the specific observation time points after the IV bolus dose. Since we are simulating only a single subject, we can zero out the random effects
= zero_randeffs(pk_48, sub1, param) zfx
(η = [0.0, 0.0, 0.0, 0.0],)
Random.seed!(123)
= simobs(pk_48, sub1, param, zfx, obstimes = 0.1:0.1:15) sim_sub1
SimulatedObservations
Simulated variables: cp, ae_p, ae_m, dv, dv_aep, dv_aem
Time: 0.1:0.1:15.0
9 Visualization
= @chain DataFrame(sim_sub1) begin
df dropmissing!(:cp)
@rsubset :time ∈ [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 15]
stack([:cp, :ae_p, :ae_m])
end
=
plt data(df) *
mapping(
:time => "Time (hrs)",
:value,
= :variable =>
color renamer([
"cp" => "Parent Plasma Concentration",
"ae_p" => "Parent Urine Amount",
"ae_m" => "Metabolite Urine Amount",
=> "Variable",
]) *
) visual(ScatterLines; linewidth = 4, markersize = 12)
= Figure()
fig = fig[1, 1]
gridpos
= draw!(
f
gridpos,
plt,= (;
axis = log10,
yscale = i -> (@. string(round(i; digits = 1))),
ytickformat = 0:2:16,
xticks = "PK48 Concentrations (μmol/L) & Amount (μmol)",
ylabel
),
)legend!(
gridpos,
f;= false,
tellwidth = :right,
halign = :center,
valign = (10, 10, 10, 10),
margin
) fig
10 Population simulation
= (;
par = 51.4061,
tvvmax = 5.30997,
tvkm = 2.46764,
tvclr = 24.5279,
tvvc = Diagonal([0.0432, 0.0368, 0.0213, 0.0123]),
Ω = 0.00140536,
σ²_prop
)
= DosageRegimen(500, cmt = 1, time = 0)
ev1 = map(i -> Subject(id = i, events = ev1), 1:55)
pop
Random.seed!(1234)
= simobs(pk_48, pop, par, obstimes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 15])
pop_sim sim_plot(pop_sim)
= DataFrame(pop_sim)
df_sim
#CSV.write("pk_48.csv", df_sim)