Skip to content

Commit

Permalink
Merge pull request #2264 from rickynilsson/fix_issue_2239
Browse files Browse the repository at this point in the history
Fix_issue_2239: Nasa Exoplanet Archive query_object method suddenly produces InvalidTableError
  • Loading branch information
bsipocz authored Mar 4, 2022
2 parents 4e35238 + 8732c6d commit 3342888
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 36 deletions.
7 changes: 6 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ gaia
the name provided by the user for the output file when the results are
returned by the TAP in compressed format. [#2077]

ipac.nexsci.nasa_exoplanet_archive
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

- Fixes to alias query, and regularize keyword removed from deprecated query_star() method. [#2264]

mast
^^^^

Expand Down Expand Up @@ -1163,4 +1168,4 @@ Infrastructure, Utility and Other Changes and Additions
0.1 (2013-09-19)
================

- Initial release. Includes features!
- Initial release. Includes features!
3 changes: 3 additions & 0 deletions astroquery/ipac/nexsci/nasa_exoplanet_archive/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ class Conf(_config.ConfigNamespace):
url_tap = _config.ConfigItem(
"https://exoplanetarchive.ipac.caltech.edu/TAP/",
"URL for the NASA Exoplanet Archive TAP")
url_aliaslookup = _config.ConfigItem(
"https://exoplanetarchive.ipac.caltech.edu/cgi-bin/Lookup/nph-aliaslookup.py?objname=",
"URL for the NASA Exoplanet Archive aliaslookup")
timeout = _config.ConfigItem(
600, "Time limit for requests from the NASA Exoplanet Archive servers")
cache = _config.ConfigItem(False, "Should the requests be cached?")
Expand Down
57 changes: 38 additions & 19 deletions astroquery/ipac/nexsci/nasa_exoplanet_archive/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import io
import re
import warnings
import requests
import json

# Import various astropy modules
import astropy.coordinates as coord
Expand Down Expand Up @@ -105,6 +107,8 @@ def get_access_url(service='tap'):
url = conf.url_tap
elif service == 'api':
url = conf.url_api
elif service == 'aliaslookup':
url = conf.url_aliaslookup
return url


Expand Down Expand Up @@ -138,7 +142,7 @@ class NasaExoplanetArchiveClass(BaseQuery):
"""

# When module us imported, __init__.py runs and loads a configuration object,
# setting the configuration parameters con.url, conf.timeout and conf.cache
# setting the configuration parameters conf.url, conf.timeout and conf.cache
URL_API = conf.url_api
URL_TAP = conf.url_tap
TIMEOUT = conf.timeout
Expand Down Expand Up @@ -377,7 +381,7 @@ def query_aliases(self, object_name, *, cache=None):
Parameters
----------
object_name : str
The name of a planet or star to regularize using the ``aliastable`` table.
The name of a planet or star to regularize using the ``aliaslookup`` service.
cache : bool, optional
Should the request result be cached? This can be useful for large repeated queries,
but since the data in the archive is updated regularly, this defaults to ``False``.
Expand All @@ -387,24 +391,47 @@ def query_aliases(self, object_name, *, cache=None):
response : list
A list of aliases found for the object name. The default name will be listed first.
"""
return list(
self.query_criteria(
"aliastable", objname=object_name.strip(), cache=cache, format="csv"
)["aliasdis"]
)
data = self._request_query_aliases(object_name)

try:
objname_split = object_name.split()
if len(objname_split) > 1 and len(objname_split[-1]) == 1 and objname_split[-1].isalpha():
pl_letter = object_name.split()[-1]
else:
pl_letter = ''

default_objname = [data['system']['system_info']['alias_set']['default_name']]
other_objnames = list(set(data['system']['objects']['stellar_set']['stars'][default_objname[0]]['alias_set']['aliases']) - set(default_objname))
other_objnames.sort()
aliases = default_objname + other_objnames

if pl_letter:
aliases = [a + ' ' + pl_letter for a in aliases]

except KeyError:
aliases = []
warnings.warn("No aliases found for name: '{0}'".format(object_name), NoResultsWarning)

return aliases

@class_or_instance
def _regularize_object_name(self, object_name):
"""Regularize the name of a planet or planet host using the ``aliastable`` table"""
"""Regularize the name of a planet or planet host using the ``aliaslookup`` service"""
try:
aliases = self.query_aliases(object_name, cache=False)
except RemoteServiceError:
except KeyError:
aliases = []
if aliases:
return aliases[0]
warnings.warn("No aliases found for name: '{0}'".format(object_name), NoResultsWarning)
return object_name

def _request_query_aliases(self, object_name):
"""Service request for query_aliases()"""
url = requests.get(get_access_url('aliaslookup')+object_name)
response = json.loads(url.text)
return response

# Look for response errors. This might need to be updated for TAP
def _handle_error(self, text):
"""
Expand Down Expand Up @@ -653,7 +680,7 @@ def _request_to_sql(self, request_payload):
@deprecated(since="v0.4.1", alternative="query_object")
@deprecated_renamed_argument(["show_progress", "table_path"],
[None, None], "v0.4.1", arg_in_kwargs=True)
def query_planet(self, planet_name, cache=None, regularize=True, **criteria):
def query_planet(self, planet_name, cache=None, **criteria):
"""
Search the ``exoplanets`` table for a confirmed planet
Expand All @@ -665,22 +692,18 @@ def query_planet(self, planet_name, cache=None, regularize=True, **criteria):
cache : bool, optional
Should the request result be cached? This can be useful for large repeated queries,
but since the data in the archive is updated regularly, this defaults to ``False``.
regularize : bool, optional
If ``True``, the ``aliastable`` will be used to regularize the target name.
**criteria
Any other filtering criteria to apply. Values provided using the ``where`` keyword will
be ignored.
"""
if regularize:
planet_name = self._regularize_object_name(planet_name)
criteria = self._handle_all_columns_argument(**criteria)
criteria["where"] = "pl_name='{0}'".format(planet_name.strip())
return self.query_criteria("exoplanets", cache=cache, **criteria)

@deprecated(since="v0.4.1", alternative="query_object")
@deprecated_renamed_argument(["show_progress", "table_path"],
[None, None], "v0.4.1", arg_in_kwargs=True)
def query_star(self, host_name, cache=None, regularize=True, **criteria):
def query_star(self, host_name, cache=None, **criteria):
"""
Search the ``exoplanets`` table for a confirmed planet host
Expand All @@ -692,14 +715,10 @@ def query_star(self, host_name, cache=None, regularize=True, **criteria):
cache : bool, optional
Should the request result be cached? This can be useful for large repeated queries,
but since the data in the archive is updated regularly, this defaults to ``False``.
regularize : bool, optional
If ``True``, the ``aliastable`` will be used to regularize the target name.
**criteria
Any other filtering criteria to apply. Values provided using the ``where`` keyword will
be ignored.
"""
if regularize:
host_name = self._regularize_object_name(host_name)
criteria = self._handle_all_columns_argument(**criteria)
criteria["where"] = "pl_hostname='{0}'".format(host_name.strip())
return self.query_criteria("exoplanets", cache=cache, **criteria)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
{
"manifest": {
"requested_name": "bet pic",
"resolved_name": "bet Pic",
"lookup_status": "OK",
"compilation_date": "2022-01-28 14:31:40.254838",
"system_snapshot": {
"number_of_stars": 1,
"number_of_planets": 2
}
},
"system": {
"system_info": {
"id": "bet Pic",
"alias_set": {
"item_count": 1,
"default_name": "bet Pic",
"aliases": [
"bet Pic"
]
}
},
"objects": {
"stellar_set": {
"item_count": 1,
"stars": {
"bet Pic": {
"alias_set": {
"item_count": 14,
"aliases": [
"TIC 270577175",
"Gaia DR2 4792774797545105664",
"GJ 219",
"HR 2020",
"bet Pic",
"HD 39060",
"HIP 27321",
"SAO 234134",
"CD-51 1620",
"CPD-51 774",
"IRAS 05460-5104",
"TYC 8099-01392-1",
"2MASS J05471708-5103594",
"WISE J054717.10-510358.4"
]
}
}
}
},
"planet_set": {
"item_count": 2,
"planets": {
"bet Pic b": {
"alias_set": {
"item_count": 14,
"aliases": [
"GJ 219 b",
"HR 2020 b",
"bet Pic b",
"HD 39060 b",
"HIP 27321 b",
"SAO 234134 b",
"CD-51 1620 b",
"CPD-51 774 b",
"IRAS 05460-5104 b",
"TYC 8099-01392-1 b",
"2MASS J05471708-5103594 b",
"WISE J054717.10-510358.4 b",
"TIC 270577175 b",
"Gaia DR2 4792774797545105664 b"
]
}
},
"bet Pic c": {
"alias_set": {
"item_count": 14,
"aliases": [
"GJ 219 c",
"HR 2020 c",
"bet Pic c",
"HD 39060 c",
"HIP 27321 c",
"SAO 234134 c",
"CD-51 1620 c",
"CPD-51 774 c",
"IRAS 05460-5104 c",
"TYC 8099-1392-1 c",
"2MASS J05471708-5103594 c",
"WISE J054717.10-510358.4 c",
"TIC 270577175 c",
"Gaia DR2 4792774797545105664 c"
]
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from astroquery.exceptions import NoResultsWarning
from astroquery.utils.mocks import MockResponse
from astroquery.ipac.nexsci.nasa_exoplanet_archive.core import NasaExoplanetArchiveClass, conf, InvalidTableError
from astroquery.ipac.nexsci.nasa_exoplanet_archive.core import NasaExoplanetArchiveClass, conf, InvalidTableError, get_access_url
try:
from unittest.mock import Mock, patch, PropertyMock
except ImportError:
Expand Down Expand Up @@ -119,16 +119,53 @@ def patch_get(request): # pragma: nocover
return mp


def test_regularize_object_name(patch_get):
NasaExoplanetArchiveMock = NasaExoplanetArchiveClass()
# aliaslookup file in data/
LOOKUP_DATA_FILE = 'bpic_aliaslookup.json'


def data_path(filename):
data_dir = os.path.join(os.path.dirname(__file__), 'data')
return os.path.join(data_dir, filename)


# monkeypatch replacement request function
def query_aliases_mock(self, *args, **kwargs):
with open(data_path(LOOKUP_DATA_FILE), 'rb') as f:
response = json.load(f)
return response


# use a pytest fixture to create a dummy 'requests.get' function,
# that mocks(monkeypatches) the actual 'requests.get' function:
@pytest.fixture
def query_aliases_request(request):
mp = request.getfixturevalue("monkeypatch")
mp.setattr(NasaExoplanetArchiveClass, '_request_query_aliases', query_aliases_mock)
return mp


def test_query_aliases(query_aliases_request):
nasa_exoplanet_archive = NasaExoplanetArchiveClass()
result = nasa_exoplanet_archive.query_aliases(object_name='bet Pic')
assert len(result) > 10
assert 'GJ 219' in result
assert 'bet Pic' in result
assert '2MASS J05471708-5103594' in result


def test_query_aliases_planet(query_aliases_request):
nasa_exoplanet_archive = NasaExoplanetArchiveClass()
result = nasa_exoplanet_archive.query_aliases('bet Pic b')
assert len(result) > 10
assert 'GJ 219 b' in result
assert 'bet Pic b' in result
assert '2MASS J05471708-5103594 b' in result

NasaExoplanetArchiveMock._tap_tables = ['list']
assert NasaExoplanetArchiveMock._regularize_object_name("kepler 2") == "HAT-P-7"
assert NasaExoplanetArchiveMock._regularize_object_name("kepler 1 b") == "TrES-2 b"

with pytest.warns(NoResultsWarning) as warning:
NasaExoplanetArchiveMock._regularize_object_name("not a planet")
assert "No aliases found for name: 'not a planet'" == str(warning[0].message)
def test_get_access_url():
assert get_access_url('tap') == conf.url_tap
assert get_access_url('api') == conf.url_api
assert get_access_url('aliaslookup') == conf.url_aliaslookup


def test_backwards_compat(patch_get):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def test_query_region():
def test_query_aliases():
name = "bet Pic"
aliases = NasaExoplanetArchive.query_aliases(name)
assert len(aliases) == 12
assert len(aliases) > 10
assert "HD 39060" in aliases


Expand Down
Loading

0 comments on commit 3342888

Please sign in to comment.