Using “Client” API

The “client” API contains modules supporting VO Cone Search’s client-side operations.

Catalog Manipulation

You can manipulate a VO catalog using VOSCatalog, which is basically a dictionary with added functionalities.

Examples

You can create a VO catalog from scratch with your own VO service by providing its title and access URL, and optionally any other metadata as key-value pairs:

>>> from astroquery.vo_conesearch.vos_catalog import VOSCatalog
>>> my_cat = VOSCatalog.create(
...     'My Own', 'http://ex.org/cgi-bin/cs.pl?',
...     description='My first VO service.', creator='J. Doe', year=2013)
>>> print(my_cat)
title: My Own
url: http://ex.org/cgi-bin/cs.pl?
>>> print(my_cat.dumps())
{
    "creator": "J. Doe",
    "description": "My first VO service.",
    "title": "My Own",
    "url": "http://ex.org/cgi-bin/cs.pl?",
    "year": 2013
}

You can modify and add fields:

>>> my_cat['year'] = 2014
>>> my_cat['new_field'] = 'Hello world'
>>> print(my_cat.dumps())
{
    "creator": "J. Doe",
    "description": "My first VO service.",
    "new_field": "Hello world",
    "title": "My Own",
    "url": "http://ex.org/cgi-bin/cs.pl?",
    "year": 2014
}

In addition, you can also delete an existing field, except the compulsory title and access URL:

>>> my_cat.delete_attribute('description')
>>> print(my_cat.dumps())
{
    "creator": "J. Doe",
    "new_field": "Hello world",
    "title": "My Own",
    "url": "http://ex.org/cgi-bin/cs.pl?",
    "year": 2014
}

Database Manipulation

You can manipulate VO database using VOSDatabase, which is basically a nested dictionary with added functionalities.

Examples

You can choose to start with an empty database:

>>> from astroquery.vo_conesearch.vos_catalog import VOSDatabase
>>> my_db = VOSDatabase.create_empty()
>>> print(my_db.dumps())
{
    "__version__": 1,
    "catalogs": {}
}

Add the custom catalog from VO catalog examples to database:

>>> my_db.add_catalog('My Catalog 1', my_cat)
>>> print(my_db)
My Catalog 1
>>> print(my_db.dumps())
{
    "__version__": 1,
    "catalogs": {
        "My Catalog 1": {
            "creator": "J. Doe",
            "new_field": "Hello world",
            "title": "My Own",
            "url": "http://ex.org/cgi-bin/cs.pl?",
            "year": 2014
        }
    }
}

You can write/read the new database to/from a JSON file:

>>> my_db.to_json('my_vo_database.json', overwrite=True)
>>> my_db = VOSDatabase.from_json('my_vo_database.json')

You can also load a database from a VO registry. The process is described in Building the Database from Registry, except that here, validation is not done, so validate_xxx keys are not added. This might generate a lot of warnings, especially if the registry has duplicate entries of similar services, so here, we silently ignore all the warnings:

>>> import warnings
>>> from astroquery.vo_conesearch.validator import conf as validator_conf
>>> with warnings.catch_warnings():  
...     warnings.simplefilter('ignore')
...     registry_db = VOSDatabase.from_registry(
...         validator_conf.conesearch_master_list, encoding='binary',
...         cache=False)
Downloading http://vao.stsci.edu/regtap/tapservice.aspx/...
|==========================================|  44M/ 44M (100.00%)         0s
>>> len(registry_db)  
21326

Find catalog names containing 'usno*a2' in the registry database:

>>> usno_a2_list = registry_db.list_catalogs(pattern='usno*a2')  
>>> usno_a2_list  
['ROSAT All-Sky Survey Bright Source Catalog USNO A2 Cross-Associations 1',
 'The USNO-A2.0 Catalogue (Monet+ 1998) 1',
 'USNO-A2 Catalogue 1']

Find access URLs containing 'stsci' in the registry database:

>>> stsci_urls = registry_db.list_catalogs_by_url(pattern='stsci')  
>>> stsci_urls  
['http://archive.stsci.edu/befs/search.php?',
 'http://archive.stsci.edu/euve/search.php?', ...,
 'http://gsss.stsci.edu/webservices/vo/ConeSearch.aspx?CAT=ultravista&',
 'http://gsss.stsci.edu/webservices/vo/ConeSearch.aspx?CAT=viking&']

Extract a catalog titled 'USNO-A2 Catalogue 1' from the registry:

>>> usno_a2 = registry_db.get_catalog('USNO-A2 Catalogue 1')  
>>> print(usno_a2)  
title: 'USNO-A2 Catalogue'
url: http://www.nofs.navy.mil/cgi-bin/vo_cone.cgi?CAT=USNO-A2&

Extract a catalog by known access URL from the registry (the iterator version of this functionality is get_catalogs_by_url(), which is useful in the case of multiple entries with same access URL):

>>> gsc_url = 'http://vizier.u-strasbg.fr/viz-bin/conesearch/I/305/out?'
>>> gsc = registry_db.get_catalog_by_url(gsc_url)  
>>> print(gsc)  
title: 'The Guide Star Catalog, Version 2.3.2 (GSC2.3) (STScI, 2006)'
url: http://vizier.u-strasbg.fr/viz-bin/conesearch/I/305/out?

Add all 'usno*a2' catalogs from registry to your database:

>>> for name, cat in registry_db.get_catalogs():  
...     if name in usno_a2_list:
...         my_db.add_catalog(name, cat)
>>> my_db.list_catalogs()  
['My Catalog 1',
 'ROSAT All-Sky Survey Bright Source Catalog USNO A2 Cross-Associations 1',
 'The USNO-A2.0 Catalogue (Monet+ 1998) 1',
 'USNO-A2 Catalogue 1']

You can delete a catalog from the database either by name or access URL:

>>> my_db.delete_catalog('USNO-A2 Catalogue 1')  
>>> my_db.delete_catalog('The USNO-A2.0 Catalogue (Monet+ 1998) 1')  
>>> my_db.delete_catalog_by_url(
...     'https://heasarc.gsfc.nasa.gov/cgi-bin/vo/cone/coneGet.pl?table=rassusnoid&')  
>>> my_db.list_catalogs()  
['My Catalog 1', 'The USNO-A2.0 Catalogue (Monet+ 1998) 1']

You can also merge two database together. In this example, the second database contains a simple catalog that only has given name and access URL:

>>> other_db = VOSDatabase.create_empty()
>>> other_db.add_catalog_by_url(
...     'My Guide Star Catalogue',
...     'http://vizier.u-strasbg.fr/viz-bin/conesearch/I/305/out?')
>>> print(other_db.dumps())
{
    "__version__": 1,
    "catalogs": {
        "My Guide Star Catalogue": {
            "title": "My Guide Star Catalogue",
            "url": "http://vizier.u-strasbg.fr/viz-bin/conesearch/I/305/out?"
        }
    }
}
>>> merged_db = my_db.merge(other_db)
>>> merged_db.list_catalogs()
['My Catalog 1', 'My Guide Star Catalogue']

General VO Services Access

astroquery.vo_conesearch.vos_catalog also contains common utilities for accessing simple VO services already validated by STScI (see Validation for Simple Cone Search).

Configurable Items

These parameters are set via Configuration System (astropy.config):

  • astroquery.vo_conesearch.conf.pedantic

    Set strictness of VO table parser (False is recommended).

  • astroquery.vo_conesearch.conf.timeout

    Timeout for remote service access.

  • astroquery.vo_conesearch.conf.vos_baseurl

    URL (or path) where VO Service database is stored.

Examples

Get all catalogs from a database named 'conesearch_good' (this contains cone search services that cleanly passed daily validations; also see Cone Search Examples):

>>> from astroquery.vo_conesearch import vos_catalog
>>> my_db = vos_catalog.get_remote_catalog_db('conesearch_good')  
Downloading https://astroconda.org/aux/vo_databases/conesearch_good.json
|==========================================|  59k/ 59k (100.00%)         0s
>>> print(my_db)  
Guide Star Catalog 2.3 Cone Search 1
SDSS DR7 - Sloan Digital Sky Survey Data Release 7 1
# ...
Two Micron All Sky Survey (2MASS) 2

If you get timeout error, you need to use a custom timeout as follows:

>>> from astropy.utils import data
>>> with data.conf.set_temp('remote_timeout', 30):  
...     my_db = vos_catalog.get_remote_catalog_db('conesearch_good')

To see validation warnings generated by Validation for Simple Cone Search for the one of the catalogs above:

>>> my_cat = my_db.get_catalog('Guide Star Catalog 2.3 Cone Search 1')  
>>> for w in my_cat['validate_warnings']:  
...     print(w)
/.../vo.xml:136:0: W50: Invalid unit string 'pixel'

By default, pedantic is False:

>>> from astroquery.vo_conesearch import conf
>>> conf.pedantic
False

To call a given VO service; In this case, a Cone Search (also see Cone Search Examples):

>>> from astropy import coordinates as coord
>>> from astropy import units as u
>>> c = coord.SkyCoord.from_name('47 Tuc')  
>>> c  
<SkyCoord (ICRS): (ra, dec) in deg
    (6.0223292, -72.0814444)>
>>> sr = 0.5 * u.degree
>>> sr
<Quantity 0.5 deg>
>>> result = vos_catalog.call_vo_service(
...     'conesearch_good',
...     kwargs={'RA': c.ra.degree, 'DEC': c.dec.degree, 'SR': sr.value},
...     catalog_db='Guide Star Catalog 2.3 Cone Search 1')  
Trying http://gsss.stsci.edu/webservices/vo/ConeSearch.aspx?CAT=GSC23&...
Downloading ...
WARNING: W50: ...: Invalid unit string 'pixel' [astropy.io.votable.tree]
>>> result  
<Table masked=True length=36184>
   _r      USNO-A1.0    RA_ICRS_   DE_ICRS_  ...   Bmag    Rmag   Epoch
  deg                     deg        deg     ...   mag     mag      yr
float64     bytes13     float64    float64   ... float64 float64 float64
-------- ------------- ---------- ---------- ... ------- ------- --------
0.499298 0150-00088188   4.403473 -72.124045 ...    20.6    19.4 1977.781
0.499075 0150-00088198   4.403906 -72.122762 ...    21.2    18.0 1977.778
0.499528 0150-00088210   4.404531 -72.045198 ...    16.2    15.4 1977.781
     ...           ...        ...        ... ...     ...     ...      ...
0.499917 0150-00226223   7.647400 -72.087600 ...    23.4    21.7 1975.829

Unlike conesearch(), call_vo_service() is a low-level function and returns astropy.io.votable.tree.Table. To convert it to astropy.table.Table:

>>> tab = result.to_table()  

To repeat the above and suppress all the screen outputs (not recommended):

>>> import warnings
>>> with warnings.catch_warnings():  
...     warnings.simplefilter('ignore')
...     result = vos_catalog.call_vo_service(
...         'conesearch_good',
...         kwargs={'RA': c.ra.degree, 'DEC': c.dec.degree, 'SR': sr.value},
...         catalog_db='Guide Star Catalog 2.3 Cone Search 1',
...         verbose=False)

You can also use custom VO database, say, 'my_vo_database.json' from VO database examples:

>>> import os
>>> with conf.set_temp('vos_baseurl', os.curdir):  
...     try:
...         result = vos_catalog.call_vo_service(
...             'my_vo_database',
...             kwargs={'RA': c.ra.degree, 'DEC': c.dec.degree,
...                     'SR': sr.value})
...     except Exception as e:
...         print(str(e))
Trying http://ex.org/cgi-bin/cs.pl?
WARNING: W25: ... failed with: <urlopen error timed out> [...]
None of the available catalogs returned valid results. (1 URL(s) timed out.)