B
    d              x   @   s  d Z ddlZddlZddlmZ ddlmZ ddl	m
Z
mZ ddlmZ ddlmZmZ d	d
dddddddddddddddddddddd d!d"d#gZd$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddddddddddddddddddddddgxZG dd$ d$eZG dd% d%eZG dd& d&eZG dd' d'eZG dd0 d0eeZeZG dd1 d1eeZeZG dd2 d2eeZeZG dd3 d3eeZeZG dd4 d4eeZeZ G dd5 d5eeZ!e!Z"G dd6 d6eeZ#e#Z$G dd7 d7eeZ%e%Z&G dd8 d8eeZ'e'Z(G dd9 d9eeZ)e)Z*G dd: d:eeZ+e+Z,G dd; d;eeZ-e-Z.G dd< d<eeZ/e/Z0G dd= d=eeZ1e1Z2G dd> d>eeZ3e3Z4G dd? d?eeZ5e5Z6G dd( d(eZ7G dd@ d@ee7Z8e8Z9G ddA dAee7Z:e:Z;G ddB dBee7Z<e<Z=G ddC dCee7Z>e>Z?G ddD dDee7Z@e@ZAG ddE dEee7ZBeBZCG ddF dFee7ZDeDZEG ddG dGee7ZFeFZGG dd) d)eZHG ddH dHeeHZIeIZJG ddI dIeeHZKeKZLG ddJ dJeeHZMeMZNG ddK dKeeHZOeOZPG ddL dLeeHZQeQZRG ddM dMeeHZSeSZTG ddN dNeeHZUeUZVG ddO dOeeHZWeWZXG dd* d*eZYG ddP dPeeYZZeZZ[G ddQ dQeeYZ\e\Z]G ddR dReeYZ^e^Z_G ddS dSeeYZ`e`ZaG ddT dTeeYZbebZcG ddU dUeeYZdedZeG ddV dVeeYZfefZgG ddW dWeeYZhehZiG dd+ d+eZjG ddX dXeejZkekZlG ddY dYeejZmemZnG ddZ dZeejZoeoZpG dd[ d[eejZqeqZrG dd, d,eZsG dd\ d\eesZtetZuG dd] d]eesZvevZwG dd^ d^eesZxexZyG dd_ d_eesZzezZ{G dd` d`eesZ|e|Z}G dda daeesZ~e~ZG dd- d-eZG ddb dbeeZeZG ddc dceeZeZG ddd ddeeZeZG dde deeeZeZG dd. d.eZdS )aK  
Implements projections--particularly sky projections defined in WCS Paper II
[1]_.

All angles are set and and displayed in degrees but internally computations are
performed in radians. All functions expect inputs and outputs degrees.

References
----------
.. [1] Calabretta, M.R., Greisen, E.W., 2002, A&A, 395, 1077 (Paper II)
    N)units   )Model)	ParameterInputParameterError)_projections)
_to_radian_to_orig_unitZAZPZSZPZTANZSTGZSINZARCZZEAZAIRZCYPZCEAZCARZMERZSFLZPARZMOLZAITZCOPZCOEZCODZCOOZBONZPCOZTSCZCSCZQSCZHPXZXPH
ProjectionPix2SkyProjectionSky2PixProjectionZenithalCylindricalPseudoCylindricalConicPseudoConicQuadCubeHEALPixAffineTransformation2D	projcodesPix2Sky_ZenithalPerspectiveSky2Pix_ZenithalPerspective Pix2Sky_SlantZenithalPerspective Sky2Pix_SlantZenithalPerspectivePix2Sky_GnomonicSky2Pix_GnomonicPix2Sky_StereographicSky2Pix_StereographicPix2Sky_SlantOrthographicSky2Pix_SlantOrthographicPix2Sky_ZenithalEquidistantSky2Pix_ZenithalEquidistantPix2Sky_ZenithalEqualAreaSky2Pix_ZenithalEqualAreaPix2Sky_AirySky2Pix_AiryPix2Sky_CylindricalPerspectiveSky2Pix_CylindricalPerspectivePix2Sky_CylindricalEqualAreaSky2Pix_CylindricalEqualAreaPix2Sky_PlateCarreeSky2Pix_PlateCarreePix2Sky_MercatorSky2Pix_MercatorPix2Sky_SansonFlamsteedSky2Pix_SansonFlamsteedPix2Sky_ParabolicSky2Pix_ParabolicPix2Sky_MolleweideSky2Pix_MolleweidePix2Sky_HammerAitoffSky2Pix_HammerAitoffPix2Sky_ConicPerspectiveSky2Pix_ConicPerspectivePix2Sky_ConicEqualAreaSky2Pix_ConicEqualAreaPix2Sky_ConicEquidistantSky2Pix_ConicEquidistantPix2Sky_ConicOrthomorphicSky2Pix_ConicOrthomorphicPix2Sky_BonneEqualAreaSky2Pix_BonneEqualAreaPix2Sky_PolyconicSky2Pix_PolyconicPix2Sky_TangentialSphericalCubeSky2Pix_TangentialSphericalCubePix2Sky_COBEQuadSphericalCubeSky2Pix_COBEQuadSphericalCubePix2Sky_QuadSphericalCubeSky2Pix_QuadSphericalCubePix2Sky_HEALPixSky2Pix_HEALPixPix2Sky_HEALPixPolarSky2Pix_HEALPixPolarPix2Sky_AZPSky2Pix_AZPPix2Sky_SZPSky2Pix_SZPPix2Sky_TANSky2Pix_TANPix2Sky_STGSky2Pix_STGPix2Sky_SINSky2Pix_SINPix2Sky_ARCSky2Pix_ARCPix2Sky_ZEASky2Pix_ZEAPix2Sky_AIRSky2Pix_AIRPix2Sky_CYPSky2Pix_CYPPix2Sky_CEASky2Pix_CEAPix2Sky_CARSky2Pix_CARPix2Sky_MERSky2Pix_MERPix2Sky_SFLSky2Pix_SFLPix2Sky_PARSky2Pix_PARPix2Sky_MOLSky2Pix_MOLPix2Sky_AITSky2Pix_AITPix2Sky_COPSky2Pix_COPPix2Sky_COESky2Pix_COEPix2Sky_CODSky2Pix_CODPix2Sky_COOSky2Pix_COOPix2Sky_BONSky2Pix_BONPix2Sky_PCOSky2Pix_PCOPix2Sky_TSCSky2Pix_TSCPix2Sky_CSCSky2Pix_CSCPix2Sky_QSCSky2Pix_QSCPix2Sky_HPXSky2Pix_HPXPix2Sky_XPHSky2Pix_XPHc               @   s6   e Zd ZdZdej ej ZdZ	e
ejdd ZdS )r
   z#Base class for all sky projections.   Fc             C   s   dS )zT
        Inverse projection--all projection models must provide an inverse.
        N )selfr   r   i/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/astropy/modeling/projections.pyinversen   s    zProjection.inverseN)__name__
__module____qualname____doc__udegnppiZr0
_separablepropertyabcabstractmethodr   r   r   r   r   r
   e   s
   c                   sH   e Zd ZdZdZdZdZdZ fddZe	dd Z
e	dd	 Z  ZS )
r   z'Base class for all Pix2Sky projections.   Tc                s   t  j|| d| _d| _d S )N)xy)phitheta)super__init__inputsoutputs)r   argskwargs)	__class__r   r   r      s    zPix2SkyProjection.__init__c             C   s   | j d tj| j d tjiS )Nr   r   )r   r   r   )r   r   r   r   input_units   s    zPix2SkyProjection.input_unitsc             C   s   | j d tj| j d tjiS )Nr   r   )r   r   r   )r   r   r   r   return_units   s    zPix2SkyProjection.return_units)r   r   r   r   n_inputs	n_outputs_input_units_strict _input_units_allow_dimensionlessr   r   r   r   __classcell__r   r   )r   r   r   v   s   c                   sH   e Zd ZdZdZdZdZdZ fddZe	dd Z
e	dd	 Z  ZS )
r   z'Base class for all Sky2Pix projections.r   Tc                s   t  j|| d| _d| _d S )N)r   r   )r   r   )r   r   r   r   )r   r   r   )r   r   r   r      s    zSky2PixProjection.__init__c             C   s   | j d tj| j d tjiS )Nr   r   )r   r   r   )r   r   r   r   r      s    zSky2PixProjection.input_unitsc             C   s   | j d tj| j d tjiS )Nr   r   )r   r   r   )r   r   r   r   r      s    zSky2PixProjection.return_units)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r      s   c               @   s   e Zd ZdZdZdS )r   a  Base class for all Zenithal projections.

    Zenithal (or azimuthal) projections map the sphere directly onto a
    plane.  All zenithal projections are specified by defining the
    radius as a function of native latitude, :math:`R_\theta`.

    The pixel-to-sky transformation is defined as:

    .. math::
        \phi &= \arg(-y, x) \\
        R_\theta &= \sqrt{x^2 + y^2}

    and the inverse (sky-to-pixel) is defined as:

    .. math::
        x &= R_\theta \sin \phi \\
        y &= R_\theta \cos \phi
    FN)r   r   r   r   r   r   r   r   r   r      s   c                   sh   e Zd ZdZeddZedeedZej	ej	f fdd	Z
ejdd Zed	d
 Zedd Z  ZS )r   u  
    Zenithal perspective projection - pixel to sky.

    Corresponds to the ``AZP`` projection in FITS WCS.

    .. math::
        \phi &= \arg(-y \cos \gamma, x) \\
        \theta &= \left\{\genfrac{}{}{0pt}{}{\psi - \omega}{\psi + \omega + 180^{\circ}}\right.

    where:

    .. math::
        \psi &= \arg(\rho, 1) \\
        \omega &= \sin^{-1}\left(\frac{\rho \mu}{\sqrt{\rho^2 + 1}}\right) \\
        \rho &= \frac{R}{\frac{180^{\circ}}{\pi}(\mu + 1) + y \sin \gamma} \\
        R &= \sqrt{x^2 + y^2 \cos^2 \gamma}

    Parameters
    --------------
    mu : float
        Distance from point of projection to center of sphere
        in spherical radii, μ.  Default is 0.

    gamma : float
        Look angle γ in degrees.  Default is 0°.
    g        )default)r   gettersetterc                s   t  j||f| d S )N)r   r   )r   mugammar   )r   r   r   r      s    z$Pix2Sky_ZenithalPerspective.__init__c             C   s   t |dkrtdd S )Nz:Zenithal perspective projection is not defined for mu = -1)r   anyr   )r   valuer   r   r   r      s    zPix2Sky_ZenithalPerspective.muc             C   s   t | jj| jjS )N)r   r   r   r   )r   r   r   r   r      s    z#Pix2Sky_ZenithalPerspective.inversec             C   s   t |||t|S )N)r   Zazpx2sr	   )clsr   r   r   r   r   r   r   evaluate   s    z$Pix2Sky_ZenithalPerspective.evaluate)r   r   r   r   r   r   r	   r   r   r   r   	validatorr   r   classmethodr   r   r   r   )r   r   r      s   
c               @   sN   e Zd ZdZeddZedeedZej	dd Ze
dd Zed	d
 ZdS )r   u8  
    Zenithal perspective projection - sky to pixel.

    Corresponds to the ``AZP`` projection in FITS WCS.

    .. math::
        x &= R \sin \phi \\
        y &= -R \sec \gamma \cos \theta

    where:

    .. math::
        R = \frac{180^{\circ}}{\pi} \frac{(\mu + 1) \cos \theta}{(\mu + \sin \theta) + \cos \theta \cos \phi \tan \gamma}

    Parameters
    ----------
    mu : float
        Distance from point of projection to center of sphere
        in spherical radii, μ. Default is 0.

    gamma : float
        Look angle γ in degrees. Default is 0°.
    g        )r   )r   r   r   c             C   s   t |dkrtdd S )Nr   z:Zenithal perspective projection is not defined for mu = -1)r   r   r   )r   r   r   r   r   r     s    zSky2Pix_ZenithalPerspective.muc             C   s   t | jj| jjS )N)rL   r   r   r   )r   r   r   r   r     s    z#Sky2Pix_ZenithalPerspective.inversec             C   s   t |||t|S )N)r   Zazps2xr	   )r   r   r   r   r   r   r   r   r     s    z$Sky2Pix_ZenithalPerspective.evaluateN)r   r   r   r   r   r   r	   r   r   r   r   r   r   r   r   r   r   r   r      s   
c               @   sX   e Zd ZdZdd ZededZedeedZ	edeedZ
edd	 Zed
d ZdS )r   u  
    Slant zenithal perspective projection - pixel to sky.

    Corresponds to the ``SZP`` projection in FITS WCS.

    Parameters
    --------------
    mu : float
        Distance from point of projection to center of sphere
        in spherical radii, μ.  Default is 0.

    phi0 : float
        The longitude φ₀ of the reference point, in degrees.  Default
        is 0°.

    theta0 : float
        The latitude θ₀ of the reference point, in degrees.  Default
        is 90°.
    c             C   s   t | dk rtd| S )Nr   z8Zenithal perspective projection is not defined for mu=-1)r   asarrayr   
ValueError)r   r   r   r   _validate_mu8  s    z-Pix2Sky_SlantZenithalPerspective._validate_mug        )r   r   )r   r   r   g     V@c             C   s   t | jj| jj| jjS )N)r   r   r   phi0theta0)r   r   r   r   r   B  s    z(Pix2Sky_SlantZenithalPerspective.inversec             C   s   t |||t|t|S )N)r   Zszpx2sr	   )r   r   r   r   r   r   r   r   r   r   G  s    z)Pix2Sky_SlantZenithalPerspective.evaluateN)r   r   r   r   r   r   r   r	   r   r   r   r   r   r   r   r   r   r   r   r   #  s   c               @   sX   e Zd ZdZdd ZededZedeedZ	edeedZ
edd Zed	d
 ZdS )r   u  
    Zenithal perspective projection - sky to pixel.

    Corresponds to the ``SZP`` projection in FITS WCS.

    Parameters
    ----------
    mu : float
        distance from point of projection to center of sphere
        in spherical radii, μ.  Default is 0.

    phi0 : float
        The longitude φ₀ of the reference point, in degrees.  Default
        is 0°.

    theta0 : float
        The latitude θ₀ of the reference point, in degrees.  Default
        is 90°.
    c             C   s   t | dk rtd| S )Nr   z8Zenithal perspective projection is not defined for mu=-1)r   r   r   r   )r   r   r   r   r   e  s    z-Sky2Pix_SlantZenithalPerspective._validate_mug        )r   r   )r   r   r   c             C   s   t | jj| jj| jjS )N)r   r   r   r   r   )r   r   r   r   r   n  s    z(Sky2Pix_SlantZenithalPerspective.inversec             C   s   t |||t|t|S )N)r   Zszps2xr	   )r   r   r   r   r   r   r   r   r   r   s  s    z)Sky2Pix_SlantZenithalPerspective.evaluateN)r   r   r   r   r   r   r   r	   r   r   r   r   r   r   r   r   r   r   r   r   P  s   c               @   s(   e Zd ZdZedd Zedd ZdS )r   z
    Gnomonic projection - pixel to sky.

    Corresponds to the ``TAN`` projection in FITS WCS.

    See `Zenithal` for a definition of the full transformation.

    .. math::
        \theta = \tan^{-1}\left(\frac{180^{\circ}}{\pi R_\theta}\right)
    c             C   s   t  S )N)r   )r   r   r   r   r     s    zPix2Sky_Gnomonic.inversec             C   s   t ||S )N)r   Ztanx2s)r   r   r   r   r   r   r     s    zPix2Sky_Gnomonic.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r   |  s   
c               @   s(   e Zd ZdZedd Zedd ZdS )r   z
    Gnomonic Projection - sky to pixel.

    Corresponds to the ``TAN`` projection in FITS WCS.

    See `Zenithal` for a definition of the full transformation.

    .. math::
        R_\theta = \frac{180^{\circ}}{\pi}\cot \theta
    c             C   s   t  S )N)r   )r   r   r   r   r     s    zSky2Pix_Gnomonic.inversec             C   s   t ||S )N)r   Ztans2x)r   r   r   r   r   r   r     s    zSky2Pix_Gnomonic.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r     s   
c               @   s(   e Zd ZdZedd Zedd ZdS )r   a  
    Stereographic Projection - pixel to sky.

    Corresponds to the ``STG`` projection in FITS WCS.

    See `Zenithal` for a definition of the full transformation.

    .. math::
        \theta = 90^{\circ} - 2 \tan^{-1}\left(\frac{\pi R_\theta}{360^{\circ}}\right)
    c             C   s   t  S )N)r   )r   r   r   r   r     s    zPix2Sky_Stereographic.inversec             C   s   t ||S )N)r   Zstgx2s)r   r   r   r   r   r   r     s    zPix2Sky_Stereographic.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r     s   
c               @   s(   e Zd ZdZedd Zedd ZdS )r   a
  
    Stereographic Projection - sky to pixel.

    Corresponds to the ``STG`` projection in FITS WCS.

    See `Zenithal` for a definition of the full transformation.

    .. math::
        R_\theta = \frac{180^{\circ}}{\pi}\frac{2 \cos \theta}{1 + \sin \theta}
    c             C   s   t  S )N)r   )r   r   r   r   r     s    zSky2Pix_Stereographic.inversec             C   s   t ||S )N)r   Zstgs2x)r   r   r   r   r   r   r     s    zSky2Pix_Stereographic.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r     s   
c               @   s<   e Zd ZdZeddZeddZedd Ze	dd Z
dS )	r   u  
    Slant orthographic projection - pixel to sky.

    Corresponds to the ``SIN`` projection in FITS WCS.

    See `Zenithal` for a definition of the full transformation.

    The following transformation applies when :math:`\xi` and
    :math:`\eta` are both zero.

    .. math::
        \theta = \cos^{-1}\left(\frac{\pi}{180^{\circ}}R_\theta\right)

    The parameters :math:`\xi` and :math:`\eta` are defined from the
    reference point :math:`(\phi_c, \theta_c)` as:

    .. math::
        \xi &= \cot \theta_c \sin \phi_c \\
        \eta &= - \cot \theta_c \cos \phi_c

    Parameters
    ----------
    xi : float
        Obliqueness parameter, ξ.  Default is 0.0.

    eta : float
        Obliqueness parameter, η.  Default is 0.0.
    g        )r   c             C   s   t | jj| jjS )N)r   xir   eta)r   r   r   r   r     s    z!Pix2Sky_SlantOrthographic.inversec             C   s   t ||||S )N)r   Zsinx2s)r   r   r   r   r   r   r   r   r     s    z"Pix2Sky_SlantOrthographic.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s
   

c               @   s<   e Zd ZdZeddZeddZedd Ze	dd Z
dS )	r   a)  
    Slant orthographic projection - sky to pixel.

    Corresponds to the ``SIN`` projection in FITS WCS.

    See `Zenithal` for a definition of the full transformation.

    The following transformation applies when :math:`\xi` and
    :math:`\eta` are both zero.

    .. math::
        R_\theta = \frac{180^{\circ}}{\pi}\cos \theta

    But more specifically are:

    .. math::
        x &= \frac{180^\circ}{\pi}[\cos \theta \sin \phi + \xi(1 - \sin \theta)] \\
        y &= \frac{180^\circ}{\pi}[\cos \theta \cos \phi + \eta(1 - \sin \theta)]
    g        )r   c             C   s   t | jj| jjS )N)r   r   r   r   )r   r   r   r   r   !  s    z!Sky2Pix_SlantOrthographic.inversec             C   s   t ||||S )N)r   Zsins2x)r   r   r   r   r   r   r   r   r   %  s    z"Sky2Pix_SlantOrthographic.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   	  s
   

c               @   s(   e Zd ZdZedd Zedd ZdS )r    z
    Zenithal equidistant projection - pixel to sky.

    Corresponds to the ``ARC`` projection in FITS WCS.

    See `Zenithal` for a definition of the full transformation.

    .. math::
        \theta = 90^\circ - R_\theta
    c             C   s   t  S )N)r!   )r   r   r   r   r   8  s    z#Pix2Sky_ZenithalEquidistant.inversec             C   s   t ||S )N)r   Zarcx2s)r   r   r   r   r   r   r   <  s    z$Pix2Sky_ZenithalEquidistant.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r    -  s   
c               @   s(   e Zd ZdZedd Zedd ZdS )r!   z
    Zenithal equidistant projection - sky to pixel.

    Corresponds to the ``ARC`` projection in FITS WCS.

    See `Zenithal` for a definition of the full transformation.

    .. math::
        R_\theta = 90^\circ - \theta
    c             C   s   t  S )N)r    )r   r   r   r   r   O  s    z#Sky2Pix_ZenithalEquidistant.inversec             C   s   t ||S )N)r   Zarcs2x)r   r   r   r   r   r   r   S  s    z$Sky2Pix_ZenithalEquidistant.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r!   D  s   
c               @   s(   e Zd ZdZedd Zedd ZdS )r"   a  
    Zenithal equidistant projection - pixel to sky.

    Corresponds to the ``ZEA`` projection in FITS WCS.

    See `Zenithal` for a definition of the full transformation.

    .. math::
        \theta = 90^\circ - 2 \sin^{-1} \left(\frac{\pi R_\theta}{360^\circ}\right)
    c             C   s   t  S )N)r#   )r   r   r   r   r   f  s    z!Pix2Sky_ZenithalEqualArea.inversec             C   s   t ||S )N)r   Zzeax2s)r   r   r   r   r   r   r   j  s    z"Pix2Sky_ZenithalEqualArea.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r"   [  s   
c               @   s(   e Zd ZdZedd Zedd ZdS )r#   a^  
    Zenithal equidistant projection - sky to pixel.

    Corresponds to the ``ZEA`` projection in FITS WCS.

    See `Zenithal` for a definition of the full transformation.

    .. math::
        R_\theta &= \frac{180^\circ}{\pi} \sqrt{2(1 - \sin\theta)} \\
                 &= \frac{360^\circ}{\pi} \sin\left(\frac{90^\circ - \theta}{2}\right)
    c             C   s   t  S )N)r"   )r   r   r   r   r   ~  s    z!Sky2Pix_ZenithalEqualArea.inversec             C   s   t ||S )N)r   Zzeas2x)r   r   r   r   r   r   r     s    z"Sky2Pix_ZenithalEqualArea.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r#   r  s   c               @   s2   e Zd ZdZeddZedd Zedd Z	dS )	r$   uA  
    Airy projection - pixel to sky.

    Corresponds to the ``AIR`` projection in FITS WCS.

    See `Zenithal` for a definition of the full transformation.

    Parameters
    ----------
    theta_b : float
        The latitude :math:`\theta_b` at which to minimize the error,
        in degrees.  Default is 90°.
    g     V@)r   c             C   s   t | jjS )N)r%   theta_br   )r   r   r   r   r     s    zPix2Sky_Airy.inversec             C   s   t |||S )N)r   Zairx2s)r   r   r   r   r   r   r   r     s    zPix2Sky_Airy.evaluateN)
r   r   r   r   r   r   r   r   r   r   r   r   r   r   r$     s   
c               @   s2   e Zd ZdZeddZedd Zedd Z	dS )	r%   uE  
    Airy - sky to pixel.

    Corresponds to the ``AIR`` projection in FITS WCS.

    See `Zenithal` for a definition of the full transformation.

    .. math::
        R_\theta = -2 \frac{180^\circ}{\pi}\left(\frac{\ln(\cos \xi)}{\tan \xi} + \frac{\ln(\cos \xi_b)}{\tan^2 \xi_b} \tan \xi \right)

    where:

    .. math::
        \xi &= \frac{90^\circ - \theta}{2} \\
        \xi_b &= \frac{90^\circ - \theta_b}{2}

    Parameters
    ----------
    theta_b : float
        The latitude :math:`\theta_b` at which to minimize the error,
        in degrees.  Default is 90°.
    g     V@)r   c             C   s   t | jjS )N)r$   r   r   )r   r   r   r   r     s    zSky2Pix_Airy.inversec             C   s   t |||S )N)r   Zairs2x)r   r   r   r   r   r   r   r     s    zSky2Pix_Airy.evaluateN)
r   r   r   r   r   r   r   r   r   r   r   r   r   r   r%     s   
c               @   s   e Zd ZdZdZdS )r   zBase class for Cylindrical projections.

    Cylindrical projections are so-named because the surface of
    projection is a cylinder.
    TN)r   r   r   r   r   r   r   r   r   r     s   c               @   sX   e Zd ZdZeddZeddZejdd Zejdd Zedd	 Z	e
d
d ZdS )r&   uZ  
    Cylindrical perspective - pixel to sky.

    Corresponds to the ``CYP`` projection in FITS WCS.

    .. math::
        \phi &= \frac{x}{\lambda} \\
        \theta &= \arg(1, \eta) + \sin{-1}\left(\frac{\eta \mu}{\sqrt{\eta^2 + 1}}\right)

    where:

    .. math::
        \eta = \frac{\pi}{180^{\circ}}\frac{y}{\mu + \lambda}

    Parameters
    ----------
    mu : float
        Distance from center of sphere in the direction opposite the
        projected surface, in spherical radii, μ. Default is 1.

    lam : float
        Radius of the cylinder in spherical radii, λ. Default is 1.
    g      ?)r   c             C   s   t || j krtdd S )Nz.CYP projection is not defined for mu = -lambda)r   r   lamr   )r   r   r   r   r   r     s    z!Pix2Sky_CylindricalPerspective.muc             C   s   t || j krtdd S )Nz.CYP projection is not defined for lambda = -mu)r   r   r   r   )r   r   r   r   r   r     s    z"Pix2Sky_CylindricalPerspective.lamc             C   s   t | jj| jjS )N)r'   r   r   r   )r   r   r   r   r     s    z&Pix2Sky_CylindricalPerspective.inversec             C   s   t ||||S )N)r   Zcypx2s)r   r   r   r   r   r   r   r   r      s    z'Pix2Sky_CylindricalPerspective.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r&     s   

c               @   sX   e Zd ZdZeddZeddZejdd Zejdd Zedd	 Z	e
d
d ZdS )r'   u  
    Cylindrical Perspective - sky to pixel.

    Corresponds to the ``CYP`` projection in FITS WCS.

    .. math::
        x &= \lambda \phi \\
        y &= \frac{180^{\circ}}{\pi}\left(\frac{\mu + \lambda}{\mu + \cos \theta}\right)\sin \theta

    Parameters
    ----------
    mu : float
        Distance from center of sphere in the direction opposite the
        projected surface, in spherical radii, μ.  Default is 0.

    lam : float
        Radius of the cylinder in spherical radii, λ.  Default is 0.
    g      ?)r   c             C   s   t || j krtdd S )Nz.CYP projection is not defined for mu = -lambda)r   r   r   r   )r   r   r   r   r   r     s    z!Sky2Pix_CylindricalPerspective.muc             C   s   t || j krtdd S )Nz.CYP projection is not defined for lambda = -mu)r   r   r   r   )r   r   r   r   r   r   %  s    z"Sky2Pix_CylindricalPerspective.lamc             C   s   t | j| jS )N)r&   r   r   )r   r   r   r   r   +  s    z&Sky2Pix_CylindricalPerspective.inversec             C   s   t ||||S )N)r   Zcyps2x)r   r   r   r   r   r   r   r   r   /  s    z'Sky2Pix_CylindricalPerspective.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r'     s   

c               @   s2   e Zd ZdZeddZedd Zedd Z	dS )	r(   uU  
    Cylindrical equal area projection - pixel to sky.

    Corresponds to the ``CEA`` projection in FITS WCS.

    .. math::
        \phi &= x \\
        \theta &= \sin^{-1}\left(\frac{\pi}{180^{\circ}}\lambda y\right)

    Parameters
    ----------
    lam : float
        Radius of the cylinder in spherical radii, λ.  Default is 1.
    r   )r   c             C   s
   t | jS )N)r)   r   )r   r   r   r   r   I  s    z$Pix2Sky_CylindricalEqualArea.inversec             C   s   t |||S )N)r   Zceax2s)r   r   r   r   r   r   r   r   M  s    z%Pix2Sky_CylindricalEqualArea.evaluateN)
r   r   r   r   r   r   r   r   r   r   r   r   r   r   r(   7  s   
c               @   s2   e Zd ZdZeddZedd Zedd Z	dS )	r)   uL  
    Cylindrical equal area projection - sky to pixel.

    Corresponds to the ``CEA`` projection in FITS WCS.

    .. math::
        x &= \phi \\
        y &= \frac{180^{\circ}}{\pi}\frac{\sin \theta}{\lambda}

    Parameters
    ----------
    lam : float
        Radius of the cylinder in spherical radii, λ.  Default is 0.
    r   )r   c             C   s
   t | jS )N)r(   r   )r   r   r   r   r   g  s    z$Sky2Pix_CylindricalEqualArea.inversec             C   s   t |||S )N)r   Zceas2x)r   r   r   r   r   r   r   r   k  s    z%Sky2Pix_CylindricalEqualArea.evaluateN)
r   r   r   r   r   r   r   r   r   r   r   r   r   r   r)   U  s   
c               @   s(   e Zd ZdZedd Zedd ZdS )r*   u   
    Plate carrée projection - pixel to sky.

    Corresponds to the ``CAR`` projection in FITS WCS.

    .. math::
        \phi &= x \\
        \theta &= y
    c             C   s   t  S )N)r+   )r   r   r   r   r   ~  s    zPix2Sky_PlateCarree.inversec             C   s$   t j| dd}t j|dd}||fS )NT)copy)r   array)r   r   r   r   r   r   r   r     s    zPix2Sky_PlateCarree.evaluateN)r   r   r   r   r   r   staticmethodr   r   r   r   r   r*   s  s   	c               @   s(   e Zd ZdZedd Zedd ZdS )r+   u   
    Plate carrée projection - sky to pixel.

    Corresponds to the ``CAR`` projection in FITS WCS.

    .. math::
        x &= \phi \\
        y &= \theta
    c             C   s   t  S )N)r*   )r   r   r   r   r     s    zSky2Pix_PlateCarree.inversec             C   s$   t j| dd}t j|dd}||fS )NT)r   )r   r   )r   r   r   r   r   r   r   r     s    zSky2Pix_PlateCarree.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r+     s   	c               @   s(   e Zd ZdZedd Zedd ZdS )r,   z
    Mercator - pixel to sky.

    Corresponds to the ``MER`` projection in FITS WCS.

    .. math::
        \phi &= x \\
        \theta &= 2 \tan^{-1}\left(e^{y \pi / 180^{\circ}}\right)-90^{\circ}
    c             C   s   t  S )N)r-   )r   r   r   r   r     s    zPix2Sky_Mercator.inversec             C   s   t ||S )N)r   Zmerx2s)r   r   r   r   r   r   r     s    zPix2Sky_Mercator.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r,     s   	c               @   s(   e Zd ZdZedd Zedd ZdS )r-   z
    Mercator - sky to pixel.

    Corresponds to the ``MER`` projection in FITS WCS.

    .. math::
        x &= \phi \\
        y &= \frac{180^{\circ}}{\pi}\ln \tan \left(\frac{90^{\circ} + \theta}{2}\right)
    c             C   s   t  S )N)r,   )r   r   r   r   r     s    zSky2Pix_Mercator.inversec             C   s   t ||S )N)r   Zmers2x)r   r   r   r   r   r   r     s    zSky2Pix_Mercator.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r-     s   	c               @   s   e Zd ZdZdZdS )r   a7  Base class for pseudocylindrical projections.

    Pseudocylindrical projections are like cylindrical projections
    except the parallels of latitude are projected at diminishing
    lengths toward the polar regions in order to reduce lateral
    distortion there.  Consequently, the meridians are curved.
    TN)r   r   r   r   r   r   r   r   r   r     s   c               @   s(   e Zd ZdZedd Zedd ZdS )r.   z
    Sanson-Flamsteed projection - pixel to sky.

    Corresponds to the ``SFL`` projection in FITS WCS.

    .. math::
        \phi &= \frac{x}{\cos y} \\
        \theta &= y
    c             C   s   t  S )N)r/   )r   r   r   r   r     s    zPix2Sky_SansonFlamsteed.inversec             C   s   t ||S )N)r   Zsflx2s)r   r   r   r   r   r   r     s    z Pix2Sky_SansonFlamsteed.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r.     s   	c               @   s(   e Zd ZdZedd Zedd ZdS )r/   z
    Sanson-Flamsteed projection - sky to pixel.

    Corresponds to the ``SFL`` projection in FITS WCS.

    .. math::
        x &= \phi \cos \theta \\
        y &= \theta
    c             C   s   t  S )N)r.   )r   r   r   r   r     s    zSky2Pix_SansonFlamsteed.inversec             C   s   t ||S )N)r   Zsfls2x)r   r   r   r   r   r   r   	  s    z Sky2Pix_SansonFlamsteed.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r/     s   	c               @   s,   e Zd ZdZdZedd Zedd ZdS )r0   z
    Parabolic projection - pixel to sky.

    Corresponds to the ``PAR`` projection in FITS WCS.

    .. math::
        \phi &= \frac{180^\circ}{\pi} \frac{x}{1 - 4(y / 180^\circ)^2} \\
        \theta &= 3 \sin^{-1}\left(\frac{y}{180^\circ}\right)
    Fc             C   s   t  S )N)r1   )r   r   r   r   r     s    zPix2Sky_Parabolic.inversec             C   s   t ||S )N)r   Zparx2s)r   r   r   r   r   r   r   "  s    zPix2Sky_Parabolic.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   r0     s   	c               @   s,   e Zd ZdZdZedd Zedd ZdS )r1   z
    Parabolic projection - sky to pixel.

    Corresponds to the ``PAR`` projection in FITS WCS.

    .. math::
        x &= \phi \left(2\cos\frac{2\theta}{3} - 1\right) \\
        y &= 180^\circ \sin \frac{\theta}{3}
    Fc             C   s   t  S )N)r0   )r   r   r   r   r   7  s    zSky2Pix_Parabolic.inversec             C   s   t ||S )N)r   Zpars2x)r   r   r   r   r   r   r   ;  s    zSky2Pix_Parabolic.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   r1   *  s   	c               @   s,   e Zd ZdZdZedd Zedd ZdS )r2   a  
    Molleweide's projection - pixel to sky.

    Corresponds to the ``MOL`` projection in FITS WCS.

    .. math::
        \phi &= \frac{\pi x}{2 \sqrt{2 - \left(\frac{\pi}{180^\circ}y\right)^2}} \\
        \theta &= \sin^{-1}\left(\frac{1}{90^\circ}\sin^{-1}\left(\frac{\pi}{180^\circ}\frac{y}{\sqrt{2}}\right) + \frac{y}{180^\circ}\sqrt{2 - \left(\frac{\pi}{180^\circ}y\right)^2}\right)
    Fc             C   s   t  S )N)r3   )r   r   r   r   r   P  s    zPix2Sky_Molleweide.inversec             C   s   t ||S )N)r   Zmolx2s)r   r   r   r   r   r   r   T  s    zPix2Sky_Molleweide.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   r2   C  s   	c               @   s,   e Zd ZdZdZedd Zedd ZdS )r3   a  
    Molleweide's projection - sky to pixel.

    Corresponds to the ``MOL`` projection in FITS WCS.

    .. math::
        x &= \frac{2 \sqrt{2}}{\pi} \phi \cos \gamma \\
        y &= \sqrt{2} \frac{180^\circ}{\pi} \sin \gamma

    where :math:`\gamma` is defined as the solution of the
    transcendental equation:

    .. math::

        \sin \theta = \frac{\gamma}{90^\circ} + \frac{\sin 2 \gamma}{\pi}
    Fc             C   s   t  S )N)r2   )r   r   r   r   r   p  s    zSky2Pix_Molleweide.inversec             C   s   t ||S )N)r   Zmols2x)r   r   r   r   r   r   r   t  s    zSky2Pix_Molleweide.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   r3   \  s   c               @   s,   e Zd ZdZdZedd Zedd ZdS )r4   a  
    Hammer-Aitoff projection - pixel to sky.

    Corresponds to the ``AIT`` projection in FITS WCS.

    .. math::
        \phi &= 2 \arg \left(2Z^2 - 1, \frac{\pi}{180^\circ} \frac{Z}{2}x\right) \\
        \theta &= \sin^{-1}\left(\frac{\pi}{180^\circ}yZ\right)
    Fc             C   s   t  S )N)r5   )r   r   r   r   r     s    zPix2Sky_HammerAitoff.inversec             C   s   t ||S )N)r   Zaitx2s)r   r   r   r   r   r   r     s    zPix2Sky_HammerAitoff.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   r4   |  s   	c               @   s,   e Zd ZdZdZedd Zedd ZdS )r5   aD  
    Hammer-Aitoff projection - sky to pixel.

    Corresponds to the ``AIT`` projection in FITS WCS.

    .. math::
        x &= 2 \gamma \cos \theta \sin \frac{\phi}{2} \\
        y &= \gamma \sin \theta

    where:

    .. math::
        \gamma = \frac{180^\circ}{\pi} \sqrt{\frac{2}{1 + \cos \theta \cos(\phi / 2)}}
    Fc             C   s   t  S )N)r4   )r   r   r   r   r     s    zSky2Pix_HammerAitoff.inversec             C   s   t ||S )N)r   Zaits2x)r   r   r   r   r   r   r     s    zSky2Pix_HammerAitoff.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   r5     s   c               @   s0   e Zd ZdZedeedZedeedZdZ	dS )r   a  Base class for conic projections.

    In conic projections, the sphere is thought to be projected onto
    the surface of a cone which is then opened out.

    In a general sense, the pixel-to-sky transformation is defined as:

    .. math::

        \phi &= \arg\left(\frac{Y_0 - y}{R_\theta}, \frac{x}{R_\theta}\right) / C \\
        R_\theta &= \mathrm{sign} \theta_a \sqrt{x^2 + (Y_0 - y)^2}

    and the inverse (sky-to-pixel) is defined as:

    .. math::
        x &= R_\theta \sin (C \phi) \\
        y &= R_\theta \cos (C \phi) + Y_0

    where :math:`C` is the "constant of the cone":

    .. math::
        C = \frac{180^\circ \cos \theta}{\pi R_\theta}
    g     V@)r   r   r   g        FN)
r   r   r   r   r   r	   r   sigmadeltar   r   r   r   r   r     s   c               @   s(   e Zd ZdZedd Zedd ZdS )r6   aB  
    Colles' conic perspective projection - pixel to sky.

    Corresponds to the ``COP`` projection in FITS WCS.

    See `Conic` for a description of the entire equation.

    The projection formulae are:

    .. math::
        C &= \sin \theta_a \\
        R_\theta &= \frac{180^\circ}{\pi} \cos \eta [ \cot \theta_a - \tan(\theta - \theta_a)] \\
        Y_0 &= \frac{180^\circ}{\pi} \cos \eta \cot \theta_a

    Parameters
    ----------
    sigma : float
        :math:`(\theta_1 + \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 90.

    delta : float
        :math:`(\theta_1 - \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 0.
    c             C   s   t | jj| jjS )N)r7   r   r   r   )r   r   r   r   r     s    z Pix2Sky_ConicPerspective.inversec             C   s   t ||t|t|S )N)r   Zcopx2sr	   )r   r   r   r   r   r   r   r   r     s    z!Pix2Sky_ConicPerspective.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r6     s   c               @   s(   e Zd ZdZedd Zedd ZdS )r7   aB  
    Colles' conic perspective projection - sky to pixel.

    Corresponds to the ``COP`` projection in FITS WCS.

    See `Conic` for a description of the entire equation.

    The projection formulae are:

    .. math::
        C &= \sin \theta_a \\
        R_\theta &= \frac{180^\circ}{\pi} \cos \eta [ \cot \theta_a - \tan(\theta - \theta_a)] \\
        Y_0 &= \frac{180^\circ}{\pi} \cos \eta \cot \theta_a

    Parameters
    ----------
    sigma : float
        :math:`(\theta_1 + \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 90.

    delta : float
        :math:`(\theta_1 - \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 0.
    c             C   s   t | jj| jjS )N)r6   r   r   r   )r   r   r   r   r     s    z Sky2Pix_ConicPerspective.inversec             C   s   t ||t|t|S )N)r   Zcops2xr	   )r   r   r   r   r   r   r   r   r     s    z!Sky2Pix_ConicPerspective.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r7     s   c               @   s(   e Zd ZdZedd Zedd ZdS )r8   a  
    Alber's conic equal area projection - pixel to sky.

    Corresponds to the ``COE`` projection in FITS WCS.

    See `Conic` for a description of the entire equation.

    The projection formulae are:

    .. math::
        C &= \gamma / 2 \\
        R_\theta &= \frac{180^\circ}{\pi} \frac{2}{\gamma} \sqrt{1 + \sin \theta_1 \sin \theta_2 - \gamma \sin \theta} \\
        Y_0 &= \frac{180^\circ}{\pi} \frac{2}{\gamma} \sqrt{1 + \sin \theta_1 \sin \theta_2 - \gamma \sin((\theta_1 + \theta_2)/2)}

    where:

    .. math::
        \gamma = \sin \theta_1 + \sin \theta_2

    Parameters
    ----------
    sigma : float
        :math:`(\theta_1 + \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 90.

    delta : float
        :math:`(\theta_1 - \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 0.
    c             C   s   t | jj| jjS )N)r9   r   r   r   )r   r   r   r   r   @  s    zPix2Sky_ConicEqualArea.inversec             C   s   t ||t|t|S )N)r   Zcoex2sr	   )r   r   r   r   r   r   r   r   r   D  s    zPix2Sky_ConicEqualArea.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r8      s   c               @   s(   e Zd ZdZedd Zedd ZdS )r9   a  
    Alber's conic equal area projection - sky to pixel.

    Corresponds to the ``COE`` projection in FITS WCS.

    See `Conic` for a description of the entire equation.

    The projection formulae are:

    .. math::
        C &= \gamma / 2 \\
        R_\theta &= \frac{180^\circ}{\pi} \frac{2}{\gamma} \sqrt{1 + \sin \theta_1 \sin \theta_2 - \gamma \sin \theta} \\
        Y_0 &= \frac{180^\circ}{\pi} \frac{2}{\gamma} \sqrt{1 + \sin \theta_1 \sin \theta_2 - \gamma \sin((\theta_1 + \theta_2)/2)}

    where:

    .. math::
        \gamma = \sin \theta_1 + \sin \theta_2

    Parameters
    ----------
    sigma : float
        :math:`(\theta_1 + \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 90.

    delta : float
        :math:`(\theta_1 - \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 0.
    c             C   s   t | jj| jjS )N)r8   r   r   r   )r   r   r   r   r   l  s    zSky2Pix_ConicEqualArea.inversec             C   s   t ||t|t|S )N)r   Zcoes2xr	   )r   r   r   r   r   r   r   r   r   p  s    zSky2Pix_ConicEqualArea.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r9   L  s   c               @   s(   e Zd ZdZedd Zedd ZdS )r:   a1  
    Conic equidistant projection - pixel to sky.

    Corresponds to the ``COD`` projection in FITS WCS.

    See `Conic` for a description of the entire equation.

    The projection formulae are:

    .. math::

        C &= \frac{180^\circ}{\pi} \frac{\sin\theta_a\sin\eta}{\eta} \\
        R_\theta &= \theta_a - \theta + \eta\cot\eta\cot\theta_a \\
        Y_0 = \eta\cot\eta\cot\theta_a

    Parameters
    ----------
    sigma : float
        :math:`(\theta_1 + \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 90.

    delta : float
        :math:`(\theta_1 - \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 0.
    c             C   s   t | jj| jjS )N)r;   r   r   r   )r   r   r   r   r     s    z Pix2Sky_ConicEquidistant.inversec             C   s   t ||t|t|S )N)r   Zcodx2sr	   )r   r   r   r   r   r   r   r   r     s    z!Pix2Sky_ConicEquidistant.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r:   y  s   c               @   s(   e Zd ZdZedd Zedd ZdS )r;   a1  
    Conic equidistant projection - sky to pixel.

    Corresponds to the ``COD`` projection in FITS WCS.

    See `Conic` for a description of the entire equation.

    The projection formulae are:

    .. math::

        C &= \frac{180^\circ}{\pi} \frac{\sin\theta_a\sin\eta}{\eta} \\
        R_\theta &= \theta_a - \theta + \eta\cot\eta\cot\theta_a \\
        Y_0 = \eta\cot\eta\cot\theta_a

    Parameters
    ----------
    sigma : float
        :math:`(\theta_1 + \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 90.

    delta : float
        :math:`(\theta_1 - \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 0.
    c             C   s   t | jj| jjS )N)r:   r   r   r   )r   r   r   r   r     s    z Sky2Pix_ConicEquidistant.inversec             C   s   t ||t|t|S )N)r   Zcods2xr	   )r   r   r   r   r   r   r   r   r     s    z!Sky2Pix_ConicEquidistant.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r;     s   c               @   s(   e Zd ZdZedd Zedd ZdS )r<   a  
    Conic orthomorphic projection - pixel to sky.

    Corresponds to the ``COO`` projection in FITS WCS.

    See `Conic` for a description of the entire equation.

    The projection formulae are:

    .. math::

        C &= \frac{\ln \left( \frac{\cos\theta_2}{\cos\theta_1} \right)}
                  {\ln \left[ \frac{\tan\left(\frac{90^\circ-\theta_2}{2}\right)}
                                   {\tan\left(\frac{90^\circ-\theta_1}{2}\right)} \right] } \\
        R_\theta &= \psi \left[ \tan \left( \frac{90^\circ - \theta}{2} \right) \right]^C \\
        Y_0 &= \psi \left[ \tan \left( \frac{90^\circ - \theta_a}{2} \right) \right]^C

    where:

    .. math::

        \psi = \frac{180^\circ}{\pi} \frac{\cos \theta}
               {C\left[\tan\left(\frac{90^\circ-\theta}{2}\right)\right]^C}

    Parameters
    ----------
    sigma : float
        :math:`(\theta_1 + \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 90.

    delta : float
        :math:`(\theta_1 - \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 0.
    c             C   s   t | jj| jjS )N)r=   r   r   r   )r   r   r   r   r     s    z!Pix2Sky_ConicOrthomorphic.inversec             C   s   t ||t|t|S )N)r   Zcoox2sr	   )r   r   r   r   r   r   r   r   r     s    z"Pix2Sky_ConicOrthomorphic.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r<     s   $c               @   s(   e Zd ZdZedd Zedd ZdS )r=   a  
    Conic orthomorphic projection - sky to pixel.

    Corresponds to the ``COO`` projection in FITS WCS.

    See `Conic` for a description of the entire equation.

    The projection formulae are:

    .. math::

        C &= \frac{\ln \left( \frac{\cos\theta_2}{\cos\theta_1} \right)}
                  {\ln \left[ \frac{\tan\left(\frac{90^\circ-\theta_2}{2}\right)}
                                   {\tan\left(\frac{90^\circ-\theta_1}{2}\right)} \right] } \\
        R_\theta &= \psi \left[ \tan \left( \frac{90^\circ - \theta}{2} \right) \right]^C \\
        Y_0 &= \psi \left[ \tan \left( \frac{90^\circ - \theta_a}{2} \right) \right]^C

    where:

    .. math::

        \psi = \frac{180^\circ}{\pi} \frac{\cos \theta}
               {C\left[\tan\left(\frac{90^\circ-\theta}{2}\right)\right]^C}

    Parameters
    ----------
    sigma : float
        :math:`(\theta_1 + \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 90.

    delta : float
        :math:`(\theta_1 - \theta_2) / 2`, where :math:`\theta_1` and
        :math:`\theta_2` are the latitudes of the standard parallels,
        in degrees.  Default is 0.
    c             C   s   t | jj| jjS )N)r<   r   r   r   )r   r   r   r   r      s    z!Sky2Pix_ConicOrthomorphic.inversec             C   s   t ||t|t|S )N)r   Zcoos2xr	   )r   r   r   r   r   r   r   r   r   $  s    z"Sky2Pix_ConicOrthomorphic.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r=     s   $c               @   s   e Zd ZdZdS )r   zrBase class for pseudoconic projections.

    Pseudoconics are a subclass of conics with concentric parallels.
    N)r   r   r   r   r   r   r   r   r   -  s   c               @   s:   e Zd ZdZedeedZdZe	dd Z
edd Zd	S )
r>   a  
    Bonne's equal area pseudoconic projection - pixel to sky.

    Corresponds to the ``BON`` projection in FITS WCS.

    .. math::

        \phi &= \frac{\pi}{180^\circ} A_\phi R_\theta / \cos \theta \\
        \theta &= Y_0 - R_\theta

    where:

    .. math::

        R_\theta &= \mathrm{sign} \theta_1 \sqrt{x^2 + (Y_0 - y)^2} \\
        A_\phi &= \arg\left(\frac{Y_0 - y}{R_\theta}, \frac{x}{R_\theta}\right)

    Parameters
    ----------
    theta1 : float
        Bonne conformal latitude, in degrees.
    g        )r   r   r   Tc             C   s   t | jjS )N)r?   theta1r   )r   r   r   r   r   N  s    zPix2Sky_BonneEqualArea.inversec             C   s   t ||t|S )N)r   Zbonx2sr	   )r   r   r   r   r   r   r   r   R  s    zPix2Sky_BonneEqualArea.evaluateN)r   r   r   r   r   r	   r   r   r   r   r   r   r   r   r   r   r   r>   4  s
   c               @   s:   e Zd ZdZedeedZdZe	dd Z
edd Zd	S )
r?   a  
    Bonne's equal area pseudoconic projection - sky to pixel.

    Corresponds to the ``BON`` projection in FITS WCS.

    .. math::
        x &= R_\theta \sin A_\phi \\
        y &= -R_\theta \cos A_\phi + Y_0

    where:

    .. math::
        A_\phi &= \frac{180^\circ}{\pi R_\theta} \phi \cos \theta \\
        R_\theta &= Y_0 - \theta \\
        Y_0 &= \frac{180^\circ}{\pi} \cot \theta_1 + \theta_1

    Parameters
    ----------
    theta1 : float
        Bonne conformal latitude, in degrees.
    g        )r   r   r   Tc             C   s   t | jjS )N)r>   r   r   )r   r   r   r   r   s  s    zSky2Pix_BonneEqualArea.inversec             C   s   t ||t|S )N)r   Zbons2xr	   )r   r   r   r   r   r   r   r   w  s    zSky2Pix_BonneEqualArea.evaluateN)r   r   r   r   r   r	   r   r   r   r   r   r   r   r   r   r   r   r?   Z  s
   c               @   s,   e Zd ZdZdZedd Zedd ZdS )r@   zf
    Polyconic projection - pixel to sky.

    Corresponds to the ``PCO`` projection in FITS WCS.
    Fc             C   s   t  S )N)rA   )r   r   r   r   r     s    zPix2Sky_Polyconic.inversec             C   s   t ||S )N)r   Zpcox2s)r   r   r   r   r   r   r     s    zPix2Sky_Polyconic.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   r@     s   c               @   s,   e Zd ZdZdZedd Zedd ZdS )rA   zf
    Polyconic projection - sky to pixel.

    Corresponds to the ``PCO`` projection in FITS WCS.
    Fc             C   s   t  S )N)r@   )r   r   r   r   r     s    zSky2Pix_Polyconic.inversec             C   s   t ||S )N)r   Zpcos2x)r   r   r   r   r   r   r     s    zSky2Pix_Polyconic.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   rA     s   c               @   s   e Zd ZdZdS )r   aw  Base class for quad cube projections.

    Quadrilateralized spherical cube (quad-cube) projections belong to
    the class of polyhedral projections in which the sphere is
    projected onto the surface of an enclosing polyhedron.

    The six faces of the quad-cube projections are numbered and laid
    out as::

              0
        4 3 2 1 4 3 2
              5

    N)r   r   r   r   r   r   r   r   r     s   c               @   s,   e Zd ZdZdZedd Zedd ZdS )rB   zv
    Tangential spherical cube projection - pixel to sky.

    Corresponds to the ``TSC`` projection in FITS WCS.
    Fc             C   s   t  S )N)rC   )r   r   r   r   r     s    z'Pix2Sky_TangentialSphericalCube.inversec             C   s   t ||S )N)r   Ztscx2s)r   r   r   r   r   r   r     s    z(Pix2Sky_TangentialSphericalCube.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   rB     s   c               @   s,   e Zd ZdZdZedd Zedd ZdS )rC   zv
    Tangential spherical cube projection - sky to pixel.

    Corresponds to the ``PCO`` projection in FITS WCS.
    Fc             C   s   t  S )N)rB   )r   r   r   r   r     s    z'Sky2Pix_TangentialSphericalCube.inversec             C   s   t ||S )N)r   Ztscs2x)r   r   r   r   r   r   r     s    z(Sky2Pix_TangentialSphericalCube.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   rC     s   c               @   s,   e Zd ZdZdZedd Zedd ZdS )rD   z
    COBE quadrilateralized spherical cube projection - pixel to sky.

    Corresponds to the ``CSC`` projection in FITS WCS.
    Fc             C   s   t  S )N)rE   )r   r   r   r   r     s    z%Pix2Sky_COBEQuadSphericalCube.inversec             C   s   t ||S )N)r   Zcscx2s)r   r   r   r   r   r   r     s    z&Pix2Sky_COBEQuadSphericalCube.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   rD     s   c               @   s,   e Zd ZdZdZedd Zedd ZdS )rE   z
    COBE quadrilateralized spherical cube projection - sky to pixel.

    Corresponds to the ``CSC`` projection in FITS WCS.
    Fc             C   s   t  S )N)rD   )r   r   r   r   r     s    z%Sky2Pix_COBEQuadSphericalCube.inversec             C   s   t ||S )N)r   Zcscs2x)r   r   r   r   r   r   r     s    z&Sky2Pix_COBEQuadSphericalCube.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   rE     s   c               @   s,   e Zd ZdZdZedd Zedd ZdS )rF   z}
    Quadrilateralized spherical cube projection - pixel to sky.

    Corresponds to the ``QSC`` projection in FITS WCS.
    Fc             C   s   t  S )N)rG   )r   r   r   r   r     s    z!Pix2Sky_QuadSphericalCube.inversec             C   s   t ||S )N)r   Zqscx2s)r   r   r   r   r   r   r     s    z"Pix2Sky_QuadSphericalCube.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   rF   	  s   c               @   s,   e Zd ZdZdZedd Zedd ZdS )rG   z}
    Quadrilateralized spherical cube projection - sky to pixel.

    Corresponds to the ``QSC`` projection in FITS WCS.
    Fc             C   s   t  S )N)rF   )r   r   r   r   r   %  s    z!Sky2Pix_QuadSphericalCube.inversec             C   s   t ||S )N)r   Zqscs2x)r   r   r   r   r   r   r   )  s    z"Sky2Pix_QuadSphericalCube.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   rG     s   c               @   s   e Zd ZdZdS )r   z(Base class for HEALPix projections.
    N)r   r   r   r   r   r   r   r   r   1  s   c               @   s@   e Zd ZdZdZeddZeddZedd Z	e
dd	 Zd
S )rH   z
    HEALPix - pixel to sky.

    Corresponds to the ``HPX`` projection in FITS WCS.

    Parameters
    ----------
    H : float
        The number of facets in longitude direction.

    X : float
        The number of facets in latitude direction.
    Tg      @)r   g      @c             C   s   t | jj| jjS )N)rI   Hr   X)r   r   r   r   r   I  s    zPix2Sky_HEALPix.inversec             C   s   t ||||S )N)r   Zhpxx2s)r   r   r   r   r   r   r   r   r   M  s    zPix2Sky_HEALPix.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rH   6  s   

c               @   s@   e Zd ZdZdZeddZeddZedd Z	e
dd	 Zd
S )rI   a	  
    HEALPix projection - sky to pixel.

    Corresponds to the ``HPX`` projection in FITS WCS.

    Parameters
    ----------
    H : float
        The number of facets in longitude direction.

    X : float
        The number of facets in latitude direction.
    Tg      @)r   g      @c             C   s   t | jj| jjS )N)rH   r   r   r   )r   r   r   r   r   h  s    zSky2Pix_HEALPix.inversec             C   s   t ||||S )N)r   hpxs2x)r   r   r   r   r   r   r   r   r   l  s    zSky2Pix_HEALPix.evaluateN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rI   U  s   

c               @   s,   e Zd ZdZdZedd Zedd ZdS )rJ   z{
    HEALPix polar, aka "butterfly" projection - pixel to sky.

    Corresponds to the ``XPH`` projection in FITS WCS.
    Fc             C   s   t  S )N)rI   )r   r   r   r   r   |  s    zPix2Sky_HEALPixPolar.inversec             C   s   t ||S )N)r   Zxphx2s)r   r   r   r   r   r   r     s    zPix2Sky_HEALPixPolar.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   rJ   t  s   c               @   s,   e Zd ZdZdZedd Zedd ZdS )rK   z{
    HEALPix polar, aka "butterfly" projection - pixel to sky.

    Corresponds to the ``XPH`` projection in FITS WCS.
    Fc             C   s   t  S )N)rH   )r   r   r   r   r     s    zSky2Pix_HEALPixPolar.inversec             C   s   t ||S )N)r   r   )r   r   r   r   r   r   r     s    zSky2Pix_HEALPixPolar.evaluateN)	r   r   r   r   r   r   r   r   r   r   r   r   r   rK     s   c                   s   e Zd ZdZdZdZdZdZeddgddggdZ	eddgdZ
e	jdd Z	e
jd	d
 Z
e	e
f fdd	Zedd Zedd Zedd Zedd Z  ZS )r   aP  
    Perform an affine transformation in 2 dimensions.

    Parameters
    ----------
    matrix : array
        A 2x2 matrix specifying the linear transformation to apply to the
        inputs

    translation : array
        A 2D vector (given as either a 2x1 or 1x2 array) specifying a
        translation to apply to the inputs
    r   Fg      ?g        )r   c             C   s   t |dkrtddS )z2Validates that the input matrix is a 2x2 2D array.)r   r   z0Expected transformation matrix to be a 2x2 arrayN)r   shaper   )r   r   r   r   r   matrix  s    zAffineTransformation2D.matrixc             C   sD   t |dkrt |dks@t |dkr8t |dks@tddS )z
        Validates that the translation vector is a 2D vector.  This allows
        either a "row" vector or a "column" vector where in the latter case the
        resultant Numpy array has ``ndim=2`` but the shape is ``(1, 2)``.
        r   )r   r   )r   r   zHExpected translation vector to be a 2 element row or column vector arrayN)r   ndimr   r   )r   r   r   r   r   translation  s    z"AffineTransformation2D.translationc                s(   t  jf ||d| d| _d| _d S )N)r   r   )r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r     s    zAffineTransformation2D.__init__c             C   sr   t j| jj}|dkr*td| jjt j	| jj}| jj
dk	rR|| jj
 }t || jj }| j||dS )z
        Inverse transformation.

        Raises `~astropy.modeling.InputParameterError` if the transformation cannot be inverted.
        r   zDTransformation matrix is singular; {} model does not have an inverseN)r   r   )r   Zlinalgdetr   r   r   formatr   r   invunitdotr   )r   r   r   r   r   r   r   r     s    zAffineTransformation2D.inversec       	      C   s   |j |j krtd|j pd}tt| t| t|j|jg}|j d dksf|j	dkrntd| 
||}t||}|d |d  }}| |_ |_ ||fS )a,  
        Apply the transformation to a set of 2D Cartesian coordinates given as
        two lists--one for the x coordinates and one for a y coordinates--or a
        single coordinate pair.

        Parameters
        ----------
        x, y : array, float
              x and y coordinates
        z,Expected input arrays to have the same shape)r   r      r   zIncompatible input shapesr   )r   r   r   Zvstackr   ZravelZonessizedtyper   _create_augmented_matrixr   )	r   r   r   r   r   r   Zinarraugmented_matrixresultr   r   r   r     s    
zAffineTransformation2D.evaluatec             C   s   d }t t|dt| dgr\tt|dt| dgs<td|j}| j|j tjks\tdtjdt	d}| |ddddf< ||dddd f _
dddg|d< |d k	r|| S |S )	Nr   zXTo use AffineTransformation with quantities, both matrix and unit need to be quantities.z0matrix and translation must have the same units.)r   r   )r   r   r   r   )r   hasattrallr   r   r   Zdimensionless_unscaledr   emptyfloatZflat)r   r   r   r   r   r   r   r     s    z/AffineTransformation2D._create_augmented_matrixc             C   s`   | j jd kr| jjd krd S | j jd k	rBtt| j| j jgd S tt| j| jjgd S d S )Nr   )r   r   r   dictzipr   )r   r   r   r   r     s
    z"AffineTransformation2D.input_units)r   r   r   r   r   r   Zstandard_broadcastingr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r     s   )r   r   numpyr   Zastropyr   r   corer   
parametersr   r    r   utilsr   r	   r   __all__r
   r   r   r   r   rL   r   rM   r   rN   r   rO   r   rP   r   rQ   r   rR   r   rS   r   rT   r   rU   r    rV   r!   rW   r"   rX   r#   rY   r$   rZ   r%   r[   r   r&   r\   r'   r]   r(   r^   r)   r_   r*   r`   r+   ra   r,   rb   r-   rc   r   r.   rd   r/   re   r0   rf   r1   rg   r2   rh   r3   ri   r4   rj   r5   rk   r   r6   rl   r7   rm   r8   rn   r9   ro   r:   rp   r;   rq   r<   rr   r=   rs   r   r>   rt   r?   ru   r@   rv   rA   rw   r   rB   rx   rC   ry   rD   rz   rE   r{   rF   r|   rG   r}   r   rH   r~   rI   r   rJ   r   rK   r   r   r   r   r   r   <module>   sx  2,*)*!"	1,$%)*%&./##