# Licensed under a 3-clause BSD style license - see LICENSE.rst
from __future__ import (absolute_import, division, print_function,
unicode_literals)
# Standard library
from abc import ABCMeta
# Third-party
import astropy.units as u
from astropy.coordinates import SkyCoord
__all__ = ["Target", "FixedTarget", "NonFixedTarget"]
[docs]class Target(object):
"""
Abstract base class for target objects.
This is an abstract base class -- you can't instantiate
examples of this class, but must work with one of its
subclasses such as `~astroplan.target.FixedTarget` or
`~astroplan.target.NonFixedTarget`.
"""
__metaclass__ = ABCMeta
def __init__(self, name=None, ra=None, dec=None, marker=None):
"""
Defines a single observation target.
Parameters
----------
name : str, optional
ra : WHAT TYPE IS ra ?
dec : WHAT TYPE IS dec ?
marker : str, optional
User-defined markers to differentiate between different types
of targets (e.g., guides, high-priority, etc.).
"""
raise NotImplementedError()
@property
def ra(self):
"""
Right ascension.
"""
if isinstance(self, FixedTarget):
return self.coord.ra
raise NotImplementedError()
@property
def dec(self):
"""
Declination.
"""
if isinstance(self, FixedTarget):
return self.coord.dec
raise NotImplementedError()
[docs]class FixedTarget(Target):
"""
Coordinates and metadata for an object that is "fixed" with respect to the
celestial sphere.
Examples
--------
Create a `~astroplan.FixedTarget` object for Sirius:
>>> from astroplan import FixedTarget
>>> from astropy.coordinates import SkyCoord
>>> import astropy.units as u
>>> sirius_coord = SkyCoord(ra=101.28715533*u.deg, dec=16.71611586*u.deg)
>>> sirius = FixedTarget(coord=sirius_coord, name="Sirius")
Create an equivalent `~astroplan.FixedTarget` object for Sirius by querying
for the coordinates of Sirius by name:
>>> from astroplan import FixedTarget
>>> sirius = FixedTarget.from_name("Sirius")
"""
def __init__(self, coord, name=None, **kwargs):
"""
Parameters
----------
coord : `~astropy.coordinates.SkyCoord`
Coordinate of the target
name : str (optional)
Name of the target, used for plotting and representing the target
as a string
"""
if not (hasattr(coord, 'transform_to') and
hasattr(coord, 'represent_as')):
raise TypeError('`coord` must be a coordinate object.')
self.name = name
self.coord = coord
@classmethod
[docs] def from_name(cls, query_name, name=None, **kwargs):
"""
Initialize a `FixedTarget` by querying for a name from the CDS name
resolver, using the machinery in
`~astropy.coordinates.SkyCoord.from_name`.
This
Parameters
----------
query_name : str
Name of the target used to query for coordinates.
name : string or `None`
Name of the target to use within astroplan. If `None`, query_name
is used as ``name``.
Examples
--------
>>> from astroplan import FixedTarget
>>> sirius = FixedTarget.from_name("Sirius")
>>> sirius.coord # doctest: +FLOAT_CMP
<SkyCoord (ICRS): (ra, dec) in deg
(101.28715533, -16.71611586)>
"""
# Allow manual override for name keyword so that the target name can
# be different from the query name, otherwise assume name=queryname.
if name is None:
name = query_name
return cls(SkyCoord.from_name(query_name), name=name, **kwargs)
def __repr__(self):
"""
String representation of `~astroplan.FixedTarget`.
Examples
--------
Show string representation of a `~astroplan.FixedTarget` for Vega:
>>> from astroplan import FixedTarget
>>> from astropy.coordinates import SkyCoord
>>> vega_coord = SkyCoord(ra='279.23473479d', dec='38.78368896d')
>>> vega = FixedTarget(coord=vega_coord, name="Vega")
>>> print(vega) # doctest: +FLOAT_CMP
<FixedTarget "Vega" at SkyCoord (ICRS): (ra, dec) in deg (279.23473479, 38.78368894)>
"""
class_name = self.__class__.__name__
fmt_coord = repr(self.coord).replace('\n ', '')[1:-1]
return '<{} "{}" at {}>'.format(class_name, self.name, fmt_coord)
@classmethod
def _from_name_mock(cls, query_name, name=None):
"""
Mock method to replace `FixedTarget.from_name` in tests without
internet connection.
"""
stars = {
"rigel": {"ra": 78.63446707*u.deg, "dec": -8.20163837*u.deg},
"sirius": {"ra": 101.28715533*u.deg, "dec": -16.71611586*u.deg},
"vega": {"ra": 279.23473479*u.deg, "dec": 38.78368896*u.deg},
"aldebaran": {"ra": 68.98016279*u.deg, "dec": 16.50930235*u.deg},
"polaris": {"ra": 37.95456067*u.deg, "dec": 89.26410897*u.deg},
"deneb": {"ra": 310.35797975*u.deg, "dec": 45.28033881*u.deg},
"m13": {"ra": 250.423475*u.deg, "dec": 36.4613194*u.deg},
"altair": {"ra": 297.6958273*u.deg, "dec": 8.8683212*u.deg}
}
if query_name.lower() in stars:
return cls(coord=SkyCoord(**stars[query_name.lower()]),
name=query_name)
else:
raise ValueError("Target named {} not in mocked FixedTarget "
"method".format(query_name))
[docs]class NonFixedTarget(Target):
"""
Placeholder for future function.
"""