Example #1
0
def pulse_ode_call(model_function, ic, t_max, parameter_name, value):
    """Handle the decision making for how to call odeint when parameter is v_clamp or not.

    Swaps model_function for voltage_clap when clamping and passes the model function in arguments

    :param model_function: Either function to pulse or function to clamp and clamp is pulsed
    :param ic: Initial conditions
    :param t_max: Simulation end_time
    :param parameter_name: Name of parameter or flag to v_clamp
    :param value: Value of parameter or clamp potential
    :return: ODE solution
    """
    # v_clamp the ic, set voltage_clamp to be solved and pass the model function in args
    if parameter_name is "v_clamp":
        ic[0] = value
        ode_function = voltage_clamp
        add_param = (model_function, )
        kwargs = {}
    else:
        # Pass parameters as args and solve the specified function
        ode_function = model_function
        add_param = ()
        kwargs = {parameter_name: value}

    t, sol = solve_ode(
        model=ode_function,
        ic=ic,
        t_max=t_max,
        additional_params=add_param,
        **kwargs,
    )
    return sol
Example #2
0
def steady_state_when_clamped(v_clamp):
    """Determine the steady-state of ode_3d when clamped to a voltage.

    :param v_clamp: Voltage to clamp to
    :return: Steady state of the neuron at v_clamp
    """
    _, state = solve_ode(model=voltage_clamp,
                         ic=[v_clamp, 1, 1],
                         t_max=500,
                         additional_params=(ode_3d, ))
    return state[-1, :]
Example #3
0
def figure1d(title, panel=0, use_modified_tau_n=True):
    """Show waveforms for 5d (ix=0) or 3d (ix=1) models.

    :param title: Plot title (panel label)
    :param panel: Set the model to use 5d/3d (panel=0/1)
    :param use_modified_tau_n: Optional parameter to use the original tau_n which does not work. Defaults to our tau_n
    :return: None
    """
    # Select appropriate model depending on the panel
    model = [ode_5d, ode_3d][panel]

    # Run the simulation for 4200ms and start at an arbitrary point "close" to the limit cycle
    initial_condition = [-55 * ureg.mV, 0, 0]
    initial_condition = resize_initial_condition(initial_condition,
                                                 model,
                                                 fill=0)

    # Solve 5d model with appropriate tau_n
    if model == ode_5d:
        model = partial(ode_5d, use_modified_tau_n=use_modified_tau_n)

    t, sol = solve_ode(model,
                       initial_condition,
                       t_max=4200 * ureg.ms,
                       rtol=1e-3)

    # Throw away the first 1000ms of the simulation
    t_throw_away = np.where(t > 1000)[0][0]
    sol = sol[t_throw_away:, :]
    t = t[t_throw_away:] - t[t_throw_away]  # set new t[0]=0

    # Plot voltage trace
    plt.plot(t, sol[:, 0], "k")
    y_label = "V (mV)" if panel == 0 else ""
    y_tick_label = None if panel == 0 else []

    # Plot properties
    set_properties(
        title,
        x_label="Time (ms)",
        y_label=y_label,
        y_tick=[-80, -40, 0],
        y_limits=[-80, 20],
        y_ticklabel=y_tick_label,
        x_tick=[0, 1000, 2000, 3000],
        x_limits=[0, 3000],
    )
Example #4
0
def figure_1c(title, use_modified_tau_n=True):
    """Compute limit cycle in n,h phase space for the 5d model and compute the approximation n=f(h) for 1C.

    :param title: Plot title (panel label)
    :param use_modified_tau_n: Optional parameter to use the original tau_n which does not work. Defaults to our tau_n
    :return: None
    """
    initial_condition = [
        -55 * ureg.mV,
        0,
        0,
        0,
        0,
    ]  # Does not need to lie on limit cycle since we throw away transient

    # Solve 5d model with appropriate tau_n
    partial_5d = partial(ode_5d, use_modified_tau_n=use_modified_tau_n)
    t, sol = solve_ode(partial_5d,
                       initial_condition,
                       t_max=4200 * ureg.ms,
                       rtol=1e-3)

    # Extract h and n and discard the first half due to transient
    ix_half_time = int(len(t) / 2)
    h = sol[ix_half_time:, 1]
    n = sol[ix_half_time:, 4]
    fit_f_approx(h, n)

    # Plot limit cycle in phase plane
    plt.plot(h, n, c="grey")
    plt.plot(h, f_approx(h), "k")

    # Plot properties
    plt.legend(["n", "n=f(h)"], loc="center left", bbox_to_anchor=(0.3, 1.05))
    set_properties(
        title,
        x_label="h",
        y_label="n",
        x_tick=[0, 0.2, 0.4, 0.6],
        y_tick=np.arange(0, 1, 0.2),
        x_limits=[0, 0.7],
    )
Example #5
0
def figure3c(title):
    """Perform bifurcation analysis of 3D system for 3C.

    :param title: Plot title (panel label)
    :return: None
    """
    # Compute contunuation and plot bifurcation diagram
    figure3c_continuation()
    ic = [-60 * ureg.mV, 0, 1]

    # solve system and overlay hs,v trajectory - zorder plotting behind bifuraction diagram
    t, sol = solve_ode(model=ode_3d, ic=ic, t_max=10000, i_app=0.16)
    plt.plot(sol[:, 2], sol[:, 0], c="grey", zorder=-1e5, linewidth=0.5)

    set_properties(
        title,
        y_label="V (mV)",
        x_limits=[0, 1],
        x_tick=[0, 0.5, 1],
        y_tick=[-80, -40, 0, 40],
        x_label="hs",
    )
Example #6
0
def current_voltage_curve(model,
                          clamp_range,
                          t_max,
                          ic,
                          follow=False,
                          **kwargs):
    """Compute IV curve in either follow mode or peak mode.

    In follow mode a traditional IV curve is computed where the I(V) is the steady state current at a clamped voltage
    for efficiency the initial condition of the next voltage level is the steady state of the present clamp.

    In peak mode (follow = False) the voltage is held at some reset voltage. The voltage is the clamped at the voltage
    for the IV curve and the peak (transient) current is used

    :param model: The function to call for voltage_clamp (the model used)
    :param clamp_range: Upper and lower range of voltage to clamp during the IV curve
    :param t_max: Time to run clamp for to equilibrate
    :param ic: Initial condition or reset condition
    :param follow: Optional flag is follow model or peak mode is used: defaults to peak mode, follow=False
    :param kwargs: Optional settings for the parameters such as g_na or i_leak
    :return: I(V)
    """
    # Initialize IV curve
    parameters = default_parameters(**kwargs)
    voltage = np.arange(*map(strip_dimension, clamp_range))
    current = np.zeros(voltage.shape)
    state = np.array([list(map(strip_dimension, ic))
                      ])  # inital state is ic; array([ic]) gives a 2d array

    # Update model inital state according to IV curve type, run voltage clamp and save I(V)
    for ix, v in enumerate(voltage):
        ic = update_ic(v, ic, state, follow)
        _, state = solve_ode(model=voltage_clamp,
                             ic=ic,
                             t_max=t_max,
                             additional_params=(model, ))
        current[ix] = compute_iv_current(state, parameters, follow)

    return current, voltage