next up gif contents index
Next: Nographics mode Up: History / Command Files Previous: History / Command Files


Flow Control in Command Files

The recored above all may be generated by spock via interactive sessions, and thus may be found in automatically generated history files. The following records, however, are not generated by spock. These records allow for more flexibility in spock command files, and, in fact, make spock's command language into a Turing-complete programming language.  

Conditionals -- if..then/else/endif

Sections of command files may be executed conditionally, using the if...then, else and endif constructs. Instead of a separate record type for these commands, they are used in conjunction with TEXT> records. The format of the commands is:

	TEXT> if (expression) then
	TEXT>  !any number of commands may be here
	TEXT> else
	TEXT>  !any number of commands may be here
	TEXT> endif

If the expression evaluates to true, of course, only the first set of instructions is carried out. If it's false, the second set is carried out. Expressions are passed to the command-line calculator for evaluation, so any expressions that are valid for the calculator are valid for these comparisons. Strings comparisons may also used, and the value of environment variables may be tested. The presence or absence of quotation marks determines of values are compared as strings or not. Note that the type of variables must match--it doesn't make sense to compare a string to a number. Examples are given below:

Note that expressions mostly use the C programming language syntax. In particular, equality is tested with a double equals sign "==". Logical ``and'' and ``or'' operations are performed with "&\&" and "||" respectively. Other valid comparators are >=, <=, <, > and <> for not equals. (Since spock treats exclamation points as beginning a comment the standard != can not be used to test for inequality. Expressions may be combined and grouped with parenthesis; otherwise the order of evaluation follows C conventions.  

Loops -- LOOP/ENDL

Loops may be introduced into a command file using the records LOOP> and ENDL. The LOOP> record should be followed by a variable name and a count specifier (e.g. LOOP> i=10). The commands between this and the corresponding ENDL> i command will be executed (in this case) 10 times. The loop index variable is treated as an environment variable, and commands with in the loop may access the its value just like any other environment variable. For example, a command within the loop defined above of TEXT> list,an=$i will list the first 10 atoms. Loop indices are also available from within math mode (§ 5.5), so that math expressions within the loop may access its value. For example, within the loop defined above a command TEXT> list,an=#i will list the first 10 atoms, or TEXT> #j=i*2 will set j to twice the loop index.

Note that loop index variables are limited to 6 characters, and are case sensitive. Loops may be nested up to 25 deep. Loop counting starts with 1.

This example demonstrates saving a series of images at a slightly different rotation using the LOOP record. This script may be used to make animated gifs for including on web pages, similar to the one on the spock homepage.      

!set for GIF output
TEXT> menu
MENU> File
MENU> Save
MENU> Image file
TEXT> menu
MENU> Image Options
MENU> RGB/Iris{0}
TEXT> menu
MENU> Image Options
FILE> cancel

!do the loop, saving the image each time
LOOP> i=10
TEXT> yr=10
TEXT> menu
TEXT> File
TEXT> Save
TEXT> Image file
FILE> test0$i.gif

Subroutines -- SUB/ENDS/CALL

Command files can also have subroutines, delimited by the records SUB> name and ENDS> name. Much like macro definitions, commands in subroutines definitions are not processed when the file is read, but only when a CALL> name record is read. Subroutines may be nested up to 50 deep. Subroutine definitions are only valid in a single file, that is, you can't call a subroutine from a previously read file. If you need to do that, you'd be better off putting the subroutine in a different file and reading that file with TEXT> read=filename.sp.

Even though you can use GOTO> (below) to jump out of a subroutine, it is a BadIdea (tm), as the interpreter maintains a stack of subroutine addresses, etc. If you want to jump out of a subroutine, place a TAG> right before the ENDS> for the subroutine and GOTO> that tag. You could even set a variable to indicate an error condition, but remember all variables have global scope, so be careful that you don't overwrite something you didn't intend.

This example demonstrates using subroutines to switch between two different formats for the list file.

!define a subroutine for setting the data to a b-factor format
SUB>  b_factor_format
TEXT> set list format
LINE> atom %d b_factor %.3f sa %.3f
LINE> an,ap2,sa
ENDS> b_factor_format

!define a subroutine for a long data format
SUB>  long_format
TEXT> set list format
LINE> #%.4s\t%3.1f\t%.14s\t%7.3f\t%.14s\t%7.3f\t%7.3f\t%7.3f\t%5d\t%.65s
LINE> pdbid,resolution,id,d,dpid,sa,ap1,ap2,an,compound
ENDS> long_format

!execution begins here
CALL> b_factor_format ! sets format to b_factor
TEXT> list,rn=(1,10)
CALL> long_format
TEXT> list,rn=(1,10)

Branches -- TAG/GOTO

Control may be transfered to a specific point in a file by using the GOTO> name record. Control may only branch to points labeled with a TAG> name record. Note that, like subroutines, TAGS> are only defined for a given file.

This example demonstrates using TAG and GOTO to branch out of a subroutine correctly, and uses of variable list formats and list commands (§5.2.2).

First, a gnuplot command file which will read in a .spocklist list file and plot the first two columns in a scatter plot.

set term x11
plot ".spocklist" using 1:2 with points
pause -1

Now here's the spock command file. This will set the list command and list format appropriately. This command file expects the user to have set the variable $DISPLAY if it's running in an interactive session.

SUB>  plot_if_display_set
! Check DISPLAY and exit if not set.  Note that this could also be
! accomplished by an if...then/else/endif construct, but the point is to
! demonstrate GOTO/TAG

TEXT> if "$DISPLAY"=="" then
TEXT> endif

! set the list format to output only the x and y coordinates of the data.
TEXT> set list format
LINE> %f %f
LINE> x,y
! set the list command to run gnuplot if there selected atoms
TEXT> set list command
LINE> gnuplot
ENDS> plot_if_display_set

!execution begins here
TEXT> fetch=1rnt.pdb
TEXT> set $SELECTION=rn=(1,10)
CALL> plot_if_display_set

Execution control -- WAIT/STOP/pause

These commands allow for a greater degree of control over the execution of history files. The WAIT> n record pauses execution for n seconds. The STOP> record stops execution of all command files. There is no way to stop reading just the current file and resume reading the previous file in the case of nested history files. STOP> should be used in the case of a fatal error in a history file. Finally, the TEXT> pause command may be issued which will suspend playback of a history file until the user types resume on the command line. This could be used to allow the user either to simply explore the current state, or to set up some variables or other state that's necessary for later execution. The user should not read any other history files in the paused state--the ability to safely nest paused history files would needlessly complicate the implementation of spock.  

next up gif contents index
Next: Nographics mode Up: History / Command Files Previous: History / Command Files

Jon Christopher
Tue Sep 14 16:44:48 CDT 1999