Example 6 — Running a Control Stream File

Script: examples/06_from_control_stream.py

Demonstrates parsing and running an existing NONMEM .ctl file directly, without any Python model building.

Output

openpkpd/estimation/fo.py:123: UserWarning: ETA1 shrinkage is 100.0% (>30%). EBE-based analyses for this parameter may be unreliable.
  res.compute_shrinkage()
openpkpd/estimation/fo.py:123: UserWarning: ETA2 shrinkage is 100.0% (>30%). EBE-based analyses for this parameter may be unreliable.
  res.compute_shrinkage()
openpkpd/estimation/fo.py:123: UserWarning: ETA3 shrinkage is 100.0% (>30%). EBE-based analyses for this parameter may be unreliable.
  res.compute_shrinkage()
Parsed control stream:
  Problem: Theophylline via control stream
  ADVAN: 2
  n_theta: 4

Running estimation (equivalent to $ESTIMATION METHOD=ZERO)...
Method: FO
OFV: 74.9139
AIC: 88.9139
BIC: 98.7222   (n_obs = 30)
n_parameters: 7
Converged: True
THETA: [1.65810486 0.04014889 0.40395477 0.11719668]
OMEGA (diagonal): [1.14171649 0.01007501 0.0016058 ]
SIGMA (diagonal): [1.]
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.

From Python

from openpkpd.parser.control_stream import ControlStream
from openpkpd.cli.runner import run_model

# Parse only — inspect records without fitting
cs = ControlStream.from_file("run001.ctl")
print(cs.problem.title)
print(cs.estimation_records[0].method)
print(cs.theta_records[0].specs)

# Parse + fit
result = run_model("run001.ctl")
print(result.summary())

From the CLI

# Run with default settings
openpkpd run run001.ctl

# Override method
openpkpd run run001.ctl --method FOCE --verbose

# Inspect records only (no estimation)
openpkpd parse run001.ctl
openpkpd parse run001.ctl --json   # Machine-readable JSON

Minimal .ctl file

$PROBLEM Theophylline 1-compartment oral FO
$DATA theo.csv IGNORE=#
$INPUT ID TIME AMT DV EVID
$SUBROUTINES ADVAN2 TRANS2
$PK
  KA = THETA(1)*EXP(ETA(1))
  CL = THETA(2)*EXP(ETA(2))
  V  = THETA(3)*EXP(ETA(3))
$ERROR
  IPRED = F
  W = THETA(4) * IPRED
  Y = IPRED + W * EPS(1)
$THETA (0.01,1.5,20) (0,0.04,2) (0,0.50,5) (0.01,0.10,0.50)
$OMEGA 0.48 0.07 0.02
$SIGMA 1 FIXED
$ESTIMATION METHOD=ZERO MAXEVAL=500
$COVARIANCE
$TABLE ID TIME DV PRED IPRED CWRES NOAPPEND NOPRINT FILE=sdtab

Supported ESTIMATION keywords

NM-TRAN METHOD=

OpenPKPD internal

ZERO

"FO"

COND

"FOCE"

COND INTER

"FOCE" + interaction

COND LAPLACE

"LAPLACIAN"

SAEM

"SAEM"

IMP

"IMP"

Notes

  • Column auto-mapping reads $INPUT and matches names to the dataset.

  • If EVID is absent from $INPUT, it is auto-generated from AMT.

  • IGNORE=# causes rows starting with # to be skipped.

  • OpenPKPD writes .lst, .ext, .phi, .cov, .cor to the same directory as the .ctl file.