astropy / pyvo

An Astropy affiliated package providing access to remote data and services of the Virtual Observatory (VO) using Python.
https://pyvo.readthedocs.io/en/latest
BSD 3-Clause "New" or "Revised" License
75 stars 52 forks source link

Crash when using Angle format as input into diameter parameter of cone search service within PyVo package #534

Closed mstalbot closed 6 months ago

mstalbot commented 6 months ago

Description

It appears "diameter=Angle(cone_search_radius 2 u.arcsec)" in PyVo (https://pyvo.readthedocs.io/en/latest/) cone search query can lead to a crash, which is suspected the "diameter" input cannot accept Angle format for at least one of cone-search-based service.

Expected behavior

Expected search to complete.

How to Reproduce

import pyvo as vo from astropy.coordinates import SkyCoord import numpy as np from astropy.coordinates import Angle from astropy import units as u

cone_search_services = vo.regsearch(servicetype='conesearch') service = cone_search_services[458] #Gives service: ('ivo://cds.vizier/ii/282', 'vs:catalogservice', 'II/282', 'The SDSS Photometric Catalog, Release 6', 'research', 'The present catalog is a subset of the data release 6 of the Sloan Digital Sky Survey (SDSS), restricted to primary and secondary photo objects (i.e. objects from PhotoPrimary of PhotoSecondary tables) and restricted to the columns described in the "Byte-by-Byte" description below. The complete SDSS data release 6 catalog is available from http://www.sdss.org/dr6/. Compared to data release 5 (Cat. II/276), this subset includes in addition the redshift and its error (for the 880680 sources observed spectroscopically), and the proper motions. The Sloan Digital Sky Survey (SDSS) will map in detail one-quarter of the entire sky, determining the positions and absolute brightnesses of more than 100 million celestial objects. It will also measure the distances to more than a million galaxies and quasars. Apache Point Observatory, site of the SDSS telescopes, is operated by the Astrophysical Research Consortium (ARC). Funding for the SDSS has been provided by the Alfred P. Sloan Foundation, the Participating Institutions, the National Aeronautics and Space Administration, the National Science Foundation, the U.S. Department of Energy, the Japanese Monbukagakusho, the Max Planck Society, and the Higher Education Funding Council for England. The SDSS is a joint project of The University of Chicago, Fermilab, the Institute for Advanced Study, the Japan Participation Group, The Johns Hopkins University, the Korean Scientist Group, Los Alamos National Laboratory, the Max-Planck-Institute for Astronomy (MPIA), the Max-Planck-Institute for Astrophysics (MPA), New Mexico State University, University of Pittsburgh, University of Portsmouth, Princeton University, the United States Naval Observatory, and the University of Washington. All details about SDSS at http://www.sdss.org/dr6/', 'https://cdsarc.cds.unistra.fr/viz-bin/cat/II/282', 'Adelman-McCarthy J.K. et al.', 'catalog', 'bibcode', '2008ApJS..175..297A', nan, 'optical', ['http://vizier.cds.unistra.fr/viz-bin/conesearch/II/282/sdss6?'], ['ivo://ivoa.net/std/conesearch'], ['vs:paramhttp'], ['std']) cone_search_radius = 3 coordinates = SkyCoord(233.319218, 48.119651, unit="deg") table = service.search(pos=coordinates, diameter=Angle(cone_search_radius 2 u.arcsec)).to_table()

ERROR>>>> TypeError Traceback (most recent call last) File /opt/conda/envs/science_demo/lib/python3.11/site-packages/pyvo/dal/query.py:244, in DALQuery.execute_votable(self, post) 243 try: --> 244 return votableparse(self.execute_stream(post=post).read) 245 except Exception as e:

File /opt/conda/envs/science_demo/lib/python3.11/site-packages/pyvo/utils/decorators.py:9, in stream_decode_content..wrapper(*args, kwargs) 7 @wraps(func) 8 def wrapper(*args, *kwargs): ----> 9 raw = func(args, kwargs) 10 raw.read = partial(raw.read, decode_content=True)

File /opt/conda/envs/science_demo/lib/python3.11/site-packages/pyvo/dal/query.py:193, in DALQuery.execute_stream(self, post) 187 """ 188 Submit the query and return the raw response as a file stream. 189 190 No exceptions are raised here because non-2xx responses might still 191 contain payload. They can be raised later by calling raise_if_error 192 """ --> 193 response = self.submit(post=post) 195 try:

File /opt/conda/envs/science_demo/lib/python3.11/site-packages/pyvo/dal/query.py:214, in DALQuery.submit(self, post) 213 else: --> 214 response = self._session.get(url, params=params, stream=True, 215 allow_redirects=True) 216 return response

File /opt/conda/envs/science_demo/lib/python3.11/site-packages/requests/sessions.py:602, in Session.get(self, url, kwargs) 601 kwargs.setdefault("allow_redirects", True) --> 602 return self.request("GET", url, kwargs)

File /opt/conda/envs/science_demo/lib/python3.11/site-packages/requests/sessions.py:575, in Session.request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json) 563 req = Request( 564 method=method.upper(), 565 url=url, (...) 573 hooks=hooks, 574 ) --> 575 prep = self.prepare_request(req) 577 proxies = proxies or {}

File /opt/conda/envs/science_demo/lib/python3.11/site-packages/requests/sessions.py:486, in Session.prepare_request(self, request) 485 p = PreparedRequest() --> 486 p.prepare( 487 method=request.method.upper(), 488 url=request.url, 489 files=request.files, 490 data=request.data, 491 json=request.json, 492 headers=merge_setting( 493 request.headers, self.headers, dict_class=CaseInsensitiveDict 494 ), 495 params=merge_setting(request.params, self.params), 496 auth=merge_setting(auth, self.auth), 497 cookies=merged_cookies, 498 hooks=merge_hooks(request.hooks, self.hooks), 499 ) 500 return p

File /opt/conda/envs/science_demo/lib/python3.11/site-packages/requests/models.py:368, in PreparedRequest.prepare(self, method, url, headers, files, data, params, auth, cookies, hooks, json) 367 self.prepare_method(method) --> 368 self.prepare_url(url, params) 369 self.prepare_headers(headers)

File /opt/conda/envs/science_demo/lib/python3.11/site-packages/requests/models.py:474, in PreparedRequest.prepare_url(self, url, params) 472 params = to_native_string(params) --> 474 enc_params = self._encode_params(params) 475 if enc_params:

File /opt/conda/envs/science_demo/lib/python3.11/site-packages/requests/models.py:124, in RequestEncodingMixin._encode_params(data) 123 vs = [vs] --> 124 for v in vs: 125 if v is not None:

File /opt/conda/envs/science_demo/lib/python3.11/site-packages/astropy/units/quantity.py:1278, in Quantity.iter(self) 1277 if self.isscalar: -> 1278 raise TypeError( 1279 f"'{self.class.name}' object with a scalar value is not" 1280 " iterable" 1281 ) 1283 # Otherwise return a generator

TypeError: 'Angle' object with a scalar value is not iterable

During handling of the above exception, another exception occurred:

DALFormatError Traceback (most recent call last) Cell In[4], line 11 9 cone_search_radius = 3 10 coordinates = SkyCoord(233.319218, 48.119651, unit="deg") ---> 11 table = service.search(pos=coordinates, diameter=Angle(cone_search_radius 2 u.arcsec)).to_table()

File /opt/conda/envs/science_demo/lib/python3.11/site-packages/pyvo/registry/regtap.py:748, in RegistryResource.search(self, *args, *keys) 743 if not self.service: 744 raise dalq.DALServiceError( 745 "resource, {}, is not a searchable service".format( 746 self.short_name)) --> 748 return self.service.search(args, **keys)

File /opt/conda/envs/science_demo/lib/python3.11/site-packages/pyvo/dal/scs.py:187, in SCSService.search(self, pos, radius, verbosity, keywords) 142 def search(self, pos, radius=1.0, verbosity=2, keywords): 143 """ 144 submit a simple Cone Search query that requests objects or observations 145 whose positions fall within some distance from a search position. (...) 185 pyvo.dal.query.DALQueryError 186 """ --> 187 return self.create_query(pos, radius, verbosity, **keywords).execute()

File /opt/conda/envs/science_demo/lib/python3.11/site-packages/pyvo/dal/scs.py:413, in SCSQuery.execute(self) 399 def execute(self): 400 """ 401 submit the query and return the results as a SCSResults instance 402 (...) 411 for errors parsing the VOTable response 412 """ --> 413 return SCSResults(self.execute_votable(), url=self.queryurl, session=self._session)

File /opt/conda/envs/science_demo/lib/python3.11/site-packages/pyvo/dal/query.py:247, in DALQuery.execute_votable(self, post) 245 except Exception as e: 246 self.raise_if_error() --> 247 raise DALFormatError(e, self.queryurl)

DALFormatError: TypeError: 'Angle' object with a scalar value is not iterable

Versions

Linux-5.10.184-175.749.amzn2.x86_64-x86_64-with-glibc2.35 Python 3.11.7 | packaged by conda-forge | (main, Dec 15 2023, 08:38:37) [GCC 12.3.0] astropy 6.0.0 Numpy 1.26.2 pyerfa 2.0.1.1 Scipy 1.11.4 Matplotlib 3.8.2

github-actions[bot] commented 6 months ago

Welcome to Astropy 👋 and thank you for your first issue!

A project member will respond to you as soon as possible; in the meantime, please double-check the guidelines for submitting issues and make sure you've provided the requested details.

GitHub issues in the Astropy repository are used to track bug reports and feature requests; If your issue poses a question about how to use Astropy, please instead raise your question in the Astropy Discourse user forum and close this issue.

If you feel that this issue has not been responded to in a timely manner, please send a message directly to the development mailing list. If the issue is urgent or sensitive in nature (e.g., a security vulnerability) please send an e-mail directly to the private e-mail feedback@astropy.org.

MridulS commented 6 months ago

From a cursory glance at the code and docs, I don't think using diameter with a Simple Cone Search will work. It expects a radius argument so changing your last line to something like

service.search(pos=coordinates, radius=Angle(cone_search_radius * u.arcsec))

should work.

ManonMarchand commented 6 months ago

Hello,

I can confirm that it works with radius.

Note that you can do

service = cone_search_services["II/282"]

Where II/282 is the short version of the ivoid for this VizieR catalog. This can prevent future bugs when you re-execute this query and the catalog is no longer the 459th result.

mstalbot commented 6 months ago

Sounds good.

pllim commented 6 months ago

Looks like this issue was opened in the wrong repo. I will transfer after the fact. Thanks, all.

bsipocz commented 6 months ago

We have already diagnosed the diameter vs radius issue (and that diameter shouldn't be used in the NAVO tutorials). However, the bug that has to be dealt with in pyvo, and that is one of my pet peeves is that we do use **kwargs way too often which swallows parameters and none of those are gone through a sanity check (eg https://github.com/astropy/pyvo/issues/466). So, this case demonstrates that real users run into this.