Skip to content

Commit 6738f84

Browse files
authored
Merge pull request #1505 from jd-au/feature/casda-astroquery
Create CASDA astroquery module
2 parents e7d94e0 + 3284d8d commit 6738f84

File tree

11 files changed

+714
-0
lines changed

11 files changed

+714
-0
lines changed

CHANGES.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
New Tools and Services
55
----------------------
66

7+
casda
8+
^^^^^
9+
10+
- Module added to access data from the CSIRO ASKAP Science Data Archive (CASDA) [#1505]
11+
712

813
Service fixes and enhancements
914
------------------------------
@@ -26,6 +31,9 @@ besancon
2631
cadc
2732
^^^^
2833

34+
casda
35+
^^^^^
36+
2937
cds
3038
^^^
3139

astroquery/casda/__init__.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""
2+
CSIRO ASKAP Science Data Archive (CASDA)
3+
"""
4+
from astropy import config as _config
5+
6+
7+
class Conf(_config.ConfigNamespace):
8+
"""
9+
Configuration parameters for `astroquery.casda`.
10+
"""
11+
12+
server = _config.ConfigItem(
13+
['https://casda.csiro.au/casda_vo_tools/sia2/query'],
14+
'Name of the CASDA SIA server to use.'
15+
)
16+
timeout = _config.ConfigItem(
17+
30,
18+
'Time limit for connecting to CASDA server.'
19+
)
20+
21+
22+
conf = Conf()
23+
24+
from .core import Casda, CasdaClass
25+
26+
__all__ = ['Casda', 'CasdaClass', 'conf']

astroquery/casda/core.py

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Licensed under a 3-clause BSD style license - see LICENSE.rst
2+
3+
# 1. standard library imports
4+
from io import BytesIO
5+
6+
# 2. third party imports
7+
import astropy.units as u
8+
import astropy.coordinates as coord
9+
from astropy.table import Table
10+
11+
# 3. local imports - use relative imports
12+
# commonly required local imports shown below as example
13+
# all Query classes should inherit from BaseQuery.
14+
from ..query import BaseQuery
15+
# has common functions required by most modules
16+
from ..utils import commons
17+
# prepend_docstr is a way to copy docstrings between methods
18+
from ..utils import prepend_docstr_nosections
19+
# async_to_sync generates the relevant query tools from _async methods
20+
from ..utils import async_to_sync
21+
# import configurable items declared in __init__.py
22+
from . import conf
23+
24+
# export all the public classes and methods
25+
__all__ = ['Casda', 'CasdaClass']
26+
27+
28+
@async_to_sync
29+
class CasdaClass(BaseQuery):
30+
31+
"""
32+
Class for accessing ASKAP data through the CSIRO ASKAP Science Data Archive (CASDA). Typical usage:
33+
34+
result = Casda.query_region('22h15m38.2s -45d50m30.5s', radius=0.5 * u.deg)
35+
"""
36+
# use the Configuration Items imported from __init__.py to set the URL,
37+
# TIMEOUT, etc.
38+
URL = conf.server
39+
TIMEOUT = conf.timeout
40+
41+
def query_region_async(self, coordinates, radius=None, height=None, width=None,
42+
get_query_payload=False, cache=True):
43+
"""
44+
Queries a region around the specified coordinates. Either a radius or both a height and a width must be provided.
45+
46+
Parameters
47+
----------
48+
coordinates : str or `astropy.coordinates`.
49+
coordinates around which to query
50+
radius : str or `astropy.units.Quantity`.
51+
the radius of the cone search
52+
width : str or `astropy.units.Quantity`
53+
the width for a box region
54+
height : str or `astropy.units.Quantity`
55+
the height for a box region
56+
get_query_payload : bool, optional
57+
Just return the dict of HTTP request parameters.
58+
cache: bool, optional
59+
Use the astroquery internal query result cache
60+
61+
Returns
62+
-------
63+
response : `requests.Response`
64+
The HTTP response returned from the service.
65+
All async methods should return the raw HTTP response.
66+
"""
67+
request_payload = self._args_to_payload(coordinates=coordinates, radius=radius, height=height,
68+
width=width)
69+
if get_query_payload:
70+
return request_payload
71+
72+
response = self._request('GET', self.URL, params=request_payload,
73+
timeout=self.TIMEOUT, cache=cache)
74+
75+
# result = self._parse_result(response)
76+
return response
77+
78+
# Create the dict of HTTP request parameters by parsing the user
79+
# entered values.
80+
def _args_to_payload(self, **kwargs):
81+
request_payload = dict()
82+
83+
# Convert the coordinates to FK5
84+
coordinates = kwargs.get('coordinates')
85+
c = commons.parse_coordinates(coordinates).transform_to(coord.FK5)
86+
87+
if kwargs['radius'] is not None:
88+
radius = u.Quantity(kwargs['radius']).to(u.deg)
89+
pos = 'CIRCLE {} {} {}'.format(c.ra.degree, c.dec.degree, radius.value)
90+
elif kwargs['width'] is not None and kwargs['height'] is not None:
91+
width = u.Quantity(kwargs['width']).to(u.deg).value
92+
height = u.Quantity(kwargs['height']).to(u.deg).value
93+
top = c.dec.degree - (height/2)
94+
bottom = c.dec.degree + (height/2)
95+
left = c.ra.degree - (width/2)
96+
right = c.ra.degree + (width/2)
97+
pos = 'RANGE {} {} {} {}'.format(left, right, top, bottom)
98+
else:
99+
raise ValueError("Either 'radius' or both 'height' and 'width' must be supplied.")
100+
101+
request_payload['POS'] = pos
102+
103+
return request_payload
104+
105+
# the methods above implicitly call the private _parse_result method.
106+
# This should parse the raw HTTP response and return it as
107+
# an `astropy.table.Table`.
108+
def _parse_result(self, response, verbose=False):
109+
# if verbose is False then suppress any VOTable related warnings
110+
if not verbose:
111+
commons.suppress_vo_warnings()
112+
# try to parse the result into an astropy.Table, else
113+
# return the raw result with an informative error message.
114+
try:
115+
# do something with regex to get the result into
116+
# astropy.Table form. return the Table.
117+
data = BytesIO(response.content)
118+
table = Table.read(data)
119+
return table
120+
except ValueError as e:
121+
# catch common errors here, but never use bare excepts
122+
# return raw result/ handle in some way
123+
print("Failed to convert query result to table", e)
124+
return response
125+
126+
127+
# the default tool for users to interact with is an instance of the Class
128+
Casda = CasdaClass()

astroquery/casda/tests/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Licensed under a 3-clause BSD style license - see LICENSE.rst
2+
"""
3+
CSIRO ASKAP Science Data Archive (CASDA)
4+
"""

astroquery/casda/tests/data/box.xml

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<?xml-stylesheet href='https://casda.csiro.au/casda_vo_tools/votable.xsl' type='text/xsl'?>
3+
<VOTABLE version="1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.ivoa.net/xml/VOTable/v1.3" xmlns:stc="http://www.ivoa.net/xml/STC/v1.30" >
4+
<RESOURCE name="CASDA SIAPv2 Result" type='results'>
5+
<INFO name="QUERY_STATUS" value="OK">Successful query</INFO>
6+
<INFO name="Instrument" value="ASKAP">Instrument from which data originated </INFO>
7+
<INFO name="Server" value="https://casda.csiro.au/casda_vo_tools//tap">URL of the CASDA VO endpoint used </INFO>
8+
<INFO name="Service Short Name" value="CASDA TAP">Short name for the TAP service </INFO>
9+
<INFO name="Service Title" value="CSIRO ASKAP Science Data Archive TAP service">TAP service title </INFO>
10+
<INFO name="Identifier" value="ivo://casda.csiro.au/casda/TAP">Unique resource registry identifier</INFO>
11+
<INFO name="Service Publisher" value="The CASDA team">Publisher for the TAP service</INFO>
12+
<INFO name="Further Information" value="http://www.atnf.csiro.au/projects/askap/index.html">Link to further information on the data and usage of the service</INFO>
13+
<INFO name="Contact Person" value="CASDA Support &lt;[email protected]&gt;">Who to contact about this service </INFO>
14+
<INFO name="Copyright" value="Creative Commons Attribution 4.0 International Licence">CASDA's Data license</INFO>
15+
<INFO name="SIAP query" value="POS=RANGE 0 0 0 0">SIAP Query submitted by the user</INFO>
16+
<INFO name="Execution Time" value="100ms">Time taken to execute query</INFO>
17+
<INFO name="Datetime Requested" value="2019-06-21 00:49:11 UTC">Date and time that the request was received</INFO>
18+
<INFO name="Table Name" value="ivoa.obscore">Name of the table queried</INFO>
19+
<INFO name="Table Description" value="null">Description of the table queried</INFO>
20+
<INFO name="Table Long Description" value=" ">Long description of the table queried</INFO>
21+
<TABLE name="results">
22+
<FIELD name="dataproduct_type" ID="dataproduct_type" datatype="char" arraysize="255" ucd="meta.id" utype="obscore:Obs.dataProductType" >
23+
<DESCRIPTION>Logical data product type from the IVOA controlled list. Catalogues will be null but described in the dataproduct_subtype field.</DESCRIPTION>
24+
</FIELD>
25+
<FIELD name="calib_level" ID="calib_level" datatype="int" ucd="meta.code;obs.calib" utype="obscore:Obs.calibLevel" >
26+
<DESCRIPTION>Calibration level {0, 1, 2, 3}</DESCRIPTION>
27+
</FIELD>
28+
<FIELD name="obs_collection" ID="obs_collection" datatype="char" arraysize="255" ucd="meta.id" utype="obscore:DataID.Collection" >
29+
<DESCRIPTION>Name of the data collection</DESCRIPTION>
30+
</FIELD>
31+
<FIELD name="obs_id" ID="obs_id" datatype="char" arraysize="255" ucd="meta.id" utype="obscore:DataID.observationID" >
32+
<DESCRIPTION>Observation ID</DESCRIPTION>
33+
</FIELD>
34+
<FIELD name="obs_publisher_did" ID="obs_publisher_did" datatype="char" arraysize="255" ucd="meta.ref.url;meta.curation" utype="obscore:Curation.PublisherDID" >
35+
<DESCRIPTION>Dataset identifier given by the publisher</DESCRIPTION>
36+
</FIELD>
37+
<FIELD name="access_url" ID="access_url" datatype="char" arraysize="2000" ucd="meta.ref.url" utype="obscore:Access.Reference" >
38+
<DESCRIPTION>URL used to access (download) dataset</DESCRIPTION>
39+
</FIELD>
40+
<FIELD name="access_format" ID="access_format" datatype="char" arraysize="255" ucd="meta.code.mime" utype="obscore:Access.Format" >
41+
<DESCRIPTION>File content format</DESCRIPTION>
42+
</FIELD>
43+
<FIELD name="access_estsize" ID="access_estsize" datatype="long" unit="kbyte" ucd="phys.size;meta.file" utype="obscore:Access.Size" >
44+
<DESCRIPTION>Estimated size of dataset in kilobytes</DESCRIPTION>
45+
</FIELD>
46+
<FIELD name="target_name" ID="target_name" datatype="char" arraysize="255" ucd="meta.id;src" utype="obscore:Target.Name" >
47+
<DESCRIPTION>Astronomical object observed, if any</DESCRIPTION>
48+
</FIELD>
49+
<FIELD name="s_ra" ID="s_ra" datatype="double" unit="deg" ucd="pos.eq.ra" utype="obscore:Char.SpatialAxis.Coverage.Location.Coord.Position2D.Value2.C1" >
50+
<DESCRIPTION>Central right ascension, ICRS</DESCRIPTION>
51+
</FIELD>
52+
<FIELD name="s_dec" ID="s_dec" datatype="double" unit="deg" ucd="pos.eq.dec" utype="obscore:Char.SpatialAxis.Coverage.Location.Coord.Position2D.Value2.C2" >
53+
<DESCRIPTION>Central declination, ICRS</DESCRIPTION>
54+
</FIELD>
55+
<FIELD name="s_fov" ID="s_fov" datatype="double" unit="deg" ucd="phys.angSize;instr.fov" utype="obscore:Char.SpatialAxis.Coverage.Bounds.Extent.diameter" >
56+
<DESCRIPTION>Diameter (bounds) of the covered region</DESCRIPTION>
57+
</FIELD>
58+
<FIELD name="s_region" ID="s_region" datatype="char" arraysize="200" ucd="phys.angArea;obs" utype="obscore:Char.SpatialAxis.Coverage.Support.Area" >
59+
<DESCRIPTION>Region covered as specified in STC or ADQL</DESCRIPTION>
60+
</FIELD>
61+
<FIELD name="s_resolution" ID="s_resolution" datatype="double" unit="arcsec" ucd="pos.angResolution" utype="obscore:Char.SpatialAxis.Resolution.refval" >
62+
<DESCRIPTION>Spatial resolution of data as FWHM</DESCRIPTION>
63+
</FIELD>
64+
<FIELD name="t_min" ID="t_min" datatype="double" unit="d" ucd="time.start;obs.exposure" utype="obscore:Char.TimeAxis.Coverage.Bounds.Limits.Interval.StartTime" >
65+
<DESCRIPTION>Start time in MJD</DESCRIPTION>
66+
</FIELD>
67+
<FIELD name="t_max" ID="t_max" datatype="double" unit="d" ucd="time.end;obs.exposure" utype="obscore:Char.TimeAxis.Coverage.Bounds.Limits.Interval.StopTime" >
68+
<DESCRIPTION>Stop time in MJD</DESCRIPTION>
69+
</FIELD>
70+
<FIELD name="t_exptime" ID="t_exptime" datatype="double" unit="s" ucd="time.duration;obs.exposure" utype="obscore:Char.TimeAxis.Coverage.Support.Extent" >
71+
<DESCRIPTION>Total exposure time</DESCRIPTION>
72+
</FIELD>
73+
<FIELD name="t_resolution" ID="t_resolution" datatype="double" unit="s" ucd="time.resolution" utype="obscore:Char.TimeAxis.Resolution.refval" >
74+
<DESCRIPTION>Temporal resolution FWHM</DESCRIPTION>
75+
</FIELD>
76+
<FIELD name="em_min" ID="em_min" datatype="double" unit="m" ucd="em.wl;stat.min" utype="obscore:Char.SpectralAxis.Coverage.Bounds.Limits.Interval.LoLim" >
77+
<DESCRIPTION>Start in spectral coordinates</DESCRIPTION>
78+
</FIELD>
79+
<FIELD name="em_max" ID="em_max" datatype="double" unit="m" ucd="em.wl;stat.max" utype="obscore:Char.SpectralAxis.Coverage.Bounds.Limits.Interval.HiLim" >
80+
<DESCRIPTION>Stop in spectral coordinates</DESCRIPTION>
81+
</FIELD>
82+
<FIELD name="em_res_power" ID="em_res_power" datatype="double" ucd="spect.resolution" utype="obscore:Char.SpectralAxis.Resolution.ResolPower.refVal" >
83+
<DESCRIPTION>Spectral resolving power</DESCRIPTION>
84+
</FIELD>
85+
<FIELD name="o_ucd" ID="o_ucd" datatype="char" arraysize="255" ucd="meta.ucd" utype="obscore:Char.ObservableAxis.ucd" >
86+
<DESCRIPTION>UCD of observable (e.g. phot. plux. density)</DESCRIPTION>
87+
</FIELD>
88+
<FIELD name="pol_states" ID="pol_states" datatype="char" arraysize="255" ucd="meta.code;phys.polarization" utype="obscore:Char.PolarizationAxis.stateList" >
89+
<DESCRIPTION>List of polarization states or NULL if not applicable</DESCRIPTION>
90+
</FIELD>
91+
<FIELD name="facility_name" ID="facility_name" datatype="char" arraysize="255" ucd="meta.id;instr.tel" utype="obscore:Provenance.ObsConfig.facility.name" >
92+
<DESCRIPTION>Name of the facility used for this observation</DESCRIPTION>
93+
</FIELD>
94+
<FIELD name="instrument_name" ID="instrument_name" datatype="char" arraysize="255" ucd="meta.id;instr" utype="obscore:Provenance.ObsConfig.instrument.name" >
95+
<DESCRIPTION>Name of the instrument used for this observation</DESCRIPTION>
96+
</FIELD>
97+
<FIELD name="dataproduct_subtype" ID="dataproduct_subtype" datatype="char" arraysize="255" ucd="meta.id" utype="obscore:Obs.dataProductSubtype" >
98+
<DESCRIPTION>Further description of the type of data product, including where the dataproduct_type is null.</DESCRIPTION>
99+
</FIELD>
100+
<FIELD name="em_ucd" ID="em_ucd" datatype="char" arraysize="255" ucd="meta.ucd" utype="obscore:Char.SpectralAxis.ucd" >
101+
<DESCRIPTION>Nature of the spectral axis</DESCRIPTION>
102+
</FIELD>
103+
<FIELD name="em_unit" ID="em_unit" datatype="char" arraysize="255" ucd="meta.unit" utype="obscore:Char.SpectralAxis.unit" >
104+
<DESCRIPTION>Units along the spectral axis</DESCRIPTION>
105+
</FIELD>
106+
<FIELD name="em_resolution" ID="em_resolution" datatype="double" unit="m" ucd="spect.resolution;stat.mean" utype="obscore:Char.SpectralAxis.Resolution.refval.value" >
107+
<DESCRIPTION>Value of Resolution along the spectral axis</DESCRIPTION>
108+
</FIELD>
109+
<FIELD name="s_resolution_min" ID="s_resolution_min" datatype="double" unit="arcsec" ucd="pos.angResolution;stat.min" utype="obscore:Char.SpatialAxis.Resolution.Bounds.Limits.Interval.LoLim" >
110+
<DESCRIPTION>Resolution min value on spatial axis (FHWM of PSF)</DESCRIPTION>
111+
</FIELD>
112+
<FIELD name="s_resolution_max" ID="s_resolution_max" datatype="double" unit="arcsec" ucd="pos.angResolution;stat.max" utype="obscore:Char.SpatialAxis.Resolution.Bounds.Limits.Interval.HiLim" >
113+
<DESCRIPTION>Resolution max value on spatial axis</DESCRIPTION>
114+
</FIELD>
115+
<FIELD name="s_ucd" ID="s_ucd" datatype="char" arraysize="255" ucd="meta.ucd" utype="obscore:Char.SpatialAxis.ucd" >
116+
<DESCRIPTION>Ucd for the nature of the spatial axis (pos or u,v data)</DESCRIPTION>
117+
</FIELD>
118+
<FIELD name="s_unit" ID="s_unit" datatype="char" arraysize="255" ucd="meta.unit" utype="obscore:Char.SpatialAxis.unit" >
119+
<DESCRIPTION>Unit used for spatial axis</DESCRIPTION>
120+
</FIELD>
121+
<FIELD name="released_date" ID="released_date" datatype="char" arraysize="24" >
122+
<DESCRIPTION>The date that this data product was released</DESCRIPTION>
123+
</FIELD>
124+
<FIELD name="quality_level" ID="quality_level" datatype="char" arraysize="15" ucd="meta.code.qual" >
125+
<DESCRIPTION>Indicator of quality level, updated by validators</DESCRIPTION>
126+
</FIELD>
127+
<FIELD name="thumbnail_id" ID="thumbnail_id" datatype="long" >
128+
<DESCRIPTION>The id of the thumbnail or preview image for this data product.</DESCRIPTION>
129+
</FIELD>
130+
<DATA>
131+
<TABLEDATA>
132+
<TR><TD>cube</TD><TD>2</TD><TD>ASKAP Early Science Broadband Survey</TD><TD>1934</TD><TD>cube-502</TD><TD>https://data.csiro.au/casda_vo_proxy/vo/datalink/links?ID=cube-502</TD><TD>application/x-votable+xml;content=datalink</TD><TD>415027</TD><TD></TD><TD>333.16767306594</TD><TD>-45.302084636451</TD><TD>73.780732638883</TD><TD>POLYGON ICRS 339.76820580537014 -49.443580029864 326.65233789508 -49.50286732922895 327.5038361349502 -40.839037046421986 338.7583703836203 -40.78819873241401</TD><TD>0.005049654966844</TD><TD></TD><TD></TD><TD>0.0</TD><TD></TD><TD>0.214062548031738</TD><TD>0.2140625481845863</TD><TD>1.40049E9</TD><TD>phot.flux.density</TD><TD>/I/</TD><TD>ASKAP</TD><TD></TD><TD>cont.restored.t0</TD><TD>em.freq</TD><TD>m</TD><TD>1.528483173363071E-10</TD><TD>0.00394983877814</TD><TD>0.005049654966844</TD><TD>pos.eq</TD><TD>deg</TD><TD>2017-08-02T03:51:19.728Z</TD><TD>UNCERTAIN</TD><TD></TD></TR>
133+
<TR><TD>cube</TD><TD>2</TD><TD>ASKAP Early Science Broadband Survey</TD><TD>1934</TD><TD>cube-504</TD><TD>https://data.csiro.au/casda_vo_proxy/vo/datalink/links?ID=cube-504</TD><TD>application/x-votable+xml;content=datalink</TD><TD>415027</TD><TD></TD><TD>333.16767306594</TD><TD>-45.302084636451</TD><TD>73.780732638883</TD><TD>POLYGON ICRS 339.76820580537014 -49.443580029864 326.65233789508 -49.50286732922895 327.5038361349502 -40.839037046421986 338.7583703836203 -40.78819873241401</TD><TD>0.005049654966844</TD><TD></TD><TD></TD><TD>0.0</TD><TD></TD><TD>0.214062548031738</TD><TD>0.2140625481845863</TD><TD>1.40049E9</TD><TD>phot.flux.density</TD><TD>/I/</TD><TD>ASKAP</TD><TD></TD><TD>cont.noise.t0</TD><TD>em.freq</TD><TD>m</TD><TD>1.528483173363071E-10</TD><TD>0.00394983877814</TD><TD>0.005049654966844</TD><TD>pos.eq</TD><TD>deg</TD><TD>2017-08-02T03:51:19.728Z</TD><TD>UNCERTAIN</TD><TD></TD></TR>
134+
</TABLEDATA>
135+
</DATA>
136+
</TABLE>
137+
</RESOURCE>
138+
</VOTABLE>

0 commit comments

Comments
 (0)