Image Access#
In this notebook, we show how to search for and retrieve images from VO services using the Registry and the Simple Image Access (SIA) protocol.
*Note: for all of these notebooks, the results depend on real-time queries. Sometimes there are problems, either because a given service has changed, is undergoing maintenance, or the internet connectivity is having problems, etc. Always retry a couple of times, come back later and try again, and only then send us the problem report to investigate.
import warnings
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
import pyvo as vo
from astropy.io import fits
import astropy.coordinates as coord
# For downloading files
from astropy.utils.data import download_file
from IPython.display import Image as ipImage, display
# There are a number of relatively unimportant warnings that show up, so for now, suppress them:
warnings.filterwarnings("ignore", module="astropy.io.votable.*")
warnings.filterwarnings("ignore", module="pyvo.utils.xml.*")
1. Finding SIA resources from the Registry#
First, how do we find out what services are available? These are listed in a registry at STScI (see here). Our Registry function gives a simple interface for how to search for services.
Let’s search for services providing images in the ultraviolet bands:
uv_services = vo.regsearch(servicetype='sia',waveband='uv')
uv_services.to_table()['ivoid','short_name','res_title']
ivoid | short_name | res_title |
---|---|---|
object | object | object |
ivo://archive.stsci.edu/sia/galex | GALEX | Galaxy Evolution Explorer (GALEX) |
ivo://archive.stsci.edu/siap/hla | HLA | Hubble Legacy Archive |
ivo://irsa.ipac/mast/scrapbook | MAST-Scrapbook | The MAST Image Scrapbook |
ivo://mast.stsci/acsggct | HST.ACSGGCT | ACS Galactic Globular Cluster Survey (ACSGGCT) |
ivo://mast.stsci/angrrr | HST.ANGRRR | Archive of Nearby Galaxies: Reduce, Reuse, Recycle (ANGRRR) |
ivo://mast.stsci/candels | CANDELS | Cosmic Assembly Near-IR Deep Extragalactic Legacy Survey (CANDELS) |
ivo://mast.stsci/clash | HST.CLASH | Cluster Lensing And Supernova survey with Hubble (CLASH) |
ivo://mast.stsci/hippies | HST.HIPPIES | Hubble Infrared Pure Parallel Imaging Extragalactic Survey (HIPPIES) |
ivo://mast.stsci/phat | PHAT | Panchromatic Hubble Andromeda Treasury (PHAT) |
ivo://mast.stsci/siap/galex_atlas | GALEX_Atlas | GALEX Atlas of Nearby Galaxies |
ivo://mast.stsci/siap/hst.maoz_atlas | HST.maoz_atlas | HST Ultraviolet Atlas of Nearby Galaxies |
ivo://mast.stsci/siap/udfuv | HST.udfuv | Hubble Space Telescope Ultraviolet Images of the UDF and HDF |
ivo://mast.stsci/siap/uit | UIT | Ultraviolet Imaging Telescope (UIT) |
ivo://nasa.heasarc/skyview/euve | EUVE | Extreme Ultraviolet Explorer: 83 A |
ivo://nasa.heasarc/skyview/galex | GALEX | Galaxy Explorer All Sky Survey: Near UV |
ivo://nasa.heasarc/skyview/skyview | SkyView | SkyView Virtual Observatory |
ivo://nasa.heasarc/skyview/swiftuvot | SWIFTUVOT | Swift UVOT Combined V Intensity Images |
ivo://nasa.heasarc/skyview/wfcf | WFCF | ROSAT Wide Field Camera: F1 |
This returns an astropy table containing information about the services available. We can then specify the service we want by using the corresponding row. We’ll repeat the search with additional qualifiers to isolate the row we want (note that in the keyword search the “%” character can be used as a wild card):
uvot_services = vo.regsearch(servicetype='sia',waveband='uv',keywords=['swift'])
uvot_services.to_table()['ivoid','short_name','res_title']
ivoid | short_name | res_title |
---|---|---|
object | object | object |
ivo://nasa.heasarc/skyview/swiftuvot | SWIFTUVOT | Swift UVOT Combined V Intensity Images |
This shows us that the data we are interested in comes from the HEASARC’s SkyView service, but the point of these VO tools is that you don’t need to know that ahead of time or indeed to care where it comes from.
2. Using SIA to retrieve an image#
Now we look for images of our favorite source. See the SIA definition for usage. In short, you can specify the central position and the size (degrees as one or two floats for the RA, DEC directions). It is up to the service to determine how to provide this. Optionally, you can limit it to the format you want, e.g., “image/fits” or “image/png” etc.
What is returned to you is not the image itself but a list of images available and how to access them. This is easiest shown by example:
coords = coord.SkyCoord.from_name("m51")
im_table = uvot_services[0].search(pos=coords,size=0.2,format='image/jpeg')
im_table.to_table()
Survey | Ra | Dec | Dim | Size | Scale | Format | PixFlags | URL | LogicalName |
---|---|---|---|---|---|---|---|---|---|
object | float64 | float64 | int32 | object | object | object | object | object | object |
swiftuvotvint | 202.469575 | 47.1952583 | 2 | [300 300] | [-0.0006666666666666668 0.0006666666666666668] | image/jpeg | F | https://skyview.gsfc.nasa.gov/cgi-bin/images?position=202.469575%2C47.1952583&survey=swiftuvotvint&pixels=300%2C300&sampler=LI&size=0.20000000000000004%2C0.20000000000000004&projection=Tan&coordinates=J2000.0&requestID=skv1734724357376&nofits=1&quicklook=jpeg&return=jpeg | 1 |
swiftuvotbint | 202.469575 | 47.1952583 | 2 | [300 300] | [-0.0006666666666666668 0.0006666666666666668] | image/jpeg | F | https://skyview.gsfc.nasa.gov/cgi-bin/images?position=202.469575%2C47.1952583&survey=swiftuvotbint&pixels=300%2C300&sampler=LI&size=0.20000000000000004%2C0.20000000000000004&projection=Tan&coordinates=J2000.0&requestID=skv1734724357660&nofits=1&quicklook=jpeg&return=jpeg | 2 |
swiftuvotuint | 202.469575 | 47.1952583 | 2 | [300 300] | [-0.0006666666666666668 0.0006666666666666668] | image/jpeg | F | https://skyview.gsfc.nasa.gov/cgi-bin/images?position=202.469575%2C47.1952583&survey=swiftuvotuint&pixels=300%2C300&sampler=LI&size=0.20000000000000004%2C0.20000000000000004&projection=Tan&coordinates=J2000.0&requestID=skv1734724358799&nofits=1&quicklook=jpeg&return=jpeg | 3 |
swiftuvotuvw1int | 202.469575 | 47.1952583 | 2 | [300 300] | [-0.0006666666666666668 0.0006666666666666668] | image/jpeg | F | https://skyview.gsfc.nasa.gov/cgi-bin/images?position=202.469575%2C47.1952583&survey=swiftuvotuvw1int&pixels=300%2C300&sampler=LI&size=0.20000000000000004%2C0.20000000000000004&projection=Tan&coordinates=J2000.0&requestID=skv1734724359238&nofits=1&quicklook=jpeg&return=jpeg | 4 |
swiftuvotuvw2int | 202.469575 | 47.1952583 | 2 | [300 300] | [-0.0006666666666666668 0.0006666666666666668] | image/jpeg | F | https://skyview.gsfc.nasa.gov/cgi-bin/images?position=202.469575%2C47.1952583&survey=swiftuvotuvw2int&pixels=300%2C300&sampler=LI&size=0.20000000000000004%2C0.20000000000000004&projection=Tan&coordinates=J2000.0&requestID=skv1734724359699&nofits=1&quicklook=jpeg&return=jpeg | 5 |
swiftuvotuvm2int | 202.469575 | 47.1952583 | 2 | [300 300] | [-0.0006666666666666668 0.0006666666666666668] | image/jpeg | F | https://skyview.gsfc.nasa.gov/cgi-bin/images?position=202.469575%2C47.1952583&survey=swiftuvotuvm2int&pixels=300%2C300&sampler=LI&size=0.20000000000000004%2C0.20000000000000004&projection=Tan&coordinates=J2000.0&requestID=skv1734724360111&nofits=1&quicklook=jpeg&return=jpeg | 6 |
Extract the fields you’re interested in, e.g., the URLs of the images made by skyview. Note that specifying as we did SwiftUVOT, we get a number of different images, e.g., UVOT U, V, B, W1, W2, etc. For each survey, there are two URLs, first the FITS IMAGE and second the JPEG.
Note that different services will return different column names, but all will have a column giving the URL to access the image. Though it has different column names in different services, it can always be accessed through the getdataurl
function.
url = im_table[0].getdataurl()
print(url)
https://skyview.gsfc.nasa.gov/cgi-bin/images?position=202.469575%2C47.1952583&survey=swiftuvotvint&pixels=300%2C300&sampler=LI&size=0.20000000000000004%2C0.20000000000000004&projection=Tan&coordinates=J2000.0&requestID=skv1734724357376&nofits=1&quicklook=jpeg&return=jpeg
3. Viewing the resulting image#
JPG images#
Since we have asked for JPEG images, we can display an image in python easily by using its URL. Each row of the result has a getdataurl() method, and you can then hand the URL to an image displayer such as IPython.display:
img = ipImage(url=im_table[0].getdataurl())
display(img)
Fits files#
Or download the FITS image and display it with imshow, or aplpy.
(This often errors off with a time out message. Just try it again, possibly a couple of times.)
# Do the search again asking for FITS
im_table = uvot_services[0].search(pos=coords,size=0.2,format='image/fits')
# Hand the url of the first result to fits.open()
hdu_list = fits.open(im_table[0].getdataurl())
hdu_list.info()
Filename: /home/runner/.astropy/cache/download/url/b76bb70fb1e0cd40080fb49ab7343f6e/contents
No. Name Ver Type Cards Dimensions Format
0 PRIMARY 1 PrimaryHDU 111 (300, 300) float32
Using imshow#
plt.imshow(hdu_list[0].data, cmap='gray', origin='lower',vmax=0.1)
<matplotlib.image.AxesImage at 0x7f37c7f5e740>