Source code for sofia_redux.scan.coordinate_systems.projection.zenithal_projection

# Licensed under a 3-clause BSD style license - see LICENSE.rst

from abc import abstractmethod
from astropy import units
import numpy as np

from sofia_redux.scan.coordinate_systems.projection.spherical_projection \
    import SphericalProjection
from sofia_redux.scan.coordinate_systems.spherical_coordinates import \
    SphericalCoordinates
from sofia_redux.scan.coordinate_systems.coordinate_2d import Coordinate2D

__all__ = ['ZenithalProjection']


[docs] class ZenithalProjection(SphericalProjection): def __init__(self): """ Initialization for the abstract zenithal projection. A zenithal projection (azimuthal projection) is one in which the surface of projection is a plane. A native coordinate system is defined such that the polar axis is orthogonal to the plane of projection. Meridians are projected as equispaced rays from a central point, and parallels are concentric circles centered on that same point. By default, the native pole is set to (0, 90) degrees LON/LAT. """ super().__init__() self.native_reference.set_native( [0.0 * units.Unit('degree'), self.right_angle])
[docs] def calculate_celestial_pole(self): """ Calculate the celestial pole. Returns ------- None """ self.set_celestial_pole(self.reference)
[docs] def get_phi_theta(self, offsets, phi_theta=None): """ Return the phi (longitude) and theta (latitude) coordinates. The phi and theta coordinates refer to the inverse projection (deprojection) of projected offsets about the native pole. phi is the deprojected longitude, and theta is the deprojected latitude of the offsets. For a zenithal projection these are given as: phi = arctan(x, -y) theta = angle_from_radius_function(sqrt(x^2 + y^2)) where `angle_from_radius_function` depends on the exact zenithal projection model. Parameters ---------- offsets : Coordinate2D phi_theta : SphericalCoordinates, optional An optional output coordinate system in which to place the results. Returns ------- coordinates : SphericalCoordinates """ if phi_theta is None: phi_theta = SphericalCoordinates(unit='degree') x, y = self.offset_to_xy_radians(offsets) x, y = x.value, y.value phi = np.arctan2(x, -y) * units.Unit('radian') theta = self.theta_of_r(np.hypot(x, y)) phi_theta.set_native([phi, theta]) return phi_theta
[docs] def get_offsets(self, theta, phi, offsets=None): """ Get the offsets given theta and phi. Takes the theta (latitude) and phi (longitude) coordinates about the celestial pole and converts them to offsets from a reference position. For a zenithal projection, this is given by: r = radius_from_angle_function(theta) x = r * sin(phi) y = -r * cos(phi) where `radius_from_angle_function` depends on the zenithal projection model. Parameters ---------- theta : units.Quantity The theta angle. phi : units.Quantity The phi angle. offsets : Coordinate2D, optional An optional coordinate system in which to place the results. Returns ------- offsets : Coordinate2D """ if offsets is None: offsets = Coordinate2D(unit='degree') # From Calabretta and Greisen 2002 r = self.r(theta) x = r * np.sin(phi) y = -r * np.cos(phi) offsets.set([x, y]) return offsets
[docs] @abstractmethod def r(self, theta): # pragma: no cover """ Return the radius of a point from the center of the projection. Parameters ---------- theta : float or numpy.ndarray or units.Quantity The latitude angle. Returns ------- r : units.Quantity The distance of the point from the central point. """ pass
[docs] @abstractmethod def theta_of_r(self, r): # pragma: no cover """ Return theta (latitude) given a radius from the central point. Parameters ---------- r : float or numpy.ndarray or units.Quantity The distance of the point from the central point. Returns ------- theta : units.Quantity """ pass