In [1]:
%matplotlib inline
Run Hay et al. (2011) layer 5b pyramidal cell model, generating and plotting a single action potential and corresponding extracellular potentials (spikes)
Copyright (C) 2017 Computational Neuroscience Group, NMBU.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
In [2]:
import numpy as np
import sys
if sys.version < '3':
from urllib2 import urlopen
else:
from urllib.request import urlopen
import ssl
from warnings import warn
import zipfile
import os
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
import LFPy
import neuron
In [3]:
if not os.path.isfile('L5bPCmodelsEH/morphologies/cell1.asc'):
#get the model files:
u = urlopen('http://senselab.med.yale.edu/ModelDB/eavBinDown.asp?o=139653&a=23&mime=application/zip',
context=ssl._create_unverified_context())
localFile = open('L5bPCmodelsEH.zip', 'wb')
localFile.write(u.read())
localFile.close()
#unzip:
myzip = zipfile.ZipFile('L5bPCmodelsEH.zip', 'r')
myzip.extractall('.')
myzip.close()
#compile mod files every time, because of incompatibility with Mainen96 files:
if "win32" in sys.platform:
pth = "L5bPCmodelsEH/mod/"
warn("no autompile of NMODL (.mod) files on Windows.\n"
+ "Run mknrndll from NEURON bash in the folder L5bPCmodelsEH/mod and rerun example script")
if not pth in neuron.nrn_dll_loaded:
neuron.h.nrn_load_dll(pth+"nrnmech.dll")
neuron.nrn_dll_loaded.append(pth)
else:
os.system('''
cd L5bPCmodelsEH/mod/
nrnivmodl
''')
neuron.load_mechanisms('L5bPCmodelsEH/mod/')
In [4]:
# define cell parameters used as input to cell-class
cellParameters = {
'morphology' : 'L5bPCmodelsEH/morphologies/cell1.asc',
'templatefile' : ['L5bPCmodelsEH/models/L5PCbiophys3.hoc',
'L5bPCmodelsEH/models/L5PCtemplate.hoc'],
'templatename' : 'L5PCtemplate',
'templateargs' : 'L5bPCmodelsEH/morphologies/cell1.asc',
'passive' : False,
'nsegs_method' : None,
'dt' : 2**-6,
'tstart' : -159,
'tstop' : 10,
'v_init' : -60,
'celsius': 34,
'pt3d' : True,
}
# Generate the grid in xz-plane over which we calculate local field potentials
X, Y, Z = np.mgrid[-4:5:1, 1:2, -4:5:1] * 20
# define parameters for extracellular recording electrode, using optional method
electrodeParameters = {
'sigma' : 0.3, # extracellular conductivity
'x' : X.flatten(), # x,y,z-coordinates of contacts
'y' : Y.flatten(),
'z' : Z.flatten(),
'method' : 'soma_as_point', #sphere source soma segment
'N' : np.array([[0, 1, 0]]*X.size), #surface normals
'r' : 2.5, # contact site radius
'n' : 20, # datapoints for averaging
}
In [5]:
# delete old sections from NEURON namespace
LFPy.cell.neuron.h("forall delete_section()")
# create extracellular electrode object for LFPs on grid
electrode = LFPy.RecExtElectrode(**electrodeParameters)
# Initialize cell instance, using the LFPy.Cell class
cell = LFPy.TemplateCell(**cellParameters)
cell.set_rotation(x=4.729, y=-3.166)
# Override passive reversal potential, AP is generated
for sec in cell.allseclist:
for seg in sec:
seg.e_pas = -59.5
# perform NEURON simulation, results saved as attributes in the cell instance
cell.simulate(electrode=electrode)
In [6]:
def plotstuff(cell, electrode):
'''plotting'''
fig = plt.figure(dpi=160)
ax1 = fig.add_axes([0.05, 0.1, 0.55, 0.9], frameon=False)
cax = fig.add_axes([0.05, 0.115, 0.55, 0.015])
ax1.plot(electrode.x, electrode.z, '.', marker='o', markersize=1, color='k',
zorder=0)
#normalize to min peak
LFPmin = electrode.LFP.min(axis=1)
LFPnorm = -(electrode.LFP.T / LFPmin).T
i = 0
zips = []
for x in LFPnorm:
zips.append(list(zip(cell.tvec*1.6 + electrode.x[i] + 2,
x*12 + electrode.z[i])))
i += 1
line_segments = LineCollection(zips,
linewidths = (1),
linestyles = 'solid',
cmap='nipy_spectral',
zorder=1,
rasterized=False)
line_segments.set_array(np.log10(-LFPmin))
ax1.add_collection(line_segments)
axcb = fig.colorbar(line_segments, cax=cax, orientation='horizontal')
axcb.outline.set_visible(False)
xticklabels = np.array([-0.1 , -0.05 , -0.02 , -0.01 , -0.005, -0.002])
xticks = np.log10(-xticklabels)
axcb.set_ticks(xticks)
axcb.set_ticklabels(np.round(-10**xticks, decimals=3))
axcb.set_label('spike amplitude (mV)', va='center')
ax1.plot([22, 38], [100, 100], color='k', lw = 1)
ax1.text(22, 102, '10 ms')
ax1.plot([60, 80], [100, 100], color='k', lw = 1)
ax1.text(60, 102, '20 $\mu$m')
ax1.set_xticks([])
ax1.set_yticks([])
axis = ax1.axis(ax1.axis('equal'))
ax1.set_xlim(axis[0]*1.02, axis[1]*1.02)
# plot morphology
zips = []
for x, z in cell.get_pt3d_polygons():
zips.append(list(zip(x, z)))
from matplotlib.collections import PolyCollection
polycol = PolyCollection(zips, edgecolors='none',
facecolors='gray', zorder=-1, rasterized=False)
ax1.add_collection(polycol)
ax1.text(-0.05, 0.95, 'a',
horizontalalignment='center',
verticalalignment='center',
fontsize=16, fontweight='demibold',
transform=ax1.transAxes)
# plot extracellular spike in detail
ind = np.where(electrode.LFP == electrode.LFP.min())[0][0]
timeind = (cell.tvec >= 0) & (cell.tvec <= 10)
xticks = np.arange(10)
xticklabels = xticks
LFPtrace = electrode.LFP[ind, ]
vline0 = cell.tvec[cell.somav==cell.somav.max()]
vline1 = cell.tvec[LFPtrace == LFPtrace.min()]
vline2 = cell.tvec[LFPtrace == LFPtrace.max()]
# plot asterix to link trace in (a) and (c)
ax1.plot(electrode.x[ind], electrode.z[ind], '*', markersize=5,
markeredgecolor='none', markerfacecolor='k')
ax2 = fig.add_axes([0.75, 0.6, 0.2, 0.35], frameon=True)
ax2.plot(cell.tvec[timeind], cell.somav[timeind], lw=1, color='k', clip_on=False)
ax2.vlines(vline0, cell.somav.min(), cell.somav.max(), 'k', 'dashed', lw=0.25)
ax2.vlines(vline1, cell.somav.min(), cell.somav.max(), 'k', 'dashdot', lw=0.25)
ax2.vlines(vline2, cell.somav.min(), cell.somav.max(), 'k', 'dotted', lw=0.25)
ax2.set_xticks(xticks)
ax2.set_xticklabels(xticks)
ax2.axis(ax2.axis('tight'))
ax2.set_ylabel(r'$V_\mathrm{soma}(t)$ (mV)')
for loc, spine in ax2.spines.items():
if loc in ['right', 'top']:
spine.set_color('none')
ax2.xaxis.set_ticks_position('bottom')
ax2.yaxis.set_ticks_position('left')
ax2.set_title('somatic potential', va='center')
ax2.text(-0.3, 1.0, 'b',
horizontalalignment='center',
verticalalignment='center',
fontsize=16, fontweight='demibold',
transform=ax2.transAxes)
ax3 = fig.add_axes([0.75, 0.1, 0.2, 0.35], frameon=True)
ax3.plot(cell.tvec[timeind], LFPtrace[timeind], lw=1, color='k', clip_on=False)
ax3.plot(0.5, 0, '*', markersize=5, markeredgecolor='none', markerfacecolor='k')
ax3.vlines(vline0, LFPtrace.min(), LFPtrace.max(), 'k', 'dashed', lw=0.25)
ax3.vlines(vline1, LFPtrace.min(), LFPtrace.max(), 'k', 'dashdot', lw=0.25)
ax3.vlines(vline2, LFPtrace.min(), LFPtrace.max(), 'k', 'dotted', lw=0.25)
ax3.set_xticks(xticks)
ax3.set_xticklabels(xticks)
ax3.axis(ax3.axis('tight'))
for loc, spine in ax3.spines.items():
if loc in ['right', 'top']:
spine.set_color('none')
ax3.xaxis.set_ticks_position('bottom')
ax3.yaxis.set_ticks_position('left')
ax3.set_xlabel(r'$t$ (ms)', va='center')
ax3.set_ylabel(r'$\Phi(\mathbf{r},t)$ (mV)')
ax3.set_title('extracellular spike', va='center')
ax3.text(-0.3, 1.0, 'c',
horizontalalignment='center',
verticalalignment='center',
fontsize=16, fontweight='demibold',
transform=ax3.transAxes)
return fig
In [7]:
# Plotting of simulation results:
fig = plotstuff(cell, electrode)
# Optional: save image
# fig.savefig('LFPy-example-4.pdf')
In [ ]: