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

ENH: Better align jplhorizons with the corresponding API #2923

Open
mkelley opened this issue Jan 11, 2024 · 3 comments
Open

ENH: Better align jplhorizons with the corresponding API #2923

mkelley opened this issue Jan 11, 2024 · 3 comments
Assignees

Comments

@mkelley
Copy link
Contributor

mkelley commented Jan 11, 2024

My experience with the current jplhorizons sub-module suggests to me that it requires more maintenance than what I think is ideal. In addition, since it was written astroquery, astropy, and Horizons have evolved substantially, including the publication of a versioned Horizons API. I am attempting to write a new jplhorizons module from scratch that is at its heart aligned with the Horizons API as closely as possible, but also taking advantage of key astropy/astroquery infrastructure. I also want a user to be able to primarily refer to the Horizons documentation to develop their query, then implement it with astroquery as seamlessly as possible.

For the moment, I'm calling this new implementation Horizons2.

Some design goals:

  1. method names closely map to Horizons ephemeris (output) types, e.g., Horizons2.query_observer for EPHEM_TYPE=OBSERVER, see https://ssd-api.jpl.nasa.gov/doc/horizons.html#ephem_type
  2. named method arguments and keyword arguments would be used to form the object query, i.e., the API's COMMAND parameter, see https://ssd-api.jpl.nasa.gov/doc/horizons.html#command
  3. an additional keyword argument would be used to specify the center of the coordinate system (e.g., the observer for an ephemeris), and could handle astropy EarthLocation objects
  4. the usual astroquery keyword arguments will be respected, e.g., get_query_payload= and cache=
  5. all other parameters are unnamed keyword arguments passed on to Horizons as is
  6. the returned data will be packaged into an astropy Table without any column renaming and including all relevant metadata in the Table.meta attribute
  7. columns will be given units as appropriate
  8. columns with dates will be converted to Time objects
  9. when practical, sky coordinates will be copied to an additional column and packaged as astropy SkyCoord objects, with the appropriate reference frame defined
  10. it should be aware of which Horizons API version it supports and will raise a warning or an error if the API response does not match an expected value

Ultimately, I'd like to more easily support all of Horizon's features, future-proof or at least simplify most minor version updates to the Horizons API, and keep the majority of the maintenance limited to astropy+astroquery version support.

This issue is intended to announce the development of Horizons2 and to collect questions and feedback. I have a branch started at: https://github.com/mkelley/astroquery/tree/horizons2 Time frame for completion is probably six to twelve months.

@mkelley mkelley self-assigned this Jan 11, 2024
@mkelley
Copy link
Contributor Author

mkelley commented Jan 11, 2024

And, here are some code examples that I am trying to design to:

        Examples
        --------

        Object specifications:

        >>> from astroquery.jplhorizons import Horizons2
        >>> Horizons2.query_observer("Jupiter")
        >>>
        >>> Horizons2.query_observer("1", center="568")
        >>>
        >>> Horizons2.query_observer("europa", center="I41", id_type="name")
        >>>
        >>> Horizons2.query_observer("2P", id_type="designation")
        >>> Horizons2.query_observer("2P",
        ...                          id_type="designation",
        ...                          closest_apparition=True)
        >>>
        >>> Horizons2.query_observer("73P",
        ...                          id_type="designation",
        ...                          closest_apparition=True,
        ...                          fragments=False)
        >>>
        >>> tab = Horizons2.query_observer(
        ...     "comet",
        ...     id_type="orbit",
        ...     epoch=Time(2450200.5, scale="tdb", format="jd"),
        ...     ec=0.8241907231263196,
        ...     qr=0.532013766859137 * u.au,
        ...     tp=Time(2450077.480966184235, scale="tdb", format="jd"),
        ...     om=89.14262290335057 * u.deg,
        ...     w=326.0591239257098 * u.deg,
        ...     in=4.247821264821585 * u.deg,
        ...     a1=-5.113711376907895D-10 * u.au / u.d**2,
        ...     a2=-6.288085687976327D-10 * u.au / u.d**2)

        The observer (ephemeris center) can also be an
        `~astropy.coordinates.EarthLocation`:

        >>> from astropy.coordinates import EarthLocation
        >>> college_park = EarthLocation.from_geodetic(-76.9378 * u.deg,
        ...                                            38.9897 * u.deg,
        ...                                            21 * u.m)
        >>> tab = Horizons2.query_observer("Jupiter", center=college_park)

        Specifying time:

        >>> from astropy.time import Time
        >>> import astropy.units as u
        >>> tab = Horizons2.query_observer("Jupiter",
        ...                                start_time=Time("2023-12-11"),
        ...                                stop_time=Time("2023-12-12"),
        ...                                step_size=1 * u.hr)
        >>>
        >>> times = Time(["2023-12-11", "2023-12-20", "2024-01-08"])
        >>> tab = Horizons2.query_observer("Jupiter", tlist=times)

@bsipocz
Copy link
Member

bsipocz commented Jan 11, 2024

Thank you @mkelley for taking care of the jplephem module. I honestly think it's one of the most used modules (if not no1) and therefore people are running into more issues than with other ones.

Some big-picture thoughts, without going into your implementation details:

  • The refactoring plans do sound to be totally reasonable, and I agree that things have changed and we also experienced a lot with how people using it since the first implementation.
  • I think it will need to be called horizon with having the old one either removed straight away or moved to a deprecated location (horizon_legacy? or something similar). We did this type of API breakage before (mostly due to upstream API having changed beyond help, or the refactor was significantly large, typically switching away from a reversed engineered webform scraping towards using an official API or even VO).

points 6 and 7: What do you think about using a QTable right away?
The rest of the points sound totally reasonable!

@mkelley
Copy link
Contributor Author

mkelley commented Jan 11, 2024

Thanks, @bsipocz . I agree with all your points! I'll try QTable first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants