Catalogues - Query with TAP#
Warning
TAP v1 vs v1.1
ESO is in the process of upgrading the catalogue TAP service from v1 to
v1.1. During this transition, some table references may differ between the
two versions. In v1.1, catalogue tables are exposed using unqualified table names.
Queries written for v1 may therefore need to be updated to include the
safcat. prefix. For example, PESSTO_TRAN_CAT_fits_V2 becomes
safcat.PESSTO_TRAN_CAT_fits_V2.
The ESO TAP service can also be used to query catalogue tables directly with
free ADQL, using query_tap(). By default,
query_tap(query) targets the observations TAP service (equivalent to
tap_endpoint="tap_obs"). To query catalogue content, pass
tap_endpoint="tap_cat" – i.e. eso.query_tap(query, tap_endpoint="tap_cat").
Basic Usage#
>>> from astroquery.eso import Eso
>>> eso = Eso()
>>> query = "SELECT table_name FROM TAP_SCHEMA.tables"
>>> table = eso.query_tap(query, tap_endpoint="tap_cat")
The examples below focus on common catalogue TAP workflows: schema discovery, spatial filtering, metadata-driven joins, and light-curve retrieval.
Schema Discovery Examples#
List Release Documentation URLs for Available Catalogues#
This example shows how to retrieve the release documentation URL for each
published catalogue directly from TAP_SCHEMA.tables. For example, for the AMBRE_V1
catalogue, the corresponding release documentation can be found at:
https://www.eso.org/rm/api/v1/public/releaseDescriptions/7
>>> query = """
... SELECT table_name, cat_id, rel_descr_url
... FROM TAP_SCHEMA.tables
... WHERE schema_name = 'safcat' AND cat_id IS NOT NULL
... ORDER BY cat_id
... """
>>> table = eso.query_tap(query, tap_endpoint="tap_cat")
>>> print(table[:2])
table_name cat_id release_documentation_url
---------------- ------ -----------------------------------------------------------
AMBRE_V1 13 https://www.eso.org/rm/api/v1/public/releaseDescriptions/7
GOODS_FORS2_V1 31 https://www.eso.org/rm/api/v1/public/releaseDescriptions/37
Inspect Columns in a Specific Catalogue Table#
Use this to list columns and data types for a specific catalogue table.
TAP_SCHEMA.columns contains column names, units, UCDs, and additional
metadata for all published ESO tables.
>>> query = """
... SELECT column_name, datatype, unit, ucd
... FROM TAP_SCHEMA.columns
... WHERE table_name='COSMOS2015_Laigle_v1_1b_latestV7_fits_V1'
... """
>>> table = eso.query_tap(query, tap_endpoint="tap_cat")
Find the Main RA/Dec Columns via UCD#
Use this to identify which columns carry the main sky coordinates in a table.
Here, the UCD values mark the primary RA and Dec fields – in this case
TRANSIENT_RAJ2000 and TRANSIENT_DECJ2000.
>>> query = """
... SELECT column_name
... FROM TAP_SCHEMA.columns
... WHERE table_name='PESSTO_TRAN_CAT_fits_V2'
... AND ucd in ('pos.eq.ra;meta.main', 'pos.eq.dec;meta.main')
... """
>>> table = eso.query_tap(query, tap_endpoint="tap_cat")
List VMC Tables with Coordinate and Source-ID Columns#
Use this to list coordinate and source-ID columns for all tables in the VMC
collection, ordered by publication date.
>>> query = """
... SELECT publication_date, T.table_name, column_name, ucd
... FROM TAP_SCHEMA.columns AS C, TAP_SCHEMA.tables AS T
... WHERE T.table_name = C.table_name
... AND cat_id IN (
... SELECT cat_id
... FROM TAP_SCHEMA.tables
... WHERE collection='VMC'
... )
... AND ucd in ('pos.eq.ra;meta.main', 'pos.eq.dec;meta.main', 'meta.id;meta.main')
... ORDER BY publication_date DESC, 2, 4
... """
>>> table = eso.query_tap(query, tap_endpoint="tap_cat")
Note that not all VMC tables have coordinates. Indeed some catalogues (e.g. variability catalogues) rely on the main source catalogue for the position of the objects. An example of that is provided in the “Discover Join Keys for VVV Tables” section.
List Coordinate and Source-ID Columns Across All Collections#
Use this to discover coordinate and source-ID columns across all published catalogues, ordered by publication date and collection.
>>> query = """
... SELECT publication_date, collection, T.table_name, column_name, ucd
... FROM TAP_SCHEMA.columns AS C, TAP_SCHEMA.tables AS T
... WHERE T.table_name = C.table_name
... AND ucd in ('pos.eq.ra;meta.main', 'pos.eq.dec;meta.main', 'meta.id;meta.main')
... ORDER BY publication_date DESC, 2, 3, 5
... """
>>> table = eso.query_tap(query, tap_endpoint="tap_cat")
Spatial Query Example#
Cone Search for PESSTO Transients Around ESO 154-10#
Search the PESSTO master catalogue for transients in a circle of 0.04 deg
(2.4 arcmin) around galaxy ESO 154-10 (ICRS position
41.2863, -55.7406).
>>> query = """
... SELECT host_id, transient_id, transient_classification,
... transient_raj2000, transient_decj2000
... FROM pessto_tran_cat_fits_V2
... WHERE CONTAINS(
... POINT('', transient_raj2000, transient_decj2000),
... CIRCLE('', 41.2863, -55.7406, 0.04)
... ) = 1
... """
>>> table = eso.query_tap(query, tap_endpoint="tap_cat")
The target coordinates can also be resolved online using a name resolver and then included in the query, as e.g.:
>>> import astropy.units as u
>>> from astropy.coordinates import SkyCoord
>>> target = SkyCoord.from_name("ESO 154-10")
>>> ra_deg = target.icrs.ra.to_value(u.deg)
>>> dec_deg = target.icrs.dec.to_value(u.deg)
>>> radius_deg = (2.4 * u.arcmin).to_value(u.deg)
>>> query = f"""
... SELECT host_id, transient_id, transient_classification,
... transient_raj2000, transient_decj2000
... FROM pessto_tran_cat_fits_V2
... WHERE CONTAINS(
... POINT('ICRS', transient_raj2000, transient_decj2000),
... CIRCLE('ICRS', {ra_deg}, {dec_deg}, {radius_deg})
... ) = 1
... """
>>> table = eso.query_tap(query, tap_endpoint="tap_cat")
Metadata Join Example#
Discover Join Keys for VVV Tables#
Use this to discover how VVV_CAT_V2 can be joined with related VVV* tables.
This pattern is common for multi-epoch catalogue products: one source can have
many epoch-level measurements, so the measurement table may contain N rows
for the same object. In those cases, coordinates are often stored only in a
source/master table and not repeated N times in each epoch table. This
reduces duplication and helps avoid inconsistencies across tables.
The VVV catalogues are a representative example: VVV_CAT_V2 provides the
source-level identifiers and coordinates, while tables such as
VVV_MPHOT_Ks_V2 (multi-epoch photometry) and VVV_VAR_V2 (variability
metrics) are linked through source keys (e.g. SOURCEID).
The resulting table shows join pairs as:
from_tableviafrom_columntarget_tableviatarget_column
>>> query = """
... SELECT k.from_table, kc.from_column, k.target_table, kc.target_column
... FROM TAP_SCHEMA.columns AS c, TAP_SCHEMA.keys AS k, TAP_SCHEMA.key_columns AS kc
... WHERE c.table_name='VVV_CAT_V2'
... AND (
... (k.from_table = c.table_name AND kc.from_column = c.column_name)
... OR
... (k.target_table = c.table_name AND kc.target_column = c.column_name)
... )
... AND k.key_id = kc.key_id
... ORDER BY table_name, column_name, 1, 3, 2
... """
>>> table = eso.query_tap(query, tap_endpoint="tap_cat")
After identifying the join keys (here, linking VVV_CAT_V2 to
VVV_MPHOT_Ks_V2 and VVV_VAR_V2), you can build a light curve while
keeping spatial constraints anchored to the master source table (see below).
Light-Curve Query Examples#
Get a VVV Source Light Curve and Variability Metrics#
Retrieve multi-epoch photometry and variability metrics for a known VVV source.
>>> query = """
... SELECT TOP 10 VVV.IAUNAME, VVV.SOURCEID, VVV.RA2000, VVV.DEC2000,
... M.MJD, M.KSMAG, M.KSERR,
... V.KSMEANMAG, V.KSAMPL, KSPROBVAR
... FROM VVV_CAT_V2 AS VVV
... JOIN VVV_MPHOT_Ks_V2 AS M ON VVV.SOURCEID = M.SOURCEID
... JOIN VVV_VAR_V2 AS V ON VVV.SOURCEID = V.SOURCEID
... WHERE VVV.IAUNAME='VVV J135433.73-594836.43'
... ORDER BY 1, 5
... """
>>> table = eso.query_tap(query, tap_endpoint="tap_cat")
In this query:
VVVis the VVV master catalogue alias.Mis the multi-epoch photometry table alias.Vis the variability table alias.
Get PESSTO Light-Curve Magnitudes in a Sky Region#
Retrieve selected magnitudes from the PESSTO light-curve catalogue for
transients within 0.05 deg (3 arcmin) around ESO 154-10.
>>> query = """
... SELECT host_id, transient_id, transient_classification,
... lc.B_VEGA_MAG, lc.B_VEGA_MAGERR,
... lc.R_AB_MAG, lc.R_AB_MAGERR,
... lc.R_VEGA_MAG, lc.R_VEGA_MAGERR
... FROM safcat.PESSTO_TRAN_CAT_V3 AS master
... JOIN safcat.PESSTO_MPHOT_V3 AS lc ON lc.SOURCE_ID = master.TRANSIENT_ID
... WHERE CONTAINS(
... POINT('', transient_raj2000, transient_decj2000),
... CIRCLE('', 41.2863, -55.7406, 0.05)
... ) = 1
... ORDER BY transient_id
... """
>>> table = eso.query_tap(query, tap_endpoint="tap_cat")
The light-curve table does not provide coordinates directly, so it is joined to
the PESSTO master catalogue for spatial filtering. To retrieve all available
magnitude columns instead of only B and R, use lc.* in the
SELECT clause.
This can also be done using a name resolver for the target coordinates, as previously shown above.
>>> import astropy.units as u
>>> from astropy.coordinates import SkyCoord
>>> target = SkyCoord.from_name("ESO 154-10")
>>> ra_deg = target.icrs.ra.to_value(u.deg)
>>> dec_deg = target.icrs.dec.to_value(u.deg)
>>> radius_deg = (3 * u.arcmin).to_value(u.deg)
>>> query = f"""
... SELECT host_id, transient_id, transient_classification,
... lc.B_VEGA_MAG, lc.B_VEGA_MAGERR,
... lc.R_AB_MAG, lc.R_AB_MAGERR,
... lc.R_VEGA_MAG, lc.R_VEGA_MAGERR
... FROM safcat.PESSTO_TRAN_CAT_V3 AS master
... JOIN safcat.PESSTO_MPHOT_V3 AS lc ON lc.SOURCE_ID = master.TRANSIENT_ID
... WHERE CONTAINS(
... POINT('', transient_raj2000, transient_decj2000),
... CIRCLE('', {ra_deg}, {dec_deg}, {radius_deg})
... ) = 1
... ORDER BY transient_id
... """
>>> table = eso.query_tap(query, tap_endpoint="tap_cat")