Interactive CAR T-cell Therapy Modeling

time of injection
tumor count
Car T count
theta
gamma
phi
rho
alpha
e
mu
r
b
Dual Car T
packages = ["numpy", "matplotlib", "scipy"] import matplotlib.pyplot as plt import numpy as np from scipy.integrate import solve_ivp from js import (document) from pyodide.ffi import create_proxy # DEFINE VARIABLES AND FUNCTIONS param_names = ["theta", "gamma", "phi", "rho", "alpha", "e", "mu", "r", "b"] default_params1 = [0.000006, 0.000003715843, 0.265, 0.35, 0.00000045, 0.15, 0.005, 0.05650026, 0.000000000001404029] default_params2 = [0.0000045, 0.000002715843, 0.125, 0.4, 0.00000004, 0.123, 0.0045, 0.05650026, 0.000000000001404029] # function returning systems of ODE for single Car-T def ode_single(t, D, params): dD1dt = params.get("phi")*D[0] - params.get("rho")*D[0] + params.get("theta")*D[2]*D[1] - params.get("alpha")*D[2]*D[0] dD2dt = params.get("e")*D[0] - params.get("theta")*D[2]*D[1] - params.get("mu")*D[1] dD3dt = params.get("r")*D[2] - params.get("r")*params.get("b")*D[2]**2 - params.get("gamma")*D[0]*D[2] return [dD1dt, dD2dt, dD3dt] # function returning systems of ODE for dual Car-T def ode_dual(t, D, params1, params2): dD1dt = params1.get("phi")*D[0] - params1.get("rho")*D[0] + params1.get("theta")*D[4]*D[2] - params1.get("alpha")*D[4]*D[0] dD2dt = params2.get("phi")*D[1] - params2.get("rho")*D[1] + params2.get("theta")*D[4]*D[3] - params2.get("alpha")*D[4]*D[1] dD3dt = params1.get("e")*D[0] - params1.get("theta")*D[4]*D[2] - params1.get("mu")*D[2] dD4dt = params2.get("e")*D[1] - params2.get("theta")*D[4]*D[3] - params2.get("mu")*D[3] dD5dt = params1.get("r")*D[4] - params1.get("r")*params1.get("b")*D[4]**2 - params1.get("gamma")*D[0]*D[4] - params2.get("gamma")*D[1]*D[4] return [dD1dt, dD2dt, dD3dt, dD4dt, dD5dt] # COMPUTE AND PLOT def plot_graph_single(self): plt.close('all') document.querySelector("#plot").innerHTML = '' ct_params = {} for param in param_names: ct_params[param] = float(document.querySelector("#" + param).value) time_of_injection = int(document.querySelector("#injection_time").value) tumor_ct = int(document.querySelector("#tumor_count").value) cart_ct = int(document.querySelector("#cart_count").value) initial_cond = [0, 0, tumor_ct] # Solve the ODEs using solve_ivp sol_before_injection = solve_ivp(lambda t, D: ode_single(t, D, ct_params), [0, time_of_injection], initial_cond, t_eval=np.linspace(0, time_of_injection, num=100), method='RK45') t_before_injection = sol_before_injection.t Dct_before_injection = sol_before_injection.y.T # Conditions at injection injection_cond = [cart_ct, Dct_before_injection[-1, 1], Dct_before_injection[-1, 2]] sol_final = solve_ivp(lambda t, D: ode_single(t, D, ct_params), [time_of_injection, 100], injection_cond, t_eval=np.linspace(time_of_injection, 100, num=100), method='RK45') t_final = np.concatenate((t_before_injection, sol_final.t[1:])) Dct_final = np.vstack((Dct_before_injection, sol_final.y[:, 1:].T)) # Plot the curves fig, ax = plt.subplots(figsize=(10, 6)) ax.set_xlabel('Time') ax.set_ylabel('Number of Car-T cells') ax.tick_params(axis='y') ax.plot(t_final, Dct_final[:, 0], label='CAR T', color='green') ax.plot(t_final, Dct_final[:, 1], label='CAR T Memory', linestyle='--', color='green') ax1 = ax.twinx() ax1.set_ylabel('Number of tumor cells') ax1.tick_params(axis='y') ax1.plot(t_final, Dct_final[:, 2], label='Tumor', color='orange') plt.title('Effect of CAR T-cells for biomarker on tumor cells') plt.xlim(0, 100) ax.set_ylim(0) ax1.set_ylim(0) ax.legend(loc='upper left') ax1.legend(loc='upper right') plt.grid(True) plt display(plt, target="plot") def plot_graph_dual(self): plt.close('all') document.querySelector("#plot").innerHTML = '' ct_params = {} ct2_params = {} for param in param_names: ct_params[param] = float(document.querySelector("#" + param).value) ct2_params[param] = float(document.querySelector("#" + param + "2").value) time_of_injection = int(document.querySelector("#injection_time").value) tumor_ct = int(document.querySelector("#tumor_count").value) cart_ct = int(document.querySelector("#cart_count").value) cart_2_ct = int(document.querySelector("#cart_2_count").value) initial_cond_dual = [0, 0, 0, 0, tumor_ct] # Solve the ODEs using solve_ivp sol_before_injection = solve_ivp(lambda t, D: ode_dual(t, D, ct_params, ct2_params), [0, time_of_injection], initial_cond_dual, t_eval=np.linspace(0, time_of_injection, num=100), method='RK45') t44_117 = sol_before_injection.t Dct44_117 = sol_before_injection.y.T # Conditions at injection injection_cond = [cart_ct, cart_2_ct, Dct44_117[-1, 2], Dct44_117[-1, 3], Dct44_117[-1, 4]] sol_final = solve_ivp(lambda t, D: ode_dual(t, D, ct_params, ct2_params), [time_of_injection, 100], injection_cond, t_eval=np.linspace(time_of_injection, 100, num=100), method='RK45') t44_117_final = np.concatenate((t44_117, sol_final.t[1:])) Dct44_117_final = np.vstack((Dct44_117, sol_final.y[:, 1:].T)) # Plot the curves fig, ax = plt.subplots(figsize=(10, 6)) ax.set_xlabel('Time') ax.set_ylabel('Number of Car-T cells') ax.tick_params(axis='y') ax.plot(t44_117_final, Dct44_117_final[:, 0], label='CAR T A', color='green') ax.plot(t44_117_final, Dct44_117_final[:, 1], label='CAR T B', color='blue') ax.plot(t44_117_final, Dct44_117_final[:, 2], label='CAR T A Memory', linestyle='--', color='green') ax.plot(t44_117_final, Dct44_117_final[:, 3], label='CAR T B Memory', linestyle='--', color='blue') ax1 = ax.twinx() ax1.set_ylabel('Number of tumor cells') ax1.tick_params(axis='y') ax1.plot(t44_117_final, Dct44_117_final[:, 4], label='Tumor', color='orange') plt.title('Effect of CAR T-cells for biomarkers on tumor cells') plt.xlim(0, 100) ax.set_ylim(0) ax1.set_ylim(0) ax.legend(loc='upper left') ax1.legend(loc='upper right') plt.grid(True) plt display(plt, target="plot") # call appropriate plotting function according to state of Dual Car-T switch def plot_graph(self): if document.querySelector("#isDual").checked: plot_graph_dual(self) else: plot_graph_single(self) # delete plot and return all parameters to default values def reset_plot(self): plt.close('all') # delete plot document.querySelector("#plot").innerHTML = '' # set parameters to default values document.querySelector("#injection_time").value = 42 document.querySelector("#tumor_count").value = 2000000 document.querySelector("#cart_count").value = 10000000 for i in range(len(param_names)): document.querySelector("#" + param_names[i]).value = default_params1[i] if document.querySelector("#isDual").checked: document.querySelector("#cart_2_count").value = 10000000 for i in range(len(param_names)): document.querySelector("#" + param_names[i] + "2").value = default_params2[i] # call proxy function when user clicks button to plot graph plot_proxy = create_proxy(plot_graph) plot_btn = document.getElementById("show_graph") plot_btn.addEventListener("click", plot_proxy) # call proxy function when user clicks button to reset model reset_proxy = create_proxy(reset_plot) reset_btn = document.getElementById("reset") reset_btn.addEventListener("click", reset_proxy)