Virtual Observatory¶
The COATpy wrapping of pyvolib exposes a number of different virtual observatory tools. We will go over each of these in turn.
Name Position Resolver¶
Sesame
is a basic name resolver that returns the position of objects as a
tuple. You can specify which service you wish to use:
from coatpy import Sesame
simbad = Sesame(opt='S')
ned = Sesame(opt='N')
ned.resolve('M51')
# the services do not agree; doing this will produce an exception.
assert simbad.resolve('IC348') == ned.resolve('IC348')
Catalog Search¶
The ConeSearch
tool is a standardized interface to one of hundreds of
catalogs. The necessary parameters are:
RA
: decimal degreesDEC
: decimal degreesSR
: cone radius in decimal degrees
An optional parameter VERB
varies the verbosity of the query response.
As with the web queries you can wrap up the parameters in a dictionary:
from coatpy import ConeSearch, Sesame
simbad = Sesame(opt='S')
params = {}
params['RA'] = simbad.resolve("IC348")[0]
params['DEC'] = simbad.resolve("IC348")[1]
params['SR'] = 1./60.
params['VERB'] = 3
enter the query URL for the target catalog (see sidebar), and create a catalog
handler ic348cxo
that wraps the query tool. We use the getRaw
function
of the ConeSearch to retrieve the raw string result that we then dump into a
file and extract back the data using astropy:
from astropy.table import Table
url = "http://vizier.u-strasbg.fr/viz-bin/votable/-A?-source=J/AJ/122/866&"
ic348cxo = ConeSearch(url)
with open('ic348cxo.xml','wb') as f:
f.write(ic348cxo.getRaw(**params))
data = Table.read(f.name, format='votable')
Image Search¶
Siap
is the tool for querying image services is:
from coatpy import Siap
The Siap
acronym stands for Simple Image Access Protocol and as with
ConeSearch
the inputs are fairly simple:
RA
: Decimal DegreesDEC
: Decimal DegreesSIZE
: An image size in degreesFORMAT
: [Optional] default: image/fits (or image/jpeg)
Note
Various image archives have appended other query parameters onto
the SIAP standard to provide additional initial filtering of the images
returned. A good example is the IRSA 2MASS
service. The Siap
tool currently throws Exceptions on extra parameters.
Exercise: find HST images of a young cluster
In this exercise we will go through the steps necessary for downloading
images with Siap
from the Hubble Legacy Archive.
The first step is to set up the query, which is nearly identical to the previous examples.
import urllib2
from coatpy import Siap, Sesame
import vo
simbad = Sesame(opt="S")
url = " http://hla.stsci.edu/cgi-bin/acsSIAP.cgi?strict=1"
hla = Siap(url)
params = {}
position = simbad.resolve('IC348')
params.update(zip(('RA', 'DEC'), position))
params['SIZE'] = 1./60.
params['FORMAT'] = 'image/fits'
with open('hla_ic348_images.xml', 'wb') as f:
f.write(hla.getRaw(**params))
The main difference between a catalog and an image query is that an image query results in a series of pointers to the image files that can be examined and filtered before the reference files are downloaded. We use the vo module to parse the results, extracting the table of images that satisfy our query.
vot = vo.table.parse_single_table('hla_ic348_images.xml')
image_table = vot.array
The returned array contains 66 fields!
print(image_table.dtype.names)
If all we want is the actual data then the important column is URL while the filename column is also useful.
# just grab the first image returned
image = image_table[0]
image_url = image['URL']
filename = image['filename'] + '.fits'
with open(filename, 'wb') as image_file:
image_handler = urllib2.urlopen(image_url)
image_file.write(image_handler.read())
image_handler.close()
Continue this exercise by examining the resulting image.
Click to Show/Hide Solution
We use astropy.io.fits to open the image file and examine its contents.
from astropy.io import fits
import aplpy
import matplotlib.pyplot as plt
hdulist = fits.open(filename)
# check for multiple FITS extensions and their contents
# in this case the "PRIMARY" header is empty
for hdu in hdulist:
print('name: {0} type: {1}'.format(hdu.name, type(hdu.data)))
fig = plt.figure(figsize=(15, 7))
f1 = aplpy.FITSFigure(filename, hdu=1, subplot=[0.1,0.1,0.3,0.65], figure=fig)
f1.set_tick_labels_font(size='x-small')
f1.set_axis_labels_font(size='small')
f1.show_grayscale()
f2 = aplpy.FITSFigure(filename, hdu=2, subplot=[0.4,0.1,0.3,0.65], figure=fig)
f2.hide_xaxis_label()
f2.hide_xtick_labels()
f2.hide_yaxis_label()
f2.hide_ytick_labels()
f2.show_colorscale()
f3 = aplpy.FITSFigure(filename, hdu=3, subplot=[0.7,0.1,0.3,0.65], figure=fig)
f3.hide_xaxis_label()
f3.hide_xtick_labels()
f3.hide_yaxis_label()
f3.hide_ytick_labels()
f3.show_colorscale(cmap='spring')