Skip to content

Commit

Permalink
addressing comments, second iteration
Browse files Browse the repository at this point in the history
  • Loading branch information
burnout87 committed May 16, 2022
1 parent 1a80f5d commit 7fd6402
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 95 deletions.
13 changes: 7 additions & 6 deletions astroquery/desi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ class Conf(_config.ConfigNamespace):
"""
Configuration parameters for `astroquery.desi`.
"""
server = _config.ConfigItem(
['https://portal.nersc.gov/cfs/cosmo/data/legacysurvey/',
legacysurvey_service_url = _config.ConfigItem(
['https://www.legacysurvey.org/viewer/fits-cutout',
],
'base url')
'url for the LegacySurvey service')

timeout = _config.ConfigItem(
30,
'Time limit for connecting to template_module server.')
tap_service_url = _config.ConfigItem(
['https://datalab.noirlab.edu/tap',
],
'url for the TAP service')


conf = Conf()
Expand Down
64 changes: 42 additions & 22 deletions astroquery/desi/core.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,48 @@
# Licensed under a 3-clause BSD style license - see LICENSE.rst
import urllib.error
import requests
import warnings

import pyvo as vo
import numpy as np
import astropy.coordinates as coord

from astroquery.exceptions import NoResultsWarning
from astroquery.query import BaseQuery
from astroquery.utils import commons, async_to_sync

from . import conf

from astroquery.desi import conf

__all__ = ['DESILegacySurvey', 'DESILegacySurveyClass']


@async_to_sync
class DESILegacySurveyClass(BaseQuery):
URL = conf.server
TIMEOUT = conf.timeout

def query_region(self, coordinates, radius, data_release=9):
def query_region(self, coordinates, radius, *, data_release=9):
"""
Queries a region around the specified coordinates.
Parameters
----------
coordinates : str or `astropy.coordinates`.
coordinates around which to query
radius : str or `astropy.units.Quantity`.
the radius of the cone search
coordinates : `astropy.coordinates`
coordinates around which to query.
radius : `astropy.units.Quantity`
the radius of the cone search.
data_release: int
the data release of the LegacySurvey to use.
Returns
-------
response : `astropy.table.Table`
"""

url = 'https://datalab.noirlab.edu/tap'
tap_service = vo.dal.TAPService(url)
qstr = "SELECT all * FROM ls_dr" + str(data_release) + ".tractor WHERE dec>" + str(coordinates.dec.deg - radius.deg) + " and dec<" + str(
coordinates.dec.deg + radius.deg) + " and ra>" + str(coordinates.ra.deg - radius.deg / np.cos(coordinates.dec.deg * np.pi / 180.)) + " and ra<" + str(
coordinates.ra.deg + radius.deg / np.cos(coordinates.dec.deg * np.pi / 180))
tap_service = vo.dal.TAPService(conf.tap_service_url)
coordinates_transformed = coordinates.transform_to(coord.ICRS)

qstr = (f"SELECT all * FROM ls_dr{data_release}.tractor WHERE "
f"dec>{coordinates_transformed.dec.deg - radius.deg} and "
f"dec<{coordinates_transformed.dec.deg + radius.deg} and "
f"ra>{coordinates_transformed.ra.deg - radius.deg / np.cos(coordinates_transformed.dec.deg * np.pi / 180.)} and "
f"ra<{coordinates_transformed.ra.deg + radius.deg / np.cos(coordinates_transformed.dec.deg * np.pi / 180)}")

tap_result = tap_service.run_sync(qstr)
tap_result = tap_result.to_table()
Expand All @@ -50,26 +52,44 @@ def query_region(self, coordinates, radius, data_release=9):

return filtered_table

def get_images(self, position, data_release=9, pixels=None, radius=None, show_progress=True, image_band='g'):
def get_images(self, position, pixels, radius, *, data_release=9, show_progress=True, image_band='g'):
"""
Downloads the images for a certain region of interest.
Parameters
-------
position: `astropy.coordinates`.
coordinates around which we define our region of interest.
radius: `astropy.units.Quantity`.
the radius of the cone search.
data_release: int
the data release of the LegacySurvey to use.
Returns
-------
A list of `astropy.io.fits.HDUList` objects.
list: A list of `astropy.io.fits.HDUList` objects.
"""

position_transformed = position.transform_to(coord.ICRS)

image_size_arcsec = radius.arcsec
pixsize = 2 * image_size_arcsec / pixels

image_url = 'https://www.legacysurvey.org/viewer/fits-cutout?ra=' + str(position.ra.deg) + '&dec=' + str(position.dec.deg) + '&size=' + str(
pixels) + '&layer=ls-dr' + str(data_release) + '&pixscale=' + str(pixsize) + '&bands=' + image_band
image_url = (f"{conf.legacysurvey_service_url}?"
f"ra={position_transformed.ra.deg}&"
f"dec={position_transformed.dec.deg}&"
f"size={pixels}&"
f"layer=ls-dr{data_release}&"
f"pixscale={pixsize}&"
f"bands={image_band}")

file_container = commons.FileContainer(image_url, encoding='binary', show_progress=show_progress)

try:
fits_file = file_container.get_fits()
except (requests.exceptions.HTTPError, urllib.error.HTTPError) as e:
# TODO not sure this is the most suitable exception
raise NoResultsWarning(f"{str(e)} - Problem retrieving the file at the url: {str(image_url)}")
fits_file = None
warnings.warn(f"{str(e)} - Problem retrieving the file at the url: {image_url}", NoResultsWarning)

return [fits_file]

Expand Down
1 change: 0 additions & 1 deletion astroquery/desi/tests/setup_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@
def get_package_data():
paths = [os.path.join('data', '*.txt'),
os.path.join('data', '*.fits'),
os.path.join('data', '*.fits.gz'),
]
return {'astroquery.desi.tests': paths}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

from astropy.table import Table
from astropy.io import fits
from pyvo.dal import TAPResults
from astropy import coordinates as coord
from astroquery.utils.mocks import MockResponse
from astroquery.utils import commons
from astroquery import desi
from urllib import parse
from contextlib import contextmanager

from ... import desi
from ...utils.mocks import MockResponse
from ...utils import commons

DATA_FILES = {
'dummy_tap_table': 'dummy_table.txt',
Expand All @@ -21,18 +21,15 @@
}

coords = commons.ICRSCoord('11h04m27s +38d12m32s')
radius = commons.ArcminRadiusGenerator(0.5)
radius = coord.Angle(0.5, unit='arcmin')
pixels = 60
data_release = 9
emispheres_list = ['north', 'south']


@pytest.fixture
def patch_get(request):
try:
mp = request.getfixturevalue("monkeypatch")
except AttributeError: # pytest < 3
mp = request.getfuncargvalue("monkeypatch")
mp = request.getfixturevalue("monkeypatch")

mp.setattr(desi.DESILegacySurvey, '_request', get_mockreturn)
return mp
Expand Down Expand Up @@ -68,10 +65,7 @@ def get_readable_fileobj_mockreturn(filename, **kwargs):

@pytest.fixture
def patch_tap(request):
try:
mp = request.getfixturevalue("monkeypatch")
except AttributeError: # pytest < 3
mp = request.getfuncargvalue("monkeypatch")
mp = request.getfixturevalue("monkeypatch")

mp.setattr(vo.dal.TAPService, 'run_sync', tap_mockreturn)
return mp
Expand All @@ -95,7 +89,7 @@ def tap_mockreturn(url, params=None, timeout=10, **kwargs):
content_table = Table.read(data_path(DATA_FILES['dummy_tap_table']),
format='ascii.csv', comment='#')
votable_table = astropy.io.votable.from_table(content_table)
return TAPResults(votable_table)
return vo.dal.TAPResults(votable_table)


def data_path(filename):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
# Licensed under a 3-clause BSD style license - see LICENSE.rst

import pytest
import astroquery.desi

from astropy.io.fits import HDUList
from astropy.coordinates import SkyCoord
from astropy.coordinates import Angle
from astropy.table import Table
from astroquery.exceptions import NoResultsWarning


@pytest.mark.remote_data
class TestLegacySurveyClass:

def test_query_region(self):
import astroquery.desi
from astropy.coordinates import SkyCoord
from astropy.coordinates import Angle
from astropy.table import Table

ra = Angle('11h04m27s', unit='hourangle').degree
dec = Angle('+38d12m32s', unit='hourangle').degree
Expand All @@ -26,9 +25,6 @@ def test_query_region(self):

@pytest.mark.parametrize("valid_inputs", [True, False])
def test_get_images(self, valid_inputs):
import astroquery.desi
from astropy.coordinates import SkyCoord
from astropy.coordinates import Angle

if valid_inputs:
ra = Angle('11h04m27s', unit='hourangle').degree
Expand All @@ -45,9 +41,9 @@ def test_get_images(self, valid_inputs):
radius = Angle(radius_input, unit='arcmin')

if valid_inputs:
query1 = astroquery.desi.DESILegacySurvey.get_images(pos, data_release=9, radius=radius, pixels=pixels)
query1 = astroquery.desi.DESILegacySurvey.get_images(pos, pixels, radius, data_release=9)
assert isinstance(query1, list)
assert isinstance(query1[0], HDUList)
else:
with pytest.raises(NoResultsWarning):
astroquery.desi.DESILegacySurvey.get_images(pos, data_release=9, radius=radius, pixels=pixels)
astroquery.desi.DESILegacySurvey.get_images(pos, pixels, radius, data_release=9)
4 changes: 0 additions & 4 deletions astroquery/utils/commons.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ def FK4CoordGenerator(*args, **kwargs):
return coord.SkyCoord(*args, frame='fk4', **kwargs)


def ArcminRadiusGenerator(*args, **kwargs):
return coord.Angle(*args, unit='arcmin', **kwargs)


ICRSCoord = coord.SkyCoord
CoordClasses = (coord.SkyCoord, BaseCoordinateFrame)

Expand Down
55 changes: 18 additions & 37 deletions docs/desi/desi.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.. _astroquery.desi:

************************************
*********************************************
DESI LegacySurvey Queries (`astroquery.desi`)
************************************
*********************************************

Getting started
===============
Expand All @@ -12,13 +12,13 @@ Presented below are examples that illustrate the different types of queries
that can be formulated.

Query a region
===============
==============

This example shows how to query a certain region with DesiLegacySurvey.
We'll use a set of coordinates that define the region of interest,
and search within a 5 arcmin radius.

.. code-block:: python
.. doctest-remote-data::

>>> from astroquery.desi import DESILegacySurvey
>>> from astropy.coordinates import Angle, SkyCoord
Expand All @@ -28,41 +28,43 @@ and search within a 5 arcmin radius.
>>> radius = Angle(5, unit='arcmin')
>>> table_out = DESILegacySurvey.query_region(coordinates, radius, data_release=9)
>>> print(table_out[:5])
ls_id dec ra ... type wise_coadd_id
---------------- ------------------ ------------------ ... ---- -------------
ls_id dec ra ... type wise_coadd_id
...
---------------- ----------------- ------------------ ... ---- -------------
9907734382838387 38.12628495570797 166.0838654387131 ... PSF 1667p378
9907734382838488 38.12798336424771 166.0922968862182 ... PSF 1667p378
9907734382838554 38.12858283671958 166.0980673954384 ... REX 1667p378
9907734382838564 38.12840803351445 166.09921863682337 ... EXP 1667p378
9907734382838584 38.12836885301038 166.10070750146636 ... REX 1667p378
9907734382838564 38.12840803351445 166.09921863682337 ... EXP 1667p378
9907734382838584 38.12836885301038 166.10070750146636 ... REX 1667p378

The result is an astropy.Table.

Get images
===============
==========

To download images for a certain region of interest,
we can define our region in the same way used in the example above.

.. code-block:: python
.. doctest-remote-data::

>>> from astroquery.desi import DESILegacySurvey
>>> from astropy.coordinates import Angle, SkyCoord
>>>
>>> ra = Angle('11h04m27s', unit='hourangle').degree
>>> dec = Angle('+38d12m32s', unit='hourangle').degree
>>> pos = SkyCoord(ra, dec, unit='degree')
>>> radius = Angle(0.5, unit='arcmin')
>>> radius_input = 0.5
>>> pixels = 60
>>> im = DESILegacySurvey.get_images(pos, data_release=9, radius=radius, pixels=pixels)
>>>
>>> pos = SkyCoord(ra, dec, unit='degree')
>>> radius = Angle(radius_input, unit='arcmin')
>>> im = DESILegacySurvey.get_images(pos, pixels, radius, data_release=9)

All the information we need can be found within the object "im".

.. code-block:: python
.. doctest-remote-data::

>>> hdul = im[0]
>>> hdul[0].header
SIMPLE = T / file does conform to FITS standard
BITPIX = -32 / number of bits per data pixel
NAXIS = 2 / number of data axes
Expand All @@ -88,24 +90,3 @@ All the information we need can be found within the object "im".

The variable "im" is a list of `~astropy.io.fits.HDUList` objects, one entry for
each corresponding object.

In case a set of not valid coordinates is provided, then a `astroquery.exceptions.NoResultsWarning`
exception is raised, as shown in the example below.

.. code-block:: python
>>> from astroquery.desi import DESILegacySurvey
>>> from astropy.coordinates import Angle, SkyCoord
>>> ra = Angle('86.633212', unit='degree').degree
>>> dec = Angle('22.01446', unit='degree').degree
>>> radius_input = 3
>>> pixels = 1296000
>>> pos = SkyCoord(ra, dec, unit='degree')
>>> radius = Angle(radius_input, unit='arcmin')
>>> pixels = 60
>>> im = DESILegacySurvey.get_images(pos, data_release=9, radius=radius, pixels=pixels)
.. code-block:: python
astroquery.exceptions.NoResultsWarning: HTTP Error 500: Internal Server Error - Problem retrieving the file at the url: https://www.legacysurvey.org/viewer/fits-cutout?ra=86.633212&dec=22.01446&size=1296000&layer=ls-dr9&pixscale=0.0002777777777777778&bands=g
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ The following modules have been completed using a common API:
cds/cds.rst
linelists/cdms/cdms.rst
dace/dace.rst
desi/desi.rst
esa/hsa/hsa.rst
esa/hubble/hubble.rst
esa/iso/iso.rst
Expand Down

0 comments on commit 7fd6402

Please sign in to comment.