Motoneuron pool input-output function (Powers & Heckman 2017)

 Download zip file 
Help downloading and running models
Accession:239582
"Although motoneurons have often been considered to be fairly linear transducers of synaptic input, recent evidence suggests that strong persistent inward currents (PICs) in motoneurons allow neuromodulatory and inhibitory synaptic inputs to induce large nonlinearities in the relation between the level of excitatory input and motor output. To try to estimate the possible extent of this nonlinearity, we developed a pool of model motoneurons designed to replicate the characteristics of motoneuron input-output properties measured in medial gastrocnemius motoneurons in the decerebrate cat with voltage- clamp and current-clamp techniques. We drove the model pool with a range of synaptic inputs consisting of various mixtures of excitation, inhibition, and neuromodulation. We then looked at the relation between excitatory drive and total pool output. Our results revealed that the PICs not only enhance gain but also induce a strong nonlinearity in the relation between the average firing rate of the motoneuron pool and the level of excitatory input. The relation between the total simulated force output and input was somewhat more linear because of higher force outputs in later-recruited units. ..."
Reference:
1 . Powers RK, Heckman CJ (2017) Synaptic control of the shape of the motoneuron pool input-output function. J Neurophysiol 117:1171-1184 [PubMed]
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:
Cell Type(s): Spinal cord lumbar motor neuron alpha ACh cell;
Channel(s):
Gap Junctions:
Receptor(s):
Gene(s):
Transmitter(s):
Simulation Environment: NEURON;
Model Concept(s):
Implementer(s): Powers, Randy [rkpowers at u.washington.edu];
Search NeuronDB for information about:  Spinal cord lumbar motor neuron alpha ACh cell;
/
RPCH_JNP17
FivecomptcMG
FivecompthTA
FivecompthTAlw
README.html
Gfluctdv.mod *
gh.mod
kdrRL.mod *
L_Ca_inact.mod *
mAHP.mod *
na3rp.mod *
naps.mod *
avrate.png
cc_command.hoc
fwave1s.txt
fwave2s.txt
init.hoc
init_5cmpt.hoc
makebiramp.hoc *
mosinit.hoc
pars2manyhocs.py *
SetConductances2.hoc *
twobirampsdel.hoc *
                            
#!/usr/bin/python

# cellpars2manyhocs.pl by Ted Ballou, Version 2. 2/7/2011.

# The purpose of this script is to create a set of cell models that
# incorporate mechanism and geometric parameters and global values that are
# extrapolated between two extremes; for convenience these two extremes are
# identified as "low threshold" and "high threshold." Each desired parameter
# or global along with their associated extreme values must be represented by
# a line in the "csv" input file according to the format described below. The
# number of cells to be generated is specified by the user, with a default
# value of 11. For each generated cell a directory is created and a "hoc" file
# that contains the hoc statements to assign the interpolated values
# appropriate to that cell is placed in its directory. The directory and the
# hoc file names are based on the csv file name, with the cell number
# appended.
#
# There are two applications for this at present: 
#
# 1. Generate a set of cells for sensitivity analysis, to illustrate the
# effects of gradually changing various parameters.
#
# 2. Generate sets of cells with gradually changing properties in
# order to simulate populations of neurons with incrementally varying
# properties; for example, spinal motoneurons with continuously varying
# properties representing slow and fatiguing muscle motor units.

# This code takes a comma-delimited file (with extension "csv" standing for
# "commma-separated-values") with four required fields and one optional field: 
#
# 1. NEURON segment name, OR the string "Global", OR "*" (see below)
# 2. NEURON mechanism, OR the global parameter name
# 3. low-threshold value ("lt") for the parameter or global
# 4. high-threshold value ("ht") for the parameter or global
# 5. (optional) nonlinear "indicator"
#
# If "*" is in the first field then what ever is in the second field is
# transferred directly to the output cell files so you can place hoc
# statements in the csv file to be transferred into the cell files.
# 
# On execution the code will prompt for the "Number of cells" to generate,
# which will be assigned to the variable $Ncells. The default value for
# $Ncells is 11, resulting in cell numbers 0, 1, 2, ..., 10.
#
# The code will generate hoc files for $Ncells cells, containing an assignment
# line for each parameter or global, with assignment values extrapolated
# between the two extremes. The low threshold value will be assigned to cell
# number 0, and the high threshold value will be assigned to cell number
# ($Ncells-1); in the default case $Ncells is ll and the ht value is assigned
# to cell number 10. For cell numbers 1 through $Ncells-2, an extrapolated
# value will be assigned based on the nonlinear indicator; if this 5th field
# is absent, the default nonlinear indicator of 0 will be used, which assigns
# a linear extrapolation between the lt and ht values.
#
# For positive nonlinear indicator values, the population will be skewed with
# most of the cells having extrapolated values less than the mean of lt and
# ht; this "$skew" is caluclated as the fraction of the range from lt to ht,
# taken to the power of (1+$nonlin_ind). For negative nonlinear indicator
# values, the population will be skewed with most of the cells having
# extrapolated values more than the mean of lt and ht; this "$skew" is
# calculated as (1 minus the fraction of the range from lt to ht), taken to
# the power of (1-$nonlin_ind), subtracted from 1. These formulas result in a
# nicely symmetric chart for positive, negative, and fractional values of
# $nonlin_ind. See subroutine intrpolate() for the details. Also see the
# documentation and examples in the excel file doc/NonlinearityScaling.xls.
#
# EXAMPLE: say the parameter soma.diam has lt=45 and ht=65. The following
# table shows sample interpolations for nonlinear indicator values of 0 (the
# default), 1, and 2. Note that most of the values for the last two columns
# are LESS than the mean of 45 and 65 (55).
#
# Indicator 	0     1     2
# Cell  0	45.00 45.00 45.00
# Cell  1 	47.00 45.20 45.02
# Cell  2 	49.00 45.80 45.16
# Cell  3 	51.00 46.80 45.54
# Cell  4 	53.00 48.20 46.28
# Cell  5 	55.00 50.00 47.50
# Cell  6 	57.00 52.20 49.32
# Cell  7 	59.00 54.80 51.86
# Cell  8 	61.00 57.80 55.24
# Cell  9 	63.00 61.20 59.58
# Cell 10 	65.00 65.00 65.00
#
# I find it convenient to create the input csv file as a table using excel or
# Open Office calc "OOcalc" and then "SaveAs" a comma-delimited csv file, but
# any text editor can be used to create the csv file.

# File structure:
# First line: ,,lt header, ht header (this line is not used by the script)
# The remaining lines have four OR five fields:
# section, mechanism, lt value, ht value, (nonlin_ind)
# OR
# designation as "Global", global parameter name, lt value, ht value, (nonlin_ind)

###############
# CODE BEGINS
###############
# Invoke perl module to get current working directory

import os # has os.getcwd()
import sys # for args passed on command line

Ncells = 11	# the total number of cells, including lt and ht
cur_cell_no = 0	# globalize this variable, "current cell #"
skew = 0.0 # a global variable
# optionally put csv file on command line, or as reply to prompt when program runs
# [Note: it's easier on command line since <TAB> provides file expansion]
global nonlin_ind
nonlin_ind=0.0 # global variable
fields=[]

print "%%%%%%%%   to abort type <ctrl-c>    %%%%%%%%\n"

if (len(sys.argv)!=2):
  myf=raw_input("Enter the name of the ht/lt parameters \".csv\" file: ")
else:
  myf = sys.argv[1]

if (len(myf)>1):
  try:
    fid=open(myf,"r")
  except:
    print("Cannot open file " + myf + " for reading" )
    print("Invoke with csv file in current directory")
    sys.exit(1)
else:
  print "No txt file supplied as input."
  exit(1)

print("Default number of cells is "+str(Ncells))
test=raw_input("If this is ok hit <return>; otherwise type the desired number: ")
if len(test):
  test_num=eval(test)
  if test_num>0:
    Ncells = float(test_num)
  else:
    print "non-numeric or zero input; using default Ncells value = ", Ncells

#Generate a base name for generated sensitivity directories & files
# mydir array is the list of directories in the full path to current dir

absolute_dir=os.getcwd()
mydir=absolute_dir.split('/')
# get the name of the parent directory: last member of the array split by '/'
basen = mydir[-1].strip()
# strip it down to only the characters preceding the first underscore

basen=basen.split('_')[0]

# Read the data into an array
datalist = fid.readlines()
fid.close()

# scrub the quotes generated by the conversion of spreadsheet to cvs
dl=[]
for line in datalist:
  dl.append(line.replace('"', '').strip())

# The first line of the data file contains the low threshold and high
# threshold headers
# [these variable are not currently used]
fields = dl[0].split(',')	# first line of the csv file

ltidx = 2
lthdr = fields[ltidx]
htidx = 3
hthdr = fields[htidx]
print("lthdr = "+lthdr+", hthdr = " + hthdr)

# scrub the first line
del dl[0]

# The remaining lines in this file have four fields:
# section, mechanism, lt value, ht value
# OR
# designation as "Global", global parameter name, lt value, ht value

# now treat each segment mechanism, generating a cell array between the 
# lt and ht values

# Use values linearly extrapolated between the lt and ht cells, and
# generate hoc files for Ncells cells, each in its own directory

##########################################
# functions

#######################


#################
# isnumeric() subroutine
#
# arg 1: string to be tested for being a numeric value
#
# Utility to validate argument as numeric  

# from 
# http://stackoverflow.com/questions/354038/how-do-i-check-if-a-string-is-a-number-float-in-python

def isnumeric(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

########################################
# getintrp subroutine
#
# arg 1: lt variable value
# arg 2: ht variable value
#
# interpolates lt and ht values; uses global variables Ncells, skew, and
# cur_cell_no. lt and ht non-ranging parameter values are passed as
# arguments

def getintrp(start, end):  
  global skew
  #print "start="+repr(start)+",end="+repr(end)+", skew="+repr(skew)
  if ((not isnumeric(start)) or (not isnumeric(end))):
    print("getintrp() bad args: "+ start +" and "+end)
    sys.exit("getintrp() requires numeric arguments")

  # The following line calculates the interpolation for the cur_cell_no'th
  # interval between the start and end values. This is a nonlinear mechanism
  # for the nonlin_ind being non-zero: skewed towards lt for positive values,
  # and skewed towards ht for negative values. See calculation of skew above.
  tmp=eval(start) + skew*(eval(end)-eval(start))
  #print "returning "+repr(tmp)
  return tmp

##########################
# extract_range subroutine
# 
# arg 1: colon-delimited lt ranging variable
# arg 2: colon-delimited ht ranging variable
#
# Returns: interpolated colon-delimited ranging variable
#
# This function extracts the start and end range values for lt and for ht,
# uses them to generate interpolated start and end range values, and returns
# the interpolated ranging variable

def extract_range(ltarg, htarg):
  # extract values from colon-delimited fields
  ltarg = ltarg.split(":")
  htarg = htarg.split(":")

  # and construct the interpolated ranging variable that is returned
  #print "debugging:"+repr(ltarg)+"|"+repr(htarg)
  #print len(ltarg)
  #print len(htarg)
  if len(ltarg)==1:
    return repr(getintrp(ltarg[0], htarg[0]))
  else:
    return repr(getintrp(ltarg[0], htarg[0]))+":"+repr(getintrp(ltarg[1], htarg[1]))

# intrpolate subroutine
#
# No arguments for this function; the cell number is accessed via the global
# variable cur_cell_no, and the low threshold (lt) and high threshold (ht)
# values are accessed via the glabal array elements fields[2] and fields[3].
#
# The "nonlinear indicator" nonlin_ind value is used to skew the interpolation,
# where skew is a value between 0 and 1, according to the formula below.
#
# Single values are interpolated between lt and ht.
# For colon-delimited ranges ("ranging variables") the range limits are
# extracted for low and high thresholds, and extrapolations between both
# elements are used, to generate the desired colon-delimited result, in the
# extract_range() subroutine.
#
# The cell number is accessed via the global variable cur_cell_no

def intrpolate():
  global fields
  global skew
  global nonlin_ind
  # Generate the "skew" for nonlinear interpolations. This converts the
  # nonlinear indicator nonlin_ind from a single number to a list of values,
  # one for each of the generated cells.
  fraction = float(cur_cell_no)/(Ncells-1)  # fraction of the range from start to
  #print "fraction = "+repr(fraction)+" for cell num " +repr(cur_cell_no)       # end 
  if (nonlin_ind >= 0):
    skew = fraction**(1+nonlin_ind)
  else:
    skew = 1-(1-fraction)**(1-nonlin_ind)
  
  #print "*** skew = ", skew;
  # Generate linearly interpolated value between lt and ht
  #print "len(fields)="+repr(len(fields))
  #print "fields = "+repr(fields)
  #print "fields[2]="+repr(fields[2])
  if (":" not in fields[2]):	# here if lt is NOT a ranging variable
    if (":" in fields[3]):
      sys.exit("high threshold (ht) is ranging but low threshold (lt) is not in "+line)
    # just a number, linearly interpolated based on the distance cur_cell_no
    # is between 0 and Ncells-1
    getintrp(fields[2], fields[3]);
  else:
    # Here if lt IS a ranging variable
    if ":" not in fields[3]:
      sys.exit("low threshold (lt) is ranging but high threshold (ht) is not")

    # generate the interpolated ranging value (two colon-delimited numbers)
  return extract_range(fields[2], fields[3])

# The make_cell() subroutine: create the interpolated hoc files.
# make_cell() argument is the cell # being generated

def make_cell(i):
  global fields
  global cur_cell_no
  global nonlin_ind
  #print "in make_cell("+str(i)+")"
  # Assign this global variable to the argument passed by caller
  cur_cell_no = i # shift;	# global variable used throughout the subroutines

  # Generate the output directory and file for the cell
  myfile = basen+"_"+str(cur_cell_no)

  # Continue even if the directory was previously present
  if not os.path.exists(myfile):
    os.makedirs(myfile)

  # Create the new hoc file; overwrite if already present
  MYF=open(myfile+"/"+myfile+".hoc","w")

  # calculate and write the values interpolated between lt and ht
  for line in dl:
    line=line.strip()

    # Populate the fields[] array with the current line from the csv file
    fields = line.split(',')
    #print "Processing line = "+repr(line)+" with fields = "+repr(fields)
    if fields[0]=='*': # asterisk transfers next field into program
      hocstatement=fields[1]
      MYF.write(hocstatement+"\n")
      continue
    else:
      if len(fields)>3:
        # Discard lines that have the lt or ht value field blank
        if (not len(fields[2])) or (not len(fields[3])):
          continue
      if len(fields)<4:
        # Discard lines that have less than 4 fields
        if not cur_cell_no:  # limit error print to one per line
          print "Less than four fields in discarded line="+repr(line)
        continue

    # fields 2 and 3 are low and high threshold values; if they are BOTH
    # colon-delimited ranging variables then field 1 (mechanism) MUST ALSO be
    # a colon-delimited ranging variable, ie Diam(10:4) intrp will then be
    # the interpolated colon-delimited ranging values

    # The nonlinear indicator field is set to 0 (NO nonlinearity) by default,
    # if 5th field is absent.
    if len(fields)>=5:
      if not len(fields[4]):
        nonlin_ind = 0.0
      else:
        # any rational number is ok
        nonlin_ind = float(fields[4])
        # print "setting nonlin_ind ="+repr(nonlin_ind)
    else:
	nonlin_ind = 0.0
    if fields[0]=='':
      hocstatement=""
    else:
      intrp = intrpolate()
      #print "intrp = "+intrp

    # generate hoc statement for:

    #  Global variables
    if ("Global" in fields[0]):
      hocstatement = fields[1]+" = "+intrp

      # OR "forall" directive
    elif ("forall" in fields[0]):
      hocstatement = fields[0]+"{"+fields[1]+" = "+intrp+"}"

      # OR (default) section.mechanism=value
    elif len(fields)>1:
      hocstatement = fields[0]+"."+fields[1]+" = "+intrp

    # save in the hoc file
    MYF.write(hocstatement+"\n")
  MYF.close()
# end of make_cell

for i in range(int(Ncells)):
  make_cell(i)	# Create each hoc file in its own directory

print("SUCCESS: created directories and hoc files for "+str(Ncells)+" cells")


############################
# END of MAIN
############################







Loading data, please wait...