Running nc, stim, and plotmod commands


nc

A model written in the NeuronC 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   (for default display)
or
     nc -v $argv | vid -X -w 1.8          (for X11 displays)
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" and "ndv" commands are similar to the "neurc" command except that they are not scripts, but a links (second names for) to "nc". Whenever "nc" finds itself called "ncv", it will attempt to generate an X window and display the output from nc.

The "nc" command has several command line switches:

    -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".

    -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.

     -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

     -n        no node numbers on graph

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

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

     -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 <var> n  Set variable from command line.  Same as "--<var>" above.

     -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 line width for "display" statement to n.

     -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.

      -R       Output symbolic scene for input to "povray" ray-tracer.
                 Use in conjunction with "-d 1" switch. 
You can run the "nc" command in several ways:
1)   neurc file.n               (run model, same as "nc -v file.n | vid")
2)   nc -t file.n               (run model, prints text on screen )
                                ( Used for "debugging" a model.) 
3)   nc -t 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 file.n | vid            (display neural circuit anatomy on vid screen)
6)   nc -d 1 file.n | vid       (same as "nd file.n | vid")
7)   plotmod file.n | vid       (Displays graph or picture from file. )   
8)   plotmod file.n | 8by11     (Draws graph or picture on color plotter. )   
9)   nc -d 1 -R file.n > file.pov (Draws scene for "povray" ray-tracer. ) 
10)  file.n ¦ vid               (run file.n as shell script file: see below )
11)  nc -I file.n               (Runs nc as interpreter without simulator }
12)  ncv file.n                 ( same as "nc -I": no simulator }

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.

nc batch files

One problem when testing parameter space is how to remember what all the files are. 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 way no 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
#
#  Batch 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 -s nostim 1             file.n >& file4.r
nc -s nostim 1 -s ssize 5  file.n >& file5.r
nc -s nostim 1 -s 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  (to make into a .ps file)
Or you can analyze the ".r" files with another script, 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.


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 in the same location as the "nc" distribution. A binary distribution is available for Linux but the source code compiles on most Unix systems. 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 files are in ".tga" (targa) format by default. 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.doc" 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.

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 -ofile.tga +dx
The "+dx" tells povray to display the scene on the X11 display. You can also view the ".tga" file afterwards. When you have the correct scene and viewing position, render the scene with:
     povray -h800 -w800 -ifile.pov -ofile.tga +dx

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.

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 -ofile.tga +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 fruitful 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".

stim

To provide blur in a stimulus for NeuronC, run the command (program) "stim", which understands a NeuronC program and makes the stimulus for NeuronC. The "stim" command understands the same language as "nc", except that it does not run the model. Instead, "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":

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 -t file1 >file1.r                (uses "file.t" as stim file,)
                                          (creates "file1.r")

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" with the "-t" switch and NeuronC will make a numerical output file which consists of a list of time recordings:
     nc -t 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. 

     -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.

     -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.
Example:
               plotmod -p 2 -p 3 -p 4  file.r | vid
               plotmod -p 2-4  file.r | vid
draws 3 plots from the "file.r" recording data file generated by a previous nc simulation run.

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.

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 -t file1 | vid        (="neurc file1") 
               nc -t file2 | vid -v     (don't erase screen)
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)

textmod

This command changes the (VGA or EGA) video screen back to text mode. Command line switches are:
   -e     EGA driver.
   -h     Hercules driver. 
   -v     Change from text mode back to video
           (restore a previous picture)
"textmod" is normally run (aliased) to run as the command "t".

ibmflt and iplot, hpflt and hplot

You use "ibmflt" (or "hpflt") to convert the picture data coming from "nc" or "plotmod" into plotting data suitable for the color pen plotter. Iplot ("hplot") sends the data to the plotter through the serial port. Switches for "ibmflt" ("hpflt") are:
     -c        sort output by pen color (waits until the end to draw)
     -m n      use "n" as mag, default 1.0
     -p n      use following number as plotter pen number.
                This overrides any pens defined in the picture file
     -r        rotate picture sideways 90 deg
     -s n      use "n" as speed for plotter (cm/sec). 4 cm/sec default.
     -x n      use "n" as x offset (default 7500).
                This is the center of the picture, calibrated in
                thousandths of an inch.  One cm = 400 units.
     -y n      use "n" as y offset (default 5000).
                Calibrated as "x" above.
     -w        wait after using each pen, to allow paper to be changed.
     -z        save individual pen files after exit; use with "-c" above.
Ibmflt is normally used from a command file, which is set up to draw pictures of the correct size and centering for the paper used. The command "8by11" runs the plotter for the widely used 8" x 11" paper. For the HP 7221 plotter, the "8by11" command looks like:
        hpflt -x 4700 -y 4000 -m .8 $argv | hplot  ( = 8by11 )
To get "hard-copy" output, you can run "nc" like this:
     nc -v file1 | ibmflt | iplot
Or you can make a data file which can then be displayed or printed afterwards:
     nc -v file1 > file1.r         (create graphics file) 
     vid   fil1.r                  (graphics display on screen)
     8by11 file1.r                 (hard copy on plotter) 
 

posit

Posit allows you to set the position of subpictures in an illustration consisting of several picture files. Posit has the same command switches as "vid" and "hpflt", but it doesn't display the files; it merely puts them on the standard output or into output files of extension ".p".

Posit command line switches:

          -i        non-interrupt mode

          -f        make ".p" output files from input

          -m        Use following number as mag, default 1.0

          -p        Use following number as plotter pen number.
                    This overrides any pens defined in the picture file. 

          -x        Use following number as x offset (default 5000)
                    This is the center of the picture, calibrated in
                    thousandths of an inch. One cm = 400 units

          -y        Use following number as y offset (default 5000)
                    Calibrated as "-x" above.
Example 1:
          posit -f -x 1000 -y 7000 file1.h -x 4000 y -6000 file2
This creates file1.p and file2.p with (x,y) offsets from existing ".h" files which had already been hidden.

batch proccessing using nc, plotmod, hpflt, posit

These programs may all be run with their standard inputs redirected to files. You can also run them like "hpflt file" without the "<" symbol for the standard input redirection. Multiple input files are also allowed on the command line, as in "hpflt file1 file2". This allows batch processing of your files into one output file.

graph

Graph is described in the Ampex Plotting Package Manual. It is similar to the standard "graph" command that comes with most UNIX systems. It takes pairs of numbers separated by spaces from the standard input as the X and Y values of a graph. Successive points are connected by straight lines. You can display the graph by piping to either "vid" for the video screen or "hpflt" for the plotter. The maximum and minimum dimensions for the graph axes are normally determined automatically from the data on the input stream. There are many useful switch options for this program, described in the manual. Graph switch options:

   -c char             char is point label
   -C char             char is point label; no connecting lines 
   -f filename     "filename" is a file containing a list
                    of points; filename "-" means standard input;
                    maximum of 8 filenames allowed.
   -g num           num is grid style; 0-> solid grid; 1-> dotted grid;
                    2-> no grid but solid maxima; 3-> no grid(default)
   -l "label"       label for x axis
   -L "label"       label for y axis
   -m val           min for y axis
   -M val           max for y axis
   -p num           num is pen/dash style when doing multiple graphs 
      with the -f switch:
        0-> dashes only (default);
        1-> pen changes and dashes;
        2-> pen changes only
   -t num           num is the tic style of x-axis:
        0 -> many tics, few numbers (default);
        1 -> few tics,  few numbers;
        2 -> many tics, many numbers;
        3 -> few tics,  many numbers
   -T num           num is the tic style of y-axis:
        0 -> many tics, few numbers (default);
        1 -> few tics,  few numbers;
        2 -> many tics, many numbers;
        3 -> few tics,  many numbers;
   -o               make x axis logarighmic (bug in axis labeling)
   -O               make y axis logarighmic (bug in axis labeling)
   -v num           point label char size, 1=small, 7=large;
   -w num           x axis char size for label, 1=small, 7=large;
   -W num           y axis char size for label, 1=small, 7=large;
You can run graph interactively by typing "graph | vid" and then entering a set of points, one x,y point pair per line (x and y separated by spaces not commas), and a CTRL-D to stop entering data and display the graph. You can also make a text file with an editor and run "graph < file | vid" which causes graph to get its input from the file instead of the keyboard.

Using graph intelligently

If you want to draw several (up to 8) lines on a graph, you can use the "-f" switch to include several files as input data. Put a "-f" before each file like this:
          graph -f file1 -f file2 -f file3
and the first one will be a solid line, the second will be a dotted line, and the third will be a dashed line. If you want colors, use the "-p" switch.

If you want to have control over the scale of the plot (so that it isn't always drawn as a square which fills the page) you can use the "-m" and "-M" switches for the y-axis, and you can include some dummy extra points to extend the x-axis, one for each end.

For instance:

     0 0                 extends left side to 0
     data points
     10 0                extends right side to 10
You can use the "grp" comand to run graph automatically on several file names:
     grp file1 file2 file3 | vid
"grp" is a C-shell command file which contains something like:
#
set pen = 1

#set axis = 
set axis = "-T 3 -t 0"
set min =
#set min = "-m -.1"
set max =
#set max = "-M 1.2"

if ($#argv == 1) then
  graph -p $pen $axis $min $max -f $1

else if ($#argv == 2) then
  graph -p $pen $axis $min $max -f $1 -f $2

 ( and so on up to 8:  "-f 1  ...  -f $8" )
endif

labels

The "labels" command takes input from the standard input and draws lines and text on the standard output for use as a pipe to either "vid" or "hpflt". It uses commands identical to the "label" command in "mpict":

     ch x                     change char size to x.
     ci x                     make circle with radius x.
     erase                    erase screen.
     flag shape size          draw flag as in "filter" in mpict(5).  
     fo x                     change text font to x.
     fr name                  move to frame "name".
     include name             include file "name".
     move x [,] y             move pen to (x,y).
     draw x [,] y             draw to (x,y).
     line x1[,]y1[,]x2[,]y2   draw line segment from (x1,y1) to (x2,y2).
     o x                      make dashed line of type x.
     or x                     set origin of frame to (x,y).
     pen num                  change pen to "num".
     rd x [,] y               relative draw to (x,y).
     rm x [,] y               relative move to (x,y).
     rl x [,] y               relative line.
     ro x                     rotate x degrees.
     rt x                     rotate text x degrees.
     size x                   set size of picture to "x".
     text x [,] y "text"      write "text" starting at (x,y).
     u "text"                 write "text" at current position.
     q,x                      quit to shell  
All "labels" commands can be abbreviated to their first letter; for example, "m x y" means "move x,y". Commands having the same first letter need two letters.

Example:

           c .05 p 3 t .7 .9 /Right Side/
           move .7 .8 flag char E 12 move .4 .7 flag tri 4
           i elephant
This command sequence writes "Right Side" starting at location (0.7,0.9) with a character size of .05 using pen 3, then writes two flags, and then runs the file "elephant" which could have other label commands in it (e.g. it could draw an elephant).

The labels program normally draws lines inside the standard video screen, which is defined to have its lower left corner at the point (0,0) and its upper right corner at (1.0, 1.0). Anything outside this square viewing window is not displayed. You may redefine the size of the window using the "size" command by giving a factor with which to scale the standard screen. You may also create sub-pictures within the standard picture which can be rotated, translated and scaled with respect to the standard picture. Each sub-picture (frame) can have its own sub-pictures, much like the UNIX file system. You move from one frame to another by using the "frame" command (".." is parent frame, "/" is root).


Predefined variables

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   .15           over-relaxation constant (0 to 0.4)
double relincr .002          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  5.0415       current (latest) version number
double tempcel  6.3 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 

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

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

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.1           relative permeability of K  in Na channels
double dpcana    0.05          relative permeability of Ca in Na channels
double dpnak     0.03          relative permeability of Na in K channels
double dpcak     0.001         relative permeability of Ca in K channels
double dpnaca    0.001         relative permeability of Na in Ca channels
double dpkca     0.001         relative permeability of K  in Ca channels

Biophysical constants

double dcap    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=533)
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 200e-12 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 dcasurfp  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 dcapkm   .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 dnataud 0.16             default tau mult for Na noise in 2-state model
double dktaud  0.6              default tau mult for K  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       3              default Q10 for K activation    (an, 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 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      12e-12  S      default unitary cond of Na chans (= 22pS @ 22deg)
double dku       12e-12  S      default unitary cond of K chans
double dkcabu    5.7e-12 S      default unitary cond of BK chans 
double dkcasu    68e-12  S      default unitary cond of SK chans
double dcalu     7.6e-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

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.

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.  Bio-
Med. 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.

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.

Programming examples

 
 1) simulation of cable (tcomp2)
 
 /* variables with special meanings: */
 
 vidmode=1;               /* video mode turned on */ 
 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)
 
 vidmode=1;
 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;
 vidmode=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
 
 vidmode=1;
 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)
 
 vidmode=1;
 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)
 
 vidmode=1;
 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)
 
 vidmode=1;
 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)
 
 vidmode=1;
 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) 
 
 vidmode=1;
 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)
 
 vidmode=1;
 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 */
 
 vidmode=0;
 timinc = 2e-4;
 plmax = -.03;
 plmin = -.08;
 endexp = .05;
 
 dcap = 1e-6;
 drg=5e4;
 
 at 1 sphere dia 10;
 at 1 cap 2e-11;
 conn 1 to 2 gj 1;
 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)
 
 vidmode=1;
 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) 
 
 vidmode=1;
 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 */
 
 vidmode=1; 
 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 */
 
 vidmode=0;
 
 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 */
 
 vidmode=1;
 
 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)
 
 vidmode=0;
 
 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)
 
 vidmode=1;
 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 */
 
 vidmode=1;
 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

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 %{ #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 */