IRAF Mini-Tutorial
IRAF is the Image Reduction and Analysis Facility, a general purpose software system for the reduction and analysis of astronomical data. The core IRAF distribution includes a good selection of tasks for general image processing and graphics plus a large number of programs for the reduction and analysis of O/IR data in the "noao" package. The bulk of IRAF software in the community is in the form of individual tasks written by users and small to rather large external packages developed by groups outside of NOAO which handle data from other observatories (e.g. HST) and wavelength regimes (EUVE for extreme ultra-violet or ROSAT/AXAF for X-ray). These external packages are distributed separately from the main IRAF distribution but can be easily installed.
Why Use IRAF for VO Applications Development?
The IRAF system includes a complete programming environment for scientific applications, which includes a programmable Command Language (CL) scripting facility, a Fortran/C programming interface, and the full SPP/VOS programming environment in which the portable IRAF system and all applications are written. A complete description of these programming interfaces is not possible in a mini-tutorial such as this and so we will focus on the scripting capabilities of the system, and the many available tasks, for creating science applications.
Script tasks may also make use of host commands through the 'foreign' command interface, making it possible to develop CL script applications that mix IRAF analysis tasks with non-IRAF tasks in any variety of languages to access data and services from VO providers. On the server-side, tasks may be trivially turned into web-services via a simple configuration file using a system currently in development. The GALCAS/GALMORPH services used to support the science theme demonstrate both of these capabilities.
Installing and Starting IRAF
The NVOSS software distribution contains a setup script that will do a network-based install of IRAF on Mac OS X and Linux systems. This includes the core system plus several external packages (STSDAS/TABLES) and support software (i.e. DS9 display server and XGterm graphics terminal) used in the following examples.
Installing IRAF requires root permissions due to links made into the system by the installer, but it is as simple as
# cd /some_dir/
# $NVOSS_HOME/iraf/iraf_setup.csh
where some_dir is the directory on your machine where you will install the IRAF software tree. The setup script may also be executed with the 'sudo' command instead of logging in as the root user (most Mac OS X users will need this option).
Once the system is installed you can login using the commands:
% mkiraf # Create the login.cl
% ecl # Start IRAF
The MKIRAF command is needed only the first time you start IRAF, it creates a "login.cl" file defining the system environment and a "uparm" directory to used to store modified task parameters. You should always login from a directory containing a 'login.cl' file, or else issue a new MKIRAF to create one. You should not copy the login.cl file created to other directories as environment variables in this file are path-relative. You can create a loginuser.cl file in the same directory to hold personal definitions or package loading, just be sure the last line in the file is keep.
The ECL is an enhanced CL for IRAF having error-handling and other new, tcsh/bash-like, features. To use the traditional CL, log into the system using the 'cl' command instead. Students on Windows machines who wish to use IRAF will be provided with an account on an NOAO system for use during the Summer School.
Navigating Around the System
| Help/Context Commands | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Upon logging into the system you'll see the standard system
banner and a menu of currently loaded packages. To load a new package
simply type its name. Tasks are likewise executed but may contain
additional arguments on the command-line to specify the parameters,
required "query" parameters will be prompted for by the system
(see below for an explanation of the parameter system) if not specified.
The phelp command will paginate output and like help takes
as an argument the name of a task or package (in which case a one-line
description of all tasks in that package is returned). The references
task takes a string argument and returns a list of task descriptions
matching that string, effectively allowing a keyword search.
Additionally, if you are using XGterm as the terminal window, a GUI
help browser is available that combines paging and searching. For example,
ecl> help implot dev=gui
ecl> refer photometry
apphot - Aperture Photometry Package [digiphot]
ccdtime - CCD photometry exposure time calculator [obsutil]
daophot - DAO Crowded-Field Photometry Package [digiphot]
digiphot - Digital stellar photometry package [noao]
:
CL Script Task Development
Basic CL Syntax
CL statements mostly follow C syntax conventions and have the same sorts of conditional and controls statements (i.e. "if-else" and "switch-case" statements, "while" and "for" loops, boolean expressions in conditionals, etc). Some differences C programmers may notice however are missing '++' and '--' operators to inc/decrement variables (although "i += 1" is valid), and fact that semi-colons are not required to terminate statements. Java programmers may notice that string concatenation may be done using a '+' sign although the double-slash '//' is more traditional in IRAF. The hash/crosshatch symbol ('#') is used to start a comment that continues until the end-of-line. Complete details of the language syntax are given in the "User's Introduction to the IRAF Command Language" and "CL Programmer's Manual" (both compressed Postscript files).
A few peculiarities of the CL deserve a bit more detailed discussion:
A "list directed parameter" is specified by prepending an asterisk to a parameter declaration of any type (but typically a string). These are used to read multiple values from a file with each reference returning the subsequent line from the file. For instance,
ecl> type testfile
this is line 1
this is line 2
ecl> string *ld
ecl> ld = "testfile"
ecl> = ld
this is line 1
ecl> = ld
this is line 2
ecl> = ld
EOF
Within a script these are typically used in a while() loop to read lines from a file, e.g.
struct line
real ra, dec
list = "testfile"
while (fscan (list, ra, dec) != EOF)
printf ("%H %h\n", ra, dec)
Note the declaration of line as a struct -- String variables terminate at whitespace while struct variables continue until the end of line. Also note the special formatting types '%H' and '%h' used in the printf() statement, these are peculiar to the CL and allow the formatting of sexigesimal numbers (as HMS or DMS respectively, a complete description of the formatting codes can be seen with "cl> help printf").
Similarly, sexigesimal values may be used in the CL directly since they are converted internally to floating-point values (always double-precision)
ecl> x = 12:34:56.7
ecl> =x
12.582416666667
ecl> = (x * 15) # or " =(12:34:56.7 * 15)"
188.73625 # to convert to RA in degrees
ecl> x = 188.73625 ; y = -35.8324762
ecl> printf ("%H %h\n", x, y) # to print degrees as RA and Dec
12:34:56.7 -35:49:56.9
Note the use of semi-colons to put multiple statements on a single line and the use of sexigesimal values in expressions. Using an equal sign at the CL prompt serves to make the CL a handy calculator or simply to inspect the value of a variable or parameter.
Below we see how fscan() can be used to read values from a string. In the print() statements that follow we output the values using both the traditional '//' and '+' concatenation operators to construct the string, but when using '+' we need to explicitly convert the type. Note also that unlike the printf() used above, a print() will automatically output a newline after the string.
ecl> string test = "word 17 3.14 now is the time"
ecl> = fscan (test, s1, i, x, line)
4
ecl> print ("s1 = " // s1 // " x = " // x)
s1 = word x = 3.14
ecl> print ("s1 = " + s1 + " x = " + str(x))
s1 = word x = 3.14
Next we'll see an example of the "scan-from-pipe" feature of the CL and how it can be used to cature the output of tasks to local variables.
ecl> imstat dev$pix format-
dev$pix 262144 108.3 131.3 -1. 19936.
ecl> imstat ("dev$pix", fields="mean,stddev", format-) | scan (x, y)
ecl> printf ("%6.2f +/- %6.2f\n", x, y) | scan (line)
ecl> = line
108.32 +/- 131.30
The CL can be called as a task to interpret a command as with the Unix eval command by constructing a command and passing it to the CL for interpretation:
ecl> printf ("imstat ('%s', fields='%s', format-)\n", s1, s2) | cl()
108.3154 262144
ecl> s1 = mktemp ("tmp$tmp")
ecl> imhead ("dev$pix", lo+, > s1)
ecl> printf ("!grep Overscan %s\n", osfn(s1)) | cl()
BT-FLAG = 'Apr 22 14:11 Overscan correction strip is [515:544,3:510]'
but, be sure you really need to do so, first:
ecl> match ("Overscan", s1)
BT-FLAG = 'Apr 22 14:11 Overscan correction strip is [515:544,3:510]'
In the first example we construct a call to the IMSTAT task for execution, but obviously one would simply make the call to an IRAF task directly. The second example is more realistic -- here we dump the image header to a file (named by the "s1" temp file) and use the '!' CL escape to call the unix grep utility to search for a string. In many (but not all) cases there is an alternative for common utilities like this already in the system.
Image Sections
| Section | Refers to | Section | Refers to | |
|---|---|---|---|---|
| pix[] | the whole image | pix[i,j] | the pixel value (scalar) at [i,j] | |
| pix[*,*] | whole image, two dimensions | pix[-*,*] | flip x-axis | |
| pix[*,-*] | flip y-axis | pix[-*,-*] | flip x and y-axis (180o rotate) | |
| pix[*,*,b] | band B of three dimensional image | pix[*,*:s] | subsample in y by S | |
| pix[*,l] | line L of image | pix[c,*] | column C of image | |
| pix[i1:i2,j1:j2] | subraster of image | pix[i1:i2:sx,j1:j2:sy] | subraster with subsampling |
All IRAF programs which operate upon images may be used to operate on the entire image (the default) or any section of the image. A special notation is used to specify image sections. The section notation is appended to the file name of the image, much like an array subscript is appended to an array name in a conventional programming language. If no section is specified, the entire image will be used.
Unfortunately image transposition is not supported by the section syntax, but almost any other combination of flips, subsamples, or range notations are supported.
Parameter Syntax
Task parameters can be either query params that will be prompted for if not supplied on the command line, or hidden params that will use a default value defined in the task or the user-specified value on the command line. Boolean values in IRAF are yes or no values and may be abbreviated on the command line with '+' or '-', i.e. "cl> <task> bpar+" will turn on the parameter 'bpar'. Sexigesimal values are understood by the CL and will be converted to floating point before being passed to the task.
| Essential Parameter Commands | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
|||||||||||||||||
Parameters are learned between task calls and if a default value is changed it will be remembered the next time the task is used. Task params may be reset to their defaults using the unlearn command. Similarly, changing the number or name of params requires that you unlearn the task to pick up the change. Editing all of the params for a task is done using the epar command, simply list parameters can be done with the lpar or dpar commands.
The CL itself has parameters, some of which can be used as variables without declaring them explicitly in a script (e.g. 'i' is an int, 's1' is a string,etc). Other parameters control behavior of the CL, to see these use a command such as "cl> lpar cl".
Declaring Custom Tasks
The task command in the CL is used to define a new application for the system. In the case of script tasks we're considering here (all of which should be procedure scripts), the syntax is simply
- task name = name.cl
The ".cl" extension on scripts is required and normally the name of the task is the name of the file as well. Tasks that have no parameters (i.e. arguments in the procedure statement) are required to be declared with a '$' before the task name, for example
- ecl> type hello.cl
procedure hello ()
begin
print ("hello world")
end
ecl> task $hello = hello.cl
ecl> hello
hello world
Tasks with parameters do not use the leading '$' on the name. So-called foreign commands (i.e. host unix commands) obviously have no IRAF parameters and in addition are declared using either the reserved word foreign to indicate these commands will be found in the user's shell, or with a leading '$' on the command itself if they are declared as command strings. For example, to declare the host commands wget and sed as well as to create a command called tpipe that executes a method in a Java file we would do something like:
- cl> task $wget $sed = "$foreign"
cl> task $tpipe = "$java -cp $NVOSS_HOME/java/lib/stilts.jar:${CLASSPATH} \
>>> uk.ac.starlink.ttools.TablePipe $*"
See the help page for the task statement for additional details. Note that in the tpipe declaration we are able to use shell environment variables, we also use the special string "$*" to pass through arguments to the task at the host level.
Task declarations and other environment variable settings may also be put into a loginuser.cl file in the same directory as the login.cl file, provided the last line of the file is keep to retain the definitions. A MKIRAF will overwrite the login.cl each time it is used, a loginuser.cl keeps from accidently overwriting custom changes.
Putting It All Together -- An Example Application
The following example implements a crude SIA table browser that allows the user to automatically download and examine the images found for a given position on the named SIA service. We first return the query result and then iterate over the resulting image references, using both foreign commands and native IRAF applications.
To run this example, cut-n-paste the code below and save to a file called siabrowser.cl in your IRAF login directory. Alternatively, the script may be downloaded from here.
Next, log into IRAF and declare the task as:
- cl> task siabrowser = home$siabrowser.cl
We will assume the wget/sed/tpipe task declarations from above are still valid. The use of "home$" illustrates the used if IRAF logical pathnames, where "home" is defined in your login.cl file as the iraf login directory.
Next, start the DS9 display server and execute the task using the coordinates of a known results (the Sextans B cluster in this case):
- cl> !ds9 &
ecl> siabrowser 10:00:00 5:19:48 0.25
Note that we use the '!' escape to start ds9 as a host command in the background before running the task. Note also the use of sexigesimal values for the position; internally these are converted to decimal (10.0, 5.33) values but in the script we must still convert RA to degrees.
A loginuser.cl file with the needed definitions is available here, this should be put in the same directory as the login.cl file and will be read automatically when you login to IRAF.
|
1 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 |
# SIABROWSER -- Given a search position and size, query an SIA server for
# results. Loop through the returned image table and download the FITS
# files, optionally displaying or analyzing them.
procedure siabrowser (ra, dec, size)
real ra { prompt = "RA (hours) of search" }
real dec { prompt = "DEC (degrees) of search" }
real size { prompt = "Size of search" }
string siap = "http://archive.noao.edu/nvo/sim/voquery.php" \
{ prompt = "SIA Service" }
begin
string url, ch, imname, res, tmplist, tabnam
int imnum = 0
# Form the URL of the query using print() and scan to the result
printf ("%s?POS=%g%%2C%g&SIZE=%g\n",
siap, (ra * 15.0), dec, size) |
sed ("-e", "'s/\?/\\\\?/g'", "-e", "'s/\&/\\\\&/g'") | scan (url)
printf ("Querying server ....")
res = mktemp ("res")
wget ("-q", "-O", "-", url, >& res//".xml")
# Convert the downloaded VOTable to a FITS bintable we can deal with.
tabnam = res // ".fits"
tpipe (res//".xml", "-ofmt", "fits-basic", "-o", tabnam)
# Print some stats about the table.
tinfo (tabnam, ttout-)
printf ("Result: %d rows %d cols\n", tinfo.nrows, tinfo.ncols)
# Create a list of the image access references.
tmplist = mktemp ("tmp$sia")
tprint (tabnam, columns="accessreference", showhdr-, showrow-,
showunits-, pwidth=1024, >& tmplist)
# Loop over the image list, downloading the file and displaying it.
list = tmplist
while (fscan (list, s1) != EOF) {
imnum = imnum + 1
printf ("sia_%.1f_%.1f_%03d.fits\n", ra, dec, imnum) | scan (imname)
# Filter the URL to make wget happy.
print (s1) |
sed ("-e", "'s/\?/\\\\?/g'", "-e", "'s/\&/\\\\&/g'") | scan (url)
# Download the image.
printf ("Downloading image ...." // imname // " ")
wget ("-q", url, "-O", imname)
for (ch = "d"; ch != "n"; ch = cl.ukey) {
print ("")
switch (ch) {
case "?": print ("help for commands here...")
case "c": tlcol (tabnam)
case "h": imheader (imname, long+)
case "e": imexamine (imname, 1)
case "d": display (imname, 1, fill+)
case "n": break
case "q": goto cleanup
case "r": tprint (tabnam, rows=imnum, showrow-)
case "s": imstat (imname)
}
printf ("Command? ")
}
}
cleanup:
list = "" # cleanup list pointer
delete (tmplist, ver-, >& "dev$null") # delete temp files
end
|
Notes:
-
- Line 24-26
- The printf() statement forms the URL from the siap
base URL parameter string and the input arguments and pipes the
result through the unix sed command to escape special chars
in the URL so they can be passed safely to the shell. The result
is scanned into the url string variable that actually gets
used below it. Note that the escape processing is minimal, a
more complete escape of URLs could be done in a helper task.
- Line 31
- The wget() host command is used to actually download the URL
and perform the SIA query. We use the CL compute mode syntax
where each argument we would specify on a unix command line is
enclosed in quotes and used as a separate argument. We could just
as easily have used a generalized version of the URLReader
example task. The result is redirected to a temp file with a ".xml"
extension.
- Line 36
- The tpipe() command is the foreign task declaration for the
STIL utility we say above. In this case we are simply using
it to convert the VOTable to a FITS bintable we will process
with the standard TABLES package tasks.
- Line 46
- The tprint() task is used to pull out the column containing
the image access reference URLs. Since the task works on the
VOTable name attribute and not the UCD this is not a general
solution. (See the TPRINT help page for an explanation of the
parameters). The result is redirected to a temp file we will iterate
over for processing.
- Line 54
- The while loop uses fscan() to read each line from
the list (i.e. the acref URL). We again call wget to download
the file and create a FITS image with a local name. Note that we're
assuming we get a simple FITS file from the SIAP, providers such as
SDSS compress their data and so a generalized task would need to
check for this. Similarly, beware that DSS images contain
plate-solution header keywords and not standard FITS WCS keywords.
- Line 70
- The for loop shows the use of the CL ukey parameter
to read a keystroke command from the user. An alternative to this
would have been to declare another query parameter in the procedure
declaration and use it in a statement -- using the param causes the
parameter prompt to be written so we don't need to ask explicitly,
and we can parse the command from the result.
- Lines 72-85
- Here we use the switch() statement to process the command,
calling a different task for each command. By default we will
display the image, the remaining commands can be used to browse the
image header or begin analysis of the image itself.
References and Useful Links
- Introductory User's Guide to IRAF Scripts
- IRAF Beginner's Guide
- User's Introduction to the IRAF Command Language
- CL Programmer's Manual
- Recommended Documentation for every site
- General Documentation and Beginner's Materials
- Photometry
- Spectroscopy
- General Image Processing
- Programming Documentation
- Installation and Site Manager's Guides
NVO Summer School 2005
