Images are data. They can be 2D, from cameras, or 1D, from spectrographs, or 3D, from IFUs (integral field units). In each case, the data come packaged as an array of numbers, which we can visualize, and do calculations with.
Let's suppose we are interested in clusters of galaxies. We choose one, Abell 1835, and propose to observe it with the XMM-Newton space telescope. We are successful, we design the observations, and they are taken for us. Next: we download the data, and take a look at it.
In [1]:
import astropy.io.fits as pyfits
import numpy as np
import os.path
import astropy.visualization as viz
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['figure.figsize'] = (10.0, 10.0)
Download the example data files if we don't already have them.
In [2]:
targdir = 'a1835_xmm/'
!mkdir -p $targdir
imagefile = 'P0098010101M2U009IMAGE_3000.FTZ'
expmapfile = 'P0098010101M2U009EXPMAP3000.FTZ'
bkgmapfile = 'P0098010101M2X000BKGMAP3000.FTZ'
remotedir = 'http://heasarc.gsfc.nasa.gov/FTP/xmm/data/rev0/0098010101/PPS/'
for filename in [imagefile,expmapfile,bkgmapfile]:
path = targdir + filename
url = remotedir + filename
if not os.path.isfile(path): # i.e. if the file does not exist already:
!wget -nd -O $path $url
imagefile = targdir+imagefile
expmapfile = targdir+expmapfile
bkgmapfile = targdir+bkgmapfile
!du -sch $targdir/*
In [3]:
imfits = pyfits.open(imagefile)
imfits.info()
imfits
is a FITS object, containing multiple data structures. The image itself is an array of integer type, and size 648x648 pixels, stored in the primary "header data unit" or HDU.
If we need it to be floating point for some reason, we need to cast it: im = imfits[0].data.astype('np.float32') Note that this (probably?) prevents us from using the pyfits "writeto" method to save any changes. Assuming the integer type is ok, just get a pointer to the image data.
Accessing the .data
member of the FITS object returns the image data as a numpy ndarray.
In [7]:
im = imfits[0].data
Let's look at this with ds9
.
In [10]:
!ds9 -log "$imagefile"
If you don't have the image viewing tool
ds9
, you should install it - it's very useful astronomical software. You can download it (later!) from this webpage.
We can also display the image in the notebook:
In [8]:
plt.imshow(viz.scale_image(im, scale='log', max_cut=40), cmap='gray', origin='lower');
In [15]:
index = np.where(im == np.max(im))
print "image dimensions:",im.shape
print "location of maximum pixel value:",index
print "maximum pixel value: ",im[index]
NB. Images read in with pyfits are indexed with eg
im[y,x]
: ds9 shows that the maximum pixel value is at "image coordinates"x=328, y=348
.pyplot
knows what to do, but sometimes we may need to take the transpose of theim
array. Whatpyplot
does need to be told is that in astronomy, the origin of the image is conventionally taken to be at the bottom left hand corner, not the top left hand corner. That's what theorigin=lower
in theplt.imshow
command was about.We will work in image coordinates throughout this course, for simplicity. Aligning images on the sky via a "World Coordinate System" is something to be learned elsewhere.
In [ ]: