For a more complete summary of how NeuronC works, refer to the modeling paper: Smith, R.G. (1990) "NeuronC: A language based on C for dynamically simulating neural networks of the visual system."
Click here to return to Table of Contents
Another requirement of NeuronC is a video card with enough resolution to display high-res graphics on the screen. NeuronC can be run without graphics to produce a list of recordings but it is useful to display this information in graphical form.
Some excellent computer choices for running NeuronC include:
1) Notebook computer with Pentium 2400 MHz and:
256-512 MB RAM Memory
20-40 GB disk
1024x768 LCD display
DVD-RW drive
Linux operating system (download from carroll.aset.psu.edu:/pub/linux)
2) Workstation/Server with:
Opteron 256 CPU (3GHz)
256-1024 MB RAM memory
256 MB video card
40-80 GB hard disk
1280x1024 monitor
DVD-RW drive
Linux operating system (download from carroll.aset.psu.edu:/pub/linux)
3) Mac G5 with:
1 GB RAM memory
256 MB video card
100-300 GB hard disk
1280x1024 monitor
DVD-RW drive
OSX 10.4
4) PC with Xeon/Opteron with:
1 GB RAM memory
256 MB video card
100-300 GB hard disk
1280x1024 monitor
DVD-RW drive
Win98,Win2000,WinXP
5) Sun, SGI, DEC, or HP workstation with 512 MB or more of memory,
UNIX operating system.
6) Mainframe computer running UNIX.
The directory "nc" contains all the files needed to run NeuronC. The "nc" directory contains the source codes for "nc", "stim" and "plotmod", along with some examples of neural circuit programs. The "pl" directory contains the source codes for "vid" and "hpflt" and "ibmflt" which are the graphics drivers for the video screen and plotter, respectively. The "plot" directory contains the Ampex plot package which is the source code for the graphics language that "vid" and "hpflt" use. Normally the plot subroutines are compiled into a library called "libP.a" which is used when linking nc and plotmod.
1) Uncompress and "un-tar" the distribution. This will make a directory called "nc" and several subdirectories:
tar xvozf nc.tgz
2) Go to the "nc" directory and type "make":
cd nc
make
3) Go to the "pl" directory and install the video
driver for "nc":
cd ../pl
ln vid ~/bin
or
ln vid /usr/bin
4) Go to the "nc/src" subdirectory and
install "stim","nc", and "plotmod":
cd ../src
ln nc stim plotmod ~/bin
or
ln nc stim plotmod /usr/bin
After these operations, the binaries of "vid", "stim", "nc" and
"plotmod" will reside in the user's "bin" subdirectory. If you
don't have a "bin" subdirectory in your home directory, you can
"ln" the binaries anywhere else you like.
For example, to edit "makefile":
cd nc/doc
make cradd
cradd.exe < makefile > m && mv m makefile
notepad makefile
If you would like to run NeuronC under DOS you can compile it with the Delorie gcc compiler (www.delorie.com). A version of NeuronC that runs under DOS is available (with limited graphcis).
Click here to return to Table of Contents
One way to think of computational modeling is "quantitative imagination"; the computational approach to neuroscience is merely an addition to conceptual modeling. The value of the computational approach is to add a quantitative dimension to our intuition about the function of a neural circuit.
The relation between a biological system and the computational model of it depends on analogy in exactly the same way that a conceptual model does. With this type of analogy, we assert that the model represents the biology in a direct quantitative way, but this assertion depends on our intuitive knowledge and experience about the biological system. Seen in this context, a language for neural simulation provides a concise description of a neural circuit's biological form/function for us, but a definition of difference equations for a computer.
Click here to return to section index
Cables and electrotonic decay over space
Several numerical method conventions for modeling neural circuitry exist in the literature. Rall's (1959) cable model allowed currents and voltages in neurons with linear passive membrane properties and branching dendritic trees to be described reasonably accurately. More recently, cable theory has been extended into the time domain (Jack et al. 1975), but still typically requires linear membrane conductances. Ideally we would like a way to model any neural element (cable, synapse, voltage-sensitive channel) in this type of continuous model.
The main idea of cable modeling is that a neural dendrite acts like an electric cable with an inside conductor (cytoplasm of neuron) covered by an insulator (membrane). Two ideas form the basis for this analogy:
1) Current flow through a patch of passive membrane is proportional to the voltage difference between the inside and outside of the membrane.
im = (Vout-Vin) / rm (1)
where:
im = current through membrane
rm = resistance of membrane
2) Voltage along the inside of the dendrite (the
conductor) is reduced by axial current flow through the
dendritic cytoplasm.
d(Vin)/dx = ri * I (2)
where:
ri = axial resistance
I = axial current
x = axial distance along dendrite
differentiating with respect to x:
d2(Vin)/dx2 = ri * dI/dx (3)
but the change in axial current within one small patch
of dendrite is precisely equal to the membrane current:
dI/dx = im (4)
combining (1) (3) and (4):
d2Vin/dx2 = (Vin-Vout) * ri/rm (5)
The solution of this differential equation defines
an electric circuit with exponential decay of voltage
along the length of a neural dendrite. Voltage and
current signals along a passive dendritic tree can be
calculated easily using exponential functions (Rall,
1959).
For an infinite cable:
V = I * ri * lambda * e^-x/lambda (6)
where:
V = voltage along cable at distance x from end
I = current injected into cable at end
ri = axial resistance of cable, ohm/cm
lambda = space constant, sqrt (rm/ri),
rm = membrane resistance of cable, ohm*cm
Click here to return to section index
Each compartment consists of a volume of cytoplasm small enough that its internal voltage is nearly the same everywhere; this condition is called "isopotential". The compartments are connected together by resistors which represent the dendritic axial resistance. The reduction of a neural circuit to a series of connected compartments is justified by analogy because a series of connected isopotential compartments acts very much like a cable if each compartment is small compared with the length of the cable. In addition to the appropriate amount of membrane, each compartment may have other properties such as multiple connections to neighboring compartments and membrane channels with special properties.
<--------------dx------------> <------------dx------------->
compartment 1 -----ri------ compartment 2 ------ri------- compartment 3
V1 < ---------- I1 ---------> V2 <-------- I2 ----------> V3
|
Im
|
Gnd
Derivation of cable equation for compartments:
dV3/dx = V3 - V2 = I2 * ri (7)
dV2/dx = V2 - V1 = I1 * ri (8)
d2V/dx2 = (V3 - V2) - (V2 - V1) (9)
By Ohm's Law, the voltage across a resistor is equal to
the electric current multiplied by the resistance:
d2V/dx2 = I2 * ri - I1 * ri (10)
= ri * (I2 - I1) (11)
by Kirchoff's Law, the current flow into a node equals
the current flow out of the node:
I2 - I1 = Im (12)
But the membrane current equals the compartment voltage
divided by the membrane resistance:
Im = V2 / rm (13)
Combining (11), (12), and (13),
d2V/dx2 = V * ri/rm (14)
Note that (14) is identical to (5).
Click here to return to section index
im = (Vout-Vin) / rm + dVin/dt * cm (15)
where:
im = current through membrane
rm = resistance of membrane
cm = capacitance of membrane
t = time
Including axial voltage drop (as in equation 3):
d2Vin/dx2 = (Vin-Vout) * ri/rm + dVin/dt * cm (16)
where:
ri = axial resistance
rm = membrane resistance
cm = membrane capacitance
t = time
Vin = voltage inside cell
This is the standard equation that neurophysiologists use to
describe voltage in a cable in space and time.
Click here to return to section index
To simulate the mechanism of neurotransmitter release, NeuronC defines a static "transfer function" which defines how much neurotransmitter is released as a function of presynaptic voltage. The neurotransmitter action is modified by a time function which delays and low-pass filter the neurotransmitter action. The time-filtered neurotransmitter level defines the conductance of the postsynaptic channel.
This synaptic model is very simplified because it leaves out details such as: presynaptic calcium channel activity, calcium activated vesicle release, neurotransmitter binding kinetics, etc. These mechanisms are available in NeuronC by selecting special values for the synapse (calcium sensitivity, postsynaptic channel type, etc.). However, the simplified NeuronC synaptic parameters are easy to understand and can simulate a wide variety of synaptic types. Each parameter is "separable"; that is changing its value does not affect other synaptic function parameters. In addition, synaptic parameters can be modified during a runtime to allow a wide variety of neural plasticity functions to be simulated.
Click here to return to section index
G = I / V
where:
I = current
G = conductance of open channel
V = reversal potential minus membrane voltage
If the ionic concentrations in the internal and external
medium are known, it is possible to calculate the voltage at
which no current flows for an ion. This is known as the
ion's Nernst potential and is very similar to the definition
of "reversal potential". It is a function of the internal
and external ion concentrations and temperature:
V = RT / zF * ln (co / ci)
where:
V = Nernst potential
T = temperature (^To^TK)
co = external concentration
ci = internal concentration
z = valency of ion
The Nernst potential is a useful approximation of the
driving force for an ion through a membrane channel
because it defines the voltage at which no net current flows
through the channel. Knowing the Nernst potential for the
major ions is a great help in understanding electric current
flow through a channel.It would be convenient if the reversal potential for a channel could be calculated directly from the Nernst potential of the channel's major ion. However, the driving force for electric current through a channel is not exactly the same as the Nernst potential for the channel's major ion, for several reasons. Every channel allows other ions to pass too. The relative permeability of "other" ions can range from 0.0005 for K through a Ca channel to 0.2 for Ca through an NMDA channel. The effect of having several ions pass through a channel is that its reversal potential is a function of all the ion concentrations and their respective permeabilities. That function is the GHK voltage equation:
( Nao * pna + Ko * pk )
V = RT / zF * ln --------------------
( Nai * pna + Ki * pk )
where:
V = GHK potential (reversal potential for the channel)
T = temperature (deg K)
Nao = Na external concentration
Nai = Na external concentration
pNa = Na permeability through channel
Ko = K external concentration
Ki = K external concentration
pK = K permeability through channel
z = valency of ions ( must be same valencies,
if different use eqn below)
To accurately compute the current through a channel, we need to
compute the reversal potential from the GHK voltage equation and
for this we need to know ion concentrations and relative
permeabilities.In NeuronC, each channel type has a data structure that contains the channel's conductance (and its temperature dependency) and the channel's permeability to several different ions so that an accurate reversal potential can be computed.
A more detailed version of the GHK voltage equation is required when both monovalent and divalent ions are permeable through a channel:
( Nao * pNa + Ko * pK + 4 * p'Ca * Cao )
V = RT / F * ln ----------------------------------------- + Vs
( Nai * pNa + Ki * pK + 4 * p'Ca * Cai * ef)
where:
V = GHK potential (reversal potential for the channel)
Vs = surface potential due to external Cao (set by dcavoff, dcaspvrev)
T = temperature (deg K)
Nao = Na external concentration
Nai = Na external concentration
pNa = Na permeability through channel
Ko = K external concentration
Ki = K external concentration
pK = K permeability through channel
Cao = Ca external concentration
Cai = Ca external concentration
pCa = Ca permeability through channel
ef = exp((V-Vs) F / RT )
p'Ca = modified Ca permeability = pCa / (1 + ef)
This more detailed GHK voltage equation is an "implicit" function,
i.e. V is on both left and right sides of the equation. The
reason for the extra terms for Ca is that Ca++ has a valence of 2
so the normal GHK equation for RT/zf is RT/2F. The extra terms
have the effect of adding the extra 2. [ This equation is derived
from the GHK current equations for mono- and di-valent ions
assuming "independence" between ion motion in a "constant field
theory" by Lewis (1979), J. Physiol. 286: 417-445. Though more
complete than the simple GHK equation above, ions in some
combinations do not have independence so even a more complex
equation would be necessary at some combinations of ion
concentrations to completely specify ion flux. ] To solve this equation, a starting value for V is given and "ef" computed, and the equation solved for a new estimate of V. The process continues for 2-5 iterations until the difference between the new and old estimates for V is small ( 0.1 mV ).
The surface potential Vs is a function of the concentration of divalent ions on the external surface of the membrane (for our purposes, Cao). External calcium shifts both gating properties and reversal potentials, though to different amounts. The shift in the gating properties is about 18 mV negative for each factor of 10 increase in Cao. Therefore an increase in Cao makes the membrane voltage more negative (for gating channels) and causes Na channels to be less activated. The effect on the reversal potential is positive but less, and is set by the "dcaspvrev" variable (default = 0.18), which multiplies dcavoff (.018) for a value of 3.2 mV positive shift / factor of 10 increase in cao.
Click here to return to section index
Click here to return to section index
NeuronC uses an automatic method for determining compartment size. It calculates each neural cable's space constant (from diameter, axial and membrane resistance) then calculates the compartment size as a fraction of the space constant (normally 1/10th). This causes the size of the compartments to be varied according to the properties of the cable that defines them.
Click here to return to section index
It is relatively easy to simulate almost any time-related change in properties of neural elements using a compartmental model, because by analogy these properties do not change for the purposes of the simulation during the course of one time step. Small jumps in channel properties, for example, are allowable over a sequence of time steps because if they're small enough, they faithfully represent the effect of continuous change.
Click here to return to section index
Click here to return to section index
The implicit method ("backwards Euler" method) of numerical integration is more difficult to calculate than the Euler method because the voltages and current flows for the end of the time step are not known until the voltage calculation for each compartment is complete. However this type of computation is equivalent to solving a system of N simultaneous equations in N unknowns (N=number of compartments), which is solvable by matrix techniques.
Although there are higher-order methods to calculate the continuous voltage during a time step, these methods always require more computation per time step. Thus, there is a compromise between accuracy and speed, and higher-order numerical integration schemes are only useful if their time steps can be made proportionately longer. Empirically, the second-order Crank-Nicolson method is often faster than the Euler or implicit methods because larger time steps can be taken as a consequence of its better accuracy (see Moore and Ramon, 1974). However, fourth-order (in time) methods are often slower than second- order methods for simulations of neural circuits with commonly used timesteps (between 10 and 100 usec).
Click here to return to section index
Voltage change in a compartment = dt/c * average of new and old currents
v2n-v2 = k * ( (i1 + i3 + i1n + i3n) / 2 - ( i2 + i2n) / 2 )
v2n-v2 = k/2 * ((v1-v2)*s1 + (v3-v2)*s2 + (v1n-v2n)*s1 +
(v3n-v2n)*s2 - (v2-vm + v2n-vm)*sm )
v2n-v2 = k/2 * ( v1*s1 + v3*s2 - v2 * (s1+s2+sm) + v1n*s1 +
v3n*s2 + 2*vm*sm - v2n * (s1+s2+sm) )
v2n * (1 + k/2 * (s1+s2+sm)) = v2 + k/2 * ( v1*s1 + v3*s2 -
v2 * (s1+s2+sm) + v1n*s1 + v3n*s2 + 2*vm*sm )
v2n = (v2 + k/2 * ( v1*s1 + v3*s2 - v2 * (s1+s2+sm) + v1n*s1 +
v3n*s2 + 2*vm*sm)) / (1 + k/2 * (s1+s2+sm))
v2n = (v2 + k/2 * ( v1*s1 + v3*s2 - v2 * (s1+s2+sm) + v1n*s1 +
v3n*s2 + 2*vm*sm)) * implicit factor
where:
v2 = voltage in this compartment at start of time step
v2n = voltage in this compartment at end of time step
vm = membrane leakage reversal potential
s1 = conductance to neighbor compartment 1
s2 = conductance to neighbor compartment 2
sm = membrane conductance in this compartment
k = dt/c
c = membrane capacitance of compartment
dt = time step
implicit factor = 1 / ( 1 + k/2 * (s1+s2+sm))
References: Joyner et al, 1978
Crank and Nicholson, 1947
Hines, 1984; 1989
Click here to return to section index
dm = alpham - (alpham+betam) * m (original HH rate equation)
dmest = alpham - (alpham+betam) * mest (implicit version)
mest = m + (dm+dmest) / 2 (second-order C-N version)
mest = m + (alpham-(alpham+betam)*m + alpham-(alpham+betam)*mest) / 2
mest (1+alpham+betam) / 2) = alpham + m * (1-(alpham+betam)) / 2)
mest = (alpham + m * (1 - (alpham+betam)/2)) / (1 + (alpham+betam)/2) ( CN )
mest = k1 * m + k2
where:
k1 = (1 - (alpham+betam)/2) / (1 + (alpham+betam)/2)
k2 = alpham / (1+(alpham+betam)/2)
Fully implicit version:
mest = m + alpham-(alpham+betam)*mest (implicit version)
mest (1+alpham+betam) = m + alpham
mest = (alpham + m) / (1 + alpham + betam)
mest = k1 * m + k2
where:
k1 = 1 / (1 + alpham + betam)
k2 = alpham / (1 + alpham + betam)
Since the multipliers k1 and k2 are functions of only voltage,
they are precomputed and placed in lookup tables, after the method
of Hines (1984). Since the rate equations are second-order, they
need not be re-computed for each iteration for a compartment's
voltage. Instead, the implicit estimated value is used and this
allows the calculation to run substantially faster. Click here to return to section index
B + Ca.B = Bt ( free buffer + Ca-bound buffer = total buffer )
f >
B + Ca <--------> Ca.B ( defines forward and reverse rates )
< r
Where:
Ca = free [Ca] in shell
B = free buffer in shell
Ca.B = Ca-bound buffer
Bt = total buffer
f = forward rate, /M/sec
r = reverse rate, /sec
[ Buffer equations here from Yamada et al. (1998) ]
d[Ca]/dt = r * [Ca.B] - f [Ca] [B] ( change in Ca from Ca buffer )
( change in Ca from spatial diffusion )
d[Ca]/dt = ( [Ca(left neighbor shell)] - [Ca(this shell)] ) * S +
( [Ca(right neighbor shell)] - [Ca(this shell)] ) * S
dCa = dt * r * (Bt - B) - f * Ca * B + (Caj - Cai) * S + (Cak - Cai) * S
dCaest = dt * r * (Bt - Best) - f * Caest * Best + (Cajest-Caest) * S + (Cakest-Caest) * S
Where:
dca = change in Ca at the beginning of the time step
dcaest = change in Ca at the end of the time step
i = shell being computed
j = i - 1 (left neighbor shell)
k = i + 1 (right neighbor shell)
Best = new estimate of B
Caest = new estimate of Ca in this shell
Cajest = new estimate of left neighbor Ca
Cakest = new estimate of right neighbor Ca
S = shell diffusion multiplier
Caest = Ca + dCaest
Caest = Ca + r*Bt - r*Best - f*Caest*Best + (Cajest+Cakest-2*Caest)*S
Caest (1+f*Best+2*S) = Ca + r*(Bt-Best) + (Cajest+Cakest)*S
Caest = Ca + r*(Bt-Best) + (Cajest+Cakest)*S / (1+f*Best+2*S) (1)
Best = B + dBest
= B + r * (Bt - Best) - f*Caest*Best
Best (1+r+f*Caest) = B + r*Bt
Best = (B + r*Bt) / (1+r+f*Caest) (2)
For Calcium:
Caest = Ca + (dca + dcaest) / 2
Substituting:
Caest = Cai + ( r * (Bt - B) - f * Ca * B + r * (Bt - Best) - f * Caest * Best +
(Caj - Cai) * S + (Cak - Cai) * S + (Cajest - Caest) * S + (Cakest - Caest) * S ) / 2
Rearranging:
Caest = Ca + ( 2*r*Bt - r*B - r*Best - f*Ca*B - f*Caest*Best +
(Caj + Cak - 2 * Ca + Cajest + Cakest - 2 * Caiest) * S ) / 2
Caest = Ca * (1 - f*B/2 - S) + r*Bt - r*(B+Best)/2 - f*Caest*Best/2 +
(Caj + Cak + Cajest + Cakest) * S / 2 - Caest * S
Solving for Caest:
Caest * (1 + f*Best/2 + S) = Ca * (1 - f*B/2 - S) + r*Bt - r*(B+Best)/2 +
(Caj + Cak + Cajest + Cakest) * S / 2
Switch f*Best with f*B: (allowed by Taylor series expansion after Yamada et al, 1998)
Caest * (1 + f*B/2 + S) = Ca * (1 - f*Best/2 - S) + r*Bt - r*(B+Best)/2 +
(Caj + Cak + Cajest + Cakest) * S / 2
Caest * (1 + f*B/2 + S) = Ca * (1-S) + r*Bt - r*B/2 - Best*(Ca*f + r) / 2 +
(Caj + Cak + Cajest + Cakest) * S / 2
Caest = [ Ca + r*(Bt-B/2) - Best*(Ca*f+r)/2 +
(Caj+Cak+Cajest+Cakest-2*Ca) * S/2 ] / implf (3)
Where:
implf = (1 + f*B/2 + S)
For Buffer:
Remove spatial diffusion, solve for Best:
Best = B + (dB + dBest) / 2
= B + (r*(Bt - Best) - f*Caest*Best + r*(Bt - B) - f*Ca*B) / 2
Solving for Best:
Best (1 + (r+f*Caest)/2) = B + r*(Bt-B/2) - f*Ca*B/2
Best = (B + r*(Bt-B/2) - f*Ca*B/2) / (1 + (r+f*Caest)/2) (4)
The idea here is to write an "implicit" equation that can be solved for the Ca concentration at the end of the time step. This number is dependent on the neighboring Ca concentrations at the end of the time step. These are unknown, but are gradually updated by iterating over all the compartments. Calculate Caest and Best alternately so that buffer gets updated along with Ca.
Iterate equations 1 and 2 (or 3,4) over all the compartments. When change in Caest from one iteration to next is small ( < 1e-10) stop.
Typical number of iterations is 2-5 so computation is relatively fast.
Click here to return to section index
Accuracy of voltage change over time can be determined by successive simulation runs with different size time steps. For example, one could decrease the time step by a factor of 2 until the voltage response of the model does not change from a previous run more than a criterion of say, 0.1 percent. This assures an absolute accuracy of 0.1 percent in the voltage calculated.
Click here to return to section index
Second, compartmental modeling breaks up neural circuits into discrete spatial "chunks" which causes the voltage response to be inaccurate. If many tiny compartments are used to describe a neural cable segment, the inaccuracy is insignificant but the model runs slowly. If just a few larger compartments are used to describe the same cable segment, the model runs faster, but waveshapes and amplitudes of the voltage response are noticeably wrong.
The overall problem with compartmental modeling, then, is the generally slow computational speed. Both of the problems with inaccuracy that occur with compartmental modeling (space, time) can be solved by making the model run more calculations, therefore slower. Thus most ambitious compartmental modelers usually end up eyeing large main-frame computers as a "way out" of their modeling problems.
Using a parallel library such as "PVM" or "MPI" and a parallel adaptation of a simulator it is possible to run a simulation job much faster. However, often we don't need to run just one simulation job, but a whole set of jobs, each running a different parameter set. In this case, a truly parallel implementation may not increase the overall speed much. If there are 20 simulation jobs, and each one runs on one CPU, it would take 20 CPUs the same (or similar) time to run 20 jobs in parallel or using all the CPUs independently. Thus with a modern "CPU farm" of high-speed CPUs we can run batches of simulations fast without resorting to parallel computing.
Click here to return to section index