ABSTRACT
A programming library ("CONICAL") is presented which
assists in the construction of compartmental models of neurons. The library
consists of approximately 20 classes in the C++ programming language. Standard
input and output are used, and the code has been co-developed under several
operating systems, to ensure maximum portability. The library is
non-monolithic, i.e. portions of it may be used as needed without the entire
library present. Complex classes were derived from simpler ones in several
steps to provide flexible opportunities for customization; and as a C++
library, the simulation code may be readily embedded in larger applications.
Documentation, including introductory material and examples, is provided in
hypertext format and can be viewed with any tables-capable World-Wide Web
browser. Classes provided include cylindrical compartments, passive and active
ion channels, and synapses, including one based on Markov kinetic models.
Performance of the library was compared to the Genesis and Neuron neural
simulators on a simple action potential simulation. The CONICAL program
required less user-written code and much less memory than the equivalent
Genesis script, and ran more than twice as fast; it was also significantly
faster and more memory-efficient than the comparable Neuron script. CONICAL
provides an alternative simulation environment which may be useful when
portability, extensibility, or efficiency is needed, especially on personal
computers or single-processor workstations.
INTRODUCTION
Biologically detailed simulations of neurons
and neural networks are typically based on compartmental modeling; that is,
each cell is divided into many isopotential compartments, joined by
conductances, and activated via simulated ion channels and current injectors.
Compartmental models are often built using dedicated Unix-based simulation
packages, e.g. Genesis (Wilson et al., 1989) or Neuron (Hines 1989). Each such
package has its own interpreted scripting language, in which users define the
components and running parameters of their simulations. In the hands of an
experienced user with access to a compatible computer system, these modeling
packages are powerful research tools. However, they do suffer several
drawbacks for other users: they can be difficult to learn; they are not easy
to modify, extend, and integrate with other software; and they are generally
not portable to operating systems other than Unix or MS-DOS.
When existing software is not suitable, it may
be necessary to write custom software. However, a significant fraction of the
time spent in developing a simulation in a general programming language is
consumed by writing, testing, and debugging core data structures and
algorithms, even though these rarely change for a particular simulation. This
extra cost may be avoided by using an existing library of code which handles
these lower-level issues, freeing the user to concentrate on the unique
aspects of the desired simulation.
Most modern code libraries make use of
object-oriented programming techniques, which offer important advantages over
procedural libraries. First, a set of object classes presents a cleaner,
simpler interface to its user. Details of implementation are hidden (a
property known as encapsulation); and all classes derived from a common base
inherit the properties of that base class. Thus, by understanding a handful of
base classes, one can grasp the general behavior of any object in the library.
Second, algorithms and data structures are tied together; instead of calling a
function and passing it some data, an object's method is called directly from
the object reference itself; this reduces the frequency of programming errors
and makes the dependencies between the data and algorithms more clear. Third,
if the object is a specialized type (i.e. of a derived class), the appropriate
code for that type will be automatically invoked. This is a very powerful
feature, as it allows new class behavior to be invoked without changing
existing classes.
A number of object-oriented languages are
currently available on a wide variety of platforms, for example, C++,
Smalltalk, and Python. Of these, C++ has a number of desirable features. It is
strongly typed, which means that many mistakes (such as trying to square a
string) are caught as soon as the program is compiled, rather than at run time
or not at all. C++ is becoming increasingly common in both business and
scientific programming; as a result, a wide variety of educational resources,
class libraries, and compilers are available. As an extension of C, many
programmers will already be comfortable with its syntax, even if they have
never used C++. Finally, it tends to be efficient in both speed and memory
usage (especially as compared to interpreted languages such as Python), and
allows the programmer to use both high-level or low-level constructs as
required. One drawback to C++ is the somewhat cryptic syntax inherited from
the C programming language, e.g., the use of "&&" for
"and". Given the widespread use of C and C++, this is apparently a
minor inconvenience.
Based on these considerations, a C++ class
library was created. CONICAL, the Computational Neuroscience Class Library, is
a hierarchy of classes in the C++ programming language. It is intended to
provide all the common functionality needed in compartmental simulations,
while remaining efficient and simple to understand. The library may be used in
whole or in part as needed, and each object class is designed to be readily
extended or modified through the standard inheritance mechanism. CONICAL has
been co-developed and tested with Unix, DOS, and MacOS compilers, and makes
use of only standard functions and calls, ensuring maximum portability among
various platforms and compilers. The result is a flexible, efficient
alternative to existing packages for compartmental modeling.
CONICAL provides classes to simulate
isopotential compartments, which may include a variety of passive or active
ion channels, and which can be joined electrically or via synapses. It is
suited to a variety of levels of simulation, from single neurons reconstructed
in great detail, to large networks of more reduced model neurons. In addition
to this basic functionality, CONICAL includes classes to simulate direct
current injection, and to simplify the recording of data. Although it is
primarily intended for low-level compartmental modeling, the library also
includes an integrate-and-fire compartment type which can greatly reduce the
computation needed for large multi-cell simulations. Integrate-and-fire
compartments can be freely intermixed with standard compartments, allowing
(for example) one to combine a detailed dendritic model with a simplified
axon.
All files and documentation are available via
the CONICAL World Wide Web site (http://www-acs.ucsd.edu/~jstrout/conical/).
This includes introductory material, a class reference, example programs and
results, and application notes.
Materials and Methods
CONICAL was developed using common C++ syntax,
conforming to the emerging ANSI standard (Koenig, 1995). Constructs which are
frequently troublesome, i.e. templates and exceptions, were avoided. File
names are restricted to eight letters, and do not depend on case sensitivity,
so that they may be used without change on any operating system.
Since the ANSI C++ standard has not yet
solidified (Koenig, 1995), various compilers often differ in their
implementation of subtle details. For example, some compilers allow you to
access a variable declared in a "for" statement from outside the
loop, while others consider this an error. To make the code as portable as
possible, it was necessary to co-develop the code under a variety of systems
(i.e. operating systems and compilers). Troublesome constructs were quickly
found in this way, and replaced with code which compiled cleanly on all
systems. At the time of this writing, the library has been compiled and tested
under four systems:
-
(1) gcc 2.7.2 running under IRIX 5.3 on a
Silicon Graphics Crimson workstation
-
(2) gcc 2.7.2 running under SunOS 4.1.3 on
a Sun Microsystems Sparc 10 workstation
-
(3) Borland Turbo C++ 3.0 running under
MS-DOS 6.0 on a Datel 386 PC
-
(4) Metrowerks CodeWarrior 8.0 running
under MacOS 7.5.3 on an Apple Macintosh 8500
Test programs compile without modification on
all four systems, and produce identical output. Given the diverse nature of
these systems, it is likely that the library would compile without change on
most C++ compilers which adhere to the emerging ANSI standard.
Compartmental modeling is a well-known
technique (e.g. Segev et al., 1989). Briefly, a neuron is represented by one
or more isopotential compartments. Each compartment consists of a resistance
and capacitance across the cell membrane, a resistive connection to
neighboring compartments, and possibly a number of active conductances which
represent voltage- or ligand-gated ion channels. In addition, each membrane
resistance is placed in series with a voltage source which results from the
relative concentrations of charged ions inside and outside the cell. (See Figure
1.)
|

|
| Figure 1 -- Overview of compartmental
modeling. In (a), a branching section of dendrite has been divided into
seven cylindrical compartments. Each is connected to its neighbors via
bidirectional links. In the CONICAL library, these objects would be
implemented with the Cylinder and Link class, respectively. (b) shows an
equivalent electric circuit for one compartment. Links to neighboring
compartments (left) are resistors; the cell membrane includes a
capacitance, a resistor and membrane potential, and variable resistors
which correspond to active channels (left to right). |
The connected network of voltage sources,
conductances, and capacitance effects produces a system of differential
equations. For the general case (i.e., compartments with active channels and
which may be connected in loops), the equations must be solved numerically.
CONICAL uses the exponential Euler integration method, which is optimized for
equations of this form (MacGregor 1987), and which produces a reasonable
combination of speed and accuracy.
CONICAL consists of approximately twenty
classes arranged in an inheritance tree, as shown in Figure
2. The tree has four roots, that is, four classes
which have no base class. The Stepper class forms a base of any object which
requires periodic updates; this includes compartments and active channels,
among others. Stepper objects can be attached to a Stepmaster object, which
streamlines the updating of multiple objects. CONICAL's one global variable,
gStepmaster, is of this type; by default, newly created Steppers are attached
to this object.
|

|
| Figure 2 -- Inheritance diagram for the
CONICAL library. Each line indicates that the class on the right is
derived from the class on the left; a derived class implements all the
functionality of its base class, and extends it with additional
capabilities. Note that Compartment, Delay, and MarkovSyn each derive
from several classes. |
Classes VSource and VSink represent any voltage
source or sink, respectively. Either may be used alone, for example, as a
constant voltage source. They are combined in the Compartment class, which is
a voltage source and sink, as well as a Stepper. On each tick of the
simulation clock, a compartment updates its voltage by exponential Euler
integration, taking into account membrane resistance and capacitance. Each
compartment may also store an axial conductance, though this is not used by
the compartment itself; rather, this variable is used to set the
intercompartment conductance when compartments are joined together. Membrane
parameters for a generic compartment must be assigned with actual values, and
no physical dimensions are stored. For most purposes, it is easier to use the
Cylinder class, which automatically computes the absolute resistances and
capacitance from cylinder dimensions plus membrane specific resistance,
specific capacitance, and specific axial resistance. Cylinder has one derived
class: Spiker, an "integrate-and-fire" compartment, which can
generate simplified action potentials with a much coarser time scale, and
without active ion channels.
Current flows into any voltage source via an
object of the Current class. This class may be instantiated directly to create
a passive ion channel or "leak" current, that is, one with a fixed
reversal potential. Several lines of derived classes extend this basic
functionality. The Injector class implements an ideal current source, i.e. one
that delivers constant current regardless of the potential of the voltage sink
to which it is connected. The Link class connects a voltage source to a
voltage sink; the amount of current flowing to the sink depends on the
relative potential of the two. This is the class commonly used to connect
compartments together (though for a two-way connection, a pair of links must
be used). Typically, the conductance of a Link is set to the average of the
axial conductances of the compartments it joins. To economically implement
conduction delays, one may substitute a Delay link, which uses the voltage of
the source at some time in the past, rather than the present voltage.
Ion channels whose conductance varies with time
are derived from the Channel class, which is itself a type of current. Real
ion channels respond to a wide variety of variables, such as ligands,
voltages, and so on; this diversity is reflected by the variety of classes
derived from the basic Channel class. One type of channel is the synapse,
which sets its conductance as a function of the concentration of
neurotransmitter in the synaptic cleft. The basic synapse models this
concentration as simply a square pulse, initiated when the voltage of the
presynaptic compartment exceeds a threshold. Specialized synapses include
AlphaSyn, which implements a simple alpha-function response, and MarkovSyn, a
more flexible synapse whose kinetics can be defined in the form of a Markov
kinetic model. The other major type of channel is the Hodgkin-Huxley-form ion
channel, a flexible base class for any channel with one or two gating
variables (Hodgkin & Huxley, 1952). Derived from this is ChanStd (standard
channel), which allows the voltage dependency and kinetics to be specified
with the standard equation forms and parameters typically used to describe
active ion channels (e.g., Migliore et al., 1995). This class is derived from
Channel in several steps, allowing its behavior to be efficiently overridden
at any point; for example, one could create a channel which uses
Hodgkin-Huxley gating variables, but adjusts these variables by a look-up
table, by overriding ChanHH and implementing only the "UpdateM" and
"UpdateH" methods.
As a C++ class library, CONICAL requires no
functions for input and output; standard C++ constructs can be used instead.
One optional output class (StepStream) is included, which simplifies the
recording of tabular data at each step of the simulation.
Typical usage of CONICAL proceeds as follows. A
small main program is written to create the simulation objects and link them
together. These will normally include a Cylinder compartment, joined by Links
to its neighbors, and each containing one or more active channels (usually
ChanStd). For a multi-cell simulation, additional cells are created in the
same manner, which may be joined by synapses (e.g., MarkovSyn) or gap
junctions (Link or Delay). In the simplest case, model parameters are
hardcoded into the main program; in this case, changing a parameter means
recompiling only the main program, not the rest of the library. For more
flexibility, parameters may be entered by the user or read from a file using
the standard C++ input/output capability. Once the simulation has been set up,
a short main loop is begun. This loop makes one call to the library ("gStepMaster.StepAll(dt)")
to simultaneously update all the simulation components, generates any output
of interest, and repeats until done. The size of the time-step is specified in
the call to "StepAll", and may be adjusted between steps to
dynamically balance speed against accuracy.
To embed compartmental modeling in a larger
software application, such as an educational demonstration or graphical
network builder, one would simply link the CONICAL classes into the project.
Objects would be created in response to the user's commands, and the graphical
display could be continuously updated as the simulation proceeds. Though such
a program has not yet been attempted, CONICAL was designed with such
applications in mind. To reduce the possibility of conflicts with existing
software frameworks, CONICAL defines only a single global variable and fewer
than five global functions (depending on the modules included). In addition,
since CONICAL does not require any other C++ libraries (except the standard
input/output classes), use of CONICAL does not dictate a particular
implementation of such classes as strings or containers.
Results
Preliminary performance benchmarks have been
performed comparing a small CONICAL program to the equivalent Genesis script
and a similar Neuron script. Each program created a single compartment with
standard Hodgkin-Huxley ion channels. A constant current was injected,
resulting in a train of action potentials. The simulation ran for 100 to 1000
ms of simulation time, with a constant time step of 0.1 ms. The code used for
the 100 ms version is available on the CONICAL web site as example program 4.
The performance results are shown in Figure
3. The CONICAL program required less user-written
code as the Genesis script, needed slightly more than one-tenth as much
memory, and ran the simulation more than twice as fast, at all simulation
times used. The Neuron script was not strictly equivalent, since it is
impossible to set most of the Hodgkin-Huxley ion channel parameters from
within the scripting language; as a result, the CONICAL program contained
slightly more code. However, it still ran significantly faster and required
less memory than the Neuron script. CONICAL's efficiency is probably due
partly due to compilation of the code, as compared to interpretation, and
partly due to linking only those components that are needed. For more complex
simulations, the advantages of CONICAL over Genesis and Neuron might be
attenuated. Further benchmarks are planned to elucidate the relationship
between simulation size and runtime efficiency.
|

|
| Figure 3 -- A CONICAL program is compared
to the equivalent Genesis and Neuron scripts on several measures: (a)
kilobytes of memory used at run time; (b) lines of user-written code,
excluding comments; (c) CPU time required as a function of simulation
time. Tests were run on a Sparc 10 workstation under SunOS 4.1.3. The
amount of code (b) for the Neuron script is not strictly comparable to
the others, since several parameters of the model could not be set from
within the scripting language. |
Discussion
CONICAL is intended to compliment existing
simulation packages. It is particularly suited to users who are already
familiar with C or C++, or who need the extra efficiency or portability not
available with larger simulators. Its modularity allows users to take as much
or as little as they need for a particular application. With the library
tending to the low-level details of integration, data structure maintenance,
and so on, the user is freed to program in an exploratory manner, quickly
trying out simulation ideas.
CONICAL currently has two major limitations.
First, it requires a C++ compiler if it is to be used alone. For some
classroom settings, that may not be practical; a graphical (or script-based)
simulator front-end might be appropriate in that situation. Second, CONICAL
currently provides no graphing capability; the user must supply some graphing
or data analysis software. While this is readily available on any platform, it
might be more convenient to have graphs generated directly from a CONICAL main
program. It also lacks some of the advanced features found in other simulation
packages; for example, it does not currently read files generated by
cell-tracing software. Despite these drawbacks, it is suggested that CONICAL
fills an important niche in our array of neural simulation tools.
Acknowledgements
The author would like to acknowledge S. Young
and M. Ellisman for helpful comments on the manuscript, and M. Wong for
technical assistance with the Neuron software. This research was supported in
part by an NSF Graduate Fellowship.
References
Hines, M. (1989). A program for simulation of
nerve equations with branching geometries. International Journal of Biomedical
Computing, 24, 33-68.
Hodgkin, A.L., and Huxley, A.F. (1952). A
quantitative description of membrane current and its application to conduction
and excitation in nerve. J. Physiol. (Lond.), 117, 500-544.
Koenig, A.(ed) (1995). ISO/ANSI C++ Draft. At
URL <http://www.cygnus.com/misc/wp/>
on 3 December 1996.
Migliore, M., Cook, E. P., Jaffe, D. B.,
Turner, D. A., and Johnston, D. (1995). Computer simulations of
morphologically reconstructed CA3 hippocampal neurons. J. Neurophysiol., 73,
1157-1168.
Segev, I., Fleshman, J. W., and Burke, R. E.
(1989). Compartmental models of complex neurons. In Koch, C. & Segev, I. (eds),
Methods in Neuronal Modeling: From Synapses to Networks. The MIT Press,
Cambridge, pp.63-96.
Wilson, M.A., Bhalla, U.S., Uhley, J.D., and
Bower, J.M. (1989). GENESIS: a system for simulating neural networks. In D.
Touretzky (ed), Advances in Neural Information Processing Systems . Morgan
Kaufman, San Mateo, pp. 485-492.