DS9+Astropy

Interoperability using SAMP

SAMP is a messaging protocol that enables astronomy software tools to interoperate and communicate. SAMP-enabled tools include TOPCAT, SAOImageDS9, Aladin, and Astropy.  SAMP defines a number of message types, or MTYPEs, which are common among SAMP tools, such as image.load.fits, table.load.votable, coord.pointAt.sky. These messages allow images and tables to be exchanged between tools. In addition, SAOImageDS9 defines 2 unique MTYPEs for invoking the SAOImageDS9 API using SAMP: ds9.set and ds9.get. Any SAOImageDS9 function, that can be invoked via the command line can also be invoked via SAMP. SAOImageDS9 SAMP support is available for all ports of DS9, including linux, MacOS, and Windows. Please use SAOImageDS9 version 8.6b1 or newer as this version contains a number of enhancements to fully support SAMP across all platforms.

The first step is to start SAOImageDS9 in a command shell window. Next within your python code, the user will:

In general, use the astropy SAMP client call ecall_and_wait to invoke both ds9.set and ds9.get. Technically, all methods can be used for ds9.set, but ecall, ecall_all, and ecall_and_wait can only be used for ds9.get. Also, all values in SAMP by definition are strings, and therefor must be quoted. SAOImageDS9 API commands can have 2 functions, depending upon whether ds9.set or ds9.get is used. For example:

ecall_and_wait("c1","ds9.set","10",cmd="cd ~/foo")

will set the default directory to $HOME/foo, but

ecall_and_wait("c1","ds9.get","10",cmd="cd")

will return the current working directory.

What follows are a number of examples on how to use the default SAMP client within astropy to complete a number of tasks using SAOImageDS9.  For documentation, please see:  IVO SAMP and Astropy SAMP

RGB Images

This example illustrates how to use SAOImageDS9 to build a RGB Image in astropy:

from astropy.samp import SAMPIntegratedClient

ds9 = SAMPIntegratedClient()

ds9.connect()

ds9.ecall_and_wait("c1","ds9.set","10",cmd="rgb")

ds9.ecall_and_wait("c1","ds9.set","10",cmd="rgb red")

ds9.ecall_and_wait("c1","ds9.set","10",cmd="url http://ds9.si.edu/download/data/673nmos.fits")

ds9.ecall_and_wait("c1","ds9.set","10",cmd="zscale")

ds9.ecall_and_wait("c1","ds9.set","10",cmd="rgb green")

ds9.ecall_and_wait("c1","ds9.set","10",cmd="url http://ds9.si.edu/download/data/656nmos.fits")

ds9.ecall_and_wait("c1","ds9.set","10",cmd="zscale")

ds9.ecall_and_wait("c1","ds9.set","10",cmd="rgb blue")

ds9.ecall_and_wait("c1","ds9.set","10",cmd="url http://ds9.si.edu/download/data/502nmos.fits")

ds9.ecall_and_wait("c1","ds9.set","10",cmd="zscale")

ds9.ecall_and_wait("c1","ds9.set","10",cmd="rotate 270")

ds9.ecall_and_wait("c1","ds9.set","10",cmd="zoom to fit")

ds9.disconnect()

3D Data Cube GIF

This example illustrates how to create a GIF movie of a 3D data cube in astropy:

from astropy.samp import SAMPIntegratedClient

ds9 = SAMPIntegratedClient()

ds9.connect()

ds9.ecall_and_wait("c1","ds9.set","10",cmd="3d")

ds9.ecall_and_wait("c1","ds9.set","10",cmd="url http://ds9.si.edu/download/data/image3d.fits")

ds9.ecall_and_wait("c1","ds9.set","10",cmd="cmap viridis")

ds9.ecall_and_wait("c1","ds9.set","10",cmd="movie 3d gif 3d.gif number 10 az from -90 az to 90 el from 45 el to 45 zoom from 4 zoom to 4 oscillate 1")

ds9.disconnect()

Imexam

This example illustrates the use of imexam, which queries the user to click the mouse and returns the coordinates at that location of the image in astropy:

from astropy.samp import SAMPIntegratedClient

ds9 = SAMPIntegratedClient()

ds9.connect()

ds9.ecall_and_wait("c1","ds9.set","10",cmd="url http://ds9.si.edu/download/data/img.fits")

ds9.ecall_and_wait("c1","ds9.set","10",cmd="zscale")

print('Click anywhere in image:')

coord = ds9.ecall_and_wait("c1","ds9.get","10",cmd="imexam wcs icrs")

print('Coordinate is ', coord['samp.result']['value'])

ds9.disconnect()

Display 2D Numpy Array

This example show how to display the contents of a numpy array as an image within SAOImageDS9. First, create your numpy array and fill it with values. Next, create a numpy memmap array and copy the contents of the original array. Now flush the content to a file on disk. Next load the filename into DS9, it will display the initial contents. Now update the numpy memmap array with new values, and flush to disk. Use the command update to inform SAOImageDS9 to update the screen with the new data values. Continue this flush / update cycle. Be sure to clear the SAOImageDS9 frame before deleting the memmap file.

from tempfile import mkdtemp

import os.path as path

filename = path.join(mkdtemp(), 'newfile.dat')

import numpy as np

aa = np.random.rand(1024,2048)

fp = np.memmap(filename, dtype='float32', mode='w+', shape=(1024,2048))

fp[:] = aa[:]

fp.flush()

from astropy.samp import SAMPIntegratedClient

ds9 = SAMPIntegratedClient()

ds9.connect()

ds9.ecall_and_wait("c1","ds9.set","10",cmd="array "+ filename +"[xdim=1024,ydim=2048,bitpix=-32]")

aa = np.random.rand(1024,2048)

fp[:] = aa[:]

fp.flush()

print("pause 1")

import time

time.sleep(2)

ds9.ecall_and_wait("c1","ds9.set","10",cmd="update")

print("pause 2")

time.sleep(2)

ds9.ecall_and_wait("c1","ds9.set","10",cmd="frame clear")

ds9.disconnect()

import os

os.remove(filename)