
4. THE NEURON SIMULATION ENVIRONMENT

|
No matter how powerful and robust its computational engine may be, the
real utility of any software tool depends largely on its ease of use.
Therefore a great deal of effort has been invested in the design of the
simulation environment provided by NEURON. In this section we first briefly
consider general aspects of the high-level language used for writing NEURON
programs. Then we turn to an example of a model of a nerve cell to introduce
specific aspects of the user environment, after which we cover these features
more thoroughly.
|

4.1 The hoc interpreter

|
NEURON incorporates a programming language based on hoc, a
floating point calculator with C-like syntax described by Kernighan and Pike
(1984). This interpreter has been extended by the addition
of object-oriented syntax (not including polymorphism or inheritance) that can
be used to implement abstract data types and data encapsulation. Other
extensions include functions that are specific to the domain of neural
simulations, and functions that implement a graphical user interface (see
below).
With hoc one can quickly write short programs that meet most
problem-specific needs. The interpreter is used to execute simulations,
customize the user interface, optimize parameters, analyze experimental data,
calculate new variables such as impulse propagation velocity, etc..
NEURON simulations are not subject to the performance penalty often associated
with interpreted (as opposed to compiled) languages because computationally
intensive tasks are carried out by highly efficient precompiled code. Some of
these tasks are related to integration of the cable equation and others are
involved in the emulation of biological mechanisms that generate and regulate
chemical and electrical signals.
NEURON provides a built-in implementation of the microemacs text editor.
Since the choice of a programming editor is highly personal, NEURON will also
accept hoc code in the form of straight ASCII files created with any
other editor.
|

4.2 A specific example

|
Here we show how NEURON might be used to model the
cell in the top of Fig. 4.1. Comments in the hoc code are preceded by
double slashes (//), and code blocks are enclosed in curly brackets
({}).
|

4.2.1 First step: establish model topology

|
One very important feature of NEURON is that it allows the user to
think about models in terms that are familiar to the neurophysiologist, keeping
numerical issues (e.g. number of spatial segments) entirely separate from the
specification of morphology and biophysical properties. As noted in a previous
section (3.2 Spatial discretization . . . ), this separation is
achieved through the use of one-dimensional cable "sections" as the basic
building block from which model cells are constructed. These sections can be
connected together to form any kind of branched cable and endowed with
properties which may vary with position along their length.
|

|
|
|
|
Figure 4.1. Top: cartoon of a neuron with a soma, three dendrites,
and an unmyelinated axon (not to scale). The diameter of the spherical soma is
50 um. Each dendrite is 200 um long and tapers uniformly along its length from
10 um diameter at its site of origin on the soma, to 3 um at its distal end.
The unmyelinated cylindrical axon is 1000 um long and has a diameter of 1 um.
An electrode (not shown) is inserted into the soma for intracellular injection
of a stimulating current. Bottom: topology of a NEURON model that represents
this cell.
|
|

|
The idealized neuron in Fig. 4.1 has several anatomical features whose
existence and spatial relationships we want the model to include: a cell body
(soma), three dendrites, and an unmyelinated axon. The following hoc
code sets up the basic topology of the model:
|
create soma, axon, dendrite[3]
connect axon(0), soma(0)
for i=0,2 { connect dendrite[i](0), soma(1) }
|
The program starts by creating named sections that correspond to the important
anatomical features of the cell. These sections are attached to each other
using connect statements. As noted previously, each section has a
normalized position parameter x which ranges from 0 at one end to 1 at
the other. Because the axon and dendrites arise from opposite sides of the
cell body, they are connected to the 0 and 1 ends of the soma section
(see bottom of Fig. 4.1). A child section can be attached to any location on
the parent, but attachment at locations other than 0 or 1 is generally employed
only in special cases such as spines on dendrites.
|

4.2.2 Second step: assign anatomical and biophysical
properties

|
Next we set the anatomical and biophysical properties of each section.
Each section has its own segmentation, length, and diameter parameters, so it
is necessary to indicate which section is being referenced. There are several
ways to declare which is the currently accessed section, but here the most
convenient is to precede blocks of statements with the appropriate section
name.
|
// specify anatomical and biophysical properties
soma {
nseg = 1 // compartmentalization parameter
L = 50 // [um] length
diam = 50 // [um] diameter
insert hh // standard Hodgkin-Huxley currents
gnabar_hh = 0.5*0.120 // max HH sodium conductance
}
axon {
nseg = 20
L = 1000
diam = 1
insert hh
}
for i = 0,2 dendrite[i] {
nseg = 5
L = 200
diam(0:1) = 10:3 // dendritic diameter tapers
insert pas // standard passive current
e_pas = -65 // [mv] equilibrium potential
// for passive current
g_pas = 0.001 // [siemens/cm2]
// conductance for passive current
}
|
The fineness of the spatial grid is determined by the compartmentalization
parameter nseg (see 3.2 Spatial discretization . . . ).
Here the soma is lumped into a single compartment (nseg = 1), while the
axon and each of the dendrites are broken into several subcompartments
(nseg = 20 and 5, respectively).
In this example, we specify the geometry of each section by assigning values
directly to section length and diameter. This creates a "stylized model."
Alternatively, one can use the "3-D method," in which NEURON computes section
length and diameter from a list of (x, y, z, diam) measurements (see
4.5 Specifying geometry: stylized vs. 3-D).
Since the axon is a cylinder, the corresponding section has a fixed diameter
along its entire length. The spherical soma is represented by a cylinder with
the same surface area as the sphere. The dimensions and electrical properties
of the soma are such that its membrane will be nearly isopotential, so the
cylinder approximation is not a significant source of error. If chemical
signals such as intracellular ion concentrations were important in this model,
it would be necessary to approximate not only the surface area but also the
volume of the soma.
Unlike the axon, the dendrites become progressively narrower with distance
from the soma. Furthermore, unlike the soma, they are too long to be lumped
into a single compartment with constant diameter. The taper of the dendrites
is accommodated by assigning a sequence of decreasing diameters to their
segments. This is done through the use of "range variables," which are discussed later
(4.4 Range variables).
In this model the soma and axon contain Hodgkin-Huxley (HH) sodium, potassium,
and leak channels (Hodgkin and Huxley 1952), while the dendrites have constant,
linear ("passive") ionic conductances . The insert statement assigns
the biophysical mechanisms that govern electrical signals in each section.
Particular values are set for the density of sodium channels on the soma
(gnabar_hh) and for the ionic conductance and equilibrium potential of
the passive current in the dendrites (g_pas and e_pas). More
information about membrane mechanisms is presented in
4.6 Density mechanisms and point processes.
|

4.2.3 Third step: attach stimulating electrodes

|
This code emulates the use of an electrode to inject a stimulating
current into the soma by placing a current pulse stimulus in the middle of the
soma section. The stimulus starts at t = 1 ms,
lasts for 0.1 ms, and has an amplitude of 60 nA.
|
objref stim
soma stim = new IClamp(0.5) // put it in middle of soma
stim.del = 1 // [ms] delay
stim.dur = 0.1 // [ms] duration
stim.amp = 60 // [nA] amplitude

4.2.4 Fourth step: control simulation time course

|
At this point all model parameters have been specified. All that
remains is to define the simulation parameters, which govern the time course of
the simulation, and write some code that executes the simulation.
This is generally done in two procedures. The first procedure initializes the
membrane potential and the states of the inserted mechanisms (channel states,
ionic concentrations, extracellular potential next to the membrane). The
second procedure repeatedly calls the built-in single step integration function
fadvance() and saves, plots, or computes functions of the desired
output variables at each step. In this procedure it is possible to change the
values of model parameters during a run.
|
dt = 0.05 // [ms] integration time step
tstop = 5 // [ms]
finitialize(-65) // initialize membrane potential,
// state variables, and time
proc integrate() {
print t, soma.v(0.5) // show starting time
// and initial somatic
// membrane potential
while (t < tstop) {
fadvance() // advance solution by dt
// function calls to save or plot results
// would go here
print t, soma.v(0.5) // show present time
// and somatic
// membrane potential
// statements that change model parameters
// would go here
}
}
|
The built-in function finitialize() initializes time t to 0,
membrane potential v to
65 mv throughout the model, and the HH state
variables m, n and h to their steady state values at
v =
65 mv.
Initialization can also be performed with a user-written routine if there are
special requirements that finitialize() cannot accommodate, such as
nonuniform membrane potential.
Both the integration time step dt and the solution time t
are global variables. For this example dt = 50 us. The
while(){} statement repeatedly calls fadvance(), which
integrates the model equations over the interval dt and increments
t by dt on each call. For this example, the time and somatic
membrane potential are displayed at each step. This loop exits when
t > = tstop.
When this program is first processed by the NEURON interpreter, the model is
set up and initiated but the integrate() procedure is not executed.
When the user enters an integrate() statement in the NEURON
interpreter window, the simulation advances for 5 ms using 50 us time steps.
|

|
Address questions and inquiries to
Michael Hines
or
Ted Carnevale
Digital preprint of "The NEURON Simulation Environment" by M.L. Hines and N.T. Carnevale,
Neural Computation, Volume 9, Number 6 (August 15, 1997), pp. 1179-1209.
Copyright © 1997 by the Massachusetts Institute of Technology, all rights reserved.
HTML formatting and graphics for page navigation
copyright © 1997 by N.T. Carnevale amd M.L. Hines.
|