# Print total time taken solve_time = time.time() - start_time if solve_time < 60.0: print("\n\n--- Took {0:.0f} seconds to solve ---".format(solve_time)) else: minutes, seconds = divmod(solve_time, 60) print( "\n\n--- Took {0:.0f} minutes and {1:.0f} seconds to solve ---".format( minutes, seconds)) del start_time, solve_time # Extract the state variables for easy plotting etc v = initialise_var_names(u, idx, 'out function') # Extract the algebraic variables for easy plotting etc a = set_algebraic_variables(u, t, idx, input_data, total_waveform, 'out function') del total_waveform, input_data # Solve for the normalised CBF, CBV, CMRO2, HbO, HbR, HbT and BOLD and put into 'a' (solved separately from odeint as they depend on the steady state conditions) a = solve_normalised_hemodynamics(a, v, t) # The variables that can be plotted sorted into alphabetical order state_vars = sorted(vars(v).keys()) #print("\nState variables: \n", state_vars, "\n") alg_vars = sorted(vars(a).keys()) #print("Algebraic variables: \n", alg_vars,"\n") '''Plotting parameters''' if p.startpulse < p.Tend: time = t / 1e3 - p.startpulse / 1e3 # Time in seconds, normalised so t=0 at the start of stimulation xlim1 = p.startpulse / 1e3 - 10 # Set left xlimit to 10 sec before stimulation begins else:
def func(u, t, idx, input_data, total_waveform, start_time): # Initialise variable names for clarity v = initialise_var_names(u, idx, 'in function') # Set the algebraic_variables a = set_algebraic_variables(u, t, idx, input_data, total_waveform, 'in function') # RHS of ODEs du = [None] * len(idx) # Initialise with correct size if p.InputCase == 'ThalamicTriangles' or p.InputCase == 'ThalamicTrianglesZheng' or p.InputCase == 'ThalamicSquarePulse': # Using thalamic input T(t) rather than P(t), Q(t) du[idx['E_t']] = 1 / p.tau_e * (-v.E_t + a.f_arg_e) du[idx['I_t']] = 1 / p.tau_i * (-v.I_t + a.f_arg_i) else: du[idx['E_t']] = 1 / p.tau_e * (-v.E_t + (a.k_e - p.r_e * v.E_t) * a.s_arg_e) du[idx['I_t']] = 1 / p.tau_i * (-v.I_t + (a.k_i - p.r_i * v.I_t) * a.s_arg_i) # "Neuron" du[idx['K_e']] = -p.beta_K_e * (v.K_e - p.K_eBase) + p.alpha_K_e * p.beta_K_e * ( (abs(v.E_t - v.I_t) - p.EImin) / (p.EI_relative - p.EImin)) du[idx['Na_sa']] = -p.beta_Na_sa * ( v.Na_sa - p.Na_saBase) + p.alpha_Na_sa * p.beta_Na_sa * ( (abs(v.E_t - v.I_t) - p.EImin) / (p.EI_relative - p.EImin)) du[idx['Na_d']] = -p.beta_Na_d * ( v.Na_d - p.Na_dBase) + p.alpha_Na_d * p.beta_Na_d * ( (abs(v.E_t - v.I_t) - p.EImin) / (p.EI_relative - p.EImin)) # haemodynamics du[idx['O2']] = a.J_O2_vascular - a.J_O2_background - a.J_O2_pump du[idx['CBV']] = 1 / (p.tau_MTT + p.tau_TAT) * (a.f_in - v.CBV**(1 / p.d)) du[idx['HbR']] = 1 / p.tau_MTT * (a.f_in * a.OEF / p.E_0 - v.HbR / v.CBV * a.f_out) # Neuron du[idx['Ca_n']] = (a.I_Ca_tot / (2 * p.Farad * p.V_spine) - (p.k_ex * (v.Ca_n - p.Ca_rest))) / (1 + p.lambda_buf) du[idx['nNOS']] = p.NOswitch_NE * (p.V_maxNOS * a.CaM / (p.K_actNOS + a.CaM) - p.mu2_n * v.nNOS) du[idx['NO_n']] = a.p_NO_n - a.c_NO_n + a.d_NO_n du[idx['K_p']] = a.J_BK_k / (p.VR_pa) + a.J_KIR_i / p.VR_ps - p.R_decay * ( v.K_p - p.K_p_min) du[idx[ 'Ca_p']] = a.J_TRPV_k / p.VR_pa + a.J_VOCC_i / p.VR_ps - p.Ca_decay_k * ( v.Ca_p - p.Capmin_k) du[idx['v_k']] = p.gamma_i * (-a.J_BK_k - a.J_K_k - a.J_Cl_k - a.J_NBC_k - a.J_Na_k - a.J_NaK_k - 2 * a.J_TRPV_k ) # - a.J_GABA_k) du[idx['Na_k']] = -a.J_Na_k - 3 * a.J_NaK_k + a.J_NKCC1_k + a.J_NBC_k du[idx[ 'K_k']] = -a.J_K_k + 2 * a.J_NaK_k + a.J_NKCC1_k + a.J_KCC1_k - a.J_BK_k du[idx['HCO3_k']] = 2 * a.J_NBC_k du[idx['Ca_k']] = a.B_cyt * (a.J_IP3 - a.J_pump + a.J_ER_leak - a.J_TRPV_k / p.r_buff + a.J_CICR_k) du[idx['Cl_k']] = du[idx['Na_k']] + du[idx['K_k']] - du[ idx['HCO3_k']] + p.z_Ca * du[idx['Ca_k']] du[idx['K_s']] = 1 / p.VR_sa * (a.J_K_k - 2 * a.J_NaK_k - a.J_NKCC1_k - a.J_KCC1_k) + a.J_K_NEtoSC du[idx['Na_s']] = 1 / p.VR_sa * (a.J_Na_k + 3 * a.J_NaK_k - a.J_NKCC1_k - a.J_NBC_k) + a.J_Na_NEtoSC du[idx['HCO3_s']] = 1 / p.VR_sa * (-2 * a.J_NBC_k) du[idx['w_k']] = a.phi_w * (a.w_inf - v.w_k) du[idx['I_k']] = p.r_h * a.G - p.k_deg * v.I_k du[idx['h_k']] = p.k_on * (p.K_inh - (v.Ca_k + p.K_inh) * v.h_k) du[idx['s_k']] = -(a.B_cyt * (a.J_IP3 - a.J_pump + a.J_ER_leak + a.J_CICR_k)) / ( p.VR_ER_cyt) du[idx['m_k']] = p.trpv_switch * ((a.minf_k - v.m_k) / p.t_TRPV_k) du[idx['eet_k']] = p.V_eet * max(v.Ca_k - p.Ca_k_min, 0) - p.k_eet * v.eet_k du[idx['NO_k']] = a.p_NO_k - a.c_NO_k + a.d_NO_k du[idx['AA_k']] = (p.AA_m * p.AA_max) / (p.AA_m + max( v.Ca_k - p.Ca0, 0))**2 * du[idx['Ca_k']] + (v.AA_i - v.AA_k) / p.tau_AA du[idx[ 'Ca_i']] = a.J_IP3_i - a.J_SR_uptake_i - a.J_extrusion_i + a.J_SR_leak_i - a.J_VOCC_i + a.J_CICR_i + a.J_NaCa_i - 0.1 * a.J_stretch_i + a.J_Ca_coup_i du[idx['s_i']] = a.J_SR_uptake_i - a.J_CICR_i - a.J_SR_leak_i du[idx['v_i']] = p.gamma_i * ( -a.J_NaK_i - a.J_Cl_i - 2 * a.J_VOCC_i - a.J_NaCa_i - a.J_K_i - a.J_stretch_i - a.J_KIR_i) + a.V_coup_i # - a.J_GABA_i) + a.V_coup_i du[idx['w_i']] = p.lambda_i * (a.K_act_i - v.w_i) du[idx['I_i']] = a.J_IP3_coup_i - a.J_degrad_i du[idx['NO_i']] = a.p_NO_i - a.c_NO_i + a.d_NO_i du[idx['E_b']] = -p.k1 * v.E_b * v.NO_i + p.k_1 * v.E_6c + a.k4 * a.E_5c du[idx['E_6c']] = p.k1 * v.E_b * v.NO_i - ( p.k_1 + p.k2) * v.E_6c - p.k3 * v.E_6c * v.NO_i du[idx['cGMP_i']] = p.V_max_sGC * a.E_5c - a.V_max_pde * v.cGMP_i / ( p.K_m_pde + v.cGMP_i) du[idx['H_i']] = p.HETswitch_20HETE * (a.f_NO * p.V_a * v.AA_i / (p.K_a + v.AA_i) + p.V_f * v.AA_i / (p.K_f + v.AA_i) - p.lambda_h * v.H_i) du[idx['AA_i']] = (v.AA_k - v.AA_i) / p.tau_AA du[idx[ 'Ca_j']] = a.J_IP3_j - a.J_ER_uptake_j + a.J_CICR_j - a.J_extrusion_j + a.J_ER_leak_j + a.J_cation_j + p.J_0_j - a.J_stretch_j - a.J_Ca_coup_i du[idx['s_j']] = a.J_ER_uptake_j - a.J_CICR_j - a.J_ER_leak_j du[idx['v_j']] = -1 / p.C_m_j * (a.J_K_j + a.J_R_j) - a.V_coup_i du[idx['I_j']] = p.J_PLC - a.J_degrad_j - a.J_IP3_coup_i du[idx['eNOS']] = p.gam_eNOS * a.Act_eNOS_Ca * p.NOswitch_EC_CA + ( 1 - p.gam_eNOS) * a.Act_eNOS_wss * p.NOswitch_EC_WSS - p.mu2_j * v.eNOS du[idx['NO_j']] = a.p_NO_j - a.c_NO_j + a.d_NO_j du[idx['Mp']] = p.wallMech * (p.K_4 * v.AMp + a.K_1 * a.M - (a.K_2 + p.K_3) * v.Mp) du[idx['AMp']] = p.wallMech * (p.K_3 * v.Mp + a.K_6 * v.AM - (p.K_4 + a.K_5) * v.AMp) du[idx['AM']] = p.wallMech * (a.K_5 * v.AMp - (p.K_7 + a.K_6) * v.AM) du[idx['R']] = p.R_init / p.eta_R * (v.R * p.trans_p / a.h - a.E * (v.R - a.R_0) / a.R_0) # du[idx['GABA']] = - a.kappa_GABA * (v.GABA - p.GABAbase ) + p.alpha_GABA * (v.I_t - p.Imin) / (p.I_relative - p.Imin) # du[idx['NPY']] = - p.beta_NPY * (v.NPY - p.NPYbase) + p.alpha_NPY * (v.I_t - p.Imin) / (p.I_relative - p.Imin) # du[idx['Glu']] = - p.beta_Glu * v.Glu + p.GluSwitch * (a.f_Ke + a.f_GABA) # Print to console the current time and percentage completed time_elapsed = time.time() - start_time print( '\r-- Time {0:.2f} / {1:.0f} -- {2:.1f}% complete -- {3:.0f} sec elapsed --' .format(t / 1e3, p.Tend / 1e3, t / p.Tend * 100, time_elapsed), end='') return du
def single_eval(QoI_flag, Param_Index, change_value): iteration = [Param_Index, change_value] data_choice = 'pre' import sys sys.path.append("./Model_Codes/") # Import modules from scipy.integrate import odeint from scipy import io from scipy.interpolate import interp1d import numpy as np import time import matplotlib.pyplot as plt import warnings from matplotlib.patches import Rectangle # Local files from indices import set_indices from ICs import set_initial_conditions from ODEsystem import func from algebraic_variables import set_algebraic_variables from state_variable_names import initialise_var_names from normalised_hemo import solve_normalised_hemodynamics from plotting_functions import plot_variables_singles, plot_variables_samegraph from model_functions import T_pulses from parameters import p_function import import_mat_files_no_fig as im from multipliers import V_IC if data_choice == 'pre': p = p_function(iteration, 'normal') elif data_choice == 'post': p = p_function(iteration, 'LNAME') # Calculate the start time start_time = time.time() # Initialise indices, initial conditions and time vector idx = set_indices() u0 = set_initial_conditions(idx, V_IC) t = np.arange(start=0, stop=p.Tend + p.dt, step=p.dt) # Import the experimental neural input profile from mat file, for InputCase = 'ZhengData', 'ThalamicTrianglesZheng' or 'ZhengFittedParams' input_data = im.import_Zheng_neural_data(p, t) # Generate the multiple triangular pulse input profile for the thalamic input T(t), for InputCase = 'ThalamicTriangles' or 'ThalamicTrianglesZheng' total_waveform = T_pulses(p) # Solve ODE system #print("\n Model simulation successfully started\n") u, solver_details = odeint(func, u0, t, args=(p, idx, input_data, total_waveform, start_time), hmax=1e2, full_output=1) if solver_details['message'] == 'Integration successful.': del solver_details # Print total time taken solve_time = time.time() - start_time if solve_time < 60.0: print("\n\n--- Took {0:.0f} seconds to solve ---".format(solve_time)) else: minutes, seconds = divmod(solve_time, 60) print("\n\n--- Took {0:.0f} minutes and {1:.0f} seconds to solve ---". format(minutes, seconds)) del start_time, solve_time # Extract the state variables for easy plotting etc v = initialise_var_names(u, idx, 'out function') # Extract the algebraic variables for easy plotting etc a = set_algebraic_variables(p, u, t, idx, input_data, total_waveform, 'out function') del total_waveform, input_data # Solve for the normalised CBF, CBV, CMRO2, HbO, HbR, HbT and BOLD and put into 'a' (solved separately from odeint as they depend on the steady state conditions) a = solve_normalised_hemodynamics(p, a, v, t) # The variables that can be plotted sorted into alphabetical order state_vars = sorted(vars(v).keys()) #print("\nState variables: \n", state_vars, "\n") alg_vars = sorted(vars(a).keys()) #print("Algebraic variables: \n", alg_vars,"\n") if p.startpulse < p.Tend: time = t / 1e3 - p.startpulse / 1e3 # Time in seconds, normalised so t=0 at the start of stimulation xlim1 = p.startpulse / 1e3 - 10 # Set left xlimit to 10 sec before stimulation begins else: time = t / 1e3 # Time in seconds, not normalised if there is no stimulation xlim1 = 0 # Set left xlimit to 0 if there is no stimulation xlim2 = p.Tend / 1e3 # Set right xlimit to end of simulation del t pulse_marker = np.where(time >= 0.0) pulse_marker = pulse_marker[0][0] pre_pulse_marker = np.where(time >= -5.0) pre_pulse_marker = pre_pulse_marker[0][0] pre_end_marker = np.where(time >= time[-1] - 5.0) pre_end_marker = pre_end_marker[0][0] radius = v.R radius = radius / radius[pulse_marker] clean_flag = 0 if not np.all(np.isfinite(radius)): clean_flag = -2 elif not np.all(np.isreal(radius)): clean_flag = -3 elif np.amax(abs(radius[pre_pulse_marker:pulse_marker + 1] - 1)) > 1e-3: clean_flag = -4 elif np.amax(abs(radius[pre_end_marker:] - 1)) > 1e-3: clean_flag = -5 elif np.amin(abs(radius[pulse_marker:])) < 0.9: clean_flag = -6 else: clean_flag = 1 if clean_flag != 1: QoI = 100 else: # Set custom xlims if wanted if data_choice == 'pre': dataset = 'tots_LNAME_pre' elif data_choice == 'post': dataset = 'tots_LNAME_post' #sys.path.remove("./Model_Codes/") Data = im.import_Berwick_HET_LNAME_Data(dataset, area='Whisker') if QoI_flag == 0: interpolator = interp1d(time, a.HBO_N) HBO_interp = interpolator(Data.time) Error_HBO = HBO_interp - Data.HbOwhisk_mean Error_HBO = list(map(lambda x: x * x, Error_HBO)) Error = Error_HBO elif QoI_flag == 1: interpolator = interp1d(time, a.HBR_N) HBR_interp = interpolator(Data.time) Error_HBR = HBR_interp - Data.HbRwhisk_mean Error_HBR = list(map(lambda x: x * x, Error_HBR)) Error = Error_HBR QoI = Error return QoI