Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed failing PANSTARRS Catalog queries #2727

Merged
merged 4 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ mast

- Expanding ``Cutouts`` functionality to support TICA HLSPs now available through
``TesscutClass``. [##2668]

- Resolved issue making PANSTARRS catalog queries when columns and sorting is specified. [#2727]

nist
^^^^
Expand Down
12 changes: 10 additions & 2 deletions astroquery/mast/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,11 @@ def query_region_async(self, coordinates, *, radius=0.2*u.deg, catalog="Hsc",
for prop, value in kwargs.items():
params[prop] = value

return self._current_connection.service_request_async(service, params, pagesize=pagesize, page=page)
# Parameters will be passed as JSON objects only when accessing the PANSTARRS API
use_json = catalog.lower() == 'panstarrs'

return self._current_connection.service_request_async(service, params, pagesize=pagesize, page=page,
use_json=use_json)

@class_or_instance
def query_object_async(self, objectname, *, radius=0.2*u.deg, catalog="Hsc",
Expand Down Expand Up @@ -313,7 +317,11 @@ def query_criteria_async(self, catalog, *, pagesize=None, page=None, **criteria)
raise InvalidQueryError("At least one non-positional criterion must be supplied.")
params["filters"] = filters

return self._current_connection.service_request_async(service, params, pagesize=pagesize, page=page)
# Parameters will be passed as JSON objects only when accessing the PANSTARRS API
use_json = catalog.lower() == 'panstarrs'

return self._current_connection.service_request_async(service, params, pagesize=pagesize, page=page,
use_json=use_json)

@class_or_instance
def query_hsc_matchid_async(self, match, *, version=3, pagesize=None, page=None):
Expand Down
22 changes: 21 additions & 1 deletion astroquery/mast/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,27 @@ def service_request_async(self, service, params, page_size=None, page=None, use_
catalogs_request.extend(self._build_catalogs_params(params))
else:
headers['Content-Type'] = 'application/json'
catalogs_request = params

# Parameter syntax needs to be updated only for PANSTARRS catalog queries
if service.lower() == 'panstarrs':
catalogs_request.extend(self._build_catalogs_params(params))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This call updates the syntax of the parameters so it's readable in the backend. It needs to be made here so that users can add criteria decorators to their PANSTARRS queries, despite it being an API that requires params to be passed as JSON. It returns the params in list format, so I then have to convert it back to dictionary so that it can be dumped as a JSON dict later in the request.


# After parameter syntax is updated, revert back to dictionary
# so params can be passed as a JSON dictionary
params_dict = {}
for key, val in catalogs_request:
params_dict.setdefault(key, []).append(val)
catalogs_request = params_dict

# Removing single-element lists. Single values will live on their own (except for `sort_by`)
for key in catalogs_request.keys():
if (key != 'sort_by') & (len(catalogs_request[key]) == 1):
catalogs_request[key] = catalogs_request[key][0]

# Otherwise, catalogs_request can remain as the original params dict
else:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This else statement will ignore all the logic from above if the service is not the PANSTARRS API. This is because the MastMissions API also requires params to be passed as JSON, but doesn't jive with the parameter syntax transformation that happens above. Namely because of the way the coordinates are passed for MastMissions.

catalogs_request = params

response = self._request('POST', request_url, data=catalogs_request, headers=headers, use_json=use_json)
return response

Expand Down
11 changes: 11 additions & 0 deletions astroquery/mast/tests/test_mast_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,17 @@ def test_catalogs_query_criteria(self):
assert isinstance(result, Table)
assert 'PSO J254.2861-04.1091' in result['objName']

result = mast.Catalogs.query_criteria(coordinates="158.47924 -7.30962",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the unit test, I'm using one of the queries that was reported to fail by one of our users. It includes the columns and sort_by arguments, both arguments were causing the 422 error observed by both users. This unit test will catch any future issues with the criteria syntax, should they arise.

radius=0.01,
catalog="PANSTARRS",
table="mean",
data_release="dr2",
nStackDetections=[("gte", "1")],
columns=["objName", "distance"],
sort_by=[("asc", "distance")])
assert isinstance(result, Table)
assert result['distance'][0] <= result['distance'][1]

def test_catalogs_query_hsc_matchid_async(self):
catalogData = mast.Catalogs.query_object("M10",
radius=.001,
Expand Down