Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
def set_algebraic_variables(p, u, t, idx, input_data, total_waveform,
                            location):

    # Initialise variable names for clarity
    v = initialise_var_names(u, idx, location)

    # Initialise class to contain the variables
    a = alg_vars()

    #%%
    '''Neuron'''

    if p.InputCase == 'ThalamicTrianglesZheng' or p.InputCase == 'ThalamicSquarePulse' or p.InputCase == 'ThalamicTriangles':  # Thalamic input, Pinto et al

        a.T = f.input_T(t, input_data, total_waveform, location)
        a.arg_e = p.wee * v.E_t - p.wie * v.I_t + p.wte * a.T
        a.arg_i = p.wei * v.E_t - p.wii * v.I_t + p.wti * a.T
        a.f_arg_e = 5.12 / (1 + np.exp(-(a.arg_e - 15) / 4.16))
        a.f_arg_i = 11.61 / (1 + np.exp(-(a.arg_i - 15) / 3.94))

    else:  # Normal P,Q input

        a.k_e = 1 / (1 + np.exp(-(p.a_e * (p.k_e_input - p.theta_e)))) - 1 / (
            1 + np.exp(p.a_e * p.theta_e))
        a.k_i = 1 / (1 + np.exp(-(p.a_i * (p.k_i_input - p.theta_i)))) - 1 / (
            1 + np.exp(p.a_i * p.theta_i))

        a.P = f.input_P(p, t, input_data, location)
        a.Q = f.input_Q(p, t, input_data, location)

        a.arg_e = p.c1 * v.E_t - p.c2 * v.I_t + a.P  # [-]           Excitatory cells response function input
        a.arg_i = p.c3 * v.E_t - p.c4 * v.I_t + a.Q  # [-]           Inhibitory cells response function input

        a.s_arg_e = 1 / (1 + np.exp(-(p.a_e * (a.arg_e - p.theta_e)))) - 1 / (
            1 + np.exp(p.a_e * p.theta_e))
        a.s_arg_i = 1 / (1 + np.exp(-(p.a_i * (a.arg_i - p.theta_i)))) - 1 / (
            1 + np.exp(p.a_i * p.theta_i))

    a.O2_p = p.O2_0 * (
        1 - p.O2switch
    ) + v.O2 * p.O2switch  # [mM]  Oxygen concentration dependent on ATP
    a.J_pump2 = 2 * (1 + p.O2_0 / ((
        (1 - p.alpha_O2) * a.O2_p) + p.alpha_O2 * p.O2_0))**(-1)  # [mM s**-1]
    a.J_pump2_0 = 0.0952  # [mM s**-1]
    a.J_pump2_O2_0 = 1  # [mM s**-1]
    a.P_02 = (a.J_pump2 - a.J_pump2_0) / (
        a.J_pump2_O2_0 - a.J_pump2_0)  # [-]  Normalised pump rate of oxygen

    a.CBF = p.CBF_init * (v.R**4 / p.R_init**4
                          )  # [-] Normalised cerebral blood flow

    a.J_O2_background = p.J_0 * a.P_02 * (
        1 - p.gamma_O2)  # [mM s**-1]    Background oxygen consumption
    a.J_pump1_sa = (1 + (p.K_init_e / v.K_e))**(-2) * (
        1 + (p.Na_init_sa / v.Na_sa))**(
            -3)  # [mM s**-1]  Oxygen consumption in soma/axon pump
    a.J_pump1init_sa = 0.0312  # [mM s**-1]   Initial consumption in soma/axon pump
    a.J_pump1_d = (1 + (p.K_init_e / v.K_e))**(-2) * (
        1 + (p.Na_init_d / v.Na_d))**(
            -3)  # [mM s**-1]  Oxygen consumption in dendrite pump
    a.J_pump1init_d = 0.0312  # [mM s**-1]   Initial consumption in dendrite pump
    a.J_O2_pump = p.J_0 * a.P_02 * p.gamma_O2 * (
        (a.J_pump1_sa + a.J_pump1_d) / (a.J_pump1init_sa + a.J_pump1init_d)
    )  # [mM s**-1]    Total oxygen consumption of the NaK pumps

    ############################################################################
    #   # Old stuff
    a.Glu = p.GluSwitch * 0.5 * p.Glu_max * (1 + np.tanh(
        (v.K_e - p.Ke_switch) / p.Glu_slope))
    a.w_NR2A = a.Glu / (p.K_mA + a.Glu)  # [-]
    a.w_NR2B = a.Glu / (p.K_mB + a.Glu)  # [-]
    a.I_Ca = (-4 * p.v_n * p.G_M * p.P_Ca_P_M *
              (p.Ca_ex / p.M)) / (1 + np.exp(-0.08 * (p.v_n + 20))) * (np.exp(
                  2 * p.v_n / p.ph)) / (1 - np.exp(2 * p.v_n / p.ph))  # [fA]
    a.I_Ca_tot = a.I_Ca * (p.n_NR2A * a.w_NR2A + p.n_NR2B * a.w_NR2B)  # [fA]

    a.rho = p.rho_min + (p.rho_max - p.rho_min) * a.Glu / p.Glu_max
    a.G = (a.rho + p.delta) / (p.K_G + a.rho + p.delta)
    ############################################################################

    a.CaM = v.Ca_n / p.m_c  # [uM]
    a.p_NO_n = p.NOswitch_NE * (
        (v.nNOS * p.V_max_NO_n * p.O2_n / (p.K_mO2_n + p.O2_n) * p.LArg_n /
         (p.K_mArg_n + p.LArg_n)))  #*****
    a.c_NO_n = p.k_O2_n * v.NO_n**2 * p.O2_n
    a.tau_nk = p.x_nk**2 / (2 * p.D_cNO)  # [ms]
    a.d_NO_n = (v.NO_k - v.NO_n) / a.tau_nk

    # Flux from ECS to SC
    a.dKedt = -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)
                             )  # K_e derivative as neuron activation in Ostby

    a.J_K_NEtoSC = p.k_syn * a.dKedt * 1e3  # Input flux: K+ flux into SC
    a.J_Na_NEtoSC = -p.k_syn * a.dKedt * 1e3  # Input flux: Na+ flux out of SC

    #%%
    ''' Astrocyte'''

    # Electroneutrality condition
    a.Cl_s = v.Na_s + v.K_s - v.HCO3_s

    # Nernst potentials (in mV)
    a.E_K_k = p.ph / p.z_K * np.log(v.K_s / v.K_k)
    a.E_Na_k = p.ph / p.z_Na * np.log(v.Na_s / v.Na_k)
    a.E_Cl_k = p.ph / p.z_Cl * np.log(a.Cl_s / v.Cl_k)
    a.E_NBC_k = p.ph / p.z_NBC * np.log(
        (v.Na_s * v.HCO3_s**2) / (v.Na_k * v.HCO3_k**2))
    a.E_BK_k = p.ph / p.z_K * np.log(v.K_p / v.K_k)
    a.E_TRPV_k = p.ph / p.z_Ca * np.log(
        v.Ca_p / v.Ca_k)  # Nernst potential TRPV

    # Flux through the Sodium Potassium pump
    a.J_NaK_k = p.J_NaK_max * v.Na_k**1.5 / (
        v.Na_k**1.5 + p.K_Na_k**1.5) * v.K_s / (v.K_s + p.K_K_s)

    # Fluxes
    a.J_BK_k = p.G_BK_k * v.w_k * (v.v_k - a.E_BK_k)  # BK flux (uM/ms)
    a.J_BK_p = a.J_BK_k / p.VR_pa  # K+ influx into the PVS (uM/ms)
    a.J_K_k = p.G_K_k * (v.v_k - a.E_K_k)
    a.J_Na_k = p.G_Na_k * (v.v_k - a.E_Na_k)
    a.J_NBC_k = p.G_NBC_k * (v.v_k - a.E_NBC_k)
    a.J_KCC1_k = p.G_KCC1_k * p.ph * np.log(
        (v.K_s * a.Cl_s) / (v.K_k * v.Cl_k))
    a.J_NKCC1_k = p.G_NKCC1_k * p.ph * np.log(
        (v.Na_s * v.K_s * a.Cl_s**2) / (v.Na_k * v.K_k * v.Cl_k**2))
    a.J_Cl_k = p.G_Cl_k * (v.v_k - a.E_Cl_k)

    # Calcium Equations
    # Flux
    a.J_IP3 = p.J_max * (v.I_k / (v.I_k + p.K_I) * v.Ca_k /
                         (v.Ca_k + p.K_act) * v.h_k)**3 * (1 - v.Ca_k / v.s_k)
    a.J_ER_leak = p.P_L * (1 - v.Ca_k / v.s_k)
    a.J_pump = p.V_max * v.Ca_k**2 / (v.Ca_k**2 + p.k_pump**2)
    a.J_TRPV_k = p.G_TRPV_k * v.m_k * (v.v_k - a.E_TRPV_k)

    # Other equations
    a.B_cyt = 1 / (1 + p.BK_end + p.K_ex * p.B_ex / (p.K_ex + v.Ca_k)**2)

    a.v_3 = p.v_6 - p.v_5 / 2 * np.tanh((v.Ca_k - p.Ca_3) / p.Ca_4)

    # Parent Calcium equations
    a.w_inf = 0.5 * (1 + np.tanh(
        (v.v_k + p.eet_shift * v.eet_k - a.v_3) / p.v_4))
    a.phi_w = p.psi_w * np.cosh((v.v_k - a.v_3) / (2 * p.v_4))

    # TRPV Channel open probability equations
    a.H_Ca_k = v.Ca_k / p.gam_cai_k + v.Ca_p / p.gam_cae_k
    a.eta = (v.R - p.R_init) / (p.R_init)
    a.minf_k = (1 / (1 + np.exp(-(a.eta - p.epshalf_k) / p.kappa_k))) * (
        (1 / (1 + a.H_Ca_k)) * (a.H_Ca_k + np.tanh(
            (v.v_k - p.v1_TRPV_k) / p.v2_TRPV_k)))

    # NO pathway
    a.tau_ki = p.x_ki**2 / (2 * p.D_cNO)  # [ms]
    a.p_NO_k = 0
    a.c_NO_k = p.k_O2_k * v.NO_k**2 * p.O2_k  # [uM/ms]
    a.d_NO_k = (v.NO_n - v.NO_k) / a.tau_nk + (v.NO_i -
                                               v.NO_k) / a.tau_ki  # [uM/ms]

    #%%
    ''' SMC/EC'''

    # SMC fluxes
    a.J_IP3_i = p.F_i * v.I_i**2 / (p.K_r_i**2 + v.I_i**2)  # IP3 channel
    a.J_SR_uptake_i = p.B_i * v.Ca_i**2 / (p.c_b_i**2 + v.Ca_i**2
                                           )  # SERCA pump
    a.J_CICR_i = p.C_i * v.s_i**2 / (p.s_c_i**2 + v.s_i**2) * v.Ca_i**4 / (
        p.c_c_i**4 + v.Ca_i**4)
    a.J_extrusion_i = p.D_i * v.Ca_i * (1 + (v.v_i - p.v_d) / p.R_d_i)
    a.J_SR_leak_i = p.L_i * v.s_i

    ####
    a.J_VOCC_i = p.G_Ca_i * (v.v_i - p.v_Ca1_i) / (
        1 + np.exp(-(v.v_i - p.v_Ca2_i) / p.R_Ca_i))
    ####

    a.J_NaCa_i = p.G_NaCa_i * v.Ca_i / (v.Ca_i + p.c_NaCa_i) * (v.v_i -
                                                                p.v_NaCa_i)

    a.h = 0.1 * v.R
    a.J_stretch_i = p.G_stretch / (1 + np.exp(
        -p.alpha_stretch *
        (p.trans_p_mmHg * v.R / a.h - p.sigma_0))) * (v.v_i - p.E_SAC)

    a.J_Cl_i = p.G_Cl_i * (v.v_i - p.v_Cl_i)
    a.J_NaK_i = p.F_NaK_i
    a.J_K_i = p.G_K_i * v.w_i * (v.v_i - p.v_K_i)
    a.J_degrad_i = p.k_d_i * v.I_i

    a.v_KIR_i = p.z_1 * v.K_p - p.z_2
    a.G_KIR_i = p.F_KIR_i * np.exp(
        p.z_5 * v.v_i + p.z_3 * v.K_p
    )  # Changed by including np.exp(-z_4) parameter into F_KIR_i parameter, no large constant in np.exponential equation
    a.J_KIR_i = a.G_KIR_i * (v.v_i - a.v_KIR_i)

    # EC fluxes
    a.J_IP3_j = p.F_j * v.I_j**2 / (p.K_r_j**2 + v.I_j**2)
    a.J_ER_uptake_j = p.B_j * v.Ca_j**2 / (p.c_b_j**2 + v.Ca_j**2)
    a.J_CICR_j = p.C_j * v.s_j**2 / (p.s_c_j**2 + v.s_j**2) * v.Ca_j**4 / (
        p.c_c_j**4 + v.Ca_j**4)
    a.J_extrusion_j = p.D_j * v.Ca_j
    a.J_stretch_j = p.G_stretch / (1 + np.exp(
        -p.alpha_stretch *
        (p.trans_p_mmHg * v.R / a.h - p.sigma_0))) * (v.v_j - p.E_SAC)
    a.J_ER_leak_j = p.L_j * v.s_j
    a.J_cation_j = p.G_cat_j * (p.E_Ca_j - v.v_j) * 0.5 * (1 + np.tanh(
        (np.log10(v.Ca_j) - p.m_3_cat_j) / p.m_4_cat_j))
    a.J_BK_Ca_j = 0.2 * (1 + np.tanh(
        ((np.log10(v.Ca_j) - p.c) * (v.v_j - p.bb_j) - p.a_1_j) /
        (p.m_3b_j * (v.v_j + p.a_2_j *
                     (np.log10(v.Ca_j) - p.c) - p.bb_j)**2 + p.m_4b_j)))
    a.J_SK_Ca_j = 0.3 * (1 + np.tanh((np.log10(v.Ca_j) - p.m_3s_j) / p.m_4s_j))
    a.J_K_j = p.G_tot_j * (v.v_j - p.v_K_j) * (a.J_BK_Ca_j + a.J_SK_Ca_j)
    a.J_R_j = p.G_R_j * (v.v_j - p.v_rest_j)
    a.J_degrad_j = p.k_d_j * v.I_j

    # Coupling
    a.V_coup_i = -p.G_coup * (v.v_i - v.v_j)
    a.J_IP3_coup_i = -p.P_IP3 * (v.I_i - v.I_j)
    a.J_Ca_coup_i = -p.P_Ca * (v.Ca_i - v.Ca_j)

    a.c_w_i = 1 / 2 * (1 + np.tanh((v.cGMP_i - 10.75) / 0.668))
    a.K_act_i = (v.Ca_i + a.c_w_i)**2 / (
        (v.Ca_i + a.c_w_i)**2 + p.alpha_act_i *
        np.exp(-(v.v_i - p.v_Ca3_i - p.Hshift *
                 (v.H_i - p.H0)) / p.R_K_i))  # Is shifted by 20-HETE ********
    a.tau_wss = v.R / 2 * p.delta_p_L  # from Dormanns 2016

    # NO pathway
    a.tau_ki = p.x_ki**2 / (2 * p.D_cNO)  # [ms]
    a.tau_ij = p.x_ij**2 / (2 * p.D_cNO)  # [ms]
    a.p_NO_i = 0
    a.c_NO_i = p.k_dno * v.NO_i
    a.d_NO_i = (v.NO_k - v.NO_i) / a.tau_ki + (v.NO_j -
                                               v.NO_i) / a.tau_ij  # [uM]
    a.k4 = p.C_4 * v.cGMP_i**2
    a.E_5c = 1 - v.E_b - v.E_6c
    a.V_max_pde = p.k_pde * v.cGMP_i
    a.R_cGMP2 = v.cGMP_i**2 / (v.cGMP_i**2 + p.K_m_mlcp**2)

    a.O2_j = v.O2 * 1e3  # Oxygen in EC taken as O2 from lumen (diffusion very fast so plausible!) instead of constant, in uM
    a.p_NO_j = (p.V_NOj_max * v.eNOS * a.O2_j / (p.K_mO2_j + a.O2_j) *
                p.LArg_j / (p.K_mArg_j + p.LArg_j))
    a.c_NO_j = p.k_O2 * v.NO_j**2 * a.O2_j  # consumption by oxygen

    a.J_lumen = -v.NO_j * 4 * p.D_cNO / (25**2)
    a.d_NO_j = (v.NO_i - v.NO_j) / a.tau_ij + a.J_lumen

    a.W_wss = p.W_0 * (
        a.tau_wss + np.sqrt(16 * p.delta_wss**2 + a.tau_wss**2) -
        4 * p.delta_wss)**2 / (a.tau_wss +
                               np.sqrt(16 * p.delta_wss**2 + a.tau_wss**2))
    a.F_wss = 1 / (1 + p.alp * np.exp(-a.W_wss)) - 1 / (1 + p.alp)
    a.Act_eNOS_Ca = p.K_dis * v.Ca_j / (p.K_eNOS + v.Ca_j)
    a.Act_eNOS_wss = p.g_max * a.F_wss

    # 20-HETE
    a.f_NO = 1 / (1 + np.exp((v.NO_i - p.NO_rest) / p.R_NO))

    #%%
    ''' Wall mechanics'''

    a.K_1 = p.gamma_cross * v.Ca_i**p.n_cross
    a.K_6 = a.K_1
    a.K_2 = 58.1395 * p.k_mlcp_b + 58.1395 * p.k_mlcp_c * a.R_cGMP2
    a.K_5 = a.K_2

    a.M = 1 - v.AM - v.AMp - v.Mp

    # Mechanical Equations
    a.F_r = v.AMp + v.AM
    a.E = p.E_passive + a.F_r * (p.E_active - p.E_passive)
    a.R_0 = p.R_init + a.F_r * (p.alpha - 1) * p.R_init

    #%%
    ''' Oxygen extraction fraction & CMRO2 equations'''
    a.f_in = a.CBF / (p.CBF_0)
    a.f_out = v.CBV**(1 / p.d) + p.tau_TAT * (
        1 / (p.tau_MTT + p.tau_TAT) *
        (a.CBF / p.CBF_init - v.CBV**
         (1 / p.d)))  # [-]   Buxton balloon model outflow

    #    a.f_in_dim = a.CBF/(p.CBF_init)                                           # inflow of blood (normalised CBF)
    #    a.f_in = a.f_in_dim/p.f_in0
    #    a.f_out = v.CBV**(1/p.d) + p.tau_TAT * ( 1/(p.tau_MTT + p.tau_TAT) * ( a.f_in  - v.CBV**(1/p.d) ) )  # [-]   Buxton balloon model outflow
    a.OEF = 1 - (1 - p.E_0)**(
        1 / a.f_in)  # oxygen extraction fraction based on Buxton 1997
    a.CMRO2 = a.f_in * a.OEF / p.E_0  # Cerebral metabolic rate of oxygen consumption
    a.J_O2_vascular = a.CBF * a.OEF / p.E_0  # [mM s**-1] Vascular supply of oxygen, previously CBF * ((p.O2_b - O2) / (p.O2_b - p.O2_0))

    #    #%%
    #    ''' GABA stuff'''
    #    # GABA-T activity, = 1 with normal levels of NO and = 2 when NO=0 (NO inhibits GABA-T activity) [-]
    ##    a.G_Tact = p.G_Tmin + (p.G_Tmax - p.G_Tmin) * np.exp(-p.p2 * v.NO_n) # old exponential form
    #    a.G_Tact = 0.5 * ( (p.G_Tmax + p.G_Tmin) - (p.G_Tmax - p.G_Tmin) * np.tanh( (v.NO_n - p.GT_midpoint)/p.GT_slope ) ) # new sigmoid form
    #
    #    a.kappa_GABA = p.beta_GABA * a.G_Tact                                     # degradation of GABA due to GABA-T [s**-1]
    #    a.g_GABA = p.G_GABA * 0.5 * ( 1 + np.tanh( (v.GABA - p.g_midpoint) / p.g_slope ) ) # Conductance of GABA dependent Cl channel, where conductance=0 when GABA=0 and conductance=G_Cl (value taken from SMC model) when GABA is max
    #
    #    # Fluxes through the GABA activated Cl channels
    #    a.J_GABA_k = a.g_GABA * (v.v_k - p.E_GABA)
    #    a.J_GABA_i = a.g_GABA * (v.v_i - p.E_GABA)
    #
    #    # Glutamate algebraic variables
    #    a.f_Ke = p.beta_Glu * 0.5 * ( 1 + np.tanh( (v.K_e - p.Ke_switch) / p.Glu_slope) )  # Release of Glu from the excitatory neuron during stimulation (occurs when Ke > 5 mM) [-]
    #    a.f_GABA = a.kappa_GABA * v.GABA       # Production of Glu from the degradation of GABA (GABA -> succinic semialdehyde + Glu) [s**-1]
    #
    #    a.w_NR2A = v.Glu / (p.K_mA + v.Glu)     # [-]
    #    a.w_NR2B = v.Glu / (p.K_mB + v.Glu)     # [-]
    #    a.I_Ca = (-4 * p.v_n * p.G_M * p.P_Ca_P_M * (p.Ca_ex / p.M)) / (1 + np.exp(-0.08 * (p.v_n + 20))) * (np.exp(2 * p.v_n / p.ph)) / (1 - np.exp(2 * p.v_n / p.ph))   # [fA]
    #    a.I_Ca_tot = a.I_Ca * (p.n_NR2A * a.w_NR2A + p.n_NR2B * a.w_NR2B)   # [fA]
    #
    #    a.rho = p.rho_min + (p.rho_max - p.rho_min) * v.Glu
    #    a.G = (a.rho + p.delta) / (p.K_G + a.rho + p.delta)
    #
    #    #%%
    #    ''' NPY: released in interneurons, has a vasoconstrictive effect by opening the VOCCs'''
    #    # Conductance increases from baseline when NPY increases
    #    a.g_VOCC = p.G_Ca_i * (1 + p.NPYswitch * p.npy_increase * 0.5 * ( 1 + np.tanh( (v.NPY - p.npy_midpoint) / p.npy_slope ) ) )
    #    a.J_VOCC_i = a.g_VOCC * (v.v_i - p.v_Ca1_i) / (1 + np.exp(-(v.v_i - p.v_Ca2_i) / p.R_Ca_i))
    #
    #    #%%
    '''New stuff'''
    # CICR channel in the astrocyte based on SMC channel
    a.J_CICR_k = p.C_k * v.s_k**2 / (p.s_c_k**2 + v.s_k**2) * v.Ca_k**4 / (
        p.c_c_k**4 + v.Ca_k**4)

    return a
Ejemplo n.º 3
0
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(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'''
Ejemplo n.º 4
0
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