This repository contains a compact, phenomenological model of L‑DOPA pharmacokinetics (PK), dopamine (DA) dynamics, and norepinephrine (NE) synthesis/regulation. The implementation uses NumPy
, SciPy
, and matplotlib
and supports multiple Parkinson’s disease (PD) capacity scenarios, with or without an L‑DOPA infusion.
- PK (3 compartments) for L‑DOPA: central/plasma (C1), peripheral/tissue (C2), brain/biophase (C3).
- DA dynamics: endogenous production + L‑DOPA–driven synthesis; saturable reuptake; first‑order removal.
- NE dynamics: DA→NE conversion with product inhibition; first‑order removal.
- Scenarios: Healthy, Early PD, Late PD via capacity scalars
f_dop
,f_ne
. - Inputs: a no‑infusion function and a 0–30 min infusion (constant rate).
All baselines are set deterministically via steady‑state solves (fsolve
).
get_common_params(k0_func)
: Returns parameter dictionary and the L‑DOPA inputk0
.model(t, y, p)
: ODEs for[C1, C2, C3, Cdop, Cne]
.compute_initial(p)
: Solves steady states for DA and NE (no infusion) to set initial conditions.tune(f_dop, target)
: ChoosesIDA_endogenous
so DA baseline equals the target value.simulate(k0_func, f_dop, f_ne, target)
: Runs the ODE and returns(t, y)
for plotting.
L‑DOPA inputs
def k0_inf(t): # constant infusion during 0–30 min
return 2.0 if t <= 30 else 0.0
def k0_zero(t): # no infusion
return 0.0
The state vector is y = [C1, C2, C3, Cdop, Cne]
. Time is in minutes; concentrations are in µM (concentration‑equivalents under the chosen volumes/flows).
Symbol | Description |
---|---|
C1 |
L‑DOPA in central/plasma |
C2 |
L‑DOPA in peripheral/tissue |
C3 |
L‑DOPA in brain/biophase |
Cdop |
Dopamine (brain/biophase) |
Cne |
Norepinephrine (brain/biophase) |
Flows/clearances (
Qij
,CL_e*
) and volumes (V*
) are set so each ODE term has units of concentration/time. If you change units, maintain dimensional consistency.
Let V1, V2, V3
be volumes; Q12, Q21, Q13
intercompartmental flows; CL_e1, CL_e3
eliminations.
- Endogenous + L‑DOPA‑driven synthesis:
$f_{\mathrm{dop}},(IDA_{\mathrm{endogenous}} + k_{3dop},C_3)$ - Saturable reuptake (Michaelis–Menten):
$$\mathrm{Reuptake} = \frac{V_{\max},C_{\mathrm{dop}}}{K_m + C_{\mathrm{dop}}}$$ - First‑order removal:
$k_{\mathrm{rem}},C_{\mathrm{dop}}$
Full DA ODE:
- Product inhibition on DA→NE:
$$k_{db,\mathrm{eff}} = k_{db}\left(1 - \frac{C_{\mathrm{ne}}}{IC_{50} + C_{\mathrm{ne}}}\right)$$ - First‑order removal:
$k_{\mathrm{rene}},C_{\mathrm{ne}}$
Full NE ODE:
Scaling interpretation: f_dop
scales DA synthetic/reuptake capacity; f_ne
scales NE synthetic capacity. Removals are first‑order (capacity‑independent).
Given a target DA baseline (µM), IDA_endogenous
is chosen so the steady‑state DA equation holds at rest (no infusion):
With tuned
These steady states initialize the simulation.
baseline_params = {
'Healthy': (1.0, 1.0, 0.015),
'Early PD': (0.5, 0.5, 0.012),
'Late PD': (0.1, 0.1, 0.005),
}
infuse_params = {
'Early PD + L-DOPA': (0.5, 0.5, 0.012),
'Late PD + L-DOPA': (0.1, 0.1, 0.005),
}
# tuples are (f_dop, f_ne, target_DA_baseline)
- Baseline runs:
k0_zero
(no infusion). - Infusion runs:
k0_inf
(0–30 min constant rate). - Time grid:
t = np.linspace(0, 300, 300)
(minutes).
Plotting note: Baseline NE reference lines are drawn from the model‑computed steady state for each scenario.
python>=3.9
numpy
scipy
matplotlib
Save your script (e.g., ne_model.py
) and run:
python ne_model.py
Two figures will display (DA panels and NE panels). To save figures, call plt.savefig("figure_name.png", dpi=300)
before plt.show()
.
- PK is a reduced linear 3‑compartment model; BBB transport is lumped and not saturable.
- DA reuptake is Michaelis–Menten; other DA losses are captured by a first‑order removal term.
- NE synthesis is driven by DA with a single product inhibition; α2‑autoreceptors/firing are not modeled.
f_dop
,f_ne
are phenomenological capacity scalars affecting synthesis, not removals.- Single pooled “brain/biophase” compartments for DA and NE (no region specificity).
IDA_endogenous # tuned per scenario
k3dop = 5.0
Vmax = 4.0
km = 0.16
krem = 0.04
Cne0 = 0.002 # initial guess for NE steady state
kdb = 0.05
krene = 0.04
IC50 = 0.0115
Q12=9.11, Q21=10.0, Q13=0.0021
CL_e1=0.50, CL_e3=0.006
V1=12.0, V2=32.0, V3=2.0
- Lower
f_dop
→ lower DA baseline and smaller DA transients to infusion. - Lower
f_ne
→ lower NE baseline and response amplitude; removal kinetics unchanged (first‑order). - During infusion, DA rises first; NE follows with sublinear growth due to product inhibition.