Writing NIRC2 Scripts

1. Introduction

The software for NIRC2 is for the most part a command-line interface (CLI). Commands are wrappers for keywords (described below), and the facility scripts provide for basic functionality of the instrument, and some level of interaction with the telescope and AO systems. The CLI is designed to allow relatively easy creation of user scripts, to accomodate observers' unforeseen needs.

2. Show, modify, xshow, and tshow

Keywords are essentially external hooks into the functionality of the instrument software, the latter generally written in C. At the very basic level, there are three commands that allow access to keywords. Show will return a keyword value, modify will change it, and xshow will monitor it. Tshow is a graphical version of xshow, plotting the changes in keyword value as a function of time.

Some examples will show how these commands are used:

show -s nirc2 camera Shows the current value of the CAMERA keyword. The "-s nirc2" specifies the "service" name, or the keyword library in which the requested keyword exists. In this case the service name is nirc2, which is where the CAMERA keyword lives.
modify -s alad itime=10 Sets the current value of the ITIME keyword to 10. In thijs case the keyword lives in the alad keyword library.
xshow -s nirc2 camera filter slitname Creates a text "GUI" with three entries for the CAMERA, FILTER, and SLITNAME keywords (all in the nirc2 keyword library).
tshow -s dcs raoff Produces a graphical display showing the value of the DCS keyword RAOFF.
show -s nirc2 -terse camera Returns only the camera name, rather than "camera = " followed by the camera name. This is a useful form in scripts, so that you don't have to extract the value from the line returned by a "show" command without "-terse".

 

There are other options with these commands, especially xshow. We will not go into detail on these; see documentation elsewhere.

Note that in NIRC2 there are three separate keyword libraries for the instrument: alad, nirc2, and pmr. The alad keywords handle interaction with the detector, including setting detector parameters and taking images. The nirc2 keywords handle communications with the motors and temperature sensors. The pmr keywords interact with the pupil rotator.

Three other keyword libraries are important: the dcs keywords control telescope functions, acs keywords control the primary mirror, and ao keywords control functions within adaptive optics.

3. Observer scripts

3.1 The list of commands

As mentioned, the simplest user script is a file containing a list of commands that the user would normally type on the command line. For instance

filt k
tint 10
goi
filt h
tint 8
goi

will insert the K filter, change the integration time to 10 seconds, and take an exposure. It then changes to the H filter, changes the integration time to 8 seconds, and takes a second exposure. This is the exact sequence of commands that the user would have entered on the command line to do the same functions. Note that this script does not have an initial "#!/bin/csh -f" line. It will run in whatever shell is currently being run by the user (usually tcsh). It is often best to explicitly define the shell in the first line, however, in case you have changed your environment in some way that will cause your script to fail.

More complex scripts may include looping, decision-making, and branching, logging to a file, and so on. Users are also encouraged to include comment lines in their code, and even syntax checking using syncheck. See the facility scripts section for examples of how to do this.

3.2 Accessing your scripts

Users should keep their scripts in their own subdirectory within ~nirc2/vis. Get to this directory using "cd ~nirc2/vis", use "mkdir" to create a subdirectory with your name or initials, and "cd" into that subdirectory. You should be able to edit your script in that directory. Note that you will have a numbered account assigned to you when you come to observe, and the files you create will be owned by that account. When you return for a second NIRC2 run you may have a different numbered account assigned. However the files you create should still be editable as the new user. If not, you can log in as your old user name, cd to the appropriate subdirectory, and type "chmod a+rwx *" to give read, write, and execute permissions to all other users. Then exit as that old user and you should now be able to edit your files.

To add your personal scripts to the default path and make them easily accessible, type "user xxx" where xxx is your subdirectory name. This will add "~nirc2/vis/xxx" to the PATH environment variable, and does a UNIX "rehash" command to make sure they are visible. Note that if you type in a directory that does not exist, the script will ask whether you want to create it. Make sure you have not made a typo; otherwise feel free to create your directory initially using this technique. If you ever want to remove your subdirectory from the PATH, type "user -d xxx" where again xxx is your subdirectory name.

If you add new scripts you may need to type "rehash" in your command window. This tells UNIX to search its PATH again for executables; otherwise it uses a cached list from either the last rehash command, the last "user" command, or the point at which you created the command window.

3.3 Scripting tips

You can script in any language you want, but the csh shell is powerful, and you have many examples of scripts in the facility scripts. Some tips for writing in the csh shell are provided in the following, but you may also want to keep a UNIX or csh manual handy for detailed questions.

Following the generic help block comes the functional part of the code. In general variables used in the script are set near the top. Usually there is an if block that checks for the correct number of parameters. Often the number of parameters can be variable, with missing parameters set to some default value. Also, in general if the command sets a single parameter, or sometimes a number of parameters, if the command is typed with no arguments the current settings of those parameters is printed. Hence typing ``tint 1'' will set the exposure time to 1 second, while typing ``tint'' will return the current value. Typing ``offset 3000 3200 3120 3030'' will set the four offsets for the four quadrants of the detector, while ``offsets'' with no arguments returns the current values.

Math

Math in the shell is painful. To make it somewhat easier, a command called ``math'' has been written as a wrapper around the ``bc'' math command. ``bc'' does floating point math, although often if integers are used as arguments, integers are returned. For purely integer arithmetic, ``expr'' can be used.

The ``math'' command replaces all ``x'' characters with ``*'', which means multiplication to the ``bc'' command. This allows the use of constructs like ``math 2 x 3'' to be used for multiplication, rather than ``echo 2 \* 3 | bc''. Note that in the latter representation the asterisk must be escaped as it is a special shell character.

Other special shell characters can be problematic, but many of these (including ``*'') can be protected by placing double quotes, "", around the expression. Hence

math "(2*7 + 3 x 4)/0.123"

will protect both the asterisk and the parantheses, which are special shell characters. Note that the spacing around charecters is relatively arbitrary.

Of course, variables can be passed by reference as well:

math $deltaX x 3

will return three times the variable deltaX.

Taking negative numbers is straightforward:

math - $deltaX

will return the opposite of deltaX.

Transcendental functions are also possible. See the man page on ``bc'' for details.

Image math

Generally the facility scripts use IDL to perform array manipulation. Arguments are passed through environment variables, including file names. The IDL scripts which are called then use ``getenv'' to read these parameters.

See one of the scripts in $FAC_SCRIPTS/pro for an example.

Repetitive tasks

Doing repetitive tasks, such as looping through a dither script or running through a list of parameters, usually involves setting up a list variable. This list can be contained within a foreach command:

foreach keyword ("object" "observer" "itime" "coadds")

or within a variable:

set list = ("object" "observer" "itime" "coadds")

In the latter case items can be easily appended to the list:

set list = ($list "frameno" "camname" "filter")

and the list can be used in a foreach statement:

foreach key ($list)

Dither scripts, in particular, use a repetition of move and ``goi'' commands. The facility scripts usually set a single parameter to be the step size, in arcsec. Then a list containing multipliers for the step size determines the positions on the sky for each dither.

set dX = $1
set dY = $2
set xoff = ( 1 -2  0  2  -1)
set yoff = (-1  0  2  0  -1)
foreach i (1 2 3 4 5)
    echo ""
    echo Position $i of 5...
    goi
    xy `math $xoff[$i] x $dX` `math $yoff[$i] x $dY`
end

Interrupt control

Sometimes you need to protect something against a premature end of the script by a Ctrl-C. Use the ``onintr'' command for this. ``onintr label'' sends the script to the specified label if a Ctrl-C is typed any time after the onintr statement. Following this label is generally some type of cleanup operation: returning the telescope to the starting point of a dither pattern, resetting keywords that have been changed by the script and must be changed back before the script exits, etc. Sometimes the script during normal execution will fall through this same code, and sometimes it will exit before it gets to the label.

Note that if you Ctrl-C in a script called by a higher-level script, the low-level one will trap it, respond if necessary, then send that Ctrl-C back up to the higher level script. So if you write a user script that calls the "goi" script to take images, if you Ctrl-C during an exposure the goi script will ask whether you want to abort the current exposure or not. Then once the goi script has completed, it will pass the Ctrl-C up to your script. If your script does not have a Ctrl-C trap in it, it will continue executing the next line of the script.Otherwise it will branch to the label defined in your "onintr label" command.

Typically you would set the interrupt control before changing anything that needs to be changed back, be it telescope position or keyword values.

One important tip; it is generally easiest in the shell to build up commands by starting with the core of a command and adding filters and other bells and whistles one by one, testing that you get the desired output at each step. For example, if I wanted to find the size of the most recent image taken in the current directory, I would start with the command "ls -l". Then I might add the flags that tell the command to order the output by time: ls -lt. Next add the commands to only keep the second line: ls -lt | head -2 | tail -1. Add the command to pull out the size from that line: ls -lt | head -2 | tail -1 | awk '{print $4}'. And so on.

4. Facility scripts

Provided as the main user interface is a set of scripts, predominantly csh shell scripts, that are another layer on top of the keywords. They range from scripts that control one keyword, to complex scripts that control much higher level functions like setting up for spectroscopy. Scripts which require image math call IDL to do the array arithmetic.

4.1 Script outline

For a shell script it is good practice to specify the shell or other program that is meant to run the script. This is done in the very first line, which starts with a "#" sign, a "!" sign, and then the path to the shell or program, plus any options. For the facility scripts, which are predominantly designed for the csh shell, the first line looks like:

#!/bin/csh -f

The "-f" option simply tells the csh shell not to rerun the user's .cshrc file, and speeds up the script somewhat.

It is useful to document your script, so that you will understand what it is used for when you come back to observe later on. We suggest that you insert a header which contains a description of the program's usage and functionality. For example:

#+
#
# camera [text]
#
# sets the camera to "text". If no argument is specified, the current camera is returned.
#
#-

The "#" sign is used as the first character of each line so that the shell does not try to interpret this header as shell commands. The first line of this block is normally "#+", which is used by the "help" command to define the comments which should be printed out by "help command"."#-" defines the end of this help block. If the help command does not see a "#+" line, it will print out all comment lines contained in the script.

Next follows a line containing the command and its arguments. Square brackets usually mean optional arguments; in this example you do not need to specify a camera name. After the usage line follows a description of the command and its options. Finally comes the "#-" line signalling an end to the help block.

In most facility scripts there follows some boiler plate to allow "command -h" to invoke the "help command" script. So typing "camera -h" has the same effect as typing "help camera", namely to print out the initial help block of comments.

Next follows some boiler plate that uses the "syncheck" syntax checker. The syncheck call is of the form:

set CheckStatus = `syncheck -command $0 $* -pattern {text}`

The "-command $0 $*" part passes the command typed by the user. This gets compared to the pattern, which will vary from script to script. In the example shown the script expects either no arguments or a single optional text argument. The curly brackets around "text" in the syncheck line tell syncheck that the text is optional. If syncheck detects a syntax error it will print out what it thinks is wrong, plus the pattern it expects to find. The boiler plate in the script generates a "help command" to aid the user in understanding what was typed incorrectly. Syncheck is described in more detail in Appendix B.

Note that the boiler plate for the "command -h" and syncheck is located in a file /kroot/kss/nirc2/scripts/info/help.inc. The "command -h" boiler plate is generic and shouldn't need to be changed. The syncheck boiler plate allows for any number or types of arguments to be passed, making it transparent to any script in which it is pasted. However, to make use of the syntax checking you will want to define the "pattern" that the script requires.

After the initial comment lines and boiler plate lies the body of the script, containing shell commands, other NIRC2 scripts, calls to IDL, or any of a variety of other commands.


Go To:
Instruments Home Page       Keck Home Page       Observer's Reference Shelf


NIRC2 Master
2 April 2001