Source code for astromodels.core.sky_direction

__author__ = 'giacomov'

import collections

from astropy import coordinates

from astromodels.core.parameter import Parameter
from astromodels.core.tree import Node


[docs]class WrongCoordinatePair(ValueError): pass
[docs]class IllegalCoordinateValue(ValueError): pass
[docs]class WrongCoordinateSystem(ValueError): pass
[docs]class SkyDirection(Node): """ This is essentially a wrapper around astropy.coordinates.SkyCoord with a possibility for being serialized and deserialized with YAML. """ def __init__(self, ra=None, dec=None, l=None, b=None, equinox='J2000'): """ :param ra: Right Ascension in degrees :param dec: Declination in degrees :param l: Galactic latitude in degrees :param b: Galactic longitude in degrees :param equinox: string :return: """ self._equinox = equinox # Create the node Node.__init__(self, 'position') # Check that we have the right pairs of coordinates if ra is not None and dec is not None: # This goes against duck typing, but it is needed to provide a means of initiating this class # with either Parameter instances or just floats # Try to transform it to float, if it works than we transform it to a parameter ra = self._get_parameter_from_input(ra, 0, 360, 'ra','Right Ascension') dec = self._get_parameter_from_input(dec, -90, 90, 'dec','Declination') self._coord_type = 'equatorial' self._add_child(ra) self._add_child(dec) elif l is not None and b is not None: # This goes against duck typing, but it is needed to provide a means of initiating this class # with either Parameter instances or just floats # Try to transform it to float, if it works than we transform it to a parameter l = self._get_parameter_from_input(l, 0, 360, 'l','Galactic longitude') b = self._get_parameter_from_input(b, -90, 90, 'b','Galactic latitude') self._coord_type = 'galactic' self._add_child(l) self._add_child(b) else: raise WrongCoordinatePair("You have to specify either (ra, dec) or (l, b).") @staticmethod def _get_parameter_from_input(number_or_parameter, minimum, maximum, what, desc): # Try to transform it to float, if it works than we transform it to a parameter try: number_or_parameter = float(number_or_parameter) except TypeError: assert isinstance(number_or_parameter, Parameter), "%s must be either a number or a " \ "parameter instance" % what # So this is a Parameter instance already. Enforce that it has the right maximum and minimum parameter = number_or_parameter assert parameter.min_value >= minimum, "%s must have a minimum greater than or equal to %s" % (what, minimum) assert parameter.max_value <= maximum, "%s must have a maximum less than or equal to %s" % (what, maximum) else: # This was a float. Enforce that it has a legal value assert minimum <= number_or_parameter <= maximum, "%s cannot have a value of %s, " \ "it must be %s <= %s <= %s" % (what, number_or_parameter, minimum, what, maximum) parameter = Parameter(what, number_or_parameter, desc=desc, min_value=minimum, max_value=maximum, unit='deg', free=False) return parameter
[docs] def get_ra(self): """ Get R.A. corresponding to the current position (ICRS, J2000) :return: Right Ascension """ try: return self.ra.value except AttributeError: # Transform from L,B to R.A., Dec return self.sky_coord.transform_to('icrs').ra.value
[docs] def get_dec(self): """ Get Dec. corresponding to the current position (ICRS, J2000) :return: Declination """ try: return self.dec.value except AttributeError: # Transform from L,B to R.A., Dec return self.sky_coord.transform_to('icrs').dec.value
[docs] def get_l(self): """ Get Galactic Longitude (l) corresponding to the current position :return: Galactic Longitude """ try: return self.l.value except AttributeError: # Transform from L,B to R.A., Dec return self.sky_coord.transform_to('galactic').l.value
[docs] def get_b(self): """ Get Galactic latitude (b) corresponding to the current position :return: Latitude """ try: return self.b.value except AttributeError: # Transform from L,B to R.A., Dec return self.sky_coord.transform_to('galactic').b.value
def _get_sky_coord(self): if self._coord_type == 'galactic': l = self.l.value b = self.b.value return coordinates.SkyCoord(l=l, b=b, frame='galactic', equinox=self._equinox, unit="deg") else: ra = self.ra.value dec = self.dec.value return coordinates.SkyCoord(ra=ra, dec=dec, frame='icrs', equinox=self._equinox, unit="deg") @property def sky_coord(self): """ Return an instance of astropy.coordinates.SkyCoord which can be used to make all transformations supported by it :return: astropy.coordinates.SkyCoord """ return self._get_sky_coord() @property def parameters(self): """ Get the dictionary of parameters (either ra,dec or l,b) :return: dictionary of parameters """ if self._coord_type == 'galactic': return collections.OrderedDict((('l', self.l), ('b', self.b))) else: return collections.OrderedDict((('ra', self.ra), ('dec', self.dec))) @property def equinox(self): """ Returns the equinox for the coordinates. :return: """ return self._equinox
[docs] def to_dict(self, minimal=False): data = collections.OrderedDict() if self._coord_type == 'equatorial': data['ra'] = self.ra.to_dict(minimal) data['dec'] = self.dec.to_dict(minimal) data['equinox'] = self._equinox else: data['l'] = self.l.to_dict(minimal) data['b'] = self.b.to_dict(minimal) data['equinox'] = self._equinox return data
[docs] def fix(self): """ Fix the parameters with the coordinates (either ra,dec or l,b depending on how the class has been instanced) """ if self._coord_type == 'equatorial': self.ra.fix = True self.dec.fix = True else: self.l.fix = True self.b.fix = True
[docs] def free(self): """ Free the parameters with the coordinates (either ra,dec or l,b depending on how the class has been instanced) """ if self._coord_type == 'equatorial': self.ra.fix = False self.dec.fix = False else: self.l.fix = False self.b.fix = False
[docs] @classmethod def from_dict(cls, data): return cls(**data)
def _repr__base(self, rich_output): if self._coord_type == 'equatorial': representation = 'Sky direction (R.A., Dec.) = (%.5f, %.5f) (%s)' % (self.ra.value, self.dec.value, self.equinox) else: representation = 'Sky direction (l, b) = (%.5f, %.5f) (%s)' % (self.l.value, self.b.value, self.equinox) return representation