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.
515 lines
16 KiB
515 lines
16 KiB
#!/usr/bin/python |
|
|
|
""" |
|
Test the basic membrane physiology of cell types. |
|
|
|
Basic Usage: python test_cells.py celltype species [--cc | --vc] |
|
|
|
This script generates a cell of the specified type and species, then tests the |
|
cell with a series of current/voltage pulses to produce I/V, F/I, and spike |
|
latency analyses. |
|
|
|
""" |
|
|
|
import argparse |
|
import os, sys |
|
from neuron import h |
|
import pyqtgraph as pg |
|
import cnmodel |
|
import cnmodel.cells as cells |
|
from cnmodel.protocols import IVCurve, VCCurve |
|
|
|
debugFlag = True |
|
ax = None |
|
h.celsius = 22 |
|
default_durs = [10.0, 100.0, 20.0] |
|
cclamp = False |
|
|
|
cellinfo = { |
|
"types": [ |
|
"bushy", |
|
"bushycoop", |
|
"tstellate", |
|
"tstellatenav11", |
|
"dstellate", |
|
"dstellateeager", |
|
"sgc", |
|
"cartwheel", |
|
"pyramidal", |
|
"octopus", |
|
"tuberculoventral", |
|
"mso", |
|
], |
|
"morphology": ["point", "waxon", "stick"], |
|
"nav": ["std", "jsrna", "nav11", "nacncoop"], |
|
"species": ["guineapig", "cat", "rat", "mouse"], |
|
"pulse": ["step", "pulse"], |
|
} |
|
|
|
# Format for ivranges is list of tuples. This allows finer increments in selected ranges, such as close to rest |
|
ccivrange = { |
|
"mouse": { |
|
"bushy": {"pulse": [(-1, 1.2, 0.05)]}, |
|
"bushycoop": {"pulse": [(-0.5, 0.7, 0.02)]}, |
|
"tstellate": {"pulse": [(-1.0, 1.01, 0.05), (-0.015, 0, 0.005)]}, |
|
"tstellatenav11": {"pulse": [(-1, 1.0, 0.1)]}, |
|
"dstellate": {"pulse": [(-0.3, 0.301, 0.015)]}, |
|
"octopus": {"pulse": [(-1.0, 1.0, 0.05)]}, |
|
"sgc": {"pulse": [(-0.3, 0.6, 0.02)]}, |
|
"cartwheel": {"pulse": [(-0.5, 0.5, 0.05)]}, |
|
"pyramidal": { |
|
"pulse": [(-0.3, 0.3, 0.025), (-0.040, 0.025, 0.005)] |
|
}, # , 'prepulse': [(-0.25, -0.25, 0.25)]}, |
|
"tuberculoventral": {"pulse": [(-0.35, 1.0, 0.05), (-0.040, 0.01, 0.005)]}, |
|
}, |
|
"guineapig": { |
|
"bushy": {"pulse": [(-1, 1.2, 0.05)]}, |
|
"tstellate": {"pulse": [(-0.15, 0.15, 0.01)]}, |
|
"dstellate": {"pulse": [(-0.25, 0.25, 0.025)]}, |
|
"dstellateeager": {"pulse": [(-0.6, 1.0, 0.025)]}, |
|
"octopus": {"pulse": [(-2.0, 6.0, 0.2)]}, |
|
"sgc": {"pulse": [(-0.3, 0.6, 0.02)]}, |
|
"mso": {"pulse": [(-1, 1.2, 0.05)]}, |
|
}, |
|
"rat": { |
|
"pyramidal": { |
|
"pulse": [(-0.3, 0.3, 0.025), (-0.040, 0.025, 0.005)] |
|
} # 'prepulse': [(-0.25, -0.25, 0.25)]}, |
|
}, |
|
} |
|
|
|
# scales holds some default scaling to use in the cciv plots |
|
# argument is {cellname: (xmin, xmax, IVymin, IVymax, FIspikemax, |
|
# offset(for spikes), crossing (for IV) )} |
|
## the "offset" refers to setting the axes back a bit |
|
scale = { |
|
"bushy": (-1.0, -160.0, 1.0, -40, 0, 40, "offset", 5, "crossing", [0, -60]), |
|
"bushycoop": (-1.0, -160.0, 1.0, -40, 0, 40, "offset", 5, "crossing", [0, -60]), |
|
"tstellate": (-1.0, -160.0, 1.0, -40, 0, 40, "offset", 5, "crossing", [0, -60]), |
|
"tstellatenav11": ( |
|
-1.0, |
|
-160.0, |
|
1.0, |
|
-40, |
|
0, |
|
40, |
|
"offset", |
|
5, |
|
"crossing", |
|
[0, -60], |
|
), |
|
"tstellatedend": (-1.0, -160.0, 1.0, -40, 0, 40, "offset", 5, "crossing", [0, -60]), |
|
"dstellate": (-1.0, -160.0, 1.0, -40, 0, 40, "offset", 5, "crossing", [0, -60]), |
|
"dstellateeager": ( |
|
-1.0, |
|
-160.0, |
|
1.0, |
|
-40, |
|
0, |
|
40, |
|
"offset", |
|
5, |
|
"crossing", |
|
[0, -60], |
|
), |
|
"sgc:": (-1.0, -160.0, 1.0, -40, 0, 40, "offset", 5, "crossing", [0, -60]), |
|
"cartwheel": (-1.0, -160.0, 1.0, -40, 0, 40, "offset", 5, "crossing", [0, -60]), |
|
"pyramidal": (-1.0, -160.0, 1.0, -40, 0, 40, "offset", 5, "crossing", [0, -60]), |
|
"tuberculoventral": ( |
|
-1.0, |
|
-160.0, |
|
1.0, |
|
-40, |
|
0, |
|
40, |
|
"offset", |
|
5, |
|
"crossing", |
|
[0, -60], |
|
), |
|
"octopus": (-1.0, -160.0, 1.0, -40, 0, 40, "offset", 5, "crossing", [0, -60]), |
|
"mso": (-1.0, -160.0, 1.0, -40, 0, 40, "offset", 5, "crossing", [0, -60]), |
|
} |
|
|
|
|
|
class Tests: |
|
""" |
|
Class to select cells for tests |
|
""" |
|
|
|
def __init__(self): |
|
pass |
|
|
|
def selectCell(self, args): |
|
""" |
|
Parameters |
|
---------- |
|
args : argparse args from command line |
|
|
|
Returns |
|
------- |
|
cell |
|
Instantiated cell of the selected celltype |
|
""" |
|
h.celsius = float(args.temp) |
|
# |
|
# Spiral Ganglion cell tests |
|
# |
|
if args.celltype == "sgc": # morphology is always "point" for SGCs |
|
cell = cells.SGC.create( |
|
debug=debugFlag, |
|
species=args.species, |
|
nach=args.nav, |
|
ttx=args.ttx, |
|
modelType=args.type, |
|
) |
|
|
|
# |
|
# Bushy tests |
|
# |
|
elif args.celltype == "bushy" and args.morphology == "point": |
|
cell = cells.Bushy.create( |
|
model="RM03", |
|
species=args.species, |
|
modelType=args.type, |
|
ttx=args.ttx, |
|
nach=args.nav, |
|
debug=debugFlag, |
|
) |
|
# cell.soma().klt.gbar = 0.0003 |
|
|
|
elif args.celltype == "bushy" and args.morphology == "waxon": |
|
cell = cells.Bushy.create( |
|
model="RM03", |
|
species=args.species, |
|
modelType=args.type, |
|
nach=args.nav, |
|
ttx=args.ttx, |
|
debug=debugFlag, |
|
) |
|
cell.add_axon() |
|
|
|
elif args.celltype == "bushy" and args.morphology == "stick": |
|
cell = cells.Bushy.create( |
|
model="RM03", |
|
species=args.species, |
|
modelType=args.type, |
|
morphology="cnmodel/morphology/bushy_stick.hoc", |
|
decorator=True, |
|
nach=args.nav, |
|
ttx=args.ttx, |
|
debug=debugFlag, |
|
) |
|
h.topology() |
|
|
|
elif args.celltype == "bushycoop" and args.morphology == "point": |
|
cell = cells.Bushy.create( |
|
model="RM03", |
|
species=args.species, |
|
modelType=args.type, |
|
ttx=args.ttx, |
|
nach=args.nav, |
|
debug=debugFlag, |
|
) |
|
|
|
# |
|
# T-stellate tests |
|
# |
|
elif args.celltype == "tstellate" and args.morphology == "point": |
|
cell = cells.TStellate.create( |
|
model="RM03", |
|
species=args.species, |
|
modelType=args.type, |
|
nach=args.nav, |
|
ttx=args.ttx, |
|
debug=debugFlag, |
|
) |
|
|
|
elif args.celltype == "tstellate" and args.morphology == "stick": |
|
cell = cells.TStellate.create( |
|
model="RM03", |
|
species=args.species, |
|
modelType=args.type, |
|
nach=args.nav, |
|
ttx=args.ttx, |
|
debug=debugFlag, |
|
morphology="cnmodel/morphology/tstellate_stick.hoc", |
|
decorator=True, |
|
) |
|
|
|
elif ( |
|
args.celltype == "tstellatenav11" and args.morphology == "point" |
|
): # note this uses a different model... |
|
print("test_cells: Stellate NAV11") |
|
cell = cells.TStellateNav11.create( |
|
model="Nav11", |
|
species=args.species, |
|
modelType=None, |
|
ttx=args.ttx, |
|
debug=debugFlag, |
|
) |
|
|
|
elif ( |
|
args.celltype == "tstellatenav11" and args.morphology == "stick" |
|
): # note this uses a different model... |
|
cell = cells.TStellateNav11.create( |
|
model="Nav11", |
|
species=args.species, |
|
modelType=None, |
|
morphology="cnmodel/morphology/tstellate_stick.hoc", |
|
decorator=True, |
|
ttx=args.ttx, |
|
debug=debugFlag, |
|
) |
|
h.topology() |
|
|
|
# |
|
# Octopus cell tests |
|
# |
|
elif args.celltype == "octopus" and args.morphology == "point": |
|
cell = cells.Octopus.create( |
|
species=args.species, |
|
modelType="RM03", # args.type, |
|
nach=args.nav, |
|
ttx=args.ttx, |
|
debug=debugFlag, |
|
) |
|
|
|
elif ( |
|
args.celltype == "octopus" and args.morphology == "stick" |
|
): # Go to spencer et al. model |
|
cell = cells.Octopus.create( |
|
modelType="Spencer", |
|
species=args.species, |
|
morphology="cnmodel/morphology/octopus_spencer_stick.hoc", |
|
decorator=True, |
|
nach=args.nav, |
|
ttx=args.ttx, |
|
debug=debugFlag, |
|
) |
|
h.topology() |
|
|
|
# |
|
# D-stellate tests |
|
# |
|
elif args.celltype == "dstellate": |
|
cell = cells.DStellate.create( |
|
debug=debugFlag, species=args.species, ttx=args.ttx, modelType=args.type |
|
) |
|
|
|
elif args.celltype == "dstellateeager": |
|
cell = cells.DStellateEager.create( |
|
debug=debugFlag, ttx=args.ttx, modelType=args.type |
|
) |
|
|
|
# |
|
# DCN pyramidal cell tests |
|
# |
|
elif args.celltype == "pyramidal": |
|
cell = cells.Pyramidal.create( |
|
modelType=args.type, ttx=args.ttx, debug=debugFlag |
|
) |
|
|
|
# |
|
# DCN tuberculoventral cell tests |
|
# |
|
elif args.celltype == "tuberculoventral" and args.morphology == "point": |
|
cell = cells.Tuberculoventral.create( |
|
species="mouse", |
|
modelType="TVmouse", |
|
ttx=args.ttx, |
|
nach=args.nav, |
|
debug=debugFlag, |
|
) |
|
|
|
elif args.celltype == "tuberculoventral" and args.morphology == "stick": |
|
cell = cells.Tuberculoventral.create( |
|
species="mouse", |
|
modelType="TVmouse", |
|
morphology="cnmodel/morphology/tv_stick.hoc", |
|
decorator=True, |
|
ttx=args.ttx, |
|
debug=debugFlag, |
|
) |
|
h.topology() |
|
|
|
# |
|
# DCN cartwheel cell tests |
|
# |
|
elif args.celltype == "cartwheel": |
|
cell = cells.Cartwheel.create( |
|
modelType=args.type, ttx=args.ttx, debug=debugFlag |
|
) |
|
|
|
# |
|
# MSO principal neuron tests |
|
# |
|
elif args.celltype == "mso" and args.morphology == "point": |
|
cell = cells.MSO.create( |
|
model="RM03", |
|
species=args.species, |
|
modelType=args.type, |
|
ttx=args.ttx, |
|
nach=args.nav, |
|
debug=debugFlag, |
|
) |
|
|
|
else: |
|
raise ValueError( |
|
"Cell Type %s and configurations nav=%s or config=%s are not available" |
|
% (args.celltype, args.nav, args.morphology) |
|
) |
|
|
|
print(cell.__doc__) |
|
self.cell = cell |
|
|
|
def run_test(self, sites, ptype, args): |
|
""" |
|
Run either vc or cc test, and plot the result |
|
|
|
Parameters |
|
---------- |
|
args : argparse args from command line |
|
|
|
""" |
|
self.cell.set_temperature(float(args.temp)) |
|
print(self.cell.status) |
|
V0 = self.cell.find_i0(showinfo=True) |
|
# self.cell.cell_initialize() |
|
print( |
|
"Currents at nominal Vrest= %.2f I = 0: I = %g " |
|
% (V0, self.cell.i_currents(V=V0)) |
|
) |
|
self.cell.print_mechs(self.cell.soma) |
|
instant = self.cell.compute_rmrintau(auto_initialize=False, vrange=None) |
|
print( |
|
" From Inst: Rin = {:7.1f} Tau = {:7.1f} Vm = {:7.1f}".format( |
|
instant["Rin"], instant["tau"], instant["v"] |
|
) |
|
) |
|
if args.cc is True: |
|
# define the current clamp electrode and default settings |
|
self.iv = IVCurve() |
|
self.iv.run( |
|
ccivrange[args.species][args.celltype], |
|
self.cell, |
|
durs=default_durs, |
|
sites=sites, |
|
reppulse=ptype, |
|
temp=float(args.temp), |
|
) |
|
ret = self.iv.input_resistance_tau() |
|
print( |
|
" From IV: Rin = {:7.1f} Tau = {:7.1f} Vm = {:7.1f}".format( |
|
ret["slope"], ret["tau"], ret["intercept"] |
|
) |
|
) |
|
self.iv.show(cell=self.cell) |
|
|
|
elif args.rmp is True: |
|
print("temperature: ", self.cell.status["temperature"]) |
|
self.iv = IVCurve() |
|
self.iv.run( |
|
{"pulse": (0, 0, 1)}, |
|
self.cell, |
|
durs=default_durs, |
|
sites=sites, |
|
reppulse=ptype, |
|
temp=float(args.temp), |
|
) |
|
self.iv.show(cell=self.cell, rmponly=True) |
|
|
|
elif args.vc is True: |
|
# define the voltage clamp electrode and default settings |
|
self.vc = VCCurve() |
|
self.vc.run((-120, 40, 5), self.cell) |
|
self.vc.show(cell=self.cell) |
|
|
|
else: |
|
raise ValueError("Nothing to run. Specify one of --cc, --vc, --rmp.") |
|
|
|
|
|
def main(): |
|
parser = argparse.ArgumentParser( |
|
description=( |
|
"test_cells.py:", |
|
" Biophysical representations of neurons (mostly auditory), test file", |
|
) |
|
) |
|
parser.add_argument("celltype", action="store") |
|
parser.add_argument("species", action="store", default="guineapig") |
|
parser.add_argument("--type", action="store", default=None) |
|
parser.add_argument( |
|
"--temp", action="store", default=22.0, help=("Temp DegC (22 default)") |
|
) |
|
# species is an optional option.... |
|
parser.add_argument( |
|
"-m", |
|
action="store", |
|
dest="morphology", |
|
default="point", |
|
help=("Set morphology: %s " % [morph for morph in cellinfo["morphology"]]), |
|
) |
|
parser.add_argument( |
|
"--nav", |
|
action="store", |
|
dest="nav", |
|
default=None, |
|
help=("Choose sodium channel: %s " % [ch for ch in cellinfo["nav"]]), |
|
) |
|
parser.add_argument( |
|
"--ttx", |
|
action="store_true", |
|
dest="ttx", |
|
default=False, |
|
help=("Use TTX (no sodium current"), |
|
) |
|
parser.add_argument( |
|
"-p", |
|
action="store", |
|
dest="pulsetype", |
|
default="step", |
|
help=("Set CCIV pulse to step or repeated pulse"), |
|
) |
|
clampgroup = parser.add_mutually_exclusive_group() |
|
clampgroup.add_argument( |
|
"--vc", action="store_true", help="Run in voltage clamp mode" |
|
) |
|
clampgroup.add_argument( |
|
"--cc", action="store_true", help="Run in current clamp mode" |
|
) |
|
clampgroup.add_argument( |
|
"--rmp", action="store_true", help="Run to get RMP in current clamp mode" |
|
) |
|
|
|
args = parser.parse_args() |
|
if args.celltype not in cellinfo["types"]: |
|
print("cell: %s is not in our list of cell types" % (args.celltype)) |
|
print("celltypes: ", cellinfo["types"]) |
|
sys.exit(1) |
|
|
|
path = os.path.dirname(cnmodel.__file__) |
|
# h.load_file("stdrun.hoc") |
|
# h.load_file(os.path.join(path, "custom_init.hoc")) # replace init with one that gets closer to steady state |
|
|
|
# print 'Species: ', args.species |
|
# print 'Morphology configuration: ', args.morphology |
|
sites = None |
|
if args.pulsetype == "step": |
|
ptype = None |
|
else: |
|
ptype = "pulses" |
|
if args.morphology in cellinfo["morphology"]: |
|
print("Morphological configuration %s is ok" % args.morphology) |
|
|
|
t = Tests() |
|
t.selectCell(args) |
|
app = pg.mkQApp() |
|
t.run_test(sites, ptype, args) |
|
|
|
if sys.flags.interactive == 0: |
|
pg.QtGui.QApplication.exec_() |
|
|
|
|
|
if __name__ == "__main__": |
|
main()
|
|
|