Source code for panoptes.pocs.utils.coords
"""Coordinate utilities for resolving targets to astropy SkyCoord objects."""
from datetime import datetime
from astropy import units as u
from astropy.coordinates import SkyCoord, get_body, solar_system_ephemeris
from astropy.coordinates.name_resolve import NameResolveError
from astropy.time import Time
from astroquery.jplhorizons import Horizons
from panoptes.utils.time import current_time
[docs]
def get_target_coords(
target: str,
obstime: datetime | Time | None = None,
is_comet: bool = False,
verbose: bool = False,
) -> SkyCoord:
"""Get the coordinates of the target.
This helper accepts a variety of inputs and returns an astropy SkyCoord.
Examples
--------
Using common target names (requires internet for name resolution):
>>> from astropy.time import Time
>>> c = get_target_coords("M42", obstime=Time("2020-01-01"))
>>> type(c).__name__
'SkyCoord'
>>> get_target_coords("Andromeda Galaxy", obstime=Time("2020-01-01"), verbose=True) # doctest: +ELLIPSIS
<SkyCoord (ICRS): (ra, dec) in deg
(10.6847..., 41.26875)>
>>> m = get_target_coords("Moon", obstime=Time("2020-01-01"))
>>> isinstance(m, SkyCoord)
True
A local, non-network coordinate string example (always works offline):
>>> get_target_coords("00h42m44.3s +41d16m9s", obstime=Time("2020-01-01"), verbose=True)
<SkyCoord (ICRS): (ra, dec) in deg
(10.6845..., 41.26916667)>
>>> get_target_coords("10h00m00s +20d00m00s", obstime=Time("2020-01-01"))
<SkyCoord (ICRS): (ra, dec) in deg
(150., 20.)>
Safety checks for hazardous or impossible targets:
>>> get_target_coords("sun", obstime=Time("2020-01-01"))
Traceback (most recent call last):
...
RuntimeError: Refusing to go to the sun.
>>> get_target_coords("earth", obstime=Time("2020-01-01"))
Traceback (most recent call last):
...
RuntimeError: It's hard for me to take a picture of earth.
Args:
target (str): The target to look for. If a comet, use a designator like `C/2025 N1` and
set the `is_comet` flag to True.
obstime (datetime, Time, optional): The time of the observation. Defaults to None.
is_comet (bool, optional): Is the target a comet? Defaults to False.
verbose (bool, optional): Print some information. Defaults to False.
Returns:
SkyCoord: The coordinates of the target.
"""
obstime = obstime or current_time()
# If the object is a solar system body, mark accordingly.
is_solar_system_body = False
if target.lower() in solar_system_ephemeris.bodies:
is_solar_system_body = True
if target.lower() == "sun":
raise RuntimeError("Refusing to go to the sun.")
if target.lower() == "earth":
raise RuntimeError("It's hard for me to take a picture of earth.")
if is_comet:
obj = Horizons(id=target, id_type="smallbody", epochs=obstime.jd1)
eph = obj.ephemerides()
coords = SkyCoord(eph[0]["RA"], eph[0]["DEC"], unit=(u.deg, u.deg))
elif is_solar_system_body:
coords = get_body(target.lower(), time=obstime)
else:
try:
coords = SkyCoord(target)
except ValueError:
try:
coords = SkyCoord.from_name(target)
except NameResolveError:
raise ValueError(f"Could not resolve target {target}")
return coords