astropy / astroquery

Functions and classes to access online data resources. Maintainers: @keflavich and @bsipocz and @ceb8
http://astroquery.readthedocs.org/en/latest/
BSD 3-Clause "New" or "Revised" License
706 stars 398 forks source link

Feature request: JplHorizons to support packed asteroid number #1442

Open MigoMueller opened 5 years ago

MigoMueller commented 5 years ago

Many asteroid catalogs contain either packed numbers or designations (or both): https://www.minorplanetcenter.net/iau/info/PackedDes.html

jplhorizons does support packed asteroid designations (which is good), but not packed asteroid numbers. Sample code to reproduce the problem:

>>> import astroquery
>>> print(astroquery.version.version)
>>> from astroquery.jplhorizons import Horizons
>>> compressed = 'q3791'
>>> hor = Horizons( id=compressed, location="@JWST", epochs={'start':'2021-04-01', 'stop':'2022-04-01', 'step':'1d'} )
>>> eph = hor.ephemerides()

0.3.9
 ---------------------------------------------------------------------------
 ValueError                                Traceback (most recent call last)
 <ipython-input-70-eaf0c903f7dc> in <module>()
      4 compressed = 'q3791'
      5 hor = Horizons( id=compressed, location="@JWST", epochs={'start':'2021-04-01', 'stop':'2022-04-01', 'step':'1d'} )
----> 6 eph = hor.ephemerides()

~/anaconda3/envs/miricle/lib/python3.5/site-packages/astroquery/utils/class_or_instance.py in f(*args, **kwds)
     23         def f(*args, **kwds):
     24             if obj is not None:
---> 25                 return self.fn(obj, *args, **kwds)
     26             else:
     27                 return self.fn(cls, *args, **kwds)

~/anaconda3/envs/miricle/lib/python3.5/site-packages/astroquery/utils/process_asyncs.py in newmethod(self, *args, **kwargs)
     27             if kwargs.get('get_query_payload') or kwargs.get('field_help'):
     28                 return response
---> 29             result = self._parse_result(response, verbose=verbose)
     30             self.table = result
     31             return result

~/anaconda3/envs/miricle/lib/python3.5/site-packages/astroquery/jplhorizons/core.py in _parse_result(self, response, verbose)
   1223             return None
   1224         else:
-> 1225             data = self._parse_horizons(response.text)
   1226 
   1227         return data

~/anaconda3/envs/miricle/lib/python3.5/site-packages/astroquery/jplhorizons/core.py in _parse_horizons(self, src)
   1096                     "No matches found" in src[idx + 1]):
   1097                 raise ValueError(('Unknown target ({:s}). Maybe try '
-> 1098                                   'different id_type?').format(self.id))
   1099             # catch any unavailability of ephemeris data
   1100             if "No ephemeris for target" in line:

ValueError: Unknown target (q3791). Maybe try different id_type?

The Horizons web interface does support compressed numbers and correctly resolves q3791 to 523791 (2015 HT171).

jplhorizons does support packed designations. E.g., replace 'q3791' in the code above with 'K10F92H' (resolves to 2010 FH92)

bsipocz commented 5 years ago

Thanks @MigoMueller for the issue. I've tuned down the tone a bit, but you're also of course welcome to open a pull request to fix these shortcoming.

MigoMueller commented 5 years ago

Thanks @bsipocz! Here's a workaround that works for me. Error handling would probably need to be improved for production code:

if len(des)==5 and not des.isnumeric() and des[1:].isnumeric():
    #Packed permanent designation, see https://www.minorplanetcenter.net/iau/info/PackedDes.html
    number = int(des[1:])
    first = ord(des[0])
    if des[0].islower():
        first -= 61
    elif des[0].isupper():
        first -= 55
    else:
        # if first character isn't alphanumeric (shouldn't happen, really)
        assert False # more robust error treatment needed, probably
    number += first*10000
    des = str(number)

I'll try to include that in the code at the right place. If I manage, I'll open a pull request. In the meantime, I hope my workaround is useful for someone.