Example 1 — Theophylline (FO)

Model: 1-compartment oral, First Order estimation Script: examples/01_theophylline_fo.py

This example fits the classic theophylline dataset using the simplest estimation method (FO) as a quick sanity check before moving to FOCE.

Model

from openpkpd import ModelBuilder

result = (
    ModelBuilder()
    .problem("Theophylline 1-cmt oral FO")
    .data("theo.csv")
    .subroutines(advan=2, trans=2)
    .pk("""
        KA = THETA(1) * EXP(ETA(1))
        CL = THETA(2) * EXP(ETA(2))
        V  = THETA(3) * EXP(ETA(3))
    """)
    .error("Y = F * (1 + EPS(1))")
    .theta([(0.01, 1.5, 20),
            (0.001, 0.08, 5),
            (0.1, 30, 500)])
    .omega([0.5, 0.3, 0.3])
    .sigma(0.1)
    .estimation(method="FO", maxeval=500)
    .build()
    .fit()
)

print(result.summary())

Output

openpkpd/estimation/fo.py:114: UserWarning: ETA1 shrinkage is 100.0% (>30%). EBE-based analyses for this parameter may be unreliable.
  res.compute_shrinkage()
openpkpd/estimation/fo.py:114: UserWarning: ETA2 shrinkage is 100.0% (>30%). EBE-based analyses for this parameter may be unreliable.
  res.compute_shrinkage()
openpkpd/estimation/fo.py:114: UserWarning: ETA3 shrinkage is 100.0% (>30%). EBE-based analyses for this parameter may be unreliable.
  res.compute_shrinkage()
Running FO estimation...
Method: FO
OFV: 79.9530
AIC: 99.9530
BIC: inf   (n_obs = 0)
n_parameters: 10
Converged: True
THETA: [1.58304071 0.02599308 0.34647754]
OMEGA (diagonal): [0.69708405 0.12915556 0.02771835]
SIGMA (diagonal): [0.47038956]
ETA shrinkage: ['100.0%', '100.0%', '100.0%']
Shrinkage warnings:
  ETA1 shrinkage is 100.0% (>30%). EBE-based analyses for this parameter may be unreliable.
  ETA2 shrinkage is 100.0% (>30%). EBE-based analyses for this parameter may be unreliable.
  ETA3 shrinkage is 100.0% (>30%). EBE-based analyses for this parameter may be unreliable.

KA = 1.5830 hr⁻¹
CL = 0.0260 L/hr
V  = 0.3465 L
Figures saved to docs/_static/examples

Figures

Spaghetti plot Concentration-time

Notes

  • FO post-hoc ETAs are all zero (no inner optimisation loop).

  • Use Example 2 — Warfarin (FOCE) to compare FOCE results on a similar dataset.

  • CWRES ≈ WRES for FO (no conditional residuals).