Migrating from Monolix
This page maps Monolix 2024R1 / Mlxtran concepts to their OpenPKPD equivalents. It also highlights the key data-format and parameterisation differences you will encounter when converting an existing Monolix project.
For the current support classification behind the mappings below, see
validation_matrix.md. In particular, some estimator
surfaces map cleanly at the API level while still having narrower empirical
validation breadth than the mature Monolix workflow.
No Mlxtran parser yet. OpenPKPD does not currently parse
.mlxtranproject files automatically. Migration is done by re-expressing the model in the PythonModelBuilderAPI (or a NONMEM-style control stream). A Mlxtran parser is on the roadmap. The NONMEM migration guide covers parsing existing.ctlfiles if you prefer to go via NONMEM syntax.
Concept mapping
Monolix concept |
OpenPKPD equivalent |
|---|---|
|
|
|
|
|
|
|
|
Monolix project |
|
Structural model library |
|
|
|
|
|
|
|
Diagnostic plots panel |
|
Simulation tab |
|
Data format
Monolix CSV (semicolon-delimited)
Monolix project data typically uses semicolons and Mlxtran column names:
id;time;amt;y;wt;evid
1;0;4.02;;70;1
1;0.25;;2.84;;0
1;0.5;;6.57;;0
NONMEM-style CSV (OpenPKPD)
OpenPKPD uses comma-delimited NONMEM format with standardised column names:
ID,TIME,AMT,DV,WT,EVID,MDV
1,0,4.02,.,70,1,1
1,0.25,.,2.84,.,0,0
1,0.5,.,6.57,.,0,0
Key differences:
Monolix convention |
OpenPKPD / NONMEM convention |
|---|---|
Semicolon ( |
Comma ( |
|
|
|
|
|
|
Blank / |
|
Dose in mg/kg (some models) |
Dose in absolute units; divide |
No |
|
Convert a Monolix CSV file:
import pandas as pd
df = pd.read_csv("monolix_data.csv", sep=";")
df = df.rename(columns={"id": "ID", "time": "TIME", "amt": "AMT",
"y": "DV", "evid": "EVID"})
df["MDV"] = (df["EVID"] == 1).astype(int)
df["DV"] = df["DV"].fillna(".")
df.to_csv("openpkpd_data.csv", index=False)
Parameter conventions
Fixed effects — natural scale vs log scale
Monolix reports fixed effects on the natural scale with _pop suffix:
Monolix |
Meaning |
NONMEM / OpenPKPD |
|---|---|---|
|
Population absorption rate (h⁻¹) |
|
|
Population volume (L/kg or L) |
|
|
Population clearance (L/h) |
|
For log-normal IIV (logNormal distribution in Mlxtran), the NONMEM / OpenPKPD
$PK block exponentiates:
; Monolix: ka ~ logNormal(ka_pop, omega_ka)
CL = THETA(3) * EXP(ETA(3))
V = THETA(2) * EXP(ETA(2))
KA = THETA(1) * EXP(ETA(1))
Random effects — SD vs variance
Monolix omega_X is a standard deviation; NONMEM/OpenPKPD $OMEGA stores
variance. Square the Monolix value when initialising:
# Monolix: omega_ka = 0.45, omega_V = 0.26, omega_Cl = 0.33
model.omega([0.45**2, 0.26**2, 0.33**2]) # variances
Residual error
Monolix combined error a + b * f:
Monolix parameter |
Meaning |
NONMEM / OpenPKPD |
|---|---|---|
|
Additive SD |
|
|
Proportional CV (fraction) |
|
; Monolix: y = f + (a + b*f)*eps, a=0.3, b=0.1
Y = F + (THETA(4) + THETA(5)*F) * EPS(1)
OpenPKPD $ERROR / .error():
model.error("Y = F + (A_ERR + B_ERR*F)*EPS(1)")
model.theta([(0, 0.3, None), (0, 0.1, None)], labels=["A_ERR", "B_ERR"])
model.sigma([1.0]) # EPS(1) is N(0,1); SD carried by THETA(4,5)
Estimation settings
Monolix setting |
OpenPKPD equivalent |
|---|---|
|
|
|
|
|
Controlled by |
|
|
|
|
|
|
Practical migration guidance:
prefer
FOCE/FOCEIfirst when validating a migrated Monolix modeltreat
SAEMas a secondary but real OpenPKPD surface: it has empirical anchors, but not Monolix-grade breadth across all model families yetprefer
IMPMAPover rawIMPwhen you want a MAP-style importance-sampling path on a basin-sensitive modeltreat
BAYES(Laplace)as a fast weak-prior summary path and nativeBAYES(NUTS)as an experimental / second-tier backend today
Worked example — Theophylline 1-compartment oral (SAEM)
This example reproduces the public Monolix 2024R1 theophylline project (available at monolixsuite.slp-software.com) using OpenPKPD.
Reference Monolix parameters (natural scale)
Parameter |
Monolix value |
Source |
|---|---|---|
|
1.533 h⁻¹ |
monolix2rx article |
|
0.456 L/kg |
monolix2rx article |
|
0.0402 L/h/kg |
monolix2rx article |
Dose normalisation: the Monolix theophylline project encodes
AMTin mg/kg. In the OpenPKPD dataset use absolute mg; divide by body weight in$PK(seeCL = THETA(3)/WT).
OpenPKPD model
from openpkpd import ModelBuilder, fit
model = (
ModelBuilder()
.problem("Theophylline 1-cmt oral — from Monolix")
.data("examples/shared_data/theophylline/theophylline.csv")
.subroutines(advan=2, trans=2) # 1-cmt oral, CL/V/KA
.pk("""
KA = THETA(1) * EXP(ETA(1))
V = THETA(2) * EXP(ETA(2)) * WT # V in L; Monolix reports L/kg
CL = THETA(3) * EXP(ETA(3)) * WT # CL in L/h; Monolix reports L/h/kg
""")
.error("Y = F + (THETA(4) + THETA(5)*F) * EPS(1)")
# Monolix natural-scale starting values
.theta([(0, 1.53, None), # KA
(0, 0.456, None), # V (L/kg, scaled by WT in $PK)
(0, 0.0402, None), # CL (L/h/kg, scaled by WT)
(0, 0.3, None), # Additive error SD
(0, 0.1, None)]) # Proportional error CV
# Monolix omega values squared (SD→variance)
.omega([0.45**2, 0.26**2, 0.33**2])
.sigma([1.0])
.estimation(method="SAEM")
)
result = fit(model)
print(result.summary())
Expected final estimates (within ±15% of Monolix):
THETA 1 (KA): ~1.5 h⁻¹
THETA 2 (V): ~0.48 L/kg
THETA 3 (CL): ~0.040 L/h/kg
OMEGA 1 (KA): ~0.20 (SD ~0.45)
OMEGA 2 (V): ~0.069 (SD ~0.26)
OMEGA 3 (CL): ~0.11 (SD ~0.33)
The external validation suite (tests/external_validation/test_vs_monolix.py)
runs this comparison automatically and checks agreement within 15% on all
population parameters.
Output file mapping
Monolix output |
OpenPKPD equivalent |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Plots (in |
|
Covariate effects
Monolix syntax |
OpenPKPD |
|---|---|
|
|
|
|
|
|
Categorical: |
|
Automated covariate search (equivalent to Monolix’s COSSAC):
from openpkpd.covariate import AMD
amd = AMD(base_model=model, covariates=["WT", "SEX", "AGE"],
parameters=["CL", "V"], method="SCM")
result = amd.run()
print(result.selected_covariates)
Current limitations
Feature |
Status |
|---|---|
Mlxtran |
Not yet implemented; on roadmap |
COSSAC covariate method |
Not implemented; SCM + FREM available |
Monolix |
Not yet implemented |
Stochastic approximation EM with Rao-Blackwellisation |
Multi-chain MH SAEM available; full Rao-Blackwell pending |
Monolix |
PyMC-backed MCMC available; native NUTS exists but is still second-tier |
Monolix Charts auto-layout |
Individual plots available; layout wizard not yet |