Hi,
I am still in the process of exploring the enterohepatic recirculation (EHC) model depicted in my original message. I used a conditional time statement to turn on and off the bile compartment and was able to simulate concentration - time profile emulated the EHC. The simulation code for is below:
ehcmodel = @model begin
@param begin
tvcl β RealDomain(lower=0.0001)
tvvc β RealDomain(lower=0.0001)
tvka β RealDomain(lower=0.0001)
tvkpb β RealDomain(lower=0.0001)
tvkgp β RealDomain(lower=0.0001)
tvk0bile β RealDomain(lower=0.0001)
st_emp β RealDomain(lower=0.0001)
dur β RealDomain(lower=0.0001)
# RUV
Ο_prop β RealDomain(lower=0.0001)
end
@pre begin
Cl = tvcl
Vc = tvvc
Ka = tvka
Kpb = tvkpb
Kgp = tvkgp
k0bile = (t < st_emp || t > st_emp+dur) ? 0 : tvk0bile
end
@dynamics begin
Depot' = - Ka*Depot
Central' = Ka*Depot - (Cl/Vc)*Central - Kpb*Central + Kgp * Gut
Bile' = Kpb*Central - k0bile
Gut' = k0bile - Kgp * Gut
end
@derived begin
cp = @. Central/Vc
dv ~ @. Normal(cp, sqrt((cp*Ο_prop)^2))
end
end
params = (;
tvcl = 4.6,
tvvc = 15,
tvka = 4.0,
tvkpb = 0.5,
tvkgp = 0.5,
tvk0bile = 20,
st_emp = 2,
dur = 3,
Ο_prop = 0.2,
)
## Dosing regimen
ev = DosageRegimen(75; time=0)
## subjects
s1 = Subject(;
id=1,
events=ev,
#covariates=(; Wt=70),
observations=(; dv=nothing),
)
s2 = Subject(;
id=2,
events=ev,
#covariates=(; Wt=70),
observations=(; dv=nothing),
)
twosubjs = [s1,s2]
## SImulation
sims1 = simobs(ehcmodel, twosubjs, params; obstimes=[0, 0.25, 0.5, 1, 1.5, 2, 3, 4, 5,5.5, 6, 8, 10, 12, 14, 16, 18, 24])
I was also able to reestimate the parameters using a NaivePooled approach.
The estimation model is below:
## Estimation of EHC model parameters
check_ehc = DataFrame(sims1)
check_ehc[!, :cmt] .= ifelse.(check_ehc.evid .== 1, 1, 2)
@rsubset! check_ehc !(ismissing(:amt) && :time == 0)
checkehc_fitdata = read_pumas(check_ehc,
id = :id,
time = :time,
amt = :amt,
cmt = :cmt,
observations = [:dv],
evid = :evid)
ehcmodel_est = @model begin
@param begin
tvcl β RealDomain(lower=0.0001)
tvvc β RealDomain(lower=0.0001)
tvka β RealDomain(lower=0.0001)
tvkpb β RealDomain(lower=0.0001)
tvkgp β RealDomain(lower=0.0001)
tvk0bile β RealDomain(lower=0.0001)
st_emp β RealDomain(lower=0.0001)
dur β RealDomain(lower=0.0001)
# RUV
Ο_prop β RealDomain(lower=0.0001)
end
@pre begin
Cl = tvcl
Vc = tvvc
Ka = tvka
Kpb = tvkpb
Kgp = tvkgp
k0bile = (t < st_emp || t > st_emp+dur) ? 0 : tvk0bile
end
@dynamics begin
Depot' = - Ka*Depot
Central' = Ka*Depot - (Cl/Vc)*Central - Kpb*Central + Kgp*Gut
Bile' = Kpb*Central - k0bile
Gut' = k0bile - Kgp * Gut
end
@derived begin
cp = @. Central/Vc
dv ~ @. Normal(cp, sqrt((cp*Ο_prop)^2))
end
end
params_ehc = (;
tvcl = 2.5,
tvvc = 15,
tvka = 2.5,
tvkpb = 0.5,
tvkgp = 0.5,
tvk0bile = 5,
st_emp = 2,
dur = 3,
Ο_prop = 0.2
)
pkfit_1cmt_ehc_np = fit(ehcmodel_est,
checkehc_fitdata,
params_ehc,
Pumas.NaivePooled(),
constantcoef = (st_emp = 2.0, dur = 3.0,))
I get reasonable estimates and the fit seems adequate.
However, when I do a two stage analysis, k0bile
is not estimated rather it takes the value 0
as mentioned in the conditional statement.
## Zero order bile - 2 stage
pkfit_2cmt_ehc = [fit(ehcmodel_est,
checkehc_fitdata[i],
params_ehc,
constantcoef = (st_emp = 2.0, dur = 3.0,)) for i in 1:length(checkehc_fitdata)]
2Γ8 DataFrame
Row β id time Cl Vc Ka Kpb Kgp k0bile
β String Float64 Float64 Float64 Float64 Float64 Float64 Float64
ββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1 β 1 0.0 3.92074 17.4281 5.71104 0.435616 0.521555 0.0
2 β 2 0.0 4.34398 13.8105 2.983 0.526967 0.508399 0.0
Any reason why that could be the case with the 2-stage approach?
Thanks.