Computer models of corticospinal neurons replicate in vitro dynamics (Neymotin et al. 2017)

 Download zip file 
Help downloading and running models
"Corticospinal neurons (SPI), thick-tufted pyramidal neurons in motor cortex layer 5B that project caudally via the medullary pyramids, display distinct class-specific electrophysiological properties in vitro: strong sag with hyperpolarization, lack of adaptation, and a nearly linear frequency-current (FI) relationship. We used our electrophysiological data to produce a pair of large archives of SPI neuron computer models in two model classes: 1. Detailed models with full reconstruction; 2. Simplified models with 6 compartments. We used a PRAXIS and an evolutionary multiobjective optimization (EMO) in sequence to determine ion channel conductances. ..."
1 . Neymotin SA, Suter BA, Dura-Bernal S, Shepherd GM, Migliore M, Lytton WW (2017) Optimizing computer models of corticospinal neurons to replicate in vitro dynamics. J Neurophysiol 117:148-162 [PubMed]
Citations  Citation Browser
Model Information (Click on a link to find other models with that property)
Model Type: Neuron or other electrically excitable cell;
Brain Region(s)/Organism: Neocortex;
Cell Type(s): Neocortex M1 L5B pyramidal pyramidal tract GLU cell; Neocortex primary motor area pyramidal layer 5 corticospinal cell;
Channel(s): I A; I h; I_KD; I K,Ca; I L high threshold; I Na,t; I N; Ca pump; Kir;
Gap Junctions:
Simulation Environment: NEURON; Python;
Model Concept(s): Parameter Fitting; Activity Patterns; Active Dendrites; Detailed Neuronal Models; Simplified Models;
Implementer(s): Suter, Benjamin ; Neymotin, Sam [samn at]; Dura-Bernal, Salvador [salvadordura at]; Forzano, Ernie ;
Search NeuronDB for information about:  Neocortex M1 L5B pyramidal pyramidal tract GLU cell; I Na,t; I L high threshold; I N; I A; I h; I K,Ca; I_KD; Ca pump; Kir;
misc.mod *
vecst.mod *
PTcell.BS0284.cfg *
PTcell.cfg *
import ConfigParser
import io
import pickle

# default config as string
def_config = """
simf =
cell =

# parameter used for evolution
class param:
  def __init__ (self, origval, minval, maxval, bounded, var):
    self.origval = origval
    self.minval = minval
    self.maxval = maxval
    self.bounded = bounded
    if var.count(',') > 0:
      self.var = var.split(',')
      self.var = var
  def __str__ (self):
    sout = ''
    for s in [self.var, self.minval, self.maxval, self.origval, self.bounded]:
      sout += str(s)
      sout += ' '
    return sout
  # generates string for execution
  def assignstr (self, val):
    if type(self.var) == list:
      astr = ''
      for var in self.var: astr += var + ' = ' + str(val) + ';'
      return astr
      return self.var + ' = ' + str(val)
  # check if value is within bounds
  def inbounds (self,val):
    if not bounded: return True
    return val >= self.minval and val <= self.maxval
  # only return assignstr if val is within bounds
  def checkassign (self,val):
    if self.inbounds(val):
      return self.assignstr(val)
      return None

# write config file starting with defaults and new entries
# specified in section (sec) , option (opt), and value (val)
# saves to output filepath fn
def writeconf (fn,sec,opt,val):
  conf = ConfigParser.ConfigParser()
  conf.readfp(io.BytesIO(def_config)) # start with defaults
  # then change entries by user-specs
  for i in xrange(len(sec)): conf.set(sec[i],opt[i],val[i])
  # write config file
  with open(fn, 'wb') as cfile: conf.write(cfile)

def str2bool (v): return v.lower() in ("true", "t", "1")

# read config file
def readconf (fn="PTcell.BS0284.cfg"):
  config = ConfigParser.ConfigParser()
  config.optionxform = str

  def conffloat (base,var,defa): # defa is default value
    val = defa
    try: val=config.getfloat(base,var)
    except: pass
    return val

  def confint (base,var,defa):
    val = defa
    try: val=config.getint(base,var)
    except: pass
    return val

  def confstr (base,var,defa):
    val = defa
    try: val = config.get(base,var)
    except: pass
    return val

  def confbool (base,var,defa):
    return str2bool(confstr(base,var,defa))

  def getparamd (base):
    d = {}
    if not config.has_section(base): return d
    lprm = config.options(base)
    if config.has_option(base,'fpath'):
      fn = config.get(base,'fpath')
      d = pickle.load(open(fn))
      print 'read dprm from ' , fn
      return d    
    #print base, ':', lprm
    for i,prm in enumerate(lprm):
      #print prm
      s = config.get(base,prm)    
      sp = s.split()
      minval,maxval,origval,bounded = float(sp[0]),float(sp[1]),float(sp[2]),str2bool(sp[3])
      p = param(origval,minval,maxval,bounded,prm)
      d[prm] = p
    return d

  lsec = config.sections()
  #print 'sections = ' , lsec

  d = {}
  d['params'] = getparamd('params') # param values optimized by evolution
  d['fixed'] = getparamd('fixed') # optional fixed values, assigned prior to assignment of evolutionary params

  recstr = confstr('run','recordV','')
  d['recordV'] = recstr.split(',') # voltage recording locations

  d['recordSpike'] = confstr('run','recordSpike','')

  d['tstop'] = conffloat('run','tstop',2000)
  d['baset'] = conffloat('run','baset',500)
  d['stimdel'] = conffloat('run','stimdel',500)
  d['stimdur'] = conffloat('run','stimdur',1000)
  d['postassign'] = confstr('run','postassign','')
  d['usecvode'] = confbool('run','usecvode','True')
  d['cellimport'] = confstr('run','cellimport','geom')
  d['cellfunc'] = confstr('run','cellfunc','makecell')
  d['useallspikes'] = confbool('run','useallspikes','False')
  d['cellfuncargs'] = confstr('run','cellfuncargs','') # eg if cellfuncargs is (1,2,3) will call makecell(1,2,3)
  d['isivolts'] = confstr('data','isivolts','')
  d['evolts'] = confstr('data','evolts','')
  d['onvolts'] = confstr('data','onvolts','')
  d['offvolts'] = confstr('data','offvolts','')
  d['lexsag'] = confstr('data','lexsag','')
  d['spikevolts'] = confstr('data','spikevolts','')
  d['spiket'] = confstr('data','spiket','')
  d['sampr'] = conffloat('data','sampr',10000)
  d['lstimamp'] = confstr('data','lstimamp','')

  return d