The Opihi shell language

Opihi is a generic command-line interpreter which has been used as the front-end for DVO, Pantasks, and other high-level programs provided by the IPP. These programs have been inherited from the CFHT Elixir project. The interpreter has a variety of features of shell-scripting languages: if statements, for loops, macros with command-line arguments, and so forth. The shell also allows for variables, arithmetic on variables, input from source files, and a variety of other useful tools. Opihi has a simple command-line interaction that resembles the UNIX tcsh, but with many additional useful features. It can also be used as a scripting language much like sh or perl.

Opihi includes tools to manipulate and display 1-D (vector) and 2-D (image) data. The image and graphics display tool is an external program called 'Kapa'. Various functions are available to perform math, statistical, and other operations on vectors and images.

User Interface

The command-line interaction is based on the readline libraries and behaves like tcsh. Arrows can be used for editing. There is both command and file completion with the TAB key. You can also use emacs-like commands such as ctrl-a to reach the beginning of the line and ctrl-e to reach the end. It is also possible to type just a fraction of a command, as long as it is unique. An ambiguous command will list the possible alternatives. For example:

 opihi: c
 ambiguous command: c ( catalog cgrid clear create cursor )

Multiple commands can generally be placed on one line with semi-colons as separators.

Data Representations

Simple Scalar Variables

Scalar variables in Opihi are prepended with a dollar sign ($). A variable may be created and the value assigned by a line which looks like:

 $var = (expression)

where (expression) is some math expression. The math expression may consist of the standard math operators (+,-,*,/) as well as any already-defined variables and the functions log(), ln(), sqrt(), exp(), ten() (10x), sin(), cos(), etc. Other special operators are the carret (^) for exponetiation (eg, 2^3 is 8) and the @ symbol as a binary arc-tangent (eg, 1@3 is 18.43 degrees). In addition, the operator << returns the minimum of the two surrounding values, and >> returns the maximum. Variables can be numeric or character strings. If the shell does not understand the syntax of the line as a math expression, it is assumed to be a string. local variables

If there is a pair of curly brackets {} anywhere on a command line, whatever is inside is assumed to be a math expression and evaluated before the line is executed. This later feature allows functions of variables to be passed as arguments to Opihi functions. (see also the discussion below about temporary vectors and images). For example:

 echo {$fred*dcos(45)}

would give the response 7.07107 if $fred had the value of 10.0. There are math functions cos, sin, and tan, which operate on radian expressions, and also dcos, dsin, dtan, which operate on degree expressions. There are also the equivalent inverse functions: eg., asin and dasin return radians and degrees, respectively. The help section on Math defines all of the available math functions.

Vectors

The Opihi language supports 1D numerical vectors as a native data type. Vector names are not prepended with an special characters (ie, no dollar sign unlike for scalars). There are a few rules governing valid vector names: they may not start with a number (why not?); they may only use the following characters: letters, numbers (expect the first), underscore, (NOTE: finish this list and validate).

NOTE: as of 2009.01.17, the Opihi parser allows the creation of vectors with invalid characters such as "-" (the minus sign!). Be careful until this bug is fixed.

Vector Manipulation Functions

 create                    -- create a new vector
 hist                      -- create histogram from a vector
 print                     -- write vectors to file
 vectors                   -- list vectors
 accum                     -- accumulate vector values in another vector
 applyfit                  -- apply fit to new vector
 applyfit2d                -- apply 2-d fit to new vector
 circstats                 -- circular statistics
 concat                    -- reduce vector dimension
 datafile                  -- define file to read vectors
 delete                    -- delete vectors or matrices
 fft1d                     -- fft on the pixel-stream in an image
 fit                       -- fit polynomial to vector pair
 gaussdev                  -- generate a gaussian deviate vector
 gaussint                  -- return the integrated gaussian vector
 histogram                 -- generate histogram from vector
 integrate                 -- integrate a vector
 interpolate               -- interpolate between vector pairs
 vectors                   -- list vectors
 medacc                    -- accumulate vector values in another vector
 peak                      -- find vector peak in range
 read                      -- read vectors from datafile
 set                       -- image and vector math
 sort                      -- sort list of vectors
 subset                    -- expand vector dimension
 uniq                      -- create a uniq vector subset from a vector
 vbin                      -- bin values in a vector to be within a range
 vclip                     -- clip values in a vector to be within a range
 select                    -- selective vector assignment
 vgauss         
 vgrid          
 vload                     -- load vectors on Kii
 vstat                     -- get info from imreg database
 vsmooth                   -- gaussian smooth of a vector
 vroll                     -- roll vector elements
 vpop                      -- remove first element
 write                     -- write vectors to datafile
 

Images

Lists

Opihi lists are grouped sets of scalar variables (which may be strings). A list consists of N variables with names of the form name:i, where the value of i ranges from 0 to N-1. In addition, the list length is defined as the value name:n. Since these are just informally grouped, a list may be defined by hand (ie, by defining each element and the length). There is also the command list which builds a list from the following lines until reaching a line consisting of the single word end:

 list sample
  value 0
  value 1
  test line
 end

will define the variables $sample:0 - $sample:2, and $sample:n, with value of 3.

The list command may also construct a list from the output of a UNIX command:

 list sample -x "ls /tmp"

will result in a list consisting of one entry for each file in the listing.

The list command may also be used to split a string by whitespace:

 list sample -split this is a test

will result in a list with 4 elements, one for each word.

Queues

 queuelist                 -- list existing queues
 queuesize                 -- return the length of the given queue
 queueinit                 -- create a zero-length queues
 queuedelete               -- delete a queues
 queuepush                 -- add an item to the end of the queue
 queuepop                  -- remove and return the first item in the queue

A queue is a data construct consisting of a sequence of lines from which simple selections can be made. Data items are added and removed from the queue with queuepush and queuepop commands which push entries on the end of the queue and pop them off the beginning. The available queues may be obtained with the command queuelist, and the length of a specific queue may be determined with the queuesize command. The contents of a queue may be printed with queueprint. Pushing data onto a non-existent queue will create the queue. An empty queue may be created with the command queueinit and a queue may be deleted with queuedelete.

The queuepush commands allows for additional options which modify how the data is pushed on the queue. The -uniq flag specifies that the queue should be search for an existing match and not add the new data item if a matching item already exists. The -replace flag is similar to the -uniq flag, but instead the new item will replace the existing match, if a match is found. These two options have identical results if the match is made based on the entire line. However, they may be more usefully distinguished by specifying a restriction on the match with the -key flag. This flag specified which whitespace-separated element of the line to use for the match, with the first element being element 0.

Numerical vectors and images (matrices) are discussed later in this document.

Opihi Shell Programming and Flow-control

 input                     -- read command lines from a file 
 macro                     -- deal with the macros 
 for                       -- for loop 
 if                        -- logical cases 
 while                     -- while loop
 break                     -- escape from function 
 continue                  -- next loop iteration

There are several options for programming in the opihi shell. First, a file which contains a series of commands can be executed with input (filename). When an opihi-based program (e.g. dvo) is started, it loads a file from the user's home directory, with a name of the form ~/.programrc (e.g. ~/.dvorc). This resource file may contain any commands, and allows a user to customize his or her environment.

It is also possible to define macros which will behave much like regular commands. A macro is defined by typing macro name or macro create name followed by the commands. Arguments to the macro are assigned to the variables $1 .. $N and the number of arguments is given by $0. Macros may be defined in input files. The following is a sample macro:

 macro test
  echo "this is a macro"
  echo "number of arguments $0"
  echo "first argument $1"
  if ($1 = 10) 
    echo first argument is 10
  end
 end

Flow Control

Opihi has several types of flow-control features. These include for-loops, while-loops, if-else blocks. These blocks are defined by the corresponding command (for, while, if) and are terminated with by a line with the single word end.

For loops

The for-loop syntax is simplistic. The for command specifies the loop variable, the starting value, the ending value, and optionally the delta for each loop. The implicit loop test is always to check if the loop variable is still less than the end value (or greater than if the delta value is negative). The definitions of this loop syntax and the value of the list length ($list:n) and the vector length (vector[]) make for natural loops over all elements of a list or vector. Below are a few examples:

 for i 1 10 0.1
  echo $i
 end

This runs the loop with the variable $i running from 1.0, 1.1, up to 9.9 (inclusive).

 for i 0 $list:n
  echo $list:$i
 end

This would print all the elements of the list.

 for i 0 vector[]
  echo vector[$i]
 end 

This would print all the elements of the vector.

While loops

The while loop begins with a line of the form while (condition) and ends with a single end. The conditions follow the same rules as the if conditional statements. continue, break, auto-break concepts

If blocks

The if-block begins with a line of the form: if (condition) and ends with a single end. A line with a single else specifies the optional else portion of the block. The conditional expression is a valid math inequality with approximately C-syntax:

 (($i < 10) && ($i > 4))

The elements of the inequality may also be string comparisons. The only valid string comparisons are == and !=.

Other Flow Control

Additional control commands: return (from within a macro), break, continue, last (yes?)

Miscellaneous Commands

 !                         -- system call
 ?                         -- list commands 
 ??                        -- list variables 
 echo                      -- type this line 
 exec                      -- system call
 exit                      -- exit program 
 help                      -- get help on a function 
 config                    -- reload configuration information
 exit                      -- exit program 
 quit                      -- exit program 
 wait                      -- wait until return is typed
 sleep                     -- sleep for N seconds
 usleep                    -- sleep for N microseconds
 which                     -- show command 
 cd                        -- change current working directory
 pwd                       -- report current working directory
 date                      -- return the current date
 file                      -- test file existence
 memory                    -- long listing of the allocated memory
 version                   -- list version information

Most of these commands should be clear from the simple descriptions above, or from the online help. The command ?? prints the system variables. The help command will provide help on a single command or, without any arguments, will list all available help files (this includes general help not associated with a specific command).

String Manipulation and other data commands

 local                     -- define local variables
 output                    -- redirect output to file
 scan                      -- scan line from keyboard or file to variable 
 sprintf                   -- formatted print to a variable
 fprintf                   -- formatted print to standard output
 getchr                    -- find character in string
 strlen                    -- string length
 substr                    -- substring

These commands provide a few tools to manipulate data in opihi variables. The local/ command specifies that the given variable is local to its macro. The output/ command changes the default output destination for functions which print results to the screen. This function does not zero the file length; new output is appended to the file. The command scan/ reads specific lines from a file, an optionally places them in an opihi variable (EOF is returned at the end of a file). The group of commands getchr/, strlen/, and substr/ provide the ability to manipulate the elements of a string. Finally, sprintf/ and fprintf/ perform formatted output to a variable and to the screen, respectively.

Math, Graphing and the Kapa Display

 box                       -- draw a box on the plot
 clear                     -- erase plot
 cursor                    -- get coords from cursor
 grid                      -- plot cartesian grid
 labels                    -- define labels for plot
 limits                    -- define plot limits
 plot                      -- plot a pair of vectors
 ps                        -- define labels for plot
 style                     -- set the style for graph plots
 zplot                     -- plot scaled points 
 device                    -- set / get current graphics device
 jpeg                      -- write text line on graph
 line                      -- plot line
 dot                       -- plot a single point
 resize                    -- set graphics/image window size
 section                   -- define section of graph
 textline                  -- write text line on graph
 zplot                     -- plot x y with size scaled by z

Math and Statistical Functions

Opihi has a variety of commands to manipulate 1-D data (vectors). Vectors can be loaded from a data file or created with uniform spacing. New vectors can be defined as the arithmetical combinations of other vectors. For example, we could create a sine wave with the following two lines:

A vector can be created based on a number sequence with the command create name Nelements start delta. The resulting vector has Nelements/ entries, starting at a value of start/ and running until start + delta*Nelements/. If delta/ is 0.0, all elements will have the value of start/. A histogram of a vector may be made with the command hist, which creates a new vector containing the histogram of the first vector. The data range and bin size of the histogram are defined in same way as with create. This makes it easy to create the index vector that goes with a histogram vector:

 hist y Ny 1 100 0.1
 create dx 1 100 0.1

The above will create a histogram of y in Ny and the index in dx. Plotting this with plot dx Ny will show the histogram.

Vector math is performed with a command of the form set new = (expression). The expression is some math function employing vectors and scalars. A complete listing of the math operators available in set can be found in the help for set.

Plotting

Once vectors are defined, they may be plotted. A pair of vectors can be plotted against each other if they have the same number of entries. The plotting is performed on the graphics window, Kapa. There are actually several graphics windows available to status, any of which may be used to plot at any time. Some of the more complex operations default to either graphics window 0 or 1, depending on the context. Except for those functions with a pre-defined window, all plotting functions apply to the current graphics window unless an option -n N is given to specify a different window.

The plotting style is determined by the command style which can set the line width, the line type (solid, dashed, dotted, etc), the point type (box, cross, etc), the point size, the color, and whether a pair of vectors is plotted as a sequence of points, a set of connected lines, or a histogram. Some functions which make plots use their own styles, as discussed below. The function limits lets the user set the range of the plot axes, or check the current setting.

  • The command plot will plot a pair of vectors on the current graphics window using the current plotting style for that window.
  • The command zplot will plot a pair of vectors with the point size scaled by a third vector, with maximum and minimum point sizes representing specified values.
  • The cursor command goes the other way: this command puts the Kapa window in cursor mode and waits for input from Kapa. The user can then type any alphanumeric key on the graphics windows and will be told both the pointer location (in the graphics coordinates) and will have the coordinates stored in status variables. For example, by typing 1 in the sky display window, the RA and DEC of the pointer are stored in the variables $R1 and $D1. This command can be used to let the user define locations or regions of interest on the Kapa window. (Future addition: button, which does the same with the mouse buttons).
 create x 1 20 0.01
 set y = sin(x)

We can plot this pair of vectors on the Kapa graphing window:

 limit x y
 plot x y
 box

The Kapa window has a variety of style options to change the plotting type (line, histogram, point), point type, line color, weight and style, and the errorbar style (if errorbars are plotted).

2D Data and the Image Displays

Opihi has many commands to manipulate 2-D data (images). Images can be loaded from FITS files and mathematical operations applied to them. Various other operations, such as rebinning, shifting, rotating, and so forth are also available. Images can be displayed using the Kii image window. In an 8-bit visual, the image window has a dynamic colormap to allow the user to change the relationship between pixel value and the displayed color.

  • There are three colormaps which can be selected by pressing the middle three buttons on the bottom row. The PS button produces a PostScript? file from the image.
  • The user can change the magnification and the position of the image with the mouse (left - recenter at cursor; middle - zoom out; right - zoom in).
  • There are four color overlays which the user can draw objects of different shapes (circles, boxes, lines) or draw a contour. The four buttons labeled R, G, B, Y turn on or off the display of the red, green, blue, and yellow overlays.

Image Manipulation Functions

 clip                      -- clip values in a buffer to be within a range
 contour                   -- create contour from image
 cut                       -- extract a cut across an image
 extract                   -- extract a portion of a buffer into another buffer
 fft2d                     -- fft on an image
 fit2d                     -- fit 2-d polynomial to vector triplet
 header                    -- print buffer header
 imcut                     -- linear image cut between arbitrary coords
 imhist                    -- histogram of an image region
 imsmooth                  -- circular gaussian smoothing
 kern                      -- convolve with 3x3 kernel
 keyword                   -- extract a FITS keyword from buffer header
 buffers                   -- list the currently allocated buffers
 mcreate                   -- create a matrix
 minterp                   -- interpolate image pixels
 rd                        -- load fits image
 rdseg                     -- read a segment of an image from a file
 rebin                     -- rebin data by factor of N
 roll                      -- roll image to new start point
 rotate                    -- rotate image
 set                       -- image and vector math
 shift                     -- shift data in an image
 spline.apply              -- apply spline fit to generate an image
 spline.const              -- create spline 2nd deriv. terms
 stats                     -- give statistics on a portion of a buffer
 subraster                 -- subraster of fits image
 unsign                    -- toggle the UNSIGN status
 wd                        -- write an image to a file
 zap                       -- delete pixels

Image Display Functions

 ps                        -- define labels for plot
 center                    -- center image on coords
 device                    -- set / get current graphics device
 erase                     -- erase objects on an overlay
 jpeg                      -- write text line on graph
 load                      -- load an SAOimage style overlay
 point                     -- load overlay with single point
 save                      -- save an SAOimage style overlay
 resize                    -- set graphics/image window size
 tv                        -- display an image on the Kii window
 tvcontour                 -- send contour to overlay
 tvgrid                    -- wait until return is typed

Other data functions

 gaussj                    -- solve Ax = B (N-D)
 gridify                   -- convert vector triplet to buffer
 ungridify                 -- convert buffer region to vector triplet
 dimendown                 -- convert matrix to vector
 dimenup                   -- convert vector to matrix
 mget                      -- extract a vector from a matrix
 mset                      -- insert a vector in a matrix
 svd                       -- singular value decomposition of a matrix
 swapbytes                 -- byte swap thing

Programming Considerations

The programming structure of the Opihi front-end makes it very easy to add commands to the package.