Running nc, stim, and plotmod commands


Interpreted nc

A model written in the NeuronC script language is "understood" by the "nc" command. Nc is, technically speaking, an interpreter, which means that as it reads the neural circuit program from a file or the keyboard, it executes the actions defined by the program. Internally, however, nc compiles (translates) the input program into a more compact program which it executes immediately. Each statement is compiled and run before the next.

To run a NeuronC program simply type:

     neurc file.n
or
     ncv file.n            (equiv to "nc -v file.n | vid")
or
     ndv file.n            (equiv to "nc -d 1 -v file.n | vid")
This prints the time and voltage/current records as a plot on the console screen. The "neurc" program is actually a command (C-shell) file which consists of:
     nc -v $argv | vid -w 1.4  
That is, neurc runs the command "nc" followed by any file names you may have place after "neurc", and pipes the plot output to the "vid" program which displays it.

The "ncv", "nd", and "ndv" commands are similar to the "neurc" command except that they are not scripts, but are a link to "nc". Whenever "nc" finds itself called "ncv", it will attempt to generate a "vid" window and display the output from nc. They are located in nc/bin.

The "nci" command runs the nc interpreter without any ability to construct or display neurons. It can be run from script files such as "ttest.n" (in nc/bin) that perform calculations.

Compiled nc

A fully-compiled version of the NeuronC language is available that runs "construction mode" faster. This version is a C/C++ API (application library) that allows a neural circuit to be defined with standard C/C++ calls. The run-time functions are shared with the interpreted version. The advantage of this arrangement is that it allows the user to apply the full power of the C++ programming language, including classes and optimization libraries.

The NeuronC API is defined in "nc/src/ncfuncs.h" and described in the NeuronC User's Manual. Each function call in "ncfuncs.h" replaces a statement in the interpreted version of NeuronC. To see an example of source code for this compiled version, see the "retsim.cc" model in nc/models/retsim", described in Retsim: a retinal simulator. The command-line switches for "retsim" are identical to those listed below for "nc", and you can see these at runtime with "nc -h", or "retsim -h". Note that in addition simulation variables can be set from the command line.

The NeuronC API is incorporated into a static library called "libnc.a". This file is created in nc/src and must be linked with a neural circuit program such as nc/models/retsim. To link this library correctly you may need to set the "NC_HOME" variable in nc/models/retsim/makefile, either by setting it as an environment variable or by changing the makefile. The libnc.a library is created as a static library because as a dynamic library it reduces run-time speed.

The experiments defined for "nc/models/retsim" are arranged to be dynamically linked to the "retsim" program at runtime. To allow this process of dynamic runtime linking, you must set the environment variable LD_LIBRARY_PATH:

(tcsh)
       setenv LD_LIBRARY_PATH .
(bash)
       export LD_LIBRARY_PATH="."

To compile "retsim", simply go to the "nc/src" subdirectory, enter "make", then go to the retsim subdirectory and enter "make":

   cd nc/src
   make
   cd ../models/retsim
   make

nc command line arguments

The "nc" command has several command line switches:
    -c         run from inside script with first line = #! nc -c
                  see "Automatic Execution" below.

    -d n set display mode (equivalent to setting "disp = n").
       1   =   allow display of neural circuit with "display" statement.
       2   =   allow display of compartments with "display comps" statement.
       4   =   allow display of connections with  "display comps".
       8   =   allow display of nodes with        "display nodes".
      16   =   allow display of stimulus with     "display stim".
      32   =   allow display of movie    with     "display". (vcolor,cacolor)

    -p n       set print mode (equivalent to setting "prmap=1".

       1   =   display compartments and their connections 
                as conductances and capacitances.
       2   =   display compartments as spheres with their Rm's,
                and channel conductances as densities.

     -e n      set Xmin on plot (overrides "setxmin", "time" for xmin )

     -E n      set Xmax on plot (overrides "setxmax", "endexp" for xmax)

     -l n       set "lamcrit" variable.  Allows you to run
                a circuit model with different compartment
                "condensation" without the need for editing.

     -f        no file name on graph

     -F        no labels on graph (i.e. no file name, node nums, calib),
                 however tic numbers are displayed. 

     -I        run as interpreter only (no knowledge of neural circuits)
	       Same as "nci" (symbolic link nci -> nc)

     -K        print out all predefined symbols and keywords on standard output

     -L n      set line width for "display" statement to n.

     -n        no node numbers on graph

     -r n      random number seed.  Allows you to set the
               seed to a certain value.  Random sequence will
               always be the same for a particular seed value.
               If "n" is negative, then the seed is randomized
               (derived from the process number) so that a
               different sequence is used every time.  The seed
               value actually used in this case is printed
               (in text mode) in the output file so that it
               may be specified at a later time if necessary
               to produce the same sequence.

     --<var> n   set variable from command line.  <var> is 
               name of variable that is used in program, "n" is
               value to set. Value can be numeric or string.

     -s        run in stim mode to make stim file, no run time 

     -t        text mode (outputs numbers).  This is the
               same as setting "vidmode=0" in a program, but
               the -t switch overrides the "vidmode" value
               of 1 (default mode). 

     -v        video mode (outputs plots on screen). 
               Overrides the "vidmode" value of 0. 
               This switch must be used with a graphics 
               driver (either vid or drawpic) because 
               it causes nc to output graphics 
               characters which aren't properly printed 
               on the text screen.

     -w n      set vid window size for "ncv" or "ncd" 

     -W n      tic label char width in terms of screen size 
                 (screen is 1.0 x 1.0).

     -y n      debug with value "n".

        1   =   printouts of subroutine calls.
        2,4 =   gives information about the numerical integration.

                Combinations are possible: a debug value 
                of 7 means include the information from 
                debug 1,2 and 4 values.

      -z n     set debug category

      -C       run input file through CPP preprocessor

      -D       print command line on stdout

      -R       Output symbolic scene for input to "povray" ray-tracer.
                 Use in conjunction with "-d 1" switch. 

      -P file  Output individual frames defined by "display newpage".
                Frame number is appended to file name given.

      -S n     Interval for showing movie frames (real time seconds).
You can run the "nc" command in several ways:
1)   neurc file.n                 (run model, same as "nc -v file.n | vid")
2)   nc file.n                    (run model, prints text on screen )
                                  ( Used for "debugging" a model.) 
3)   nc file.n > file.r           (saves a run file for later)
                                  ( Used for running long simulations. )
4)   nc -v file.n | vid           (run model and display graphics on vid screen)
5)   nd -v file.n | vid           (display neural circuit anatomy on vid screen)
6)   nc -d 1 -v file.n | vid      (same as "nd -v file.n | vid")
7)   plotmod file.r | vid         (Displays graph or picture from file. )   
8)   plotmod file.r | vid -c >file.ps  (Make .ps file for color printer. )   
9)   nc -d 1 -R file.n > file.pov (Draws scene for "povray" ray-tracer. ) 
10)  tail -f -c +1 file.r | plotmod | vid    (Displays plot from .r file during run. )   
11)  tailf file.r | plotmod | vid (Same as above; displays plot from .r file during run. )   
12)  file.n args ¦ vid            (run file.n as shell script file.)
                                  (   see "Automatic Execution" below )
You can 1) run "nc" from a command file "neurc" to plot graphs on the screen; 2) run "nc" without graphics output so that the recording data is printed as a list of numbers on the screen; 3) create a file out of these numbers; 4) send the graphics output to the video screen manually (use the -v switch); or 5) send the graphics output to a pen plotter ("drawpic" draws pictures on the plotter).

Since nc is an interpreter, you can use nc as a calculator to make quick calculations. An expression typed on the keyboard gets evaluated and printed immediately. You can run nc this way simply by typing:

     nc
followed by the "enter" key.

You can "include" files with predefined functions and use the functions as you would a calculator key. For instance the function "lambda" returns the space constant of a cable with a defined diameter and specific membrane resistance (Rm):

     proc lambda (Rm,dia) {

      Ri = 100;
      return (sqrt ((Rm/Ri) * (dia/4)));
     };
You could write this function in a file called "lambda.m", and then "include" this file whenever you wanted to make use of the function:
     nc
     include "lambda.m"
     lambda (5000,2);
Nc prints out the answer immediately.

Macros (cpp)

You can include macros in a Neuron-C script file and process them using the standard "CPP" C pre-processor using the "nc -C" command line switch. This gives the ability to define macros with the "#define" statement. See "Macros" in "NeuronC statements and syntax".


Batch files

You can make a script file to run "nc" several times. You do this by creating a text file with a text editor program (e.g. "vi" or "pico") and changing its mode to "executable" with:

   chmod +x scripfile

Such a script is also known as a "batch file", and its first line tells the shell which interpreter to run to execute the batch file. If no interpreter is specified, the system shell (normally /bin/sh) runs the script. You an specify another interpreter (e.g. another shell such as "tcsh", or a data processor command like "awk") like this:

   #! /bin/tcsh
   .
   .
   .

When you run this script, the shell looks at the first character on the first line. Since the # is a "comment" character, normally the shell would ignore a line starting with #. But when the first 2 characters are #!, the shell looks further to find the interpreter. Then the remaining lines of the script can be written in a different language meant for the other program specified after #!.

The commands in a shell script are exactly what you might type in from the keyboard.
   #! /bin/tcsh
   #  
   #  Script file runsim-1
   #    written by Dave
   #
   nc file.n > file.r
   .
   .
   .
When testing parameter space, it's sometimes difficult to remember what all the data files are and how they were generated. Once you get a simulation going, you might want to copy it, change a few parameters, and rename the changed version to a different filename, maybe with a sequence number. Then you can run the new simulation script to make a new output file:

   nc file1.n > file1.r
   nc file2.n > file2.r
or
   file1 > file1.r     (If you make file1 a "nc shell" script,)
   file2 > file2.r     (  see "Automatic Execution". )
This has the advantage that the ".r" files (run files) are always the same name as the simulation scripts. However, this way you will end up with a lot of simulation scripts, and really the file names don't give you any idea of what parameters were changed. You can always run "diff" to find the differences, but that gets frustrating when you just want to find one run where you changed a particular parameter.

A better way to run simulations with different parameters is to maintain only one simulation script file. Then run "nc" from a script file, setting parameters on the command line:

#! /bin/tcsh -f
#
#  script file "runsim-1"
#

nc -s ssize 5  file.n  >& file1.r
nc -s ssize 10 file.n  >& file2.r
nc -s ssize 50 file.n  >& file3.r

nc --nostim 1             file.n >& file4.r
nc --nostim 1 --ssize 5  file.n >& file5.r
nc --nostim 1 --ssize 10 file.n >& file6.r
This batch file has the advantage that you can see exactly how you made all the ".r" files, and you can run it over again if necessary if you need to make a basic change in the "file.n" script. The ">&" in each line tells the shell to place both the standard output and the standard error in the output file.

The ".r" files produced by such a batch file will contain numbers that you can plot with the "plotmod" program:

  plotmod -p 2-5 file4.r | vid     (to see on the X screen)
  plotmod -p 2-5 file4.r | vid -c > file.ps (to make into a .ps file)
  plotmod -p 2-5 file4.r | vid -c | ps2pdf - - > file.pdf (to make into a .pdf file)
  plotmod -p 2-5 file4.r | vidpdf > file.pdf (equiv to above, to make into a .pdf file)

Generating .r files while plotting to vid

Often when you're running one or more simulations you want to save them as .r files but you also want to see the progress of the simulations. You can do that with:

tail -f -n +1 file.r | plotmod | vid
The tail command continually re-reads file.r during the time the simulation is running so that plotmod can convert it for vid to display.

You can put that command into a script like this:

-----tailf-----------------

#! /bin/tcsh -f
#
tail -f -n +1 $argv

---------------------------
and (put it in ~/bin, and run "rehash" so the shell recognizes it) run the script like this:
tailf xxx.r | plotmod | vid

Automatic Execution of nc from script file

You can run nc automatically when you run a script file by placing:
   #! nc -c
   #
   #  script file "runnc"
   #
     (nc commands)
     
   if (expt=="runspike") {
     x = xoffset + 5;
     .
     .
   };
   .
   .
   .

"#! nc -c" as the first line in the file ("runnc" in this example). The -c argument tells nc to get its command line arguments from the script's command line instead of from the remainder of the "nc -c" line. Note that you may include command-line arguments on the command line:

   runnc --expt runspike  --xoffset 56.78

In this type of "nc" script file, you use the "nc" language to run a simulation. To run only the interpreter in this way use "#! nci -c" as the first line. You can also run other scripts from inside a "nc" script file like this:

   #! nci -c
   #
   #  script file run_multsim_1
   #
    system ("nc --var1 23.5 file.n > file.r");
or
    system ("file.n --var1 23.5 > file.r");
   .
   .
   .

If you have a script that prints out a number or a small amount of text, you can run a nc script several times, each time returning the output into a variable in the parent script. This method avoids making any output files, and is appropriate when you want to run several closely related simulations (e.g. with a different random seed):

   #! nc -c
   #
   #  script file run_multsim_1
   #

   /*--------------------------------------------------------*/

   func runnc(randnum, lim, td)

   /* function to run an nc script with different values of parameters */
   /*  and return its output. */

   {
     fmt = "nc -r %8.8g --limit %g --td %g --info 1 file.n";
     sprintf (str,fmt,randnum,lim,td);
     return system(str);
   };

   /*--------------------------------------------------------*/

   proc runtest (lim, td)

   /* procedure to run an nc script and return a value to an "nc" variable. */
   {
 
     for (m=i=0; i<nsim; i++) {
       randum = int(rand()*1e8);
       m += runnc(randnum, lim, td);
     };
     printf ("lim %g  td  %g m %-10.5g\n", lim, td, m/nsim);
  };
   .
   .
   .

Analyzing data files with the shell or awk

You can analyze the output data (".r") files with another script, which can be in one of several different languages (e.g. "shell", "awk", or "nc"), like this:

-------------------------------------------------------
#! /bin/csh -f
#
#  conversion from temporal to spatial plots
#
#  parameters:
#
#  hzpn start stop center scale offset file
#
#
# hz284: 60 x 60 array of cones
#
#
hzpn 1 16 820 1 0 hz284s.r    > hz284s.pn
hzp  1 16 820 1 0 hz284s.r    > hz284s.p
hzpn 1 16 820 1 0 hz284sx.r   > hz284sx.pn
hzp  1 16 820 1 0 hz284sx.r   > hz283sx.p
-------------------------------------------------------
In the above script, "hzpn" and "hzp" are commands that take the parameters listed and produce an analysis file on their standard output. It's easy to write such commands in "nc" script format, or with "awk" or "perl". "nc" can read in a numerical file into an array, and "awk" can process lines and do arithmetic on columns, much like a spreadsheet (see "man awk"). A typical analysis command:

-------------------------------------------------------
# hzpn
#
#
awk 'NR==1 { k=1; scal = 6*scale; drift = 0; limit=220}
     $1 == "#x" { x[k]= (center-$3-xoffset)*scal; k++;}
     $1 == 0.04 { for (i=start; i<=stop; i++) d[i] = $(i+1) - drift;}
     $1 == 0.10   { for (i=start; i<=stop; i++) avg[i]  = $(i+1);}
     $1 == 0.105  { for (i=start; i<=stop; i++) avg[i] += $(i+1);
     $1 == 0.105  { for (i=start; i<=stop; i++) avg[i] += $(i+1);
     END { max = -1000;
           for (i=start; i<=stop; i++) {
              d[i] -= avg[i]/2;
              if (max < d[i]) max = d[i];
           }
        for (i=start; i<=stop; i++) {
           if (x[i]<=limit) printf "%3g  %-8.4g\n", x[i], d[i]/max;
           else             printf "%3g  %-8.4g\n", limit, d[i]/max;
        } }
    ' start=$1 stop=$2 center=$3 scale=$4 xoffset=$5 $6
-------------------------------------------------------
Note the single quotes just after "awk" and after the awk script before the command line arguments.

Analyzing data files with nc

You can also read data files into an "nc" script with the "fread" command, which reads data automatically from a file into a 1D or 2D array. Or you can use the "fscanf" command, which is very similar to the C library version.

   fread ("file.r", spikdat, n, ncols);
or
   fread ("stdin", spikdat, n, ncols);
In this example, the "fread" command reads a file (or the standard input) into a 2D array "spikdat", and sets n and ncols to the number of rows and columns. The file can contain the "#" char at the beginning of a line to denote a comment, and can also contain symbolic variables that are defined in the main script (see "fread" in the nc manual).


POVRAY: ray-traced 3D output

You can use "nc" to display your neural circuit in 3D perspective using the "-R" command-line switch. The "center", "size", and rotation display statements function the same way they do with the "-v" option for output to the "vid" display program. The difference is that the file produced by the "-R" switch is a text file in the format of the "povray" program.

The "povray" (Persistence of Vision) ray-tracer interprets a symbolic description of a 3D scene to produce a realistic surface-rendering of it that includes accurate 3D shapes, surface textures, light sources, shadows, and reflections. The "povray" distribution is available at www.povray.org, in both binary and source versions. A binary distribution is available for Linux but the source code compiles on most Linux/Unix systems (http://www.povray.org). You can run povray with command-line switches to generate pictures of any (x,y) dimension, for any output file name, or for display on the X11 screen. Its output image files are in ".tga" (targa) format by default, but you can specify the default output file format to be .png in 5 to 16 bit resolution (see below). You can view these files with "xli" and you can view, convert, and print them with Adobe Photoshop.

"nc -d 1 -R" produces a file that contains a "camera" statement and a list of objects like "spheres", "cylinders", and other shapes. Since spheres and cylinders are similar to the "nc element" definitions of "sphere" and "cable", these symbolic objects are declared directly in the povray format. Other "nc" elements, such as photoreceptors, are a little more complex so they are predefined in the "nc.doc" standard include file (included in the ".pov" file produced by "nc"). You can redefine the shapes of such predefined elements by commenting out the existing definition and writing your own. The "nc" output file will use your definition instead, possibly modifying color and size, and positioning your objects correctly. The "nc.pov" file also contains default definitions of the light sources, surface texture, and background. You can readily modify these to your taste. For more information about "povray", read the "pov/doc/povray.doc" file in the "povray" distribution.

To set the background color, you can set the "bknd_color" variable to a color, 0=(Black) or 7 (White), or other colors. The background color in the .pov file is set by a "fog" statement. This defines a foggy background that has no shadows, where the fog over a large distance looks white or black (or some other color). When you set the background color (bknd_color) to white (7) or black (0), the plotlabel and the calibration bar will be automatically set the opposite color, i.e. if bknd_color==0, then the plotlabel and the calibration bar will be white. To set the color of node numbers, you can set the "node_color" variable (default black).

The ".pov" file produced by "nc" describes a standard camera location and rotates all the objects with respect to the standard reference frame. Each object is sized, translated and rotated (in that order), so the scene looks as if the camera rotated instead. Although it is possible to move the camera location (and this is the best way to look closely at details of the neural circuit), the objects in the ".pov" file are pre-rotated according to the rotation commands given "nc" in its input file. The reason for this scheme is to allow several display statements in the "nc" input file to produce different rotations and translations for different neural elements, which is sometimes useful for displaying a neural circuit (e.g. "pulling-apart" a circuit to show the separate neurons).

Using "povray"

To use "povray", extract your povray distribution with "tar" and create a "pov" directory tree. Link "ln" or copy pov/bin/povray to /usr/bin or another appropriate "bin" directory. Tell "povray" where its home directory tree is by setting the environment variable to the location of the povray include files (referred to by "nc.pov"):
   setenv POVRAYOPT -l/usr/src/ray/pov/include
You can put this line in your .cshrc Cshell startup file, or a similar file can be placed in you ksh or sh .profile startup file.

Set up the a test scene from your neural circuit, and establish the general outline and the desired rotation by viewing the scene with:


    nc -d 1 -v file.n | vid
Then generate the ".pov" file with:
     nc -d 1 -R file.n > file.pov
Look at this test scene by rendering it small so it displays fairly fast:
     povray -h100 -w100 -ifile.pov +dx
The "+dx" tells povray to display the scene on the X11 display. You can also view the ".png" file afterwards. When you have the correct scene and viewing position, render the scene with:
     povray -h1000 -w1000 -ifile.pov +dx
or
     povray -h1000 -w1000 -ifile.pov -ofile.png +dx

You can set many of the options for povray using the ".povrayrc" file in your home directory. You can copy it from "povray.ini" in the povray distribution. Among other parameters, in .povrayrc you can set the location of the povray libraries and the default output file type:

  ;; File output type control.
  ;;     T    Uncompressed Targa-24
  ;;     C    Compressed Targa-24
  ;;     P    UNIX PPM
  ;;     N    PNG (8-bits per colour RGB)
  ;;     Nc   PNG ('c' bit per colour RGB where 5 <= c <= 16)

  Output_to_File=true
  Output_File_Type=N8             ;; (set 8 bit .png file type)

Increasing speed

You can save time by refining your file with lower- resolution (smaller) images at first, then working up to higher-resolution images later. The rendering CPU time is directly related to the number of pixels in the output picture, the number and complexity of objects in the scene, and the number and complexity of the light sources. You can improve the speed by commenting out all but one light source and keeping the scene simple, and by enclosing objects in "bounding boxes" (see the povray.doc file for more on this). And of course, run "povray" on a computer with a fast floating-point CPU. A typical scene (several hundred spheres and cables) requires about 1 hour at 800x400 (HxV) resolution on a 66Mhz 80486. A new version of Povray (3.7) is being released to make use of symmetric multi-processing (SMP), that is, more than one core in a CPU chip, and multiple CPUs.

If your scene has a non-square aspect ratio, you can save rendering time by modifying the

    up    <0, 1, 0>
    right <1, 0, 0>
statement in the camera definition in the ".pov" file created by "nc -R", and then creating an output file with a corresponding rectangular shape. For example, if your neural circuit scene is wide and not very tall, you might make a 2:1 aspect ratio by defining:
    up    <0, .5, 0>
    right <1, 0, 0>
and then creating the corresponding picture with:
   povray -h400 -w800 -ifile.pov +dx
If you forget and don't change both of these aspect ratio declarations your picture will be distorted so spheres look squashed flat.

See the "povray.doc" file for more information about the aspect ratio. It is helpful and lots of fun to experiment with the light source, texture, and background features.


ncv

This command is identical to the "nc" command but it is used to display the graphs output from a neural circuit experiment onto an X-window for immediate viewing. "ncv" is equivalent to "nc -v file.n | vid" (where file.n is the file you type after "ncv"). You create "ncv" this way: "ln -s nc ncv".

nd

This command is identical to the "nc" command but it is used to display a neural circuit with "display" statements. Normally, "nc" does not display the circuit (unless the "disp" variable is set) but only runs the simulation and produces the associated graphs or data. The "nd" command is useful to display a circuit without re-editing the circuit program to modify the variable "disp". "nd" is equivalent to "nc -d 1". You create "nd" this way: "ln -s nc nd".

ndv

This command is identical to the "nc" command but it is used to display a neural circuit with display statements onto an X-window for immediate viewing. "ndv" is equivalent to "nc -d 1 -v file.n | vid" (where file.n is the file you type after "ndv"). You create "ndv" this way: "ln -s nc ndv".

nci bare interpreter

To run the nc interpreter in a script (such as ttest.n) that explicitly should have only "C/C++" keywords, without any ability to construct or display neurons, you can call "nc" with a symbolic link named "nci". This is already provided in nc/bin:
ln -s nc nci

stim

To provide blur in a stimulus for NeuronC, run the command (program) "stim", which understands a NeuronC program and makes the stimulus stimulus file for NeuronC. An equivalent way to make the stimulus file is to run "nc" and set a value of 1 for "makestim", e.g. set "--makestim 1" on the command line. The "stim" command understands the same language as "nc", except that it does not run the model. "stim" ignores most NeuronC statements except "stim" statements and "rod" or "cone" statements. It creates a stimulus file based on the stimulus conditions and locations of all photoreceptors. "Stim" creates an internal light intensity array based on the stimulus spots, bars, etc, and any optical blur defined. Then "stim" checks each rod or cone, and calculates the stimulus intensity for each photoreceptor separately. Stim expects to find the following line in its input file:
   stim file filename;
This is a statement in the NeuronC file which names a text file "filename" to contain a list of stimulus events. Stim calculates all the stimuli, blurs them, finds what intensity and wavelength exists at each rod or cone at each stimulus time, and writes the list into the stimulus event file. Stim and NeuronC both use the same NeuronC program to define the neural circuit and stimuli, but Stim creates the file and NeuronC reads from the file. Once a stimulus file is generated, it need not be remade each time a new NeuronC model is run; if a new NeuronC program defines the same pattern of photoreceptors, it may refer to the same stimulus file.

The "stim file" statement tells NeuronC to ignore any other light stimulus statements and get its stimuli instead from the file. NeuronC cannot blur stimuli and ignores "blur" in a "stim" statement. If the "stim file" statement is omitted, NeuronC will understand stimulus statements but will ignore the "blur" parameter in them.

Example of how to use "stim" (or "nc --makestim 1"):

File that generates model (call it "file1"):

    .
    .
    statements that make rods or cones
    .
    .
    .
    stim file file1.t;
    stimulus generation statements (i.e. "stim spot ...")
    run;
    
To make stimulus, first run "stim" and then run "nc":

    stim file1                          (this creates "file1.t")
    nc file1 > file1.r                  (uses "file.t" as stim file,)
                                          (creates "file1.r")
or
    nc --makestim 1 file1              (this creates "file1.t")
    nc file1 > file1.r                 (uses "file.t" as stim file,)

plotmod

Plotmod is used to plot files generated by NeuronC, and contains the same graphics output subroutines that NeuronC uses to write to the video screen. Plotmod is especially useful when long NeuronC simulations run in the background, where simultaneous graphics output is not appropriate. In this case, run "nc" without the "-v" switch and NeuronC will make a numerical output file which consists of a list of time recordings:
     nc file.n > file.r
     plotmod file.r | vid
The ".r" file contains the numerical plot records. These may be plotted on the screen exactly as NeuronC would have if the "vidmode" variable was set (=1). Plotmod has several command line switches:
     -a        draws graphs with automatic scaling
 from simple ascii text files. 

     -c x      use char "x" to plot points on line.
     -C x      use char "x" to plot points, no lines.

     -e n      set xmin to "n"
     -E n      set xmax to "n"
     -m n      set ymin to "n"
     -M n      set ymax to "n"

     -w n      set char size for data points on line to "n", in terms
                 of screen size. Must set size before "-c" switch.

     -W n      tic label char width in terms of screen size 
                 (screen is 1.0 x 1.0).

     -f        no file name on graph
     -n        no node numbers on graph
     -F        no labels on graph (i.e. no file name, node nums, calib),
                 however tic numbers are displayed. 
     -l x      set x as label text, must be non-numeric or inside quotes

     -d        draws plots with dashes (use for monochrome or xerox)
     -t        text mode (outputs numbers, not graphics)
     -r        "row" mode. Numbers for a variable are on one line.

     -o n      sets color of the next plot defined by -p (n = alpha or numeric)
     -p n      display plot "n" (n= 1 to 32) selectively
                (multiple -p n switches for several plots)
     -p a-b     (n can also be a range in the format "a-b")

     -y        input data has only "y" values, no "x" value.

     -Y        draw multiple Y axes in graph, on left.

     -R        draw multiple Y axes on right.

     -S        draw separate graph for each trace.
Example:
               plotmod -p 2 -p 3 -p 4  file.r | vid
               plotmod -p 2-4 -l "plots 2,3,4" file.r | vid
	       plotmod -p 2-4 -l "plots 2,3,4" file.r | vidpdf < file.pdf
               plotmod -p 2-3 -o green -p 4 -l "plots 2,3,4" file.r | vid
draws 3 plots from the "file.r" recording data file generated by a previous nc simulation run. The -l command line switch allows you to add a label at the top of the plot. The -o command allows you to change ghe color of a plot trace or traces.

Simple graphs

Plotmod can also be used to make simple graphs using its feature of calculating the scale of the axes automatically. The format for "plotmod -a" input files is:

    x  y1  y2  y3  .  .  .
    x  y1  y2  y3  .  .  .
    x  y1  y2  y3  .  .  .
That is, each line in the file normally contains an x value and one or more y values. Plotmod will also graph single y values without an x value on the line. In this case, the x value used to plot the y value is the line number. The values are all read into "plotmod", the minimum and maximum values are calculated, and the graph is scaled appropriately. Labels may be added using the "labels" command, or with the graphics primitives available in "nc".

Row mode

Plotmod can also graph data files that contain all the values for a variable on a line (i.e. the rows and columns are switched). As above, single y values without an x value can also be plotted. The format for "plotmod -a -r" input files is:
   x  x  x  x  x  .  .  .
   y1 y1 y1 y1 y1 .  .  .
   y2 y2 y2 y2 y2 .  .  .
   y3 y3 y3 y3 y3 .  .  .

Labeling plot points with chars

Plotmod can make plots with characters instead of just lines. The "-c x" (where "x" is the character label) labels points with the character on top of the line and the "-C x" switch labels points without a line. To label different plots on the same graph, use multiple "-c x" or "-C x" switches. To use no character label on a plot where later plots use labels, use -c ' ' or -C ' '. This "saves" the plot in the corresponding position from being labeled with characters. For instance:
   plotmod -a -c ' ' -c o -C x datafile | vid
This would label the second 2 plots from "datafile". The first plot would have no character labels, the second would have "o"'s on top of the plot line, and the third would have "x"'s with no lines.

Plotting compressed files

Plotmod can read files that are compressed by gzip or bzip, i.e. have a .gz or bz2 appended on the end of the filename. A typical .r file from "nc" can be compressed by a factor of 3-4 to save space. You can specify the filename either with or without the .gz or .bz2, and plotmod will figure out whether the file exists and will uncompress it if necessary. To compress your files you can enter:

  gzip file*.r
or 
  bzip file*.r

Then you can plot these files like this:

plotmod file.r.gz | vid
plotmod file.r.bz2 | vid

Plotmod will find the .gz or .bz version of the .r file:
plotmod file.r | vid

vid

You use "vid" to display graphics data that comes from "nc" or "plotmod".

Vid command line switches are:

   -a      make "PostScript" file on stdout: "vid -a > file"
   -c      make color "PostScript" file on stdout: "vid -c > file"
   -l      make "postscript" raster file on stdout.
   -e      use Enhanced Graphics Adapter
   -h      use monochrome Hercules board
   -t      use Tektronix 4014 type display terminal
   -X      use X-windows for graphics display
   -d name  define name of X-windows screen to display on  
   -k      invert screen (upside down).
   -m n    use "n" as mag, default 1.0.
   -p n    use "n" as color (16 colors).
   -B n    use "n" as background color.
   -r      rotate picture sideways 90 deg.
   -w n    use "n" as size of X-window. 
   -x n    use "n" as x offset (default 8192)
               This defines center of picture.
   -y n    use "n" as y offset (default 8192)
               This defines center of picture.
   -v      don't erase screen when first starting video graphics mode.
Example:
               nc file1 | vid        ( = "neurc file1") 
Vid normally erases the screen when you first run it, but you can tell it not to with the "-v" switch listed above. Vid normally doesn't erase its picture when it is finished displaying. To get back to text mode you use the "t" (or "textmod") command. This doesn't erase the graphics screen, so you can run vid several times with as many text commands in between as you want. For instance:
   vid file1         (make first picture on screen)
   t
   ls -l
   cd otherdir
   vid -v file2      (superimpose 2nd picture on first)

MOSIX cluster management system

The MOSIX cluster management system is a set of tools that allow running simulation jobs in a local area network. Each job is started on a MOSIX server machine, which automatically migrates the jobs to run on other CPUs in the local cluster. MOSIX runs on linux without any changes to the kernel.

To run MOSIX, download the package from the MOSIX download page. You can then uncompress with:

tar xvjf MOSIX-4.4.4.tbz
To install Mosix, read the README and ADMINISRATOR-GUIDE and USER_GUIDE files. You will need to copy the commands to various "bin" directories:
mosbestnode             /bin                    chmod u+s /bin/mosbestnode
mosctl                  /bin
mosenv                  /bin
moskillall              /bin                    chmod u+s /bin/moskillall
mosmigrate              /bin                    chmod u+s /bin/mosmigrate
mosmon                  /bin
mosnative               /bin
mospipe                 /bin
mosps                   /bin                    chmod u+s /bin/mosps
mosrun                  /bin                    chmod u+s /bin/mosrun
mostestload             /bin
mostimeof               /bin                    chmod u+s /bin/mostimeof

man/*                   wherever manuals live - suggest /usr/local/man
mos_checkconf           /sbin
mos_in_job              /sbin
mosconf*                /sbin
mosd                    /sbin
mosixd                  /sbin
mospostald              /sbin
mosremoted              /sbin
mossetpe                /sbin

killall mosd

cp mosbestnode mosctl mosenv moskillall mosmigrate mosmon mosnative mospipe mosps mosrun mostestload mostimeof /bin
cp mos_checkconf mos_in_job mosconf* mosd mosixd mospostald mosremoted mossetpe /sbin

cp -r man/*                /usr/local/man          

chmod u+s /bin/mosbestnode
chmod u+s /bin/moskillall
chmod u+s /bin/mosmigrate
chmod u+s /bin/mosps
chmod u+s /bin/mosrun
chmod u+s /bin/mostimeof
Then, you'll need to add "/sbin/mosd" to your rc.local file, to start mosd running in the background. You can also do this manually every time you start a Mosix session, but it's easier to have it run automatically.

You then will need to set up /etc/mosix. You'll need to set up mosix.map and mosip files, and a few others.

You then should copy the mosix files to all of the machines in the cluster.

To run a simulation job on the cluster, allowing it to migrate to the CPU that is least loaded, enter:

    mosrun -l nc ... &
 
where "nc ..." is the simulation command line.

You can run several jobs together, allowing them to be moved from one CPU to another with:
    mosrun -l nc ... &
    mosrun -l nc ... &
    mosrun -l nc ... &
    .
    .
    .

You can see the Mosix jobs, where they were run from, and where they are running, with:
mosps
Then, to move them to another CPU, use:
    migrate x n

where "x" is the job number, and "n" is the CPU number.
You can then monitor the CPU and memory usage on all the machines with:
mosmon
To learn more about these Mosix commands, you can run e.g. "man mosmon" to see the manual for mosmon.


Predefined variables

See "nc/src/init.cc" 

name          default   unit  meaning of variable
----------------------------------------------------------------
Simulation variables

double complam 0.1           fraction of space constant per compartment
double lamcrit 0.3           fraction of complam for minimum size compartment
double timinc  1e-4    sec   time step for numeric integration in comps(sec)
double stiminc 1e-4    sec   time step for synapses (sec)
double endexp  50e-3   sec   time for end of experiment
double crit    1e-8    V     criterion for convergence for time step
double relax   .1            over-relaxation constant (0 to 0.4)
double relincr .0001         relaxation increment
double synaptau 1            synaptic time constant multiplier (0.1 => faster)
int euler       0            use Euler integration (0=CN, 1=Euler)
int implicit    0            use implicit integration (0=CN, 1=implicit)
int scatter     0            use light scatter with light blur function
int debug       0            turn on debugging features "-y" (0=none,7=many)
int debugz      0            type of debugging features "-z" (0=none,7=many)
long int rseed  123456       random number seed.
double time     0            absolute time at start (may be negative) 
double version  6.020        current (latest) version number
double tempcel  37 deg C     temperature for voltage-sensitive channels.   
double djnoise  0            Johnson noise for all Rm's (on if > 0)

int ncomps      0            Number of compartments
int time        0            absolute time in simulation (can be set by user)

Plot variables

double plmax   .04     V     default maximum for plot on graph
double plmin  -.07     V     default minimum for plot on graph     
double ploti   .001    sec   time step for plot increment (sec)
int plsep       0            draw separate graphs (0=all in one, 1=sep)
int dashfl      0            draw graph with dashes (0=solid, 1=dash)
int vidmode     0            flag for numerical output  (0=text, 1=graphics)
int prmap       0            flag for print connection map 
                              (1 = display compartments and connections)
                              (2 = display compartments as spheres with rm)
int disp        0            flag for display circuit (0 = no display)
                              (1  = display circuit with "display" statement) 
                              (2  = display compartments)
                              (4  = display connections betw. compartments) 
                              (8  = display nodes)
                              (16 = display stimulus)

Ion concentrations and batteries

External concentrations (from Ames Medium)

double dnao    0.143    M     External sodium concentration
double dko     0.0036   M     External potassium concentration
double dclo    0.1254   M     External chloride concentration
double dcao    0.0023   M     External calcium concentration
double dmgo    0.0012   M     External magnesium concentration
double dcoo    0        M     External cobalt concentration

Internal concentrations   (calculated at 37 deg C)

double dnai    0.0125   M     Internal sodium concentration
double dki     0.1408   M     Internal potassium concentration
double dcli    0.0091   M     Internal chloride concentration
double dcai    50e-9    M     Internal calcium concentration
double dtcai   10e-9    M     Threshold for [Ca]i for calcium pump

Batteries                 (calculated at 37 deg C)

double vk     -.098     V     potassium battery voltage
double vna     .065     V     sodium battery voltage
double vcl    -.07      V     chloride leakage battery voltage

double calcnernst  0.6       =1 -> calculate vrevs from ion concentrations
                             =0 -> calculate ion concs from Nernst potentials

Relative permeabililties

double dpkna     0.08          relative permeability of K  in Na channels
double dpcana    0.01          relative permeability of Ca in Na channels
double dpnak     0.01          relative permeability of Na in K channels
double dpcak     0.0001        relative permeability of Ca in K channels
double dpnaca    0.001         relative permeability of Na in Ca channels
double dpkca     0.0003        relative permeability of K  in Ca channels

Biophysical constants

double dcm     1e-6   fd/cm2    default membrane capacitance
double dri     200    ohm cm    default axial resistance 
double drg     5e6    ohm um2   default gap junction resistance 
double drm     40000  ohm cm2   default membrane resistance ohm cm2
double dfta   .2      msec      default pre-synaptic time const.
double dsfa    2                default pre-synaptic number of filters.
double dftb   .2      msec      default post-rel time const.
double dsfb    0                default post-rel number of filters.


double dsvn    5                default synaptic vesicle rel site number
double dvsz    100              default synaptic vesicle size 
double dst    -.04    V         default synaptic threshold
double dsc     "expon"          default synaptic curve (expon=543)
double dskd    1                default synaptic half-max saturation gain 
double dshd    1                default synaptic binding Hill coeff 
double dsvn    10               default synaptic vesicle number 
double dsvd    .001   sec       default synaptic vesicle duration
double dscd    .01    sec       default synaptic channel duration
double dmaxsyn 1e-9 S           default maximum cond for synapse
double dstr    100e-6  M        default synaptic neurotrans conc
double dgkd    0.1              default synaptic half-max cGMP saturation (kd)
double dsn     2                default synaptic gain, linear or exponential
double dsg     1                default synaptic cGMP gain 
double dmaxrod 35e-12  S        default maximum dark conductance for rod
double dmaxcon 1.4e-9 S         default maximum dark conductance for cone 

double dnadens   0.25   S/cm2   default density for Na chans (S/cm2)
double dkdens    0.0707 S/cm2   default density for K  chans (S/cm2)
double dcadens    .005  S/cm2   default density of Ca V-gated channel

double dcavoff   0.018  V       Q10 for voffset due to cao (additive) 
double dcaspvrev 0.18   V       Ca surface potential (mult dcavoff) 

double ddca    2e-6  cm2/sec    diffusion const for Ca in cytoplasm

double dcabnd    10.0           default ratio of bound to free calcium
double dcabti    30e-6 M        default Ca buffer total in first shell
double dcabt     3e-6  M        default Ca buffer total in shells
double dcabf     1e8  /M/sec    default Ca buffer forw rate to Ca.B 
double dcabr     100  /sec      default Ca buffer reverse rate to Ca.B 
double dcashell  10             default Number of Ca diffusion shells
double dcm      .2e-6  M        default 1/2 sat conc. of Ca pump
double dcavmax   5e-6  mA/cm2   default vmax for Ca pump
double dcakex    5e-9  A/mM4/cm2 default rate for Na/Ca exchanger 
double dcaoffs   0     V        default activation offset for Ca chans
double dcataum   1              default activation   tau mult for Ca chans
double dcatauh   1              default inactivation tau mult for Ca chans
double dkcataum  1              default activation   tau mult for KCa channel
double dkcatauh  1              default inactivation tau mult for KCa channel

double dnatauf   1              default tau mult for Na noise in 2-state model
double dktauf    1              default tau mult for K  noise in 2-state model
double dcatauf   1              default tau mult for Ca noise in 2-state model

double dqm       2              default Q10 for Na activation   (am, bm)
double dqh       3              default Q10 for Na inactivation (ah, bh)
double dqn       0              default Q10 for K activ. an, bn (use dqna/b if 0)
double dqna      3.2            default Q10 for K activation an
double dqnb      2.8            default Q10 for K activation bn
double dqca      3              default Q10 for Ca activation   (ac, bc)
double dqd       3              default Q10 for KA inactivation (ad, bd)
double dqkca     3              default Q10 for Kca activation  (a,  b)
double dqsyn     3              default Q10 for synaptic chans (ampa, etc)
double dqcavmax  2              default Q10 for Ca pump
double dqcab     2              default Q10 for Ca buffer
double dqc       1.4            default Q10 for unitary channel conductances

double dnmdamg   2e-3  M        default external [Mg++] for NMDA chans 

double dbasetdc  22             temperature for calculating Ca diffusion. 
double dbasetca  22             temperature for calculating Ca pump/buf. 
double dbasetc   22             temperature for calculating channel rates.
double dbasetsyn 22             temperature for calculating channel rates.

double dratehhm  2.9690 	rate for HH m from 6.3 to dbaset (22) deg.
double dratehhh  5.6115 	rate for HH m from 6.3 to dbaset (22) deg.
double dratehhna 6.2099 	rate for HH na from 6.3 to dbaset (22) deg.
double dratehhnb 5.0354 	rate for HH nb from 6.3 to dbaset (22) deg.

double dmaxna    1e-9  S        default cond of Na voltage-gated chans
double dmaxk     2e-10 S        default cond of K  voltage-gated chans
double dmaxca    100e-12 S      default cond of Ca voltage gated chans

double dnaoffsm  0     V        default activation   offset for Na chans
double dnaoffsh  0     V        default inactivation offset for Na chans
double dnataum   1              default inactivation offset for Na chans
double dnatauh   1              default inactivation offset for Na chans
double dkoffs    0     V        default activation   offset for K chans
double dktaum    1              default inactivation offset for K chans
double dktauh    1              default inactivation offset for K chans

double dgjoff    0.015 V        default gap junction voltage offset
double dgjtau    1              default activation tau for gap junctions
double dgjnv     0.2            default non-voltage sensitive fract of gj cond

double dbd1      1              default voltage multiplier for BK chan alpha
double dbd2      1              default voltage multiplier for BK chan beta
double dbk1      1e-6           default Ca multiplier for BK chan alpha 
double dbk3      1e-6           default Ca multiplier for BK chan beta 

double dsd1      0              default voltage multiplier for SK chan alpha
double dsd2      0              default voltage multiplier for SK chan beta
double dsk1      1e-7           default Ca multiplier for SK chan alpha 
double dsk3      1e-7           default Ca multiplier for SK chan beta 

double dscu      25e-12   S     default unitary conductance of channels
double dnau      22e-12   S     default unitary cond of Na chans
double dku       11.5e-12 S     default unitary cond of K chans (=15pS @ 30)
double dkihu     33e-12   S     default unitary cond of Ih chan
double dkcabu    74.3e-12 S     default unitary cond of BK chans 
double dkcasu    14.2e-12 S     default unitary cond of SK chans
double dcalu     8e-12    S     default unitary cond of Ca L-type chan (= 20pS @35deg) 
double dcatu     3e-12   S      default unitary cond of Ca T-type chan (= 8 pS @35deg) 
double dampau    25e-12  S      default unitary cond of AMPA chans
double dcgmpu    25e-12  S      default unitary cond of cGMP chans

double dsyntau   1              default time constant for synaptic chans

List of source code files

Descriptions of source code modules

nc/src files	description

blackbody.n     calculates spectral light curves for photrecs in "wave.cc"
bnldev.cc	binomial devation test program.
chanampa.cc     AMPA channel definition
chanca1.cc      calcium channel definition
chancgmp.cc     cGMP channel definition
chanclca.cc     Ca-activate Cl channel definition
chanfunc.cc     channel initialization functions
changaba.cc     GABA channel definition
chanif.cc       integrate-and-fire channel definition
chank1.cc       Kdr HH channel definition
chank3.cc       KA channel definition
chank4.cc       Ih channel definition
chank5.cc       Kir channel definition
chankca.cc      KCa channel definition
channa1.cc      Na HH channel definition
channa2.cc      Nav1.2, Nav1.8 channel defs 
channa3.cc      Na 12-state channel definition
channa5.cc      Nav1.1 channel definition
channa6.cc      Na resurgent channel definition
channmda.cc     NMDA channel definition
chansyn.cc      simple 2-state postsyn channel definition
code.cc		subroutines for pseudo-machine operations.
colors.h	color definitions for nc graphics 
cone.cc		cone photoreceptor test file, used to develop model.
cone6-8.cc	"
coneb*.cc	"
control.h	header file, variables used to control simulation.
controlx.h	"
convarr.cc      defines arrays for stimulus convolution
defaultdraw.cc  default graphics drawing routines
defaultdraw.h   external definitions of default graphics drawing routines
digfilt.cc	digital filters for general use
digfilt.h	"
drand.cc	pseudo-random number generator functions.
drand.h		external defs of for pseudo-random functions
emalloc.cc	malloc subroutine for "nc".
emalloc2.cc	substitute standalone memory malloc subroutine
extdraw.h       external defs of default graphics primitives
fft.cc		fast fourier transform test program.
gausnn.cc	gausnn subroutine to calculate random cell arrays.
gmain.cc	main routine for standalone "gausnn" program.
gprim.cc	graphics primitives, either text or Ampex graphics lib.
gprim.h		definitions of subroutines in "gprim.cc" 	
gr.cc		graphics primitives, dummy routines.
gr.h		definitions of subroutines in "gr.cc" 	
gaussfit.cc	2D Gaussian least-squares fit
init.cc		initializes nc symbol table.
initchan.cc	initializes nc channel lookup tables.
interpdum.cc    dummy routines not used in interpreter only
linesp.c        curve fit of 2D point spread func for fovea, for "stimsub.cc" 
linespr.c	curve fit of 2D point spread func, for "stimsub.cc" 
lm_eval.cc	Levenburg-Marquardt least squares fitting routines
lm_evali.cc	Levenburg-Marquardt least squares fitting routines for interpreter
lm_funcs.cc	Levenburg-Marquardt high level least squares fitting routines
lm_test.cc	test routine for lm_funcs
lmmin.cc	L-M high level funcs
lmmin.h		"
main.cc         main procedure for standalone nc
makcomp.cc      functions to make nc compartments
math.cc		math functions for basic "nc" interpeter.
modcode.cc	generates neural elements, etc; called from interpreter.
movconvert.cc   standalone program to integrate changes in movie frames
nc.h		basic header file for "nc" syntax parser.
nc.y		syntax for "nc" interpeter.
ncconvert.cc	makes low level structures from neural elements at "run".
ncdisp.cc	subroutines called by nc "display" statement.
ncelem.cc       functions to make nc neural elements
ncelem.h        include defs for nc elements
ncfuncs.cc      nc C++ API definitions for all neural elements and plots
ncfuncs.h       header file for all nc C++ API definitions, include in your C++ simulation 
ncinit.h	defines setptrs() to null if not used
ncinit.h	defines setptrs() to null if not used
ncio.cc         defines fprintf() compatible with C++.
ncm.cc		token parser, etc. for "nc" interpreter.
ncm_f.cc	token parser, orig version using files instead of istreams
ncmain.cc	"nc" main subroutine, interprets command line. 
ncmain_.cc	"nc" main subroutine, orig version using files instead of istreams 
ncmak.cc	makes and erases all structures, high or low level.
ncnode.cc	makes and saves nodes in a hash table for quick access.
ncomp.cc	computation of difference equations.
ncomp.h		header file defs of runtime structures
nconst.h	header file basic math and physical constants 
ncpack.cc       low level pack procedures
ncpacks.cc      high level pack procedures for exporting nc structs.
ncplot.cc	plots "nc" output on graph or text file.
ncplot.h	header file structures for plotting
ncray.cc	generates symbolic output files for "povray".
ncrot.cc	3D rotation package.
ncsave.cc       functions to save/restore state to a file	
ncstim.cc	stimulus generation.
ncstimfuncs.cc	nc C++ definitions for stimuli
ncstimin.cc	low level stimulus routines.
ncsub.cc	runtime package, scheduling, synapses, stimuli, plots.
ncsub.h		header file describing all low-level structures.
ncsymb.cc	draws symbols for ncplot.cc	
nctest.cc       sample procedure to call interpreter from outside program 
ncupack.cc      low level unpack procedures
ncupacks.cc     high level unpack procedures
ncv.cc          print/scan version numbers
ncval.h         constants for command-line argument input
ndef.h          defs of abs, max, min
perlman.txt     original def of turtle cone spectral sensitivity and explanation
plotmod.cc	"plotmod" main subroutine.
prcomp.cc	subroutines to display compartments and connections.
rndpnt.cc	fills a square with random points, used to test drand().
rnd_glibc.cc    clib vers of random number routines
rnd_taus.cc     taus2 vers of random number routines from GSL,fast,indep (default)
rndev.cc        poisson, gauss, binom, gamma random distributions
rod.cc		rod photoreceptor test file, used to develop model.
rod4.cc		"
scheduler.cc    scheduler functions allowing any func to be executed at intervals.
scheduler.h     include file defs of scheduler functions
stdplt.h	header file, standard plot, for Ampex library (libP.a).
stim.h		header file, stimulus structures.
stimsub.cc	stimulus generating subroutines for "stim"
strtod.cc	string to double subroutine, used when not in library.
symbol.cc	symbol table subroutines.
synfilt.cc      functions implementing synaptic filters
tan.cc		old tan() subroutine used for debugging
tfilt.cc        digital filter program
turtlesens.cc   functions to produce cone spectral sensitivity "turtle.h"
turtlesens.n    interpreted version of funcs to make "turtle.h"
vec.h           vector function defs
vecsub.cc       functions to compute dist and closest appr. between 3D lines
wave.cc		program to generate "wave.h", included by ncstim.cc.
wave.h		header file, values for photoreceptor and light spectra.
x.tab.h		header file, copy of y.tab.h
y.tab.h		header file, constants generated by "nc.y"


nc/pl files	description

Plotdb.c	Ampex Plot Library debugger.
btest.c		subroutine that determines if hardware is "byte-swapped".
chars.h		ascii, greek chars, 5 x 7 vector font for "putsym.c".
colors.h	VGA colors.
ctest.c		PostScript color test program, prints colors on Tek Phaser III.
getws.c		get word subroutine, machine independent with BYTESWAP.
graph.c		graph program that uses libP.a (Ampex plot pkg).
graph.mod.c     modified graph pgm for machines where args are not on stack.
header.c	standard Unix header for starting your own program.
herc.c		Hercules (mono) driver for Unix without direct hardware I/O.
hfile.c		hidden line file I/O module.
hpflt.c		HP vector plot filter, takes input from graph, labels, nc, etc.
hplot.c		HP 7221A driver, takes input from hpflt, handshakes to ttyport.
hvirt.c		virtual memory driver for hidden line routines (mprintl.c).
ibmflt.c	HPGL plotter filter, takes input from graph, nc, etc.
iopriv.c	sets up I/O in Venix to allow direct memory, port I/O.
iplot.c		sends output from "ibmflt" to ttyport.
label.c		subroutine to interpret input to "labels"
labels.c	simple graphics language, designed to draw labels on plots.
mdef.h		header file, contains useful definitions and macros.
mdraw.c		used by "labels" to draw symbols of flags from "montage".
mprinta.c	PS driver, monochrome.
mprintc.c	PS driver, color, for Tek Phaser III but works on HP LJ II PS.
mprinte.c	EGA driver.
mprinth.c	Hercules monochrome driver.
mprintl.c	HP LJ PS driver, raster mode, 2900 x 2900.
mprintm.c	IBM monochrome driver.
mprintt.c	Tek 4014 driver.
mprintv.c	VGA driver.
mprintx.c	X11 driver, written in Xlib.
mvid.c		runtime coordinator of all "mprint?.c" drivers.
pdigit.c	simple digitizing program for HP 7221A.
plotdr.c	subroutines for "hplot.c"
plothp.c	subroutines for "hpflt.c"
plotibm.c	subroutines for "ibmflt.c"
plotidr.c	subroutines for "iplot.c"
plotsub.c	subroutines for "pdigit.c"
plsub.c		subroutines to extend Ampex Plot pkg. (libP.a)
posit.c		program to position pictures from graph, labels, nc, etc.
psym.c		old vector font subroutines (putsym.c)
putsym.c	vector font subroutines for "vid.c"
putsym.h	old header file for vector fonts.
putws.c		put word subroutine, machine independent with BYTESWAP.
stdplt.h	header file, Ampex Plot pkg.
symcomp.c	symbol compiler, makes "chars.h" for vector font
term.c		simple terminal graphics driver.
textmod.c	program to switch EGA, VGA from graphics to text and back.
vdef.h		video screen definitions.
vid.c		video graphics driver, for EGA,VGA,Hercules,X11,PS

Neuron-C library: list of functions

Neuron-C Applications Programmer Interface (API) Neuron-C library:

ncfuncs.h:

/* functions for C++ NC script language */

#include "ncsub.h"
#include "ncelem.h"
#include "ncomp.h"
#include "control.h"
#include "nc.h"
#include "y.tab.h"

#include "scheduler.h"

#define NCFUNCS 1

extern scheduler sched;

extern elem *elempnt;
extern node *nodepnt;
extern double *rcolors;

extern const char *infile;
extern const char *progname;
void ncinit(int argc, char **argv);
void ncexit(void);
void setexptvar(void);

void setptr (const char *name, int    *iptr);
void setptr (const char *name, float  *fptr);
void setptr (const char *name, double *dptr);
void setptr (const char *name, const char **sptr);

void setptrn (const char *name, int    *iptr);
void setptrn (const char *name, float  *fptr);
void setptrn (const char *name, double *dptr);
void setptrn (const char *name, const char **sptr);

node *nd(int na, int nb, int nc, int nd);
node *nd(int na);
node *nd(int na, int nb);
node *nd(int na, int nb, int nc);
node *ndn(int na, int nb, int nc, int nd);
node *ndn(int na);
node *ndn(int na, int nb);
node *ndn(int na, int nb, int nc);
node *nde(int na, int nb, int nc, int nd);
node *nde(int na);
node *nde(int na, int nb);
node *nde(int na, int nb, int nc);
node *ndt(int na, int nb, int nc, int nd);
node *ndt(int na);
node *ndt(int na, int nb);
node *ndt(int na, int nb, int nc);
node *ndt(void);
node *ndt_free(node *nd);
node *loc(node *npnt,double xloc,double yloc,double zloc);
node *loc(node *npnt,double xloc,double yloc,double zloc,int region,int dendn);
void label(node *npnt, int color);
void label(synapse *spnt, int color);

node *findnode(nodeint node1a, nodeint node1b, nodeint node1c,
			       nodeint node1d, const char *s);
node *findnode(nodeint node1a, nodeint node1b, nodeint node1c, const char *s);
node *findnode(nodeint node1a, nodeint node1b, const char *s);
node *findnode(nodeint node1a, const char *s);

elem *at (node *node1, int elemtype);
elem *at (int node1a, int node1b, int node1c, int node1d, int elemtype);
elem *at (int node1, int elemtype);
elem *at (int node1a, int node1b, int elemtype);
elem *at (int node1a, int node1b, int node1c, int elemtype);
void at(elem *epnt, node *pnode, double distfrac, node *nnode);
elem *modify (int elnum);
elem *makelem(int etype, elem *oepnt);
elem *findelem(int elnum);

elem *conn (node *n1, node *n2, int elemtype);
elem *conn (int node1a, int node1b, int node1c, int node1d,
                 int node2a, int node2b, int node2c, int node2d, int elemtype);
elem *conn (int node1, int node2, int elemtype);
elem *conn (int node1a, int node1b, int node2a, int node2b, int elemtype);
elem *conn (int node1a, int node1b, int node1c,
                 int node2a, int node2b, int node2c, int elemtype);

elem *get_elempnt(int elnum);
elem *get_elempnt(node *npnt, int elnum);
int   elemtype(int elnum);
double get_length(elem *epnt);

node *get_elemnode1 (elem *epnt);
node *get_elemnode2 (elem *epnt);

double get_nfield(node *npnt, int field, int elnum);
double get_nfield(node *npnt, int field);

double get_efield(elem *epnt, int field);
double get_efield(int  elnum, int field);
char *get_elabel(elem  *epnt, int field);
attrib *get_chanattr(elem *epnt);

double dist2d (node *n1, node *n2);
double dist3d (node *n1, node *n2);
double distzd (node *n1, node *n2);

double endist2d(elem *epnt, node *npnt);
double endist3d(elem *epnt, node *npnt);
double endistzd(elem *epnt, node *npnt);
double enfrac(elem *epnt, node *npnt);

double endist2d(int elnum, node *npnt);
double endist3d(int elnum, node *npnt);
double endistzd(int elnum, node *npnt);

double ttest(double *array, int nrows);
double ttest2(double *array, int nrows);
double pvalue(double t_score, int df);

electrode *make_electrode (node *node1, node *node2);
electrode *make_electrode (node *node1, node *node2, double r, double c);

cable *make_cable (node *node1, node *node2);
cable *make_cable (node *node1, node *node2, double dia);
cable *make_cable (node *node1, node *node2, double dia, double dia2);
photorec *make_cone (node *node1);
photorec *make_cone (node *node1, int pigm);
photorec *make_cone (node *node1, double dia);
photorec *make_cone (node *node1, int pigm, double dia);
photorec *make_rod  (node *node1);
photorec *make_rod  (node *node1, double dia);
photorec *make_rod  (node *node1, int pigm, double dia);
photorec *make_transducer(node *node);
photorec *make_recel(node *node1);
sphere *make_sphere (node *node1, double dia);
sphere *make_sphere (node *node1, double dia, double Rm);
synapse *make_synapse (node *node1, node *node2);
synapse *make_synapse (node *node1, node *node2, int connum);
gapjunc *make_gj (node *node1, node *node2, double maxcond);
vbuf *make_vbuf (node *node1, node *node2, double offset, double gain, double tau, double delay, int stype);
vbuf *make_vbuf (node *node1, node *node2, double offset, double gain, double tau, double delay);
float *makfiltarr (int newsiz, int oldsiz, float *oarr, double val);
chattrib *chanattr(elem *elpnt, short int ctype);
int get_chan_nstate (int elnum);
double setq10s(void);

void ename (elem *epnt, int *num);
void ename (elem *epnt, double *num);

chan *addchan_extern_ca(comp *pnt, chan *chpnt);
chan *addchan_extern(comp *pnt, chan *chpnt);
chan *addchan_extern_ph(comp *pnt, chan *chpnt);
chattrib *make_chan (elem *epnt, int ctype, int stype);
elem *make_chan (node *npnt, int ctype, int stype);
double get_chan_trconc (chattrib *cpnt);


nattrib *make_chnoise  (elem *epnt);
nattrib *make_vesnoise (elem *epnt);

void chset(elem *epnt);
void set_chancalc (int ctype, int stype, int np, double (*func)(double, int));

float *make_filt(double val);
float *make_filt(double val1,double val2);
float *make_filt(double val1,double val2,double val3);
float *make_filt(double val1,double val2,double val3,double val4);
float *make_filt(double val1,double val2,double val3,double val4,double val5);

int gausnn (float **xarr, float **yarr, int ncells, double density, int rsd, double reg,
                double xcent, double ycent, int ginfo);
int gausnn (float **xarr, float **yarr, double density, int rsd, double reg,
                double xsize, double ysize, double xcent, double ycent, int ginfo);
int gausnn (float **xarr, float **yarr, int ncells, int rsd, double reg,
                double xsize, double ysize, double xcent, double ycent, int ginfo);
int gausnn (float **xarr, float **yarr, double nnd, double reg, int rsd, 
                double xsize, double ysize, double xcent, double ycent, int ginfo);

void stim_node (node *npnt, double inten, double start, double dur, double wavel);
void stim_node (node *npnt, double inten, double start, double dur);
void stim_cone (node *npnt, double inten, double start, double dur, double wavel);
void stim_cone (node *npnt, double inten, double start, double dur);
void stim_rod  (node *npnt, double inten, double start, double dur, double wavel);
void stim_rod  (node *npnt, double inten, double start, double dur);

void stim_bar (double width, double length, double xloc, double yloc,
               double xcent, double ycent, double scale, double orient,
               double inten, double start, double dur, double wavel, double mask);

void stim_bar (double width, double length, double xloc, double yloc, double orient,
          double inten, double start, double dur, double wavel, double mask);

void stim_bar (double width, double length, double xloc, double yloc, double orient,
          double inten, double start, double dur);

void stim_spot (double dia, double xloc, double yloc, double xcent, double ycent,
                double scale, double inten, double start, double dur, double wavel, double mask);

void stim_spot (double dia, double xloc, double yloc, double inten,
                        double start, double dur, double wavel, double mask);

void stim_spot (double dia, double xloc, double yloc, double inten, double start, double dur);

void stim_grating (int type, double speriod, double sphase, double orient,
		double xloc, double yloc, double tfreq, double drift,
		double inten, double contrast, double wavel,
		double xenv, double yenv, double mask,
		double start, double dur);

void stim_sine(double speriod, double sphase, double orient,
		double xloc, double yloc, double xcent, double ycent,
		double tfreq, int drift, double scale,
		double inten, double contrast, double start, double dur,
		double wavel, double mask);

void stim_sine(double speriod, double sphase, double orient, double
		xloc, double yloc, double tfreq, int drift,
		double inten, double contrast, double start, double dur);
		
void stim_gabor(double speriod, double sphase, double orient,
		double xloc, double yloc, double xcent, double ycent,
		double tfreq, double drift, double scale,
		double inten, double contrast, double xenv, double yenv, int sq,
		double start, double dur, double wavel, double mask);

void stim_gabor(double speriod, double sphase, double orient, double xloc, double yloc,
		double tfreq, double drift, double inten, double contrast,
		double xenv, double yenv, int sq, double start, double dur);
		
void stim_sineann(double speriod, double sphase, double xloc, double yloc,
		double xcent, double ycent, 
		double tfreq, double drift, double scale,
		double inten, double contrast, double xenv, int sq,
		double start, double dur, double wavel, double mask);

void stim_sineann(double speriod, double sphase, double xloc, double yloc,
		double tfreq, double drift, double inten, double contrast,
		double xenv, double start, double dur);

void stim_sineann(double speriod, double sphase, double xloc, double yloc,
		double tfreq, double drift, double inten, double contrast,
		double xenv, int sq, double start, double dur);

void stim_windmill(double speriod, double sphase, double xloc, double yloc,
		double xcent, double ycent, double tfreq, double drift, 
		double scale, double inten, double contrast, double xenv, 
		int sq, double start, double dur, double wavel, double mask);

void stim_windmill(double speriod, double sphase, double xloc, double yloc,
		double tfreq, double drift, double inten, double contrast,
		double xenv, double start, double dur);

void stim_windmill(double speriod, double sphase, double xloc, double yloc,
		double tfreq, double drift, double inten, double contrast,
		double xenv, int sq, double start, double dur);

void stim_checkerboard(double width, double height, int xn, int yn,
		double orient, double xloc, double yloc,
		double xcent, double ycent, double scale,
		double tfreq, double inten, double contrast,
		double start, double dur, double **stim_rndarr, int *stim_nfr);

void stim_checkerboard(double width, double height, int xn, int yn, 
		double orient, double xloc, double yloc,
		double tfreq, double inten, double contrast,
		double start, double dur,double **stim_rndarr, int *stim_nfr);

void stim_file (const char *filename);
void stim_backgr (double backgr, double wavel, double mask, double start);
void stim_backgr (double backgr, double start);
void stim_backgr (double backgr);

void vclamp (node *npnt, double inten, double start, double dur);
void cclamp (node *npnt, double inten, double start, double dur);
void puff (node *npnt, int puffmsg, double inten, double start, double dur);

void plot (int param, int ename);
void plot (int param, int cagparm, int ename);
void plot (int param, int cagparm, int ename, double max, double min);
void plot (int param, int ename, double max, double min);
void plot (int param, int ename, double frac);
void plot (int param, node *npnt);
void plot (int param, node *npnt, double max, double min);
void plot (int param, int cagparm, node *npnt);
void plot (int param, int cagparm, node *npnt, double max, double min);
void plot_func (double(*func)(double val, double t), double plval, double max, double min);
void plot_func (double(*func)(double val, double val2, double t), double plval, double plval2, double max, double min);
void plot_func (double(*func)(double val, double val2, double val3, double t), double plval, double plval2, double plval3, double max, double min);
void plot_var (double *var, double plval, double max, double min);

void plot_param (const char *name, int plnum, double plsize);
void plot_param (const char *name, int pen, int plnum, double plsize);
void plot_param (const char *name, int pen, int plnum);
void plot_param (const char *name, int pen, int plnum, double plsize, double plval);
void plot_pen (int pen);
void plot_vpen (double (*vpen)(int, double, double));

void plotinit(int numplots);
void plotpen (int val, int i);
void plotchar (int val,int lines, int i);
void plotvpenc  (double (vpen)(int,double,double));
void plotname (const char *plname);
void plotsize (double plotsiz);
void plotfilt (int nfilt, float *timec);
void plotfilt (int nfilt, float *timec, double initval);

void set_synapse_dr (void (*synapse_drpnt)(synapse *,int,double,double,double,double,double,int));
// void set_synapse_dr (void (*synapse_drpnt)(int,double,double,double,double,double,int));
void set_phot_dr (void (*phot_drpnt)(int,int,int,double,double,double,int));
void set_elec (void (*elec_drpnt)(int,double,double,double,double,int,int));
void set_gapjunc_dr (void (*gapjunc_drpnt)(int,double,double,double,int));
void dr_node (node *npnt, double dscale);

void graph(double x, double y1);
void graph(double x, double y1, double y2);
void graph(double x, double y1, double y2, double y3);
void graph(double x, double y1, double y2, double y3, double y4);
void graph(double x, double y1, double y2, double y3, double y4, double y5);
void graph(double x, double y1, double y2, double y3, double y4, double y5, double y6);
void graph(double x, double y1, double y2, double y3, double y4, double y5, double y6, double y7);
void graph(double x, double y1, double y2, double y3, double y4, double y5, double y6, double y7, double y8);
void graph(double x, double *y, int n);

void graph_x (double xmax, double xmin);
void graph_y (double ymax, double ymin);
void graph_init (void);
void graph_restart(void);

void graph_pen (int *val, int n);
void graph_pen (int pen1);
void graph_pen (int pen1, int pen2);
void graph_pen (int pen1, int pen2, int pen3);
void graph_pen (int pen1, int pen2, int pen3, int pen4);
void graph_pen (int pen1, int pen2, int pen3, int pen4, int pen5);
void graph_pen (int pen1, int pen2, int pen3, int pen4, int pen5, int pen6);
void graph_pen (int pen1, int pen2, int pen3, int pen4, int pen5, int pen6, int pen7);
void graph_pen (int pen1, int pen2, int pen3, int pen4, int pen5, int pen6, int pen7, int pen8);

void graph_char (char val);
void graph_cchar (char val);
void graph_csiz (double val);
void graph_set (const char *name, int plnum, double plsize, double plval);
void graph_set (const char *name, int plnum, double plsize);
void graph_filt (float *val, int n);
void graph_vpen (double (*vpen)(int,double,double));

double v(node *npnt);
double v(int node1a, int node1b, int node1c, int node1d);
double v(int node1a, int node1b, int node1c);
double v(int node1a, int node1b);
double v(int node1a);
double v(int elemnum, double fracdist);

double i(node *npnt);
double i(int node1a, int node1b, int node1c, int node1d);
double i(int node1a, int node1b, int node1c);
double i(int node1a, int node1b);
double i(int node1a);
double l(node *npnt);

double record_nt (node *npnt, int nt);
double record_ca (node *npnt, int caval);
double record_ca (node *npnt, int caval, int pval);
double record_chan (int elnum, int nf);
double record_chan (int elnum, int nf, int pval);
double record_chan (elem *epnt, int nf, int pval);
double record_synapse(int snum, int nf);
double record_synapse(synapse *spnt, int nf);
double record (int cnod1, int cnod2, int cnod3, int cnod4, int pmod, int pval);

elem *foreach (elem *epnt, int etype);
elem *foreach (elem *epnt, int etype, double radius, 
					double (*distfunc)(elem *e1, node *n2), 
					node *npntw);

elem *foreach (elem *epnt, int etype, int na1, int na2, int na3, int na4,
				      int nb1, int nb2, int nb3, int nb4, int xxx);
elem *foreach (elem *epnt, int etype, int na1, int na2, int na3, 
				      int nb1, int nb2, int nb3, int xxx);
elem *foreach (elem *epnt, int etype, int na1, int na2, int nb1, int nb2, int xxx);

elem *foreach (elem *epnt, int etype, int na, int nb, int nc, int nd);
elem *foreach (elem *epnt, int etype, int na, int nb, int nc);
elem *foreach (elem *epnt, int etype, int na, int nb);

elem *foreach (elem *epnt, int etype, int na, int nb, int nc, int nd,
                                      int *pa, int *pb, int *pc, int *pd);
elem *foreach (elem *epnt, int etype, int na, int nb, int nc,
                                      int *pa, int *pb, int *pc);
elem *foreach (elem *epnt, int etype, int na, int nb,
                                      int *pa, int *pb);

elem *foreach (elem *epnt, int etype, int na, int nb, int nc, int nd,
                                      int *pa, int *pb, int *pc, int *pd,
                                        double radius, double (*distfunc)(node *n1, node *n2), 
					node *npntw);

node *foreach (node *npnt, int na, int nb, int nc, int nd,
                           int *pa, int *pb, int *pc, int *pd);

node *foreach (node *npnt, int na, int nb, int nc, int *pa, int *pb, int *pc);

node *foreach (node *npnt, int na,  int  nb, int *pa, int *pb);

node *foreach (node *npnt, int na, int nb, int nc, int nd,
                           int *pa, int *pb, int *pc, int *pd,
                           double radius, double (*distfunc)(node *n1, node *n2), node *npntw);

chan *findchan (conlst *cpnt, int ctype, int stype);

void set_disp_rot( double xrot,  double yrot,  double zrot,
             double dxcent, double dycent, double dzcent,
             double rxcent, double rycent, double rzcent, double dsize);
void display_rot( double xrot,  double yrot,  double zrot);
void display_center( double dxcent,  double dycent,  double dzcent);

void display_size (double size);

void display               (int disptype, node *nd1, int dcolor);
void display (int elemtype, int disptype, node *nd1, int dcolor);

void display               (int disptype, node *nd1, int dcolor, double dscale);
void display (int elemtype, int disptype, node *nd1, int dcolor, double dscale);

void display               (int disptype, node *nd1, int exceptype, node *nexc, int dcolor, double dscale);
void display (int elemtype, int disptype, node *nd1, int exceptype, node *next, int dcolor, double dscale);

void display               (int disptype, node *nd1, double (*vpenn)(int elnum, int dcolor));
void display (int elemtype, int disptype, node *nd1, double (*vpenn)(int elnum, int dcolor));

void display               (int disptype, node *nd1, int dcolor, double vmax, double vmin);
void display (int elemtype, int disptype, node *nd1, int dcolor, double vmax, double vmin);

void display               (int disptype, node *nd1, int excl, int dcolor,
		                        double vmax, double vmin, int cmap, double dscale);

void display (int elemtype, int disptype, node *nd1, int excl, int dcolor,  
					double vmax, double vmin, int cmap, double dscale);

void display                (int disptype, node *nd1, int dcolor, double(*vpenn)(int elnum, int color), 
					int cmap, double vmax, double vmin,
             				double dscale, int hide, int excl, double stime);

void display (int elemtype, int disptype, node *nd1, int dcolor, double(*vpenn)(int elnum, int color),
             				int cmap, double vmax, double vmin,
             				double dscale, int hide, int excl, double stime);

void display               (int disptype, node *nd1, node *nd2, node *nexc, int exceptype,
             				int dcolor, double(*vpenn)(int, int),
             				int cmap, double vmax, double vmin,
             				double dscale, int hide, int excl, double stime);
void display (int elemtype, int disptype, node *nd1, node *nd2, node *nexc, int exceptype,
             				int dcolor, double(*vpenn)(int, int),
             				int cmap, double vmax, double vmin,
             				double dscale, int hide, int excl, double stime);
void display (int elemtype, int elnum, int dcolor, double(*vpenn)(int, int),
	     				int cmap, double vmax, double vmin,
	     				double dscale, int hide);
void display (int elemtype, int elnum, int dcolor, double dscale);

void display (elem *epnt, int dcolor, double dscale);

void display_z (double z2, double z1);

void display_stim (double sttime, double attime, double dscale, int cmap, double max_flux, double min_flux);
void display_stim (double sttime, double attime, double dscale, double max_flux, double min_flux);
void display_stim (double sttime, double attime, double dscale);

void display_stim (double attime, double dscale, double max_flux, double min_flux);
void display_stim (double attime, double dscale);

void display_page(void);

void set_phot_dr (void (*phot_drpnt)(int,int,int,double,double,double,int));

void drcalib    (double xcalib,double ycalib,double cline,double dsize,int dcolor);
void disp_calib (double xcalib,double ycalib,double cline,double dsize,int dcolor);
void display_calib (double cline,int dcolor);

int setcmap (int *parr, int cmapsize);
int setcmap (int cmap);

void elimit (int param, double emax, double emin);
void elimit (int elnum);
void elimit (elem *elnum);

node *erasenode(node *npnt);
elem *eraseelem(elem *epnt);
node *erase(node *npnt);
elem *erase(elem *epnt);

int setvar(void);
int setvars(int argc, char **argv);
double getval(const char *var);

int notinit(double var);
int notinit(float var);
int notinit(int   var);
int notinit(const char *var);
double *fread(const char *str, int *nlong, int *nwid);
char *emalloc(unsigned int n);
void efree(void *p);

void savemodel (const char *filnam);
void restoremodel (const char *filnam);

void ncmdlin(int argc, char **argv);
void step(double time);
void run(void);
// void exit(int n);
void initsim(void);

void __runonplot(void);
void setonplot(void (*plpnt)());
void __runonexit(void);
void set_run_on_exit(void (*runonexpnt)());
void set_run_on_step(void (*runonstpnt)());

double drand(void);
void setrand(int val);
unsigned long irand(void);
double rrand(int ngen);
void initrand (int ngen, int nrseed);
double gasdev(void);
double rgasdev(int ngen);
int  binomdev(double p, int n);
int  poisdev(double xm);
double gamdev(double a);

#include "digfilt.h"

#include "lm_funcs.h"

char *xsystem(const char *str);
double system_speed(void);
char *print_version(double version);
double elap_time(void);
void simwait(double nsecs);
int streq (const char *str1, const char *str2);
double set_int_val (double val);

References

Armstrong, C.M., and Matteson, D.R. (1984)  Sequential models of 
   sodium channel gating.  Current Topics in Membranes and 
   Transport.  22: 331-352.

Attwell, D., Werblin, F.S., and Wilson, M.  (1982)  The 
   properties of single cones isolated from the tiger 
   salamander retina.  J. Physiol. 328: 259-283.
 
Attwell, D., Mobbs, P., Tessier-Lavigne, M., and 
   Wilson, M.  (1987)  Neurotransmitter-induced 
   currents in retinal bipolar cells of the 
   axolotl, Ambystoma Mexicanum.  J. Physiol.  387: 125-161.

Baylor, D., and Nunn, B.J.  (1986)  Electrical 
   properties of the light-sensitive conductance of 
   rods of the salamander Ambystoma tigrinum. 
   J. Physiol. 371: 115-145.
  
Belgum, J.H., and Copenhagen, D.R. (1988)  Synaptic 
   transfer of rod signals to horizontal and bipolar 
   cells in the retina of the toad (Bufo Marinus).  J. 
   Physiol. 396: 225-245.

Carnevale, N.T., and Lebeda, F.J. (1987)  Numerical 
   analysis of electrotonus in multicompartmental 
   neuron models.  J. Neurosci. Meth. 19: 69-87.

Ding H, Smith RG, Poleg-Polsky A, Diamond JS, Briggman KL (2016) 
   Species-specific wiring for direction selectivity in the 
   mammalian retina. Nature 535:105-110, doi:10.1038/nature18609.

Ellias, S.A., and Stevens, J.K., (1980)  The  dendritic 
   varicosity: a mechanism for electrically isolating  the 
   dendrites  of cat retinal amacrine cells?   Brain  Res. 
   196: 365-372.

Falk, G., and Fatt, P. (1972)  Physical changes induced 
   by light in the rod outer segment of vertebrates.  
   In Handbook of Sensory Physiology, vol VII/1. 
   Photochemsitry of Vision, ed. Dartnall, H.J.A., 
   p200-244.  Berlin: Springer.

Hines, M. (1989)  A program for simulation of nerve 
   equations with branching connections.  
   Int. J. BioMed. Comput. 24: 55-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. 117: 500-544.

Jack, J.J.B., Noble, D., and Tsien, R.W. (1983)  Electric Current 
  Flow in Excitable Cells.  Clarendon Press, Oxford, UK.

Joyner, R.W., Westerfield, M., Moore, J.W., and 
   Stockbridge, N.  (1978)  A numerical method to model 
   excitable cells.  Biophys. J. 22: 155-170.

Kernighan, B.W., and Pike, R. (1984) The UNIX 
   programming environment.  Prentice-Hall, Englewood 
   Cliffs, N.J.

Koch, C., and Poggio, T. (1985)  A simple algorithm for 
   solving the cable equation in dendritic trees of 
   arbitrary geometry.  J. Neurosci. Meth.  12: 303-315.

Koch, C., and Segev, I. (eds) (1989) Methods in Neuronal 
   Modeling.  MIT Press, Cambridge, MA.

Korn, H., Mallet, A., Triller, A., and Faber, D.S. (1982)  
   Transmission at a central synapse. II. Quantal description of 
   release with a physical correlate for binomial n.
   J. Neurophys. 48: 679-707.

Lamb, T.D., and Simon, E.J. (1976)  The relation 
   between intercellular coupling and electrical noise 
   in turtle photoreceptors.  J. Physiol. 263: 257-286.

Moore, J.W., and Ramon, F., (1974)  On numerical 
   Integration of the Hodgkin and Huxley equations for 
   a membrane action potential.  J. Theor. Biol.  45: 
   249-273.

Nawy, S., and Copenhagen, D.R. (1987)  Multiple classes 
   of glutamate receptor in depolarizing biploar cells 
   in retina.  Nature 325: 56-58.

Perkel, D.H.,  and Mulloney, B. (1978)  Electrotonic 
   properties of neurons:  steady-state compartmental 
   model.  J. Neurophysiol.41: 621-639.

Perkel, D.H., Mulloney, B. and Budelli, R.W. (1981)  
   Quantitative methods for predicting neuronal 
   behavior.  Neuroscience 6: 823-837.

Pugh, E., and Altman, J., (1988)  A role for calcium in 
   adaptation.  Nature 334: 16-17.

Puthussery T, Venkataramani S, Gayet-Primo J, Smith RG, 
   Taylor WR (2013) NaV1.1 Channels in axon initial segments 
   of retinal bipolar cells augment input to magnocellular 
   visual pathways. J Neurosci 33(41): 16045-16059, 
   doi: 10.1523/jneurosci.1249-13.2013.

Rall, W. (1959)  Branching dendritic trees and 
   motoneuron membrane resistivity.  Exp. Neurol. 1: 
   491-527.

Rall, W. (1967)  Distinguishing theoretical synaptic 
   potentials computed for different soma-dendritic 
   distributions of synaptic input.  J. Neurophysiol. 
   30: 1138-1168.

Schachter MJ, Oesch N, Smith RG, Taylor WR. (2010) 
   Dendritic Spikes Amplify the Synaptic Signal to 
   Enhance Detection of Motion in a Simulation of the 
   Direction-Selective Ganglion Cell. PLoS Comput Biol 
   6(8): e1000899. doi:10.1371/journal.pcbi.1000899. 

Stincic T, Smith RG, Taylor WR (2016) Time-course of 
   EPSCs in On-type starburst amacrine cells in mouse retina 
   is independent of dendritic location. J. Physiol. (2016)
    doi: 10.1113/jp272384.

van Rossum, M.C.W., O'Brien, B., and Smith, R.G. (2003) 
   Effects of noise on the spike timing precision of 
   retinal ganglion cells. J. Neurophysiol. 89:2406-2419. 

Interpreted script programming examples

These examples and more are in "nc/tcomp", a set of scripts used to test the features of "nc" as they were developed.

 
 1) simulation of cable (tcomp2)
 
 /* variables with special meanings: */
 
 timinc = 1e-4;           /* simulation time step 100 microsec */
 endexp = .05;            /* end of experiment */
 complam=.1;              /* fraction of lambda per compartment */
 relax = .15;             /* relaxation constant for matrix solve */
 crit=1e-8;               /* criterion for stopping time step */
 ploti = .001;            /* time increment for plotting during run */
 drm = 5000;              /* default Rm changed to new value */
 
 seg = 353;               /* new variable for cable segment length */
 
 conn 1 to 2 cable length seg dia 1;      /* cable segments */
 conn 2 to 3 cable length seg dia 1;
 conn 3 to 4 cable length seg dia 1;
 conn 4 to 5 cable length seg dia 1;
 conn 5 to 6 cable length seg dia 1;
 conn 6 to 7 cable length seg dia 1;
 conn 7 to 8 cable length seg dia 1;
 conn 8 to 9 cable length seg dia 1;
 conn 9 to 10 cable length seg dia 1;
 
 stim node 1 vclamp -.01 start 0 dur 1;          /* voltage clamp stimulus */
 
 plot V[1] max 0 min -.07;        /* plots during run */
 plot V[2] max 0 min -.07;
 plot V[3] max 0 min -.07;
 plot V[4] max 0 min -.07;
 plot V[5] max 0 min -.07;
 plot V[6] max 0 min -.07;
 plot V[7] max 0 min -.07;
 run;
 
 2)  Cable with voltage clamp (tcomp3)
 
 timinc = 1e-4;
 crit = 1e-8;
 complam=.1;
 endexp=.5;
 ploti = endexp/200;
 relax=0.57;
 
 conn 1 to 2 cable length 150 dia .2;
 conn 2 to 3 cable length 150 dia .4;
 stim node 1 vclamp -.02 start .002 dur .2;
 plot V[2],V[1];
 run;






 
 3) Test of cables connected to spheres.
      Transient stimulus at end of cable. (tcomp4)
 
 debug=0;
 plmax 0
 timinc = 4e-6;
 plsep = 0;
 euler = 1;
 
 at 1 sphere dia 10;
 conn 1 to 2 cable length 10 dia 1;
 at 2 sphere dia 10;
 conn 2 to 3 cable length 10 dia 1;
 at 3 sphere dia 10;
 
 stim node 1 vclamp -.01 start 0 dur .002;
 plot V[3],V[2],V[1];
 run;
 
 
 
 4)  Same as 3) but longer cables
 
 endexp = .02;
 
 at 1 sphere dia 10;
 conn 1 to 2 cable length 100 dia 1;
 at 2 sphere dia 10;
 conn 2 to 3 cable length 100 dia 1;
 at 3 sphere dia 10;
 
 stim node 1 vclamp .04 start 0 dur .001;
 stim node 3 vclamp -.07 start 0 dur .001;
 plot V[3],V[2],V[1];
 run;
 






 5) Test of linear synapse  (tcomp7)
 
 timinc = 5e-5;
 crit = 1e-5;
 endexp = .02;
 
 at 1 sphere dia 10;
 conn 1 to 2 synapse linear 2 maxcond 1e-9 thresh -.04;
 at 2 sphere dia 10;
 
 stim node 1 vclamp .04 start 0 dur .005;
 plot V[2],V[1];
 run;
 
 
 
 6) Test of expon synapse  (tcomp7a)
 
 timinc = 5e-5;
 crit = 1e-5;
 endexp = .02;
 
 at 1 sphere dia 10;
 conn 1 to 2 synapse open expon 10 maxcond 1e-9 thresh -.04;
 at 2 sphere dia 10;
 
 stim node 1 vclamp .04 start 0 dur .005;
 plot V[2],V[1];
 run;
 
 
 7) test of voltage clamp (tcomp8)
 
 endexp = .02;
 
 at 1 sphere dia 10;
 conn 1 to 2 synapse linear .5 maxcond 4e-9 thresh -.07;
 at 2 sphere dia 10;
 
 stim node 1 vclamp -.02 start 0 dur .002;
 stim node 1 vclamp .01 start .002 dur .002; 
 stim node 1 vclamp -.02 start .004 dur .008;
 plot V[2],V[1];
 run;






 
 8) Test of current clamp (tcomp9)
 
 endexp = .05;
 
 at 1 sphere dia 10;
 conn 1 to 2 synapse expon 5 thresh -.08; 
 at 2 sphere dia 10;
 conn 2 to 3 synapse expon 5 thresh -.08;
 at 3 sphere dia 10;
 
 stim node 1 cclamp 5e-11 start .004 dur .02; 
 plot V[3],V[2],V[1];
 run;
 
 
 
 
 9) Test of reciprocal synapse (tcomp11) 
 
 endexp = .05;
 plmax = -.00;
 plmin = -.06;
 
 at 1 sphere dia 5;
 conn 1 to 2 cable length 50 dia 1.5 rm 5000;
 at 2 sphere dia 5;
 
 conn 2 to 3 synapse linear thresh -.06;
 conn 3 to 2 synapse linear thresh -.06;
 
 conn 3 to 5 cable length 10 dia .1;
 conn 5 to 6 cable length 10 dia .5;
 conn 6 to 7 cable length 10 dia 2;
 at 7 sphere dia 30;
 conn 7 to 8 cable length 50 dia 5;
 
 stim node 1 cclamp 5e-11 start .002 dur .02; 
 plot V[6],V[5],V[3],V[2],V[1];
 run;
 
 






 10) Test of synapse onto horiz cell (tcomp12)
 
 plmax = -.03;
 plmin = -.08;
 endexp = .05;
 
 at 1 sphere dia 5;
 conn 1 to 2 cable length 50 dia 1.5 rm 5000;
 at 2 sphere dia 5;
 
 conn 2 to 3 synapse linear 1 thresh -.06;
 
 /*
 conn 3 to 2 synapse linear 1 thresh -.06;
 */
 
 conn 3 to 5 cable length 10 dia .1;
 conn 5 to 6 cable length 10 dia .5;
 conn 6 to 7 cable length 10 dia 2;
 at 7 sphere dia 30;
 conn 7 to 8 cable length 50 dia 5;
 
 stim node 1 cclamp 1e-11 start .002 dur .02; 
 stim node 5 cclamp 1e-10 start 0 dur .03;
 plot V[6],V[5],V[3],V[2],V[1];
 run;
 
 
 11) Test of gap junction and instability (tcomp13)
 
 /* must make time constant longer than 5 x timinc */
 
 timinc = 1e-5;
 plmax = -.03;
 plmin = -.08;
 endexp = .05;
 
 dcm = 1e-6;
 
 at 1 sphere dia 10;
 at 1 gndcap 2e-11;
 conn 1 to 2 gj 1e-2;
 at 2 sphere dia 10;
 
 stim node 1 cclamp 1e-10 start .002 dur .02; 
 plot V[1],V[2];
 run;
 
 






 12) /* test of rod */ (tcomp14)
 
 timinc = 1e-4;
 plmax = -.01;
 plmin = -.06;
 endexp = .10;
 ploti = endexp / 200;
 
 rodrm = 5000;
 at 1 sphere dia 5 rm rodrm;    /* rod anatomy */
 at 1 rod (0,0); 
 conn 1 to 2 cable length 50 dia 1.5 rm rodrm;
 at 2 sphere dia 5 rm rodrm;
       /* synapse from rod to horiz */
 conn 2 to 3 synapse linear 1 thresh -.06;
 
 conn 3 to 5 cable length 10 dia .1;
 conn 5 to 6 cable length 10 dia .5;
 conn 6 to 7 cable length 10 dia 2;
 at 7 sphere dia 30;
 conn 7 to 8 cable length 50 dia 5;
 
 stim rod 1 inten 1e4 start .008 dur .002;
 
 plot V[6],V[5],V[3],V[2],V[1];
 run;
 
 
 
 13) Test of current recording from voltage clamp (tcomp16) 
 
 plmax =  .02;
 plmin = -.02;
 endexp = .02;
 ploti = endexp / 200;
 vcl = 0;
 
 at 1 load 1e6;
 at 1 cap  1e-9; 
 
 
 stim node 1 cclamp 1e-8 start .002 dur .002;
 stim node 1 cclamp 2e-8 start .004 dur .004; 
 
 stim node 1 vclamp .01 start .001 dur .005;
 
 
 plot V[1];
 plot I[1] max 1e-7 min -1e-7;
 
 run;






 14) Test of voltage clamp current recording
    from a rod with simultaneous voltage recording (tcomp17)
  
 /* calibrate at flash intensity of 20e3 for 1e-3 sec,
    then at 500e3 for tail length */
 
 timinc = 1e-4;
 plsep = 1; 
 plmax = -.01;
 plmin = -.06;
 
 endexp = 2.50;
 ploti = endexp / 200;
 
 rodrm=5000;
 at 1 sphere dia 1 rm rodrm;             /* rod anatomy */
 at 1 rod (0,0); 
 
 at 2 sphere dia 10 rm rodrm;            /* rod anatomy */
 at 2 rod (0,0); 
 
 flash=20e3;
 stim rod 1 inten flash start .009 dur .001;
 stim node 1 vclamp -.06 start .008 dur 1.5;
 
 stim rod 2 inten flash start .009 dur .001;
 
 plot I[1] max 0e-12 min -60e-12;
 plot V[2] max 0 min -.08;
 
 run;
 






 15)  Test of voltage clamp current recording
    from a rod with simultaneous voltage recording. (tcomp18)
 
 /* calibrate at 1 photon for 1 msec for 8e-12 A peak response */
 
 
 timinc = 1e-4;
 plmax = -.01;
 plmin = -.06;
 endexp = 1.5;
 ploti = endexp / 200;
 
 dmaxrod=35e-11;
 
 rodrm=5000;
 at 1 sphere dia 1 rm rodrm;             /* rod anatomy */
 at 1 rod (0,0); 
 
 /*at 2 sphere dia 1 rm rodrm;  /* rod anatomy */
 /*at 2 rod (0,0); 
 */    /* synapse from rod to horiz */
 
 flash=100e3;
 stim rod 1 inten flash start .009 dur .001;
 stim node 1 vclamp -.06 start .008 dur 1.5;
 
 /*
 stim rod 2 inten flash start .009 dur .001;
 */
 
 plot I[1] max 35e-12 min 0e-12;
 
 /*plot V[1] max .04 min -.06;
 */
 run;
 






 16)  Test of voltage clamp current recording
    from a cone with simultaneous voltage recording. (tcomp20)
 
 /* calibrate at inten 100e3 for 1e-3 dur to give
    8e-12 A peak response */
 
 
 plmax = -.01;
 plmin = -.06;
 endexp = 1.0;
 ploti = endexp / 200;
 
 dmaxcon = 35e-12;
  
 include cone.m;
 
 n=mcone (0,0,1);
 n=mcone (0,0,2);
 
 flash= 2000e3;
 
 stim cone 1 inten flash start .009 dur .001;
 stim node 1 vclamp -.06 start .008 dur 1.5;
 stim cone 2 inten flash start .009 dur .001;
 
 plot I[1] max 3.5e-10 min 0e-12;
 plot V[2] max -.020 min -.050; 
 plot V[2] max .04 min -.06;
 
 run;
 
 






 17) Test of rod; 
       same as tcomp15 but uses "rod.m" (tcomp21)
 
 
 plmax = .0;
 plmin = -.06;
 endexp = 1.0;
 ploti = endexp/200;
 drm = 10000;
 relax= 0.57;
 
 pois = 0;
 
  include "rod.m";       /* */
 
 n = 100;
 
 n = mrod(0,0,n+1);
 
 conn n to 6  cable length 10 dia .1;
 
 conn 6 to 7 cable length 10 dia .5;
 conn 7 to 8 cable length 10 dia 2;
 at 8 sphere dia 30; 
 
 conn 8 to 9 cable length 50 dia 5;
               /* */
 
 stim rod 101 inten 1e3 start .009 dur .001;
 
 /*stim node 101 vclamp -.06 start .005 dur 1;  */
 
 /*plot I[101] max 40e-12 min 0; */
 
 plot V[8],V[7],V[101];          /* */
 
 run; 






 18) Saturation test of 10 cones (tcomp23)
 
 plmax = .0;
 plmin = -.06;
 endexp = .4;
 ploti = .001;
 
 fdur = .002;
 istart = 500*1/fdur;
 
 for (i=0; i<10; i++) {
  at i sphere dia 2 rm 10000;
  at i cone (0,0);
  stim cone i inten istart*(2^i) start .02 dur fdur; /* */
  stim node i vclamp -.03 start 0 dur .4;  /* */
  plot I[i] max 10e-12 min -40e-12;
 };  /* for */
 
 plot L[0] max istart*20 min -istart;
 
 run;
 






 19) Transfer function for synapse. (tcomp24)
 
 crit = 1e-8;
 endexp = 1;
 ploti=.0001;
 
 at 1 sphere dia 10;
 conn 1 to 2 synapse open expon 5 maxcond 1e-9 thresh -.04;
 at 2 sphere dia 10;
 conn 1 to 3 synapse open linear 2 maxcond 1e-9 thresh -.04;
 at 3 sphere dia 10;
 
 
 /* plot V[1] max .04 min -.07;
 plot V[2] max .04 min -.07;
 */
 
 stimlen = .015;
 
 graph X max .04 min -.08;      /* volts */
 graph Y max .04 min -.08;      /* psp (volts) (expon)  */
 graph Y max .04 min -.08;      /* psp (volts) (linear) */
 
 graph init;   /* draw axes */
 
 /* stim node 2 vclamp -.07 start 0 dur 1;       /* */
 
 for (i=0,vc=-.045; vc<-.01; vc+=.001,i++) {
    stim node 1 vclamp vc start i * stimlen dur stimlen; /* */
    step stimlen;               /* wait for equilbration */
    graph (V[1], V[2], V[3]);   /* graph result */
 
 };
 






 20) /* 3 varicosities on single dendrite (varic1.n) */
     /* demonstration of electrotonic decay */
 
 endexp = .012;
 plmax = -.01;
 ploti = endexp / 100;
 disp=0;
 
 drm = 3000;
 
 at   1 sphere dia 3;
 conn 1 to 2 cable length 10 dia 0.1;
 at   2 sphere dia 3;
 conn 2 to 3 cable length 10 dia 0.1;
 at   3 sphere dia 3;
 
 at 4 sphere dia 3;
 at 5 sphere dia 3;
 
 conn 4 to 1 synapse expon 5 maxcond .51e-9 thresh -.04;
 conn 5 to 2 synapse expon 5 maxcond .51e-9 thresh -.04;
 
 stim node 4 vclamp -.03 start 0 dur .008;
 stim node 5 vclamp -.03 start .004 dur .008; 
 plot V[5],V[4],V[3],V[2],V[1];
 run;
 






 21) Functions defining parts of neural circuits.
 
 /* cone function (cone.m) */
 
 func mcone (xpos,ypos,n) { 
 
 conerm = 3000;
 at   [n] cone (xpos,ypos); 
 
 /*conn [n] to [n][1] cable dia 10 length 10 ri 5000 rm 1e4;/* 5 x rod os area*/ 
 
 at   [n]           sphere dia  16           rm 500000;  /* 5 x rod o.s. area */ 
 /*conn [n] to [n+1]cable  dia  .1 length .2 rm conerm;  /* connecting cilium */
 at   [n]           sphere dia   3           rm conerm;
 conn [n] to [n][1]  cable  dia   1 length 50 rm conerm; 
 at   [n][1]         sphere dia   5           rm conerm;
 return (1);     /* return minor node num for cone pedicle */
 };
 
 
 /* procedure to connect cones with gap junctions  (congj.m) */
 
 proc congj(xi,xj,xh,xk) {
 
 source = conarr[xi][xj][0];             /* source cone */
 sz     = conarr[xi][xj][1];
 
 dest   = conarr[xh][xk][0];             /* dest cone */
 dz     = conarr[xh][xk][1];
 
 found=0;
  for (zi=0; zi=arrsiz) continue;
           if (h<0 || h>=arrsiz) continue;
           if (i==h && j==k) continue;
           congj (i,j,h,k);
       };
 
 
 for (hztype=0; hztype<2; hztype++) {
  if (hztype == 0) {            /* B-type Hz */
   hznum = 6;
   hzsiz = 10;
   hznode = 5000;
   hzoff = hzsiz/2.828;
  };
  if (hztype == 1) {            /* A-type Hz */
   hznum = hzmax;
   hzsiz = 14;
   hznode = 6000;
   hzoff = hzsiz/2;
  };
 
  hzcount = 0;
  hzst  = hzsiz/2;
  for (hzly=hzst,j=0; j=arrsiz) continue;
      if (y<0 || y>=arrsiz) continue;
      cnode = conarr[x][y][0];
      ped2  = conarr[x][y][1];
      htip1 = cnode;
      htip2 = conarr[x][y][2]++;
      htip3 = conarr[x][y][2]++;
      conn [cnode][ped2] to (htip1,htip2)
   synapse  linear 2 maxcond 1e-9 thresh -.050 vrev -.01;
 
     if (hztype == 0) {
     conn [htip1][htip2] to (cnode,ped2)
   synapse  linear 2 maxcond 7e-10 thresh -.055 vrev -.08;
     }
     else if (hztype == 1) {
     conn [htip1][htip2] to (cnode,ped2)
   synapse  linear 2 maxcond 1e-9 thresh -.055 vrev -.08;
     };
 
      conn [htip1][htip2] to [htip1][htip3]
          cable dia .1 length 10 rm hbrm vrev hzrev vrest hrest;
 
      conn [htip1][htip3] to [hznode]
          cable dia 2 length 20 rm hbrm vrev hzrev vrest hrest;
    };
   at [hznode] sphere dia 30 rm hbrm vrev hzrev vrest hrest;
   if (hztype > 0) {
          hzarr[i][j][0] = hzcount;
          hzarr[i][j][1] = hznode;
   };
  };
  print "#  hzcount",hzcount;
 
 }; /* for (hztype; ;) */
 
                /* make gap junctions betw A hz cells */
 for (i=0; i=hznum) continue;
           if (h<0 || h>=hznum) continue;
           if (i==h && j==k) continue;
           conhz (i,j,h,k);
       };
 






 stim file hz53.t;
 
 stim center (150,90); 
 
 stim backgr 100 start 0;
  
 stim spot 1 loc (150,90) blur 22 inten 2.5e9 start 0.05 dur .001;
 
 plot V[475][1] max -.04 min -.07;
 plot V[474][1] max -.04 min -.07;
 plot V[473][1] max -.04 min -.07;
 plot V[472][1] max -.04 min -.07;
 plot V[471][1] max -.04 min -.07;
 plot V[470][1] max -.04 min -.07;
 plot V[469][1] max -.04 min -.07;
 plot V[468][1] max -.04 min -.07;
 plot V[467][1] max -.04 min -.07;
 plot V[465][1] max -.04 min -.07;
 plot V[460][1] max -.04 min -.07;
 plot V[455][1] max -.04 min -.07;
 plot V[450][1] max -.04 min -.07;
 plot V[5023] max -.04 min -.07;
 plot V[5022] max -.04 min -.07;
 plot V[5021] max -.04 min -.07;
 plot V[5020] max -.04 min -.07;
 plot V[5019] max -.04 min -.07;
 plot V[5018] max -.04 min -.07;
 plot V[5000] max -.04 min -.07;
 plot V[6003] max -.04 min -.07;
 
 run;
 
 

NeuronC syntax listing

Syntax for interpreted version (see "nc/src/nc.y")

Terminals and non-terminals

The following table (Table 1 below) is the syntax for NeuronC (see "nc.y" for an up-to-date version) in the format for the UNIX language-generator, YACC (yet another compiler-compiler). "Non- terminals" to the left of colons represent grammatical structures recognized by NeuronC; after them is a list of constituent structures, called rules; the "|" (logical "or") in front of a rule means the rule is a possible alternate. If the syntax is not followed exactly, the NeuronC parser identifies the first error and prints its line and character. Extra spaces (more than those needed to separate words) are ignored, as are newlines (line feeds or the "enter" key).

In the table below, words in upper case are called "terminals" meaning that they character strings recognized by the lexical analyzer directly from their spelling. They are upper case in the syntax listing for clarity only; in a NeuronC program, they are normally lower case. Curly braces "{}" enclose "C" language statements for the action to be taken when the parser has identified a particular grammatical structure. The action is normally a sequence of pseudo-code to be compiled into a run-time program, which defines calls to "C" language subroutines. Curly braces after a rule contain the action taken when the parser recognizes the rule; you can ignore this. Comments are inside the familiar "/* comment */".

A NeuronC program is a "list" in the following table. The first rule for "list" is "/* nothing */" which means that a blank line is acceptable (no error), although it does nothing. One of the possible alternatives to "list" is:


 list:     /* nothing */
      .
      .
      .
      | list stmt listerm        { code(STOP); return 1; }
 

In other words, "list" can also mean a list followed by a "stmt" and then a "listerm". "listerm" is defined as a semicolon for the "end of line" character, as in the "C" language. Thus "nothing", followed by a single statement, followed by a semicolon is an acceptable NeuronC program. Looking for the definition of the non-terminal "stmt", we see that it includes the definition of all neural elements:

 stmt:
      .
      .
      .
      | elemlist         { }

The description of a neural element must start with a keyword that defines the element's node connection(s), either "at" or "connect", and then may include other keywords to describe geometry or membrane parameters:

 elemlist: connect               {}
         | elemlist geometry     {}
         | elemlist membrtype    {}
         ;

"geometry" in turn describes the type of neural element, and may include parameters specific to that element type. Note that many grammatical structures are self-referential (the same word on left and right of the colon) and are therefore recursive. This allows more flexibility in describing neural elements because in these cases a parameter list need not be specified in any particular order. For example, an "elemlist" can be any of:

           "connect geometry"
           "connect geometry" 
           "connect geometry membrane" 
           "connect membrane geometry"
 
 






Table 1 NeuronC syntax (from "nc.y") %{ #include #include "nc.h" #define code2(c1,c2) code(c1); code(c2) #define code3(c1,c2,c3) code(c1); code(c2); code(c3) #define code4(c1,c2,c3,c4) code(c1); code(c2); code(c3); code(c4) extern int indef, inlocal, argcount, formal, fname; %} %union { Symbol *sym; /* symbol table pointer */ Inst *inst; /* machine instructions */ int narg; /* number of arguments */ char *name; /* name of file */ } %token NUMBER STRING PRINT PRINTF %token CONST VAR BLTIN UNDEF WHILE IF ELSE %token FUNCTION PROCEDURE RETURN FUNC PROC READ FREAD %token FOR BREAK CONTINUE EDIT INCLUDE COMNDLINE SYSTEM FOREACH %token INCROP DECROP PFIELD ARG LOCAL LOCALVAR DIM ARRAY FFT PFFT %token FNAME SFILE PLOT V I L S MAX MIN %token DISPLAY GRAPH INIT PEN RESTART %token X Y Z XLOC YLOC ZLOC FA0 FA1 FA2 FA3 FA4 FB0 FB1 FB2 FB3 FB4 %token GMOVE GDRAW GRMOVE GRDRAW GPEN GFRAME GROT GCSIZ GDASH GTEXT %token ELEMENT EXCEPT RANGE SIZE DSCALE COLOR HIDE %token XROT YROT ZROT CALIBLIN %token CABLE SPHERE GJ SYNAPSE LOAD RESISTOR AXIALRES MATCHING %token ROD CONE MAXCOND CENTER RECT WAVEL SUN XENON PIGM PATHL ATTF %token STIM BAR SPOT SINE WIDTH LOC DUR START INTEN BACKGR BLUR FILT %token LENGTH DIA RADIUS VCLAMP CCLAMP GNDBATT BATT GNDCAP CAP NODE %token CHAN HH NA K TYPE DENSITY RM RI RG CM OPAMP BUF %token CONNECT AT TO EDIST EFRAC NDIST ONLY NUMCONN NODE1 NODE2 %token CHNOISE PHOTNOISE VESNOISE TIMEC1 NFILT1 TIMEC2 NFILT2 N %token OPEN CLOSE THRESH VREV VREST DELAY IGAIN KD LINEAR EXPON %token RUN STEP ERASE ALL MODIFY ENAME PLACE CPLAM OFFSET PUT %type cexpr commaexpr expr stmt asgn prlist prflist stmtlist stmtls %type cond while if begin end defn txtflist %type for forexpr var foreach elemtype %type elemlist geometry %type stimulus stimlist stimtype stimloc stimstart stimdur stiminten %type stimblur stimfile stimwave stimcenter graphlist graphtype maxmin %type cableparam sphereparam membrtype connect chantype noisetype %type synaptype receptype plotype displist disptype rotatype %type elemfield nodefield elemnum plotlist %type procname listerm arrname %type arglist parglist formarg localvar vararg prfargs %type dimlist nodenum snode %type filename %right '=' %right ADDEQ SUBEQ MULEQ DIVEQ %left OR AND XOR BITAND BITOR %left GT GE LT LE EQ NE %left '+' '-' %left '*' '/' %left UNARYMINUS NOT %right '^' %% list: /* nothing */ | list listerm { code(STOP); return 1; } | list defn listerm { code(STOP); return 1; } | list asgn listerm { code2(expop,STOP); return 1; } | list stmt listerm { code(STOP); return 1; } | list expr listerm { code2(print, STOP); return 1; } | list error listerm { yyerrok; } ; listerm: ';' {} ; elemlist: connect {} | elemlist geometry {} | elemlist membrtype {} | elemlist ENAME var { code2(xmod,(Inst)$2); } | elemlist MODIFY expr { code2(xmod,(Inst)$2); } ; geometry: CABLE cableparam { $$=$2; } | SPHERE sphereparam { $$=$2; } | synaptype { $$=$1; } | CHAN chantype { $$=$2; } | receptype { $$=$1; } | GJ expr { $$=$2; code(gj); } | LOAD expr { $$=$2; code(rload); } | RESISTOR expr { $$=$2; code(resistor); } | CAP expr { $$=$2; code(rcap); } | GNDCAP expr { $$=$2; code(gcap); } | BATT expr { $$=$2; code(rbatt); } | GNDBATT expr { $$=$2; code(gbatt); } | BUF { $$=(Inst *)code(vbuf); } ; cableparam: LENGTH expr { $$=$2; code2(xcable,(Inst)$1); } | DIA expr { $$=$2; code2(xcable,(Inst)$1); } | CPLAM expr { $$=$2; code2(xcable,(Inst)$1); } | cableparam LENGTH expr { code2(xcable,(Inst)$2); } | cableparam DIA expr { code2(xcable,(Inst)$2); } | cableparam CPLAM expr { code2(xcable,(Inst)$2); } ; sphereparam: expr { code2(sphere,(Inst)0); } | DIA expr { $$=$2; code2(sphere,(Inst)$1); } ; chantype: HH { $$=(Inst *)code2(xchan,(Inst)$1);} | NA { $$=(Inst *)code2(xchan,(Inst)$1);} | K { $$=(Inst *)code2(xchan,(Inst)$1);} | chantype TYPE expr { code2(xchan,(Inst)$2); } | chantype VREV expr { code2(xchan,(Inst)$2); } | chantype THRESH expr { code2(xchan,(Inst)$2); } | chantype DELAY expr { code2(xchan,(Inst)$2); } | chantype MAXCOND expr { code2(xchan, (Inst)$2); } | chantype DENSITY expr { code2(xchan, (Inst)$2); } | chantype noisetype { } ; membrtype: chantype { } | RM expr { $$=$2; code(rm); } | RI expr { $$=$2; code(ri); } | RG expr { $$=$2; code(rg); } | CM expr { $$=$2; code(mcap); } | VREV expr { $$=$2; code(mvrev); } | VREST expr { $$=$2; code(mvrest); } | membrtype chantype { } | membrtype RM expr { code(rm); } | membrtype RI expr { code(ri); } | membrtype RG expr { code(rg); } | membrtype VREV expr { code(mvrev); } | membrtype VREST expr { code(mvrest); } ; connect: AT begin nodenum { $$=$2; code2(conn1,(Inst)$3); } | AT begin nodenum LOC parglist /* args backwards here: */ { $$=$2; code3(conn1l,(Inst)$5,(Inst)$3); } | AT begin nodenum ':' elemnum OFFSET expr PUT nodenum { $$=$2; code3(conn1m,(Inst)$9, (Inst)$3); } | CONNECT begin nodenum TO nodenum /* args backwards here */ { $$=$2; code2(conn2d,(Inst)$5); code2(conn2s,(Inst)$3); } | CONNECT begin nodenum LOC parglist TO nodenum { $$=$2; code2(conn2d,(Inst)$7); code3(conn2sl,(Inst)$5,(Inst)$3); } | CONNECT begin nodenum TO nodenum LOC parglist { $$=$2; code3(conn2dl,(Inst)$7,(Inst)$5); code2(conn2s,(Inst)$3); } /* args backwards here: */ | CONNECT begin nodenum LOC parglist TO nodenum LOC parglist { $$=$2; code3(conn2dl,(Inst)$9,(Inst)$7); code3(conn2sl,(Inst)$5,(Inst)$3); } ; synaptype: SYNAPSE begin { $$=$2; } | synaptype OPEN { code2(synapse,(Inst)$2); } | synaptype CLOSE { code2(synapse,(Inst)$2); } | synaptype VREV expr { code2(synapse,(Inst)$2); } | synaptype THRESH expr { code2(synapse,(Inst)$2); } | synaptype TIMEC1 expr { code2(synapse,(Inst)$2); } | synaptype NFILT1 expr { code2(synapse,(Inst)$2); } | synaptype TIMEC2 expr { code2(synapse,(Inst)$2); } | synaptype NFILT2 expr { code2(synapse,(Inst)$2); } | synaptype IGAIN expr { code2(synapse,(Inst)$2); } | synaptype MAXCOND expr { code2(synapse,(Inst)$2); } | synaptype KD expr { code2(synapse,(Inst)$2); } | synaptype LINEAR { code2(synapse,(Inst)$2); } | synaptype EXPON expr { code2(synapse,(Inst)$2); } | synaptype noisetype { } ; noisetype: CHNOISE { $$=(Inst *)code2(noise,(Inst)$1); } | VESNOISE { $$=(Inst *)code2(noise,(Inst)$1); } | noisetype N expr { code2(noise,(Inst)$2); } | noisetype DUR expr { code2(noise,(Inst)$2); } ; receptype: ROD begin parglist { $$=$2;code3(recept,(Inst)$1,(Inst)$3);} | CONE begin parglist { $$=$2;code3(recept,(Inst)$1,(Inst)$3);} | receptype MAXCOND expr { code2(recparm, (Inst)$2); } | receptype DIA expr { code2(recparm, (Inst)$2); } | receptype PIGM expr { code2(recparm, (Inst)$2); } | receptype PATHL expr { code2(recparm, (Inst)$2); } | receptype ATTF expr { code2(recparm, (Inst)$2); } | receptype FILT expr { code2(recparm, (Inst)$2); } | receptype PHOTNOISE { code2(recparm, (Inst)$2); } ; stimulus: stimlist {} | stimulus stimlist {} ; stimlist: stimtype {} | stimloc {} | stimcenter {} | stimstart {} | stimdur {} | stimwave {} | stiminten {} | stimblur {} | stimfile {} ; stimtype: BAR expr { $$=$2; code2(xstim,(Inst)$1); } | SPOT expr { $$=$2; code2(xstim,(Inst)$1); } | RECT begin arglist { $$=$2; code3(xstim,(Inst)$1,(Inst)$3); } | ROD expr { $$=$2; code3(xstim,(Inst)$1,(Inst)1);} | ROD begin dimlist { $$=$2; code3(xstim,(Inst)$1,(Inst)$3);} | CONE expr { $$=$2; code3(xstim,(Inst)$1,(Inst)1);} | CONE begin dimlist { $$=$2; code3(xstim,(Inst)$1,(Inst)$3);} | NODE expr { $$=$2; code3(xstim,(Inst)$1,(Inst)1);} | NODE begin dimlist { $$=$2; code3(xstim,(Inst)$1,(Inst)$3);} ; stimloc: LOC begin parglist { $$=$2; code3(xstim,(Inst)$1,(Inst)$3); } ; stimcenter: CENTER begin parglist {$$=$2;code3(xstim,(Inst)$1,(Inst)$3); } ; stimstart: START expr { $$=$2; code2(xstim,(Inst)$1); } ; stimdur: DUR expr { $$=$2; code2(xstim,(Inst)$1); } ; stimwave: WAVEL expr { $$=$2; code3(xstim,(Inst)$1,(Inst)0); } | WAVEL SUN { $$=(Inst *)code3(xstim,(Inst)$1,(Inst)$2); } | WAVEL XENON { $$=(Inst *)code3(xstim,(Inst)$1,(Inst)$2); } ; stiminten: INTEN expr { $$=$2; code2(xstim,(Inst)$1); } | BACKGR expr { $$=$2; code2(xstim,(Inst)$1); } | VCLAMP expr { $$=$2; code2(xstim,(Inst)$1); } | CCLAMP expr { $$=$2; code2(xstim,(Inst)$1); } ; stimblur: BLUR expr { $$=$2; code2(xstim,(Inst)$1); } ; stimfile: SFILE {fname=1;} filename {fname=0;$$=(Inst *)code3(xstim,(Inst)$1, (Inst)$3);} ; asgn: var '=' expr { code(assign); } | var ADDEQ expr { code(addeq); } | var SUBEQ expr { code(subeq); } | var MULEQ expr { code(muleq); } | var DIVEQ expr { code(diveq); } ; stmt: expr { code(expop); } | LOCAL { inlocal=1; } localvar {inlocal=0; defnonly("local"); $$=(Inst *)code2(local,(Inst)$3);} | RETURN { defnonly("return"); code(procret); } | RETURN expr {defnonly("return"); $$=$2; code(funcret); } | PROCEDURE begin parglist { $$=$2; code3(call, (Inst)$1, (Inst)$3); } | PRINT prlist { $$ = $2; code(crlf); } | PRINTF '(' prflist ')' { $$ = $3; } | for '(' forexpr ';' forexpr ';' forexpr ')' stmt end { ($1)[1] = (Inst)$5; /* body of loop */ ($1)[2] = (Inst)$7; /* body of loop */ ($1)[3] = (Inst)$9; /* body of loop */ ($1)[4] = (Inst)$10; } /* end expr */ | BREAK end { $$ = (Inst *)code(breakcode); } | CONTINUE end { $$ = (Inst *)code(contcode); } | while cond stmt end { ($1)[1] = (Inst)$3; /* body of loop */ ($1)[2] = (Inst)$4; } /* end, if cond fails */ | if cond stmt end { /* else-less if */ ($1)[1] = (Inst)$3; /* thenpart */ ($1)[3] = (Inst)$4; } /* end, if cond fails */ | if cond stmt end ELSE stmt end { /* if with else */ ($1)[1] = (Inst)$3; /* thenpart */ ($1)[2] = (Inst)$6; /* elsepart */ ($1)[3] = (Inst)$7; } /* end, if cond fails */ | foreach stmt end { /* look through all nodes */ ($1)[2] = (Inst)0; ($1)[3] = (Inst)0; ($1)[4] = (Inst)0; ($1)[5] = (Inst)0; ($1)[6] = (Inst)$2; /* body of loop */ ($1)[7] = (Inst)$3; } /* end, when done */ | foreach NODE snode end stmt end { /* look through all nodes */ ($1)[2] = (Inst)1; ($1)[3] = (Inst)$3; ($1)[4] = (Inst)0; ($1)[5] = (Inst)0; ($1)[6] = (Inst)$5; /* body of loop */ ($1)[7] = (Inst)$6; } /* end, when done */ | foreach NODE snode snode end stmt end { ($1)[2] = (Inst)2; ($1)[3] = (Inst)$3; ($1)[4] = (Inst)$4; ($1)[5] = (Inst)0; ($1)[6] = (Inst)$6; /* body of loop */ ($1)[7] = (Inst)$7; } /* end, when done */ | foreach NODE snode snode snode end stmt end { ($1)[2] = (Inst)3; ($1)[3] = (Inst)$3; ($1)[4] = (Inst)$4; ($1)[5] = (Inst)$5; ($1)[6] = (Inst)$7; /* body of loop */ ($1)[7] = (Inst)$8; } /* end, when done */ | stmtlist { } | EDIT { fname=1; } filename { fname=0; edit ($3); } | INCLUDE {fname=1;} filename { fname=0; $$=(Inst *)code2(pushfil,(Inst)$3); } | COMNDLINE { system ((char *)$1); } | SYSTEM STRING { system ((char *)$2); } | elemlist { } | STIM stimulus { $$=$2; code2(xstim, (Inst)$1); } | PLOT plotlist { $$=$2; } | PLOT plotype begin nodenum maxmin { $$=$3; code3(vplotm,(Inst)$2,(Inst)$4); } | PLOT S var maxmin { $$=$3; code2(vplot,(Inst)$2); } | DISPLAY displist { $$=$2; code2(dispnod,(Inst)$1); } | GRAPH graphlist { $$=$2; } | GMOVE begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GDRAW begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GRMOVE begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GRDRAW begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GPEN begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GROT begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GCSIZ begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GDASH begin parglist { $$=$2; code3(gplot,(Inst)$1,(Inst)$3); } | GFRAME STRING { $$=(Inst *)code3(gplot,(Inst)$1,(Inst)$2); } | GTEXT '(' txtflist ')'{ $$=$3; } | FREAD begin '('{fname=1;} filename {fname=0;} ',' VAR ',' vararg ')' { $$=$2; code4(xfread,(Inst)$5,(Inst)$8,(Inst)$10); } | DIM begin arrname dimlist {$$=$2;code3(darray,(Inst)$3,(Inst)$4);} | FFT begin '(' ARRAY ')' { $$=$2; code3(dofft,(Inst)$1,(Inst)$4); } | PFFT begin '(' ARRAY ')' { $$=$2; code3(dofft,(Inst)$1,(Inst)$4); } | ERASE ARRAY { $$=(Inst *)code2(erarr,(Inst)$2); } | ERASE ALL { erase(); } | RUN { $$ = (Inst *)code2(modrun,(Inst)$1); } | STEP expr { $$ = $2; code2(modrun,(Inst)$1); } ; plotype: V { } | I { } | L { } | FA0 { } | FA1 { } | FA2 { } | FA3 { } | FA4 { } | FB0 { } | FB1 { } | FB2 { } | FB3 { } | FB4 { } plotlist: plotype begin nodenum { $$=$2; code3(vplot,(Inst)$1,(Inst)$3); } | plotlist ',' plotype nodenum { $$=$1; code3(vplot,(Inst)$3,(Inst)$4); } ; graphlist: graphtype { $$=$1; } | graphlist graphtype { $$=$1; } ; graphtype: begin parglist { $$ = $1; code3 (grph,0L,(Inst)$2);} | INIT { $$ = (Inst *) code3 (grph, (Inst)$1, 0L); } | RESTART { $$ = (Inst *) code3 (grph, (Inst)$1, 0L); } | PEN expr { $$ = $2; code3 (grph,(Inst)$1,(Inst)1); } | PEN begin parglist { $$ = $2; code3 (grph,(Inst)$1,(Inst)$3); } | X maxmin { $$ = $2; code3 (grph, (Inst)$1, 0L); } | Y maxmin { $$ = $2; code3 (grph, (Inst)$1, 0L); } ; maxmin: MAX expr MIN expr { $$ = $2; } ; displist: disptype { $$=$1; } | displist disptype { $$=$1; } disptype: MATCHING begin nodenum { $$=$2; code4(dispnod,(Inst)$1,(Inst)0,(Inst)$3); } | CONNECT begin nodenum TO nodenum { $$=$2; code4(dispnod,(Inst)$1,(Inst)$5,(Inst)$3); } | RANGE begin nodenum TO nodenum { $$=$2; code4(dispnod,(Inst)$1,(Inst)$5,(Inst)$3); } | ELEMENT elemnum { $$=$2; code4(dispnod,(Inst)$1,(Inst)0,(Inst)1); } | elemtype { $$=(Inst *)code2(dispnod,(Inst)$1); } | disptype EXCEPT { code2(dispnod,(Inst)$2); } | rotatype expr { $$=$2; code2(dispnod,(Inst)$1); } | SIZE expr { $$=$2; code2(dispnod,(Inst)$1); } | DSCALE expr { $$=$2; code2(dispnod,(Inst)$1); } | COLOR expr { $$=$2; code2(dispnod,(Inst)$1); } | CALIBLIN expr { $$=$2; code2(dispnod,(Inst)$1); } | HIDE { $$=(Inst *)code2(dispnod,(Inst)$1); } | CENTER begin parglist { $$=$2; code3(dispnod,(Inst)$1,(Inst)$3); } | ONLY { $$=(Inst *)code2(dispnod,(Inst)$1); } ; filename: /* nothing */ { $$ = 0; } | FNAME { $$ = $1->name; } | STRING { $$ = (char *)$1; } ; cond: '(' cexpr ')' {code(STOP); $$ = $2; } ; while: WHILE { $$ = (Inst *)code3(whilecode,STOP,STOP); } ; forexpr: cexpr {code(STOP); $$ = $1; } ; for: FOR { $$ = (Inst *)code(forcode); code4(STOP,STOP,STOP,STOP); } ; if: IF { $$ = (Inst *)code(ifcode); code3(STOP,STOP,STOP); } ; foreach: FOREACH { $$ = (Inst *)code(foreacode); code3((Inst)0,STOP,STOP); code4(STOP,STOP,STOP,STOP); } | FOREACH elemtype '?' var { $$ = (Inst *)code(foreacode); code3((Inst)$2,STOP,STOP); code4(STOP,STOP,STOP,STOP); } | FOREACH ELEMENT '?' var { $$ = (Inst *)code(foreacode); code3((Inst)$2,STOP,STOP); code4(STOP,STOP,STOP,STOP); } ; elemtype: CABLE { } | SPHERE { } | SYNAPSE { } | CHAN { } | ROD { } | CONE { } | GJ { } | LOAD { } | RESISTOR { } | CAP { } | GNDCAP { } | BATT { } | GNDBATT { } | BUF { } ; begin: /* nothing */ { $$ = progp; } ; end: /* nothing */ { code(STOP); $$ = progp; } ; stmtlist: '{' stmtls '}' { $$ = $2; } ; stmtls: /* nothing */ { $$ = progp; } | stmtls stmt listerm ; expr: NUMBER { $$ = (Inst *)code2(constpush, (Inst)$1); } | CONST { $$ = (Inst *)code3(varpush,(Inst)$1,eval); } | var { $$ = $1; code(eval); } | var INCROP { $$ = $1; code(postinc); } | var DECROP { $$ = $1; code(postdec); } | INCROP var { $$ = $2; code(preinc); } | DECROP var { $$ = $2; code(predec); } | asgn | FUNCTION begin parglist { $$ = $2; code3(call,(Inst)$1,(Inst)$3); } | READ '(' var ')' { $$ = (Inst *)code2(varread, (Inst)$3); } | BLTIN begin parglist { $$=$2; code3(bltin,(Inst)$3,(Inst)$1->u.ptr);} | plotype begin nodenum { $$=$2; code3(xrecord, (Inst)$1, (Inst)$3); } | EDIST begin '(' nodenum ',' elemnum ')' { $$=$2; code2(edist, (Inst)$4); } | EFRAC begin '(' nodenum ',' elemnum ')' { $$=$2; code2(efrac, (Inst)$4); } | NDIST begin '(' nodenum ',' nodenum ')' /* args are backward here: */ { $$=$2; code3(ndist, (Inst)$6, (Inst)$4); } | ELEMENT elemnum PFIELD elemfield { $$=$2; code2(efield, (Inst)$4); } | NODE begin nodenum PFIELD nodefield { $$=$2; code3(nfield,(Inst)$5, (Inst)$3);} | '(' cexpr ')' { $$ = $2; } | expr '+' expr { code (add); } | expr '-' expr { code (sub); } | expr '*' expr { code (mul); } | expr '/' expr { code (xdiv); } | expr '^' expr { code (power); } | '-' expr %prec UNARYMINUS { $$=$2; code(negate); } | expr GT expr { code (gt); } | expr GE expr { code (ge); } | expr LT expr { code (lt); } | expr LE expr { code (le); } | expr EQ expr { code (eq); } | expr NE expr { code (ne); } | expr AND expr { code (xand); } | expr OR expr { code (orx); } | expr BITAND expr { code (bitand); } | expr BITOR expr { code (bitor); } | NOT expr { $$ = $2; code (xnot); } ; commaexpr: expr ',' expr { code(popone); } | commaexpr ',' expr { code(popone); } ; cexpr: expr { } | commaexpr { } ; var: VAR { $$ = (Inst *)code2 (varpush, (Inst)$1); } | ARRAY begin dimlist {$$ = $2; code3 (varpush, (Inst)$1,(Inst)$3); } | ARG {$$=(Inst *)code2(varpush,(Inst)$1->u.argnum);} | LOCALVAR {$$=(Inst *)code2(varpush,(Inst)$1->u.argnum);} ; prlist: expr { code(prexpr); } | STRING { $$ = (Inst *)code2(prstr, (Inst)$1); } | prlist ',' expr { code(prexpr); } | prlist ',' STRING { code2(prstr, (Inst)$3); } ; prflist: STRING { $$=(Inst *)code3(pprintf,(Inst)0,(Inst)$1);} | STRING ',' begin prfargs {$$=$3; code3(pprintf, (Inst)$4, (Inst)$1);} ; txtflist: STRING { $$= (Inst *)code3(txtf,(Inst)0,(Inst)$1);} | STRING ',' begin prfargs {$$=$3;code3(txtf,(Inst)$4,(Inst)$1);} ; prfargs: expr { $$ = 1; } | prfargs ',' expr { $$ = $1 + 1; } /* how many args? */ ; defn: FUNC procname { $2->type=FUNCTION; indef=1; formal=1; } '(' formarg ')' { formal=0; } stmt {code(procret); define($2); erasarg();indef=0; } | PROC procname { $2->type=PROCEDURE; indef=1; formal=1; } '(' formarg ')' { formal=0; } stmt {code(procret); define($2); erasarg();indef=0; } ; dimlist: '[' expr ']' { $$ = 1; } | dimlist '[' expr ']' { $$ = $1 + 1; } ; nodenum: expr { $$ = 1; } | dimlist { $$ = $1; } ; elemnum: expr { $$ = $1; } ; snode: '?' var { $$ = 1; } | '[' expr ']' { $$ = 0; } ; elemfield: TYPE { } | LENGTH { } | NDIST { } | DIA { } | RM { } | RI { } | CPLAM { } | NODE1 { } | NODE2 { } ; nodefield: NUMCONN { } | XLOC { } | YLOC { } | ZLOC { } | expr { $$ = (Inst *)0; } /* relative elem # */ ; procname: VAR | FUNCTION | PROCEDURE ; rotatype: XROT { } | YROT { } | ZROT { } ; arrname: VAR ; arglist: /* nothing */ { $$ = 0; } | expr { $$ = 1; } | arglist ',' expr { $$ = $1 + 1; } ; parglist: '(' arglist ')' { $$ = $2; } ; formarg: /* nothing */ { $$ = 0; argcount=0; } | ARG { $$ = $1->u.argnum = 1; argcount=1; } | formarg ',' ARG { $$ = $3->u.argnum = $1 + 1; argcount++; } ; localvar: /* nothing */ { $$ = 0; } | LOCALVAR { $$ = 1; $1->u.argnum = ++argcount; } | localvar ',' LOCALVAR { $$ = $1 + 1; $3->u.argnum = ++argcount; } ; vararg: var { $$ = 1; } | vararg ',' var { $$ = $1 + 1; } ; %% /* end of grammar */