from ipywidgets import interactive, FloatSlider, IntSlider, VBox, Label, HBox, Layout, interactive_output
import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import odeint
from IPython.display import display
# ODE system
def chaperone_dynamics(y, t, N, k_syn, f1, f2, f3, kd):
= y
F, U, D = f1 * k_syn*N + f2 * F * U - kd * F - f3 * F
dFdt = (1 - f1) * k_syn*N + f3 * F - f2 * F * U - kd * U
dUdt = kd * F + kd * U
dDdt return [dFdt, dUdt, dDdt]
# Plotting function
def plot_chaperone_dynamics(N, k_syn, f1, f2, f3, kd, t_max):
= f1 * N
F0 = (1 - f1) * N
U0 = [F0, U0, 0.0]
y0 = np.linspace(0, t_max, 50000)
t = odeint(chaperone_dynamics, y0, t, args=(N, k_syn, f1, f2, f3, kd))
solution = solution.T
F, U, D =(8, 5))
plt.figure(figsize='Functional (F)')
plt.plot(t, F, label='Non-functional (U)')
plt.plot(t, U, label'Time (s)')
plt.xlabel('Chaperone Level')
plt.ylabel('Chaperone Dynamics (Interactive)')
plt.title(
plt.grid()
plt.legend() plt.show()
State Variables
- ( F(t) ): Functional chaperone concentration
- ( U(t) ): Non-functional chaperone concentration
- ( D(t) ): Degraded (dead) protein concentration
Parameters
\(N\): Number of proteins produced
$k_{} $: Chaperone synthesis rate per cell
$ f_1 $: Fraction of synthesized chaperones that are functional
$ f_2 $: Refolding rate constant (U → F)
$ f_3 $: Misfolding rate constant (F → U)
$ k_d $: Degradation rate of both F and U
System of ODEs
$ \[\begin{aligned} \frac{dF}{dt} &= f_1 \cdot k_{\text{syn}} \cdot N + f_2 \cdot F \cdot U - f_3 \cdot F - k_d \cdot F \\ \frac{dU}{dt} &= (1 - f_1) \cdot k_{\text{syn}} \cdot N + f_3 \cdot F - f_2 \cdot F \cdot U - k_d \cdot U \\ \frac{dD}{dt} &= k_d \cdot F + k_d \cdot U \end{aligned}\]$
def param_box(slider, text):
return VBox([slider, Label(text)], layout=Layout(width='350px'))
= param_box(
N_slider min=1, max=100, step=1, value=1, description='N'),
IntSlider("Number of proteins synthesis at once"
)
= param_box(
k_syn_slider min=0.01, max=1, step=0.01, value=0.1, description='k_syn'),
FloatSlider("Rate of chaperone synthesis."
)
= param_box(
f1_slider min=0.01, max=1.0, step=0.01, value=0.1, description='f1'),
FloatSlider("Frac. of synthesized that are functional."
)
= param_box(
f2_slider
FloatSlider(min=0.0, max=0.005, step=0.0001, value=0.0005,
='f2',
description=True,
readout='.4f',
readout_format
),"Refolding eff. (U → F)."
)
= param_box(
f3_slider
FloatSlider(min=0.0, max=0.01, step=0.0001, value=0.001,
='f3',
description=True,
readout='.4f',
readout_format
),"Misfolding rate (F → U)."
)
= param_box(
kd_slider
FloatSlider(min=0.0, max=0.01, step=0.0001, value=0.005,
='kd',
description=True,
readout='.4f',
readout_format
),"Degradation rate for F and U."
)
= param_box(
tmax_slider min=0, max=1e4, step=100, value=2000, description='t_max'),
IntSlider("Max value of time to simulate."
)
= HBox([
controls =Layout(border='1px solid gray', padding='10px')),
VBox([N_slider, k_syn_slider, f1_slider],layout=Layout(border='1px solid gray', padding='10px')),
VBox([f2_slider, f3_slider, kd_slider],layout=Layout(border='1px solid gray', padding='10px'))
VBox([tmax_slider],layout
])
= interactive_output(
widget
plot_chaperone_dynamics,
{'N': N_slider.children[0],
'k_syn': k_syn_slider.children[0],
'f1': f1_slider.children[0],
'f2': f2_slider.children[0],
'f3': f3_slider.children[0],
'kd': kd_slider.children[0],
't_max': tmax_slider.children[0]
}
)
display(controls, widget)