Next Previous Contents

6. Using DS9 from S-Lang

This chapter describes the DS9 package, which provides a series of S-Lang functions, layered above the XPA module, that streamline interactions with the SAOds9 image display and analysis tool widely used in astronomy. We assume some familiarity with the FITS file format and related conventions, as described at the FITS website. The package may be accessed from any S-Lang-enabled interpreter through the usual means, such as autoload(), or

        () = evalfile ("ds9");
or, if the application embedding the interpreter supports the require function,
        require ("ds9");

6.1 Examples

In this section we illustrate a number of ways in which the DS9 package may be employed, with an emphasis on the common case and ease of use. For context we show the functions as they might be invoked from the interactive prompts of ChIPS and ISIS (and in the latter case assume Isis_Append_Semicolon = 1). The examples may also be executed in batch within slsh scripts, or interactively from the prompt of the readline-enabled slsh, and so forth.

Additional details are available in the function reference in the next chapter, or in the short usage message that most of the DS9 functions will emit when invoked with zero arguments. The reader may also wish to inspect the DS9-related scripts, within the tests subdirectory, for supplemental examples.

Getting Started

If DS9 is not already running it may be launched from S-Lang via commands such as

        isis> ds9_launch
        Struct_Type

        isis> ds9_view( "image.fits" )

        isis> ds9_view( [ 1 : 512 * 512] )

A second DS9 process will not be invoked here if one is already running, even if it was started outside of S-Lang. Moreover, DS9 will continue running after the S-Lang application from which it may have been launched has been terminated.

In the first command parentheses have been intentionally omitted, since ds9_launch may be called with zero or more arguments. Likewise, the return value, a so-called handle structure, has been purposely left on the stack (and is subsequently cleared/echoed by ISIS).

The second and third forms are likely to be preferred, since ds9_view not only launches DS9 but also causes it to immediately display the specified image. The first view command shown here simply sends the name of a file, from which DS9 will load the default image. The second is more interesting: it creates an 1D inlined array of 262144 elements, initialized to the values 1 through 512*512, and transmits the result directly to DS9, resulting in a visual which should resemble


Sending Images to DS9

Our next example reveals one of the most powerful features in the DS9 package, namely the ds9_put_array function. With it we can rewrite the preceding example as

        isis> ds9_launch
        isis> ds9_put_array( [ 1 : 512 * 512] )
The ds9_put_array method is faster and cleaner than alternatives, such as dumping data to temporary files and explicitly constructing command strings to pass to the system() function for launching external processes. Instead, by fostering direct communication between S-Lang and DS9 we avoid creating file litter which must be cleaned up later, as well as the need to load additional software to read and write FITS files. As a result the analysis process becomes more fluid and nimble, promoting iterative exploration.

Similarly, if DS9 is already running then

        isis> ds9_put_file ( "image.fits" )
may be used to transmit the name of a file from which DS9 should visualize an image.

Retrieving Images from DS9

The put functions described above have natural inverses. For example, to retrieve the name of the file currently being displayed we might do

        chips> filename = ds9_get_file()
        chips> print(filename)
        image.fits
or, more succinctly,
        chips> ds9_get_file
        image.fits
Likewise, to retrieve the actual image being displayed one might do
        chips> image = ds9_get_array
following which one can perform all of the expected S-Lang array manipulations, such as
        chips> image
        UChar_Type[900,900]
which reveals the image dimensions, or
        chips> image2 = sqrt(image)
which constructs a new image (of Double_Type) as the square root of the first, or
        chips> ds9_put_array(image2)
which sends the result back to DS9.

6.2 Point and Click Interactivity

See the function reference (in the next chapter) and test scripts.

6.3 Regions

Here's the simplest case showing how regions may be retrieved directly to a S-Lang string array

        isis> s = ds9_get_regions()
        isis> print(s)
yielding a result like
        # Region file format: DS9 version 4.0
        # Filename: im1.fits
        global color=green font=\"helvetica 10 normal\" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source
        image
        circle(268,257,20)
The regions were returned in the "image" coordinate system because it is what was selected in the Region menu of the GUI. A different coordinate system may be selected using the named coord_sys qualifier
        isis> s = ds9_get_regions( ; coord_sys="physical")
        isis> print(s)
which might change the last two lines of the above output to something like
        "physical"
        "circle(4280.5,4104.5,320)"
Named qualifiers in S-Lang must appear after positional parameters, and are separated from them by the semicolon delimiter. Another way to achieve the same end would be to reset the region coordinate system prior to retrieving the regions themselves, such as
        isis> ds9_send("regions system physical")
This setting persists until changed, allowing the region retrieval to again be as cleanly expressed
        isis> s = ds9_get_regions()
as in the first example. Regions may also be saved to a file, e.g.
        isis> s = ds9_get_regions("/tmp/my.reg")
        isis> !cat /tmp/my.reg

        # Region file format: DS9 version 4.0
        # Filename: im1.fits
        global color=green font="helvetica 10 normal" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source
        physical
        circle(4280.5,4104.5,320)
Observe that the regions were again returned in the "physical" coordinate system, because the GUI retains the previous selection.

6.4 World Coordinate Systems

Our examples so far have treated images only as arrays of raw pixel values. We now highlight how coordinate systems may be attached to these images, thereby rendering them of greater practical significance to the astronomer.

Formatted WCS Strings

Suppose we would like to attach a WCS transform described by the strings

        "CRPIX1    256"
        "CRVAL1    512"
        "CDELT1    2"
        "CTYPE1    X"
        "CRPIX2    256"
        "CRVAL2    512"
        "CDELT2    2"
        "CTYPE2    Y"
(which simply multiplies the coordinate values of each axis by 2) to the DS9 image generated by
        chips> ds9_view( [ 1 : 512 * 512] )
If the transform was contained within the text file image.wcs, then the command
        chips> ds9_put_wcs_keys("image.wcs")
would attach it to the current image. The same function would be used if the transform strings were instead contained within an 8-element array variable named wcs, only now it would be invoked as
        chips> ds9_put_wcs_keys(wcs)
As the function reference indicates, the key/value pairs given here may also be formatted in accordance with the FITS 80 character card standard.

Raw/Unformatted WCS Values

Now suppose that we wanted to apply the transform not from formatted strings, but rather from raw S-Lang values. For example, we might apply the transform to the first axis of the image with

        chips> ds9_put_wcs(256, 512, 2)
or to both axes of the image via something like
        chips> crpix = [256, 256]
        chips> crval = [512, 512]
        chips> cdelt = [2, 2]
        chips> ds9_put_wcs(crpix, crval, cdelt)

WCS Structures

Now suppose that the arrays given in the preceding example were morphed into fields of the same name within an S-Lang structure, such as

        isis> s = struct { crpix, crval, cdelt, ctype, cunit}
        isis> s.crpix = crpix
        isis> s.crval = crval
        isis> s.cdelt = cdelt
The entire structure could then be applied at once via
        isis> ds9_put_wcs_struct(s)

Alternate WCS

Both FITS and DS9 allow multiple coordinate systems to be associated with an image. The DS9 module facilitates this by supporting an optional alt_wcs_char parameter in each of its WCS functions. For example,

        isis> ds9_put_wcs_struct(s, 'a')
would create a so-called WCSa coordinate system. Similarly,
        isis> crpix = [256, 256]
        isis> crval = [512, 512]
        isis> cdelt = [2, 2]
        isis> ds9_put_wcs(crpix, crval, cdelt, , , 'p')
would create a WCSp coordinate system. As a convenience the DS9 module assigns the WCSp coordinate system as the physical coordinate system within the DS9 GUI, by transparently passing an additional FITS keyword WCSNAMEP with value 'PHYSICAL'. Note that in the above call ctype and cunit have been omitted (positional parameters 4 and 5 are empty); their values will default to NULL. More information on how DS9 treats alternate WCS is available within the DS9 FAQ, which can be accessed through Help->FAQ->Coordinates within the GUI.

Erasing WCS

A transform may be removed simply by replacing it with an empty transform, such as

        chips> ds9_put_wcs_keys("")

6.5 WCS Editor GUI

If you have SLgtk installed then you'll also be able to modify image WCS values from within the WCS editor guilet, launched via

        ds9_wcs_edit
The next figure shows the GUI being used to double image coordinate values along the X axis, and halve them along the Y axis.

6.6 Shutting Down

A DS9 process may be terminated either interactively from the GUI or programmatically via

        isis> ds9_quit()

6.7 Optional Arguments

As discussed earlier in Omitted_Arguments, order matters when specifying optional arguments. For example, consider ds9_clear(), which accepts 2 optional arguments: a handle cannot be specified when this function is invoked unless the frame argument is also specified. Fortunately, the API has been coded to accept NULL as a default value in such cases. This exploits the fact that omitted arguments delimited by commas default to the value NULL in S-Lang, allowing such functions to be conveniently invoked, for example, as

        ds9_clear( , handle);

6.8 Return Values

Note that some routines in the DS9 package do not return a value which can be inspected for an error condition. There are two reasons for this. One is that the package is intended primarily for interactive use, so when a function fails such will be immediately evident to the user. Second, functions can only return error codes when SAOds9 itself indicates that an error condition exists, but unfortunately this information is not returned to the caller in all cases.

While XPA supports sending to and receiving from multiple servers in a single call, the functions described here return results from at most 1 instance of SAOds9.


Next Previous Contents