# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# %pylab inline

# +
## uncomment to install LFPy and dependencies in the EBRAINS VM running this notebook:
# # !pip install LFPy
# -

#
#
#
# # Example 10: Extracellular stimulation of neurons
# This is an example of **``LFPy``** running in an **``Jupyter notebook``**. To run through this example code and produce output, press **``<shift-Enter>``** in each code block below.
#
# First step is to **import ``LFPy``** and other packages for analysis and plotting:

import LFPy
import MEAutility as mu
import numpy as np
from matplotlib.gridspec import GridSpec

# Create some dictionarys with parameters for cell:

cellParameters = {
    'morphology' : 'morphologies/L5_Mainen96_LFPy.hoc',
    'tstart' : -50, # ignore startup transients
    'tstop' : 100,
    'dt' : 2**-4,
    'v_init' : -60, 
    'passive' : False,
}


# Create an helper function to instantiate a **cell** object given a set of parameters:

def instantiate_cell(cellParameters):
    cell = LFPy.Cell(**cellParameters, delete_sections=True)
    cell.set_pos(x=0, y=0, z=0)
    cell.set_rotation(z=np.pi)

    # insert hh mechanism in everywhere, reduced density elsewhere
    for sec in cell.allseclist:
        sec.insert('hh')
        if not 'soma' in sec.name():
            # reduce density of Na- and K-channels to 5% in dendrites
            sec.gnabar_hh = 0.006
            sec.gkbar_hh = 0.0018
            
    return cell


def plot_results(cell, electrode):
    fig = figure(figsize=(10, 6))
    gs = GridSpec(2, 2)

    ax = fig.add_subplot(gs[0, 1])
    im = ax.pcolormesh(np.array(cell.t_ext), cell.z.mean(axis=-1), np.array(cell.v_ext),
                       cmap='RdBu', vmin=-100, vmax=100,
                       shading='auto')
    ax.set_title('Applied extracellular potential')
    ax.set_ylabel('z (um)', labelpad=0)
    rect = np.array(ax.get_position().bounds)
    rect[0] += rect[2] + 0.01
    rect[2] = 0.01
    cax = fig.add_axes(rect)
    
    cbar = fig.colorbar(im, cax=cax, extend='both')
    cbar.set_label('(mV)', labelpad=0)

    ax = fig.add_subplot(gs[1, 1], sharex=ax)
    ax.plot(cell.tvec, cell.somav, 'k')
    ax.set_title('somatic voltage')
    ax.set_ylabel('(mV)', labelpad=0)
    ax.set_xlabel('t (ms)')
    ax.set_ylim([-90, 20])
    ax.set_xlim(cell.tvec[0], cell.tvec[-1])

    ax = fig.add_subplot(gs[:, 0])
    for sec in cell.allseclist:
        idx = cell.get_idx(sec.name())
        ax.plot(cell.x[idx], cell.z[idx],
                color='k')
        if 'soma' in sec.name():
            ax.plot(cell.x[idx], cell.z[idx], color='b', lw=5)
    ax.plot(electrode.x, electrode.z, marker='o', color='g', markersize=3)
    ax.plot(electrode.x[stim_elec], electrode.z[stim_elec], marker='o', color='r', markersize=5)
    ax.axis([-500, 500, -400, 1200])


# Instantiate a **`LFPy.Cell`** object:

cell = instantiate_cell(cellParameters)

# Create an **electrode** using a commercially available design from Neuronexus:

probe = mu.return_mea('Neuronexus-32')

# Rotate the probe and move it so that it is in the xz plane and 50 $\mu$m away from the soma:

probe.rotate(axis=[0, 0, 1], theta=90)
probe.move([0, 100, 0])

# Create a pulse stimulation current:

# +
amp = 20000
n_pulses = 2
interpulse = 10
width = 2
dt = cell.dt
t_stop = cell.tstop
t_start = 20
stim_elec = 15

current, t_ext = probe.set_current_pulses(el_id=stim_elec, amp1=amp, width1=width, dt=dt, t_stop=t_stop,
                                          t_start=t_start, n_pulses=n_pulses, interpulse=interpulse)
# -

figure(figsize=(10, 6))
plot(t_ext, current)
title("Stimulating current")
xlabel('t (ms)')
ylabel('(nA)')
xlim(0, cell.tstop)

# Create ``LFPy`` **electrode** object:

electrode = LFPy.RecExtElectrode(cell=cell, probe=probe)

# Enable extracellular stimulation for the **cell** using stimulating currents of the **electrode** object:

v_ext = cell.enable_extracellular_stimulation(electrode, t_ext=t_ext) 

# Run the simulation with **`electrode`** as input to **`cell.simulate()`**

cell.simulate(probes=[electrode], rec_vmem=True)

# Then plot the **somatic potential**, the **extracellular field** and the **LFP**
# from electrode object:

plot_results(cell, electrode)

np.diff(cell.t_ext), np.diff(cell.z.mean(axis=-1))

# Positive pulses close to the soma location cause an hyperpolarization in the cell. Let's try something else!

cell = instantiate_cell(cellParameters)

# Use the ``probe`` field in the **electrode** object created before to overwrite currents:

# +
amp = -20000
n_pulses = 2
interpulse = 10
width = 2
dt = cell.dt
t_stop = cell.tstop
t_start = 20
stim_elec = 15

electrode = LFPy.RecExtElectrode(cell=cell, probe=probe)
current, t_ext = electrode.probe.set_current_pulses(el_id=stim_elec, amp1=amp, width1=width, dt=dt, 
                                                    t_stop=t_stop, t_start=t_start, n_pulses=n_pulses,
                                                    interpulse=interpulse)
# -

v_ext = cell.enable_extracellular_stimulation(electrode, t_ext=t_ext) 
cell.simulate(probes=[electrode], rec_vmem=True)

plot_results(cell, electrode)

# Now the membrane potential is depolarizing, but stimulation is not strong enough to elicit an action potential.
# Try to crank up the stimulation current to 50$\mu A$

# +
amp = -75000

electrode = LFPy.RecExtElectrode(cell=cell, probe=probe)
current, t_ext = electrode.probe.set_current_pulses(el_id=stim_elec, amp1=amp, width1=width, dt=dt, 
                                                    t_stop=t_stop, t_start=t_start, n_pulses=n_pulses,
                                                    interpulse=interpulse)
cell = instantiate_cell(cellParameters)
v_ext = cell.enable_extracellular_stimulation(electrode, t_ext=t_ext) 
cell.simulate(probes=[electrode], rec_vmem=True)
# -

plot_results(cell, electrode)

# Finally we got two spikes. We can maybe get the same effect with smaller currents and higher stimulation frequencies / number of pulses / pulse width. Try to increase the pulse width:

# +
amp = -30000
n_pulses = 1
interpulse = 10
width = 15
dt = cell.dt
t_stop = cell.tstop
t_start = 20
stim_elec = 15

electrode = LFPy.RecExtElectrode(cell=cell, probe=probe)
current, t_ext = electrode.probe.set_current_pulses(el_id=stim_elec, amp1=amp, width1=width, dt=dt, 
                                                    t_stop=t_stop, t_start=t_start, n_pulses=n_pulses,
                                                    interpulse=interpulse)
cell = instantiate_cell(cellParameters)
v_ext = cell.enable_extracellular_stimulation(electrode, t_ext=t_ext) 
cell.simulate(probes=[electrode], rec_vmem=True)
# -

plot_results(cell, electrode)



StarcoderdataJupyterScriptsDedupFiltered