LSSTApplications  1.1.2+25,10.0+13,10.0+132,10.0+133,10.0+224,10.0+41,10.0+8,10.0-1-g0f53050+14,10.0-1-g4b7b172+19,10.0-1-g61a5bae+98,10.0-1-g7408a83+3,10.0-1-gc1e0f5a+19,10.0-1-gdb4482e+14,10.0-11-g3947115+2,10.0-12-g8719d8b+2,10.0-15-ga3f480f+1,10.0-2-g4f67435,10.0-2-gcb4bc6c+26,10.0-28-gf7f57a9+1,10.0-3-g1bbe32c+14,10.0-3-g5b46d21,10.0-4-g027f45f+5,10.0-4-g86f66b5+2,10.0-4-gc4fccf3+24,10.0-40-g4349866+2,10.0-5-g766159b,10.0-5-gca2295e+25,10.0-6-g462a451+1
LSSTDataManagementBasePackage
How to display images

How to %display images

Using DS9 in the LSST framework

At present (July 2009) we are using ds9 (http://hea-www.harvard.edu/RD/ds9) to display Images, Masks, and MaskedImages. This has a number of drawbacks (slow; slightly unstable API; awkward to use with firewalls) as well as a number of advantages: Supported by the CfA; ubiquitous in astronomy; support for WCS; support for multiple frames).

The basic functionality is in lsst.afw.display.ds9, and the workhorse routine is mtv. The simplest use is simply to setup afw and ds9, start ds9 and python, and type:

import lsst.afw.display.ds9 as ds9
import lsst.afw.image as afwImage
im = afwImage.ImageF("myFile.fits")
ds9.mtv(im)

You can display images in multiple frames, either by explicitly specifying the frame, or by setting the default with ds9.setDefaultFrame(). If there's a strong desire for multiple instances of ds9 this could be supported (by choosing different tcp ports); file a ticket if this is really important for you.

The mtv command handles all of the LSST image types:

Image

The pixels are displayed on ds9. Images don't have a Wcs, so no astronomical WCS information is available, but we do support WCSA and WCSB; the former is 0-indexed pixel coordinates allowing for the Image's XY0; the latter is 0-indexed pixel coordinates relative to the bottom left pixel being (0, 0).

mtv accepts an optional wcs argument, which allows you to provide an astronomical Wcs (but if you have an DecoratedImage or Exposure this is done for you)

DecoratedImage

Displayed like Image, but with the default WCS set from the DecoratedImage's Wcs

Mask

Overlay the current display with the Mask. A bug in ds9 prevents you from displaying a pure Mask, but you can use the isMask argument to force the Mask to be treated as a 16-bit image.

The Mask display isn't as fast as you might like, as ds9's current API requires us to send each mask plane as a separate 16-bit image (I have asked Bill Joy at CfA to change this). Each bitplane may be given a separate colour; you can inspect the current mapping with getMaskPlaneColor or set it with setMaskPlaneColor. If a mask plane has no defined colour, one will be chosen for you.

Recent versions of ds9 allow you to vary the mask's transparency, either via the GUI or with e.g. setMaskTransparency(50).

MaskedImage

The image-plane pixels are displayed, overlaid with the mask. If you want to look at the variance too, you'll need to say something like:

mi = afwImage.MaskedImageF("mi.fits")
ds9.mtv(mi, frame=0)
ds9.mtv(mi.getVariance(), frame=1)
ds9.mtv(mi.getMask(), frame=1)

Exposure
Displayed like MaskedImage, but with the default WCS set from the MaskedImage's Wcs

How to build a mosaic image

There are facilities to build mosaics of images in lsst.afw.display.utils

The basic class is Mosaic:

m = Mosaic()
m.setGutter(5)
m.setBackground(10)
m.setMode("square") # the default
mosaic = m.makeMosaic(im1, im2, im3) # build the mosaic
ds9.mtv(mosaic) # display it
m.drawLabels(["Label 1", "Label 2", "Label 3"]) # label the panels
# alternative way to build a mosaic
images = [im1, im2, im3]
labels = ["Label 1", "Label 2", "Label 3"]
mosaic = m.makeMosaic(images)
ds9.mtv(mosaic)
m.drawLabels(labels)
# Yet another way to build a mosaic (no need to build the images/labels lists)
for i in range(len(images)):
m.append(images[i], labels[i])
mosaic = m.makeMosaic()
ds9.mtv(mosaic)
m.drawLabels()

You can return the (ix, iy)th (or nth) bounding box with getBBox()

All supported ds9 commands

Colours may be specified as any X11-compliant string (e.g. "orchid"), or by one of the following constants defined in ds9; the advantage of the latter approach is that the python interpreter can detect typos: BLACK, WHITE, RED, BLUE, GREEN, CYAN, MAGENTA, YELLOW.

How to use ds9 through a firewall

On your home machine, type

export XPA_PORT="DS9:ds9 22345 22346"
# ^^^^^ ^^^^^
# Choose any 2 consecutive numbers over 4095
ssh -N -f lsstXXX.ncsa.uiuc.edu -R 22345:localhost:22345 -R 22346:localhost:22346 > /dev/null 2>&1
ds9 &

(setenv XPA_PORT "DS9:ds9 22345 22346" for csh users, of course)

On lsstXXX.ncsa.uiuc.edu, set XPA_PORT to the same value, start python, import lsst.afw.display.ds9 and proceed:

export XPA_PORT="DS9:ds9 22345 22346"
python
>>> import lsst.afw.display.ds9 as ds9
>>> ds9.erase()

xpa afficianados will note that I'm bypassing the xpa name server; it needs another set of 2 or 3 ports tunnelled, and setting up ACLs.

Here's a script (in afw/examples) to run on your home machine that should simplify setting up/tearing down the ssh tunnels. It's not great, so improvements would/will be welcomed.