model of DCN pyramidal neuron
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

313 lines
10 KiB

#!/usr/bin/python
"""
Basic test of initialization of multiple cells in the model, and running multiple cells at one time.
Plots the resposnes to a series of current injections for most implemented baseic cell types in
in cnmodel.
Usage:
python examples/toy_model.py (no arguments)
"""
from __future__ import print_function
import sys
from neuron import h
import numpy as np
import cnmodel.cells as cells
from cnmodel.protocols import Protocol
from cnmodel.util import custom_init
from collections import OrderedDict
import re
import pyqtgraph.exporters
from cnmodel.util import pyqtgraphPlotHelpers as PH
from cnmodel.protocols import IVCurve
try: # check for pyqtgraph install
import pyqtgraph as pg
except ImportError:
raise ImportError("This model requires pyqtgraph")
from cnmodel.util.stim import make_pulse
def autorowcol(n):
"""
return a reasonable layout (cols, rows) for n plots on a page
up to 16.
Otherwise return floor(sqrt(n)) + 1 for both r and c.
"""
nmap = {
1: (1, 1),
2: (2, 1),
3: (3, 1),
4: (2, 2),
5: (3, 2),
6: (3, 2),
7: (3, 3),
8: (3, 3),
9: (3, 3),
10: (3, 4),
11: (3, 4),
12: (3, 4),
13: (4, 4),
14: (4, 4),
15: (4, 4),
16: (4, 4),
}
if n <= 16:
return nmap[n][0], nmap[n][1]
else:
nx = np.floor(np.sqrt(n)) + 1
return nx, nx
def makeLayout(cols=1, rows=1, letters=True, margins=4, spacing=4, nmax=None):
"""
Create a multipanel plot, returning the various pyptgraph elements.
The layout is always a rectangular grid with shape (cols, rows)
if letters is true, then the plot is labeled "A, B, C..."
margins sets the margins around the outside of the plot
spacing sets the spacing between the elements of the grid
"""
import string
letters = string.ascii_uppercase
widget = pg.QtGui.QWidget()
gridLayout = pg.QtGui.QGridLayout()
widget.setLayout(gridLayout)
gridLayout.setContentsMargins(margins, margins, margins, margins)
gridLayout.setSpacing(spacing)
plots = [[0 for x in range(cols)] for x in range(rows)]
i = 0
for c in range(cols):
for r in range(rows):
plots[r][c] = pg.PlotWidget()
gridLayout.addWidget(plots[r][c], r, c)
# labelUp(plots[r][c], 'T(s)', 'Y', title = letters[i])
i += 1
if i > 25:
i = 0
if nmax is not None and i >= nmax:
break # that's all - leave out empty plots
return (plots, widget, gridLayout)
def getnextrowcol(plx, row, col, cols):
col += 1
if col >= cols:
col = 0
row += 1
return (plx[row][col], row, col)
class Toy(Protocol):
"""
Calls to encapsulate the model runs
Run a set of cells with defined parameters to show excitability patterns.
Note that cells from Rothman and Manis are run at 22C; others at various
temperatures depending on how they were initially measured and defined.
"""
def __init__(self):
super(Toy, self).__init__()
def current_name(self, name, n):
"""
From the name of the current model, get the current injection information
Parameters
---------
name : str (no default)
name of the cell type
n : int (no default)
"""
if len(self.celltypes[name][3]) > 2:
injs = self.celltypes[name][3]
injarr = np.linspace(injs[0], injs[1], injs[2], endpoint=True)
return "%.3f" % injarr[n]
else:
return "%.3f" % self.celltypes[name][3][n]
def getname(self, cell, ninj):
name = self.make_name(cell)
iname = self.current_name(name, ninj)
nname = name + " " + iname
return name, nname
def make_name(self, cell):
return cell + ", " + self.celltypes[cell][1] + ":"
def run(self):
sre = re.compile(
"(?P<cell>\w+)(?:[, ]*)(?P<type>[\w-]*)(?:[, ]*)(?P<species>[\w-]*)"
) # regex for keys in cell types
self.celltypes = OrderedDict(
[
("Bushy, II", (cells.Bushy, "II", "guineapig", (-0.5, 0.5, 11), 22)),
(
"Bushy, II-I",
(cells.Bushy, "II-I", "guineapig", (-0.5, 0.5, 11), 22),
),
(
"DStellate, I-II",
(cells.DStellate, "I-II", "guineapig", (-0.3, 0.3, 9), 22),
),
(
"TStellate, I-c",
(cells.TStellate, "I-c", "guineapig", (-0.15, 0.15, 9), 22),
),
(
"TStellate, I-t",
(cells.TStellate, "I-t", "guineapig", (-0.15, 0.15, 9), 22),
),
(
"Octopus, II-o",
(cells.Octopus, "II-o", "guineapig", (-2.5, 2.5, 11), 22),
),
("Bushy, II, Mouse", (cells.Bushy, "II", "mouse", (-1, 1.2, 13), 34)),
(
"TStellate, I-c, Mouse",
(cells.TStellate, "I-c", "mouse", (-1, 1, 9), 34),
),
(
"DStellate, I-II, Mouse",
(cells.DStellate, "I-II", "mouse", (-0.5, 0.5, 9), 34),
),
(
"Pyramidal, I, Rat",
(cells.Pyramidal, "I", "rat", (-0.3, 0.4, 11), 34),
),
(
"Cartwheel, I, Mouse",
(cells.Cartwheel, "I", "mouse", (-0.5, 0.5, 9), 34),
),
(
"Tuberculoventral, I, Mouse",
(cells.Tuberculoventral, "I", "mouse", (-0.35, 1, 11), 34),
),
("SGC, bm, Mouse", (cells.SGC, "bm", "mouse", (-0.2, 0.6, 9), 34)),
("SGC, a, Mouse", (cells.SGC, "a", "mouse", (-0.2, 0.6, 9), 34)),
]
)
dt = 0.025
h.dt = dt
h.celsius = 22
stim = {"NP": 1, "delay": 10, "dur": 100, "amp": 0.0, "dt": h.dt}
tend = stim["delay"] + stim["dur"] + 20.0
netcells = {}
for c in list(self.celltypes.keys()):
g = sre.match(c)
cellname = g.group("cell")
modelType = g.group("type")
species = self.celltypes[c][2]
if g.group("type") == "":
netcells[c] = self.celltypes[c][0].create()
else:
netcells[c] = self.celltypes[c][0].create(
modelType=modelType, species=species, debug=False
)
# dicts to hold data
pl = OrderedDict([])
pl2 = OrderedDict([])
rvec = OrderedDict([])
vec = OrderedDict([])
istim = OrderedDict([])
ncells = len(list(self.celltypes.keys()))
#
# build plotting area
#
app = pg.mkQApp()
self.win = pg.GraphicsWindow()
self.win.setBackground("w")
self.win.resize(800, 600)
cols, rows = autorowcol(ncells)
row = 0
col = 0
labelStyle = {"color": "#000", "font-size": "9pt", "weight": "normal"}
tickStyle = pg.QtGui.QFont("Arial", 9, pg.QtGui.QFont.Light)
self.iv = IVCurve() # use standard IVCurve here...
for n, name in enumerate(self.celltypes.keys()):
nrn_cell = netcells[
name
] # get the Neuron object we are using for this cell class
injcmds = list(self.celltypes[name][3]) # list of injections
injcmds[2] = (injcmds[1] - injcmds[0]) / (
float(injcmds[2] - 1)
) # convert to pulse format for IVCurve
temperature = self.celltypes[name][4]
nrn_cell.set_temperature(float(temperature))
ninjs = len(injcmds)
print("cell: ", name)
# print( 'injs: ', injcmds)
pl[name] = self.win.addPlot(
labels={"left": "V (mV)", "bottom": "Time (ms)"}
)
PH.nice_plot(pl[name])
pl[name].setTitle(title=name, font=pg.QtGui.QFont("Arial", 10))
col += 1
if col >= cols:
col = 0
self.win.nextRow()
row += 1
self.iv.reset()
self.iv.run(
{"pulse": [injcmds]},
nrn_cell,
durs=(stim["delay"], stim["dur"], 20.0),
sites=None,
reppulse=None,
temp=float(temperature),
)
for k in range(len(self.iv.voltage_traces)):
pl[name].plot(
self.iv.time_values,
self.iv.voltage_traces[k],
pen=pg.mkPen("k", width=0.75),
)
pl[name].setRange(xRange=(0.0, 130.0), yRange=(-160.0, 40.0))
PH.noaxes(pl[name])
PH.calbar(
pl[list(self.celltypes.keys())[0]],
calbar=[0, -120.0, 10.0, 20.0],
unitNames={"x": "ms", "y": "mV"},
)
text = u"{0:2d}\u00b0C {1:.2f}-{2:.2f} nA".format(
int(temperature),
np.min(self.iv.current_cmd),
np.max(self.iv.current_cmd),
)
ti = pg.TextItem(text, anchor=(1, 0))
ti.setFont(pg.QtGui.QFont("Arial", 9))
ti.setPos(120.0, -120.0)
pl[name].addItem(ti)
# get overall Rin, etc; need to initialize all cells
nrn_cell.cell_initialize()
for n, name in enumerate(self.celltypes.keys()):
nrn_cell = netcells[name]
nrn_cell.vm0 = nrn_cell.soma.v
pars = nrn_cell.compute_rmrintau(auto_initialize=False)
print(
"{0:>14s} [{1:>24s}] *** Rin = {2:6.1f} M\ohm Tau = {3:6.1f} ms Vm = {4:6.1f} mV".format(
nrn_cell.status["name"], name, pars["Rin"], pars["tau"], pars["v"]
)
)
if __name__ == "__main__":
t = Toy()
t.run()
if sys.flags.interactive == 0:
pg.QtGui.QApplication.exec_()
# exporter = pg.exporters.ImageExporter(t.win.scene())
# exporter.export('~/Desktop/Model_Figure2.svg')