Validation
Educational model, not for clinical dosing. This page checks that MaatiRx solves its own model correctly. It does not show that the model predicts real patients. The model itself, equation by equation, is in Model and methods.
Running the checks in your browser…
The 146 scenarios' peaks, troughs, areas and times in window, the 20 Bayesian estimates' clearance and volume, the 12 antimicrobial regimens' fT>MIC, Cmax/MIC and AUC24/MIC, the 15 indirect responses at five times and at their largest change, and the 15 dialysis scenarios' levels and sessions are being compared with the independent solver's, to the tolerances below. The largest difference in each group will show here.
The date of the reference run, the Python, NumPy and SciPy versions it used, and the engine file checked will show here when the checks finish.
What is checked
- An independent solver.
validation/reference.pyintegrates the model's differential equations with SciPy'ssolve_ivp(DOP853, relative tolerance 10⁻¹¹), piecewise between doses. An extra state accumulates the area under the curve, and for an effect-site delay two more follow the effect-site level, dCe/dt = ke0·(C − Ce), and its area. It was written from the equations, not translated from MaatiRx's JavaScript: the JavaScript builds linear curves, one- or two-compartment, and their effect-site levels from closed-form sums of exponentials and integrates saturable ones with a fixed-step RK4. - A scenario matrix of 146 scenarios:
- Routes: oral, IV bolus, IV infusion, and a mixed-route schedule.
- Regimens: single dose, repeated, with a loading dose, with a missed dose, and a custom schedule with irregular times, amounts and a missed dose.
- Drugs: a first-order drug, a first-order drug with a salt factor, a saturable (Michaelis–Menten) drug, and a two-compartment drug (a central and a peripheral compartment exchanging at uneven rates).
- Patients: a simple-mode patient at 100% organ function, and a clinical patient (a 75-year-old woman, 60 kg, serum creatinine 1.8 mg/dL) whose clearance follows Cockcroft–Gault.
- An effect-site delay: 20 first-order scenarios (one and two compartments, every route, a single dose, a loading dose, custom and mixed-route schedules) read at the effect site instead of plasma. Their ids end in
-effect.
- Four numbers per scenario over 0–96 h:
- the peak
- the trough (just before the next dose would be due, or at 96 h)
- the area under the curve
- the time between MEC 4 and MTC 12 mg/L
- Tolerances:
- Peak, trough and AUC within 0.5% for first-order scenarios and 1% for saturable ones.
- Time in window within 0.5 percentage points for first-order scenarios and 1 point for saturable ones.
- Analytic identities, in the test suite (
tests/validation.test.js):- the accumulation ratio 1 / (1 − e^(−kₑτ))
- 90% of steady state at 3.32 half-lives
- AUC = F·S·D / CL for every route
- the infusion plateau R₀ / CL
- the Michaelis–Menten steady state Km·R / (Vmax − R), its time to 90%, and its first-order limit at low levels
- the Cockcroft–Gault and Devine hand values
- the time above a target effect across bolus jumps, in closed form
- Bayesian individualization (MAP). 20 scenarios with one to three measured levels (every route, single, repeated, loading and missed-dose regimens, normal and reduced kidney function, different prior CVs). The reference minimises the same objective, the squared standardised residuals plus the log-normal prior terms, with SciPy's Nelder–Mead on the ODE solver's predictions. The estimated clearance and volume must agree within 0.5%.
- Antimicrobial PK/PD indices. 12 regimens (piperacillin as 30-minute, 3-hour, 4-hour and continuous infusions, and with reduced kidney function; meropenem; gentamicin divided and once daily; vancomycin; an oral and an IV-bolus regimen; two compartments). The reference runs each in the ODE solver until it repeats itself, then reads its last interval: the time the unbound level is above the MIC (crossings by bisection), the peak, and the area. fT>MIC must agree within 0.01 percentage points, Cmax/MIC and AUC24/MIC within 0.01%. The test suite also holds fT>MIC to its closed forms: ln(C₀,ss / (MIC/fu)) / kₑ for an IV bolus, both crossings of an infusion, and exactly 100% for a continuous infusion above the MIC.
- Indirect responses. 15 scenarios across the four types of Dayneka, Garg and Jusko (1993): every route, a custom schedule, two compartments, saturable elimination, a patient with reduced creatinine clearance, and three responses driven through an effect-site delay. The reference integrates the response together with the drug (and, with a delay, the effect-site level) in one ODE system. The response must agree within 0.01% at five times and at its largest change, and the time of that change within 0.01 h. The test suite also holds it to its analytic behaviour: no change without drug, and at a constant level an exponential approach to the plateau with time constant 1/kout (types 1 and 3) or 1/(kout·(1 ∓ D)) (types 2 and 4).
- Hemodialysis. 15 scenarios with the dialysis clearance switched on during each session: an IV bolus, end-stage kidney disease with 8-hour sessions, oral and infused regimens, a session overlapping an infusion, a mixed-route schedule, loading and missed doses, a fast dialyzer, three with two compartments (where the level rebounds) and four with saturable elimination (an oral daily regimen, infusions after a loading dose with sessions overlapping them, a bolus far above Km, and a mixed schedule with reduced kidney function). The reference integrates the drug and the amount the dialyzer removes in one ODE system. The level at six times, and each session's level as it starts and ends and the amount it removes, must agree within 0.01%. The test suite also holds the model to mass balance: what the body clears plus what the dialyzer removes equals what was given.
- A standing cross-check, also in the test suite. Seeded random scenarios (routes, loading and missed doses, one and two compartments, custom schedules, saturable elimination) compare every dose-table peak, the last-dose and steady-state peaks, the window's area and times, and the time above a target effect with dense scans of the engine's own curve.
Published worked examples aren't included: none could be checked against an accessible source.
Results
| Scenario | Peak (ref) | Peak Δ | Trough (ref) | Trough Δ | AUC (ref) | AUC Δ | In window (ref) | Δ pp | Within |
|---|
Bayesian estimates (MAP)
| Scenario | Levels | CL prior (L/h) | CL MAP (ref) | CL Δ | V prior (L) | V MAP (ref) | V Δ | Within |
|---|
Antimicrobial PK/PD indices
| Regimen | fT>MIC (ref) | Δ pp | Cmax/MIC (ref) | Δ | AUC24/MIC (ref) | Δ | Within |
|---|
Indirect responses
| Scenario | Largest change (ref, %) | Δ | When (ref, h) | Δ h | Worst of 5 times | Within |
|---|
Hemodialysis
| Scenario | Sessions | First session removes (ref) | Worst level Δ | Worst session Δ | Within |
|---|
How to reproduce
node --test tests/ # the engine, the cases and this comparison (Node 20, no dependencies) python3 -m pip install numpy scipy python3 validation/reference.py # regenerates validation/reference-results.json
This page runs the same comparison as tests/validation.test.js in your browser, with the engine the site ships.