Skip to content

Commit a5dfeb8

Browse files
authored
Merge pull request #2092 from bsipocz/irsa_add_cache
Cleanup Irsa module
2 parents f819810 + 2f0ab40 commit a5dfeb8

File tree

4 files changed

+75
-113
lines changed

4 files changed

+75
-113
lines changed

CHANGES.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ heasarc
3939
- Add alternative instance of HEASARC Server, maintained by
4040
INTEGRAL Science Data Center. [#1988]
4141

42+
irsa
43+
^^^^
44+
45+
- Adding ``cache`` kwarg to the class methods to be able to control the use
46+
of local cache. [#2092]
47+
48+
- Making optional kwargs keyword only. [#2092]
49+
4250
nasa_exoplanet_archive
4351
^^^^^^^^^^^^^^^^^^^^^^
4452

astroquery/irsa/core.py

Lines changed: 29 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -99,96 +99,34 @@
9999
constraints.
100100
"""
101101

102-
103102
import warnings
103+
from io import BytesIO
104104
import xml.etree.ElementTree as tree
105105

106-
import six
107106
import astropy.units as u
108107
import astropy.coordinates as coord
109108
import astropy.io.votable as votable
110109

111-
from ..query import BaseQuery
112-
from ..utils import commons
113-
from . import conf
114-
from ..exceptions import TableParseError, NoResultsWarning, InvalidQueryError
110+
from astroquery.query import BaseQuery
111+
from astroquery.utils import commons, async_to_sync
112+
from astroquery.irsa import conf
113+
from astroquery.exceptions import TableParseError, NoResultsWarning, InvalidQueryError
115114

116115

117116
__all__ = ['Irsa', 'IrsaClass']
118117

119118

119+
@async_to_sync
120120
class IrsaClass(BaseQuery):
121121
IRSA_URL = conf.server
122122
GATOR_LIST_URL = conf.gator_list_catalogs
123123
TIMEOUT = conf.timeout
124124
ROW_LIMIT = conf.row_limit
125125

126-
def query_region(self, coordinates=None, catalog=None, spatial='Cone',
127-
radius=10 * u.arcsec, width=None, polygon=None,
128-
get_query_payload=False, verbose=False, selcols=None):
129-
"""
130-
This function can be used to perform either cone, box, polygon or
131-
all-sky search in the catalogs hosted by the NASA/IPAC Infrared
132-
Science Archive (IRSA).
133-
134-
Parameters
135-
----------
136-
coordinates : str, `astropy.coordinates` object
137-
Gives the position of the center of the cone or box if
138-
performing a cone or box search. The string can give coordinates
139-
in various coordinate systems, or the name of a source that will
140-
be resolved on the server (see `here
141-
<https://irsa.ipac.caltech.edu/search_help.html>`_ for more
142-
details). Required if spatial is ``'Cone'`` or ``'Box'``. Optional
143-
if spatial is ``'Polygon'``.
144-
catalog : str
145-
The catalog to be used. To list the available catalogs, use
146-
:meth:`~astroquery.irsa.IrsaClass.print_catalogs`.
147-
spatial : str
148-
Type of spatial query: ``'Cone'``, ``'Box'``, ``'Polygon'``, and
149-
``'All-Sky'``. If missing then defaults to ``'Cone'``.
150-
radius : str or `~astropy.units.Quantity` object, [optional for spatial is ``'Cone'``]
151-
The string must be parsable by `~astropy.coordinates.Angle`. The
152-
appropriate `~astropy.units.Quantity` object from
153-
`astropy.units` may also be used. Defaults to 10 arcsec.
154-
width : str, `~astropy.units.Quantity` object [Required for spatial is ``'Polygon'``.]
155-
156-
The string must be parsable by `~astropy.coordinates.Angle`. The
157-
appropriate `~astropy.units.Quantity` object from `astropy.units`
158-
may also be used.
159-
polygon : list, [Required for spatial is ``'Polygon'``]
160-
A list of ``(ra, dec)`` pairs (as tuples), in decimal degrees,
161-
outlining the polygon to search in. It can also be a list of
162-
`astropy.coordinates` object or strings that can be parsed by
163-
`astropy.coordinates.ICRS`.
164-
get_query_payload : bool, optional
165-
If `True` then returns the dictionary sent as the HTTP request.
166-
Defaults to `False`.
167-
verbose : bool, optional.
168-
If `True` then displays warnings when the returned VOTable does not
169-
conform to the standard. Defaults to `False`.
170-
selcols : str, optional
171-
Target column list with value separated by a comma(,)
172-
173-
174-
Returns
175-
-------
176-
table : `~astropy.table.Table`
177-
A table containing the results of the query
178-
"""
179-
response = self.query_region_async(coordinates, catalog=catalog,
180-
spatial=spatial, radius=radius,
181-
width=width, polygon=polygon,
182-
get_query_payload=get_query_payload,
183-
selcols=selcols)
184-
if get_query_payload:
185-
return response
186-
return self._parse_result(response, verbose=verbose)
187-
188-
def query_region_async(self, coordinates=None, catalog=None,
126+
def query_region_async(self, coordinates=None, *, catalog=None,
189127
spatial='Cone', radius=10 * u.arcsec, width=None,
190128
polygon=None, get_query_payload=False,
191-
selcols=None):
129+
selcols=None, verbose=False, cache=True):
192130
"""
193131
This function serves the same purpose as
194132
:meth:`~astroquery.irsa.IrsaClass.query_region`, but returns the raw
@@ -228,6 +166,11 @@ def query_region_async(self, coordinates=None, catalog=None,
228166
Defaults to `False`.
229167
selcols : str, optional
230168
Target column list with value separated by a comma(,)
169+
verbose : bool, optional.
170+
If `True` then displays warnings when the returned VOTable does not
171+
conform to the standard. Defaults to `False`.
172+
cache : bool, optional
173+
Use local cache when set to `True`.
231174
232175
Returns
233176
-------
@@ -246,7 +189,8 @@ def query_region_async(self, coordinates=None, catalog=None,
246189
if get_query_payload:
247190
return request_payload
248191
response = self._request("GET", url=Irsa.IRSA_URL,
249-
params=request_payload, timeout=Irsa.TIMEOUT)
192+
params=request_payload, timeout=Irsa.TIMEOUT,
193+
cache=cache)
250194
return response
251195

252196
def _parse_spatial(self, spatial, coordinates, radius=None, width=None,
@@ -391,7 +335,7 @@ def _parse_result(self, response, verbose=False):
391335

392336
# Read it in using the astropy VO table reader
393337
try:
394-
first_table = votable.parse(six.BytesIO(response.content),
338+
first_table = votable.parse(BytesIO(response.content),
395339
pedantic=False).get_first_table()
396340
except Exception as ex:
397341
self.response = response
@@ -410,33 +354,41 @@ def _parse_result(self, response, verbose=False):
410354

411355
return table
412356

413-
def list_catalogs(self):
357+
def list_catalogs(self, cache=False):
414358
"""
415359
Return a dictionary of the catalogs in the IRSA Gator tool.
416360
361+
Parameters
362+
----------
363+
cache : bool
364+
Use local cache when set to `True`. Default is `False`.
365+
417366
Returns
418367
-------
419368
catalogs : dict
420369
A dictionary of catalogs where the key indicates the catalog
421370
name to be used in query functions, and the value is the verbose
422371
description of the catalog.
372+
423373
"""
424374
response = self._request("GET", url=Irsa.GATOR_LIST_URL,
425-
params=dict(mode='xml'), timeout=Irsa.TIMEOUT)
375+
params=dict(mode='xml'), cache=cache,
376+
timeout=Irsa.TIMEOUT)
426377

427378
root = tree.fromstring(response.content)
428379
catalogs = {}
429380
for catalog in root.findall('catalog'):
430381
catname = catalog.find('catname').text
431382
desc = catalog.find('desc').text
432383
catalogs[catname] = desc
384+
433385
return catalogs
434386

435-
def print_catalogs(self):
387+
def print_catalogs(self, cache=False):
436388
"""
437389
Display a table of the catalogs in the IRSA Gator tool.
438390
"""
439-
catalogs = self.list_catalogs()
391+
catalogs = self.list_catalogs(cache=cache)
440392
for catname in catalogs:
441393
print("{:30s} {:s}".format(catname, catalogs[catname]))
442394

@@ -447,7 +399,7 @@ def print_catalogs(self):
447399
def _parse_coordinates(coordinates):
448400
# borrowed from commons.parse_coordinates as from_name wasn't required in
449401
# this case
450-
if isinstance(coordinates, six.string_types):
402+
if isinstance(coordinates, str):
451403
try:
452404
c = coord.SkyCoord(coordinates, frame='icrs')
453405
warnings.warn("Coordinate string is being interpreted as an "

astroquery/irsa/tests/test_irsa.py

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
import astropy.coordinates as coord
1111
import astropy.units as u
1212

13-
from ...utils.testing_tools import MockResponse
14-
from ...utils import commons
15-
from ... import irsa
16-
from ...irsa import conf
13+
from astroquery.utils.testing_tools import MockResponse
14+
from astroquery.utils import commons
15+
from astroquery.irsa import Irsa, conf
16+
from astroquery import irsa
1717

1818
DATA_FILES = {'Cone': 'Cone.xml',
1919
'Box': 'Box.xml',
@@ -35,11 +35,11 @@ def patch_get(request):
3535
mp = request.getfixturevalue("monkeypatch")
3636
except AttributeError: # pytest < 3
3737
mp = request.getfuncargvalue("monkeypatch")
38-
mp.setattr(irsa.Irsa, '_request', get_mockreturn)
38+
mp.setattr(Irsa, '_request', get_mockreturn)
3939
return mp
4040

4141

42-
def get_mockreturn(method, url, params=None, timeout=10, **kwargs):
42+
def get_mockreturn(method, url, params=None, timeout=10, cache=False, **kwargs):
4343
filename = data_path(DATA_FILES[params['spatial']])
4444
content = open(filename, 'rb').read()
4545
return MockResponse(content, **kwargs)
@@ -78,45 +78,45 @@ def test_parse_coordinates(coordinates, expected):
7878

7979

8080
def test_args_to_payload():
81-
out = irsa.core.Irsa._args_to_payload("fp_psc")
81+
out = Irsa._args_to_payload("fp_psc")
8282
assert out == dict(catalog='fp_psc', outfmt=3, outrows=conf.row_limit,
8383
selcols='')
8484

8585

8686
@pytest.mark.parametrize(("coordinates"), OBJ_LIST)
8787
def test_query_region_cone_async(coordinates, patch_get):
88-
response = irsa.core.Irsa.query_region_async(
88+
response = Irsa.query_region_async(
8989
coordinates, catalog='fp_psc', spatial='Cone',
9090
radius=2 * u.arcmin, get_query_payload=True)
9191
assert response['radius'] == 2
9292
assert response['radunits'] == 'arcmin'
93-
response = irsa.core.Irsa.query_region_async(
93+
response = Irsa.query_region_async(
9494
coordinates, catalog='fp_psc', spatial='Cone', radius=2 * u.arcmin)
9595
assert response is not None
9696

9797

9898
@pytest.mark.parametrize(("coordinates"), OBJ_LIST)
9999
def test_query_region_cone(coordinates, patch_get):
100-
result = irsa.core.Irsa.query_region(
100+
result = Irsa.query_region(
101101
coordinates, catalog='fp_psc', spatial='Cone', radius=2 * u.arcmin)
102102

103103
assert isinstance(result, Table)
104104

105105

106106
@pytest.mark.parametrize(("coordinates"), OBJ_LIST)
107107
def test_query_region_box_async(coordinates, patch_get):
108-
response = irsa.core.Irsa.query_region_async(
108+
response = Irsa.query_region_async(
109109
coordinates, catalog='fp_psc', spatial='Box',
110110
width=2 * u.arcmin, get_query_payload=True)
111111
assert response['size'] == 120
112-
response = irsa.core.Irsa.query_region_async(
112+
response = Irsa.query_region_async(
113113
coordinates, catalog='fp_psc', spatial='Box', width=2 * u.arcmin)
114114
assert response is not None
115115

116116

117117
@pytest.mark.parametrize(("coordinates"), OBJ_LIST)
118118
def test_query_region_box(coordinates, patch_get):
119-
result = irsa.core.Irsa.query_region(
119+
result = Irsa.query_region(
120120
coordinates, catalog='fp_psc', spatial='Box', width=2 * u.arcmin)
121121

122122
assert isinstance(result, Table)
@@ -129,12 +129,9 @@ def test_query_region_box(coordinates, patch_get):
129129
(10.0 * u.deg, 10.0 * u.deg)]
130130

131131

132-
@pytest.mark.parametrize(("polygon"),
133-
[poly1,
134-
poly2
135-
])
132+
@pytest.mark.parametrize(("polygon"), [poly1, poly2])
136133
def test_query_region_async_polygon(polygon, patch_get):
137-
response = irsa.core.Irsa.query_region_async(
134+
response = Irsa.query_region_async(
138135
"m31", catalog="fp_psc", spatial="Polygon",
139136
polygon=polygon, get_query_payload=True)
140137

@@ -145,7 +142,7 @@ def test_query_region_async_polygon(polygon, patch_get):
145142
b1 = float(b1)
146143
np.testing.assert_almost_equal(a1, b1)
147144

148-
response = irsa.core.Irsa.query_region_async(
145+
response = Irsa.query_region_async(
149146
"m31", catalog="fp_psc", spatial="Polygon", polygon=polygon)
150147

151148
assert response is not None
@@ -156,7 +153,7 @@ def test_query_region_async_polygon(polygon, patch_get):
156153
poly2,
157154
])
158155
def test_query_region_polygon(polygon, patch_get):
159-
result = irsa.core.Irsa.query_region(
156+
result = Irsa.query_region(
160157
"m31", catalog="fp_psc", spatial="Polygon", polygon=polygon)
161158

162159
assert isinstance(result, Table)
@@ -166,7 +163,7 @@ def test_query_region_polygon(polygon, patch_get):
166163
zip(('Cone', 'Box', 'Polygon', 'All-Sky'),
167164
('Cone', 'Box', 'Polygon', 'NONE')))
168165
def test_spatial_valdi(spatial, result):
169-
out = irsa.core.Irsa._parse_spatial(
166+
out = Irsa._parse_spatial(
170167
spatial, coordinates='m31', radius=5 * u.deg, width=5 * u.deg,
171168
polygon=[(5 * u.hour, 5 * u.deg)] * 3)
172169
assert out['spatial'] == result
@@ -176,4 +173,4 @@ def test_spatial_valdi(spatial, result):
176173
'All-sky', 'invalid', 'blah')])
177174
def test_spatial_invalid(spatial):
178175
with pytest.raises(ValueError):
179-
irsa.core.Irsa._parse_spatial(spatial, coordinates='m31')
176+
Irsa._parse_spatial(spatial, coordinates='m31')

0 commit comments

Comments
 (0)