ó
šßÈ[c           @` s\  d  Z  d d l m Z m Z m Z m Z d d l Z d d l Z d d l	 m
 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 d d l m Z m Z d d d d g Z d e f d „  ƒ  YZ d e e
 f d „  ƒ  YZ d e e
 f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ  d e
 f d „  ƒ  YZ! d S(   u°  
Implements rotations, including spherical rotations as defined in WCS Paper II
[1]_

`RotateNative2Celestial` and `RotateCelestial2Native` follow the convention in
WCS Paper II to rotate to/from a native sphere and the celestial sphere.

The implementation uses `EulerAngleRotation`. The model parameters are
three angles: the longitude (``lon``) and latitude (``lat``) of the fiducial point
in the celestial system (``CRVAL`` keywords in FITS), and the longitude of the celestial
pole in the native system (``lon_pole``). The Euler angles are ``lon+90``, ``90-lat``
and ``-(lon_pole-90)``.


References
----------
.. [1] Calabretta, M.R., Greisen, E.W., 2002, A&A, 395, 1077 (Paper II)
i    (   t   absolute_importt   unicode_literalst   divisiont   print_functionNi   (   t   Model(   t	   Parameteri   (   t   zip(   t   rotation_matrixt   matrix_product(   t   units(   t
   deprecated(   t
   _to_radiant   _to_orig_unitu   RotateCelestial2Nativeu   RotateNative2Celestialu
   Rotation2Du   EulerAngleRotationt   _EulerRotationc           B` sƒ   e  Z d  Z d „  Z e d „  ƒ Z e d „  ƒ Z e d ƒ e d „  ƒ ƒ Z d „  Z	 e
 Z e
 Z e d „  ƒ Z e d „  ƒ Z RS(	   u7   
    Base class which does the actual computation.
    c   	      C` s•   g  } xo t  | | | g | ƒ D]U \ } } t | t j ƒ rI | j } n  | j ƒ  } | j t | | d t j ƒƒ q Wt	 | d  d  d … Œ  } | S(   Nt   unitiÿÿÿÿ(
   R   t
   isinstancet   ut   Quantityt   valuet   itemt   appendR   t   radR   (	   t   selft   phit   thetat   psit
   axes_ordert   matricest   anglet   axist   result(    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyt   _create_matrix.   s    %#c         C` s{   t  j |  ƒ }  t  j | ƒ } t  j |  ƒ t  j | ƒ } t  j | ƒ t  j |  ƒ } t  j | ƒ } t  j | | | g ƒ S(   N(   t   npt   deg2radt   cost   sint   array(   t   alphat   deltat   xt   yt   z(    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyt   spherical2cartesian8   s    c         C` sR   t  j |  | ƒ } t  j t  j | |  ƒ ƒ } t  j t  j | | ƒ ƒ } | | f S(   N(   R    t   hypott   rad2degt   arctan2(   R'   R(   R)   t   hR%   R&   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyt   cartesian2sphericalA   s    g       @c         C` sD   t  j t j |  ƒ t j |  ƒ g t j |  ƒ t j |  ƒ g g ƒ S(   u   
        Clockwise rotation matrix.

        Parameters
        ----------
        angle : float
            Rotation angle in radians.
        (   R    R$   t   mathR"   R#   (   R   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyt   rotation_matrix_from_angleH   s    !c         C` sÇ   d  } t | t j ƒ rK | j d k rK | j ƒ  } | j ƒ  } | j } n  |  j | | ƒ } |  j | | | | ƒ }	 t j	 |	 | ƒ }
 |  j
 |
 Œ  \ } } | d  k	 r½ | | _ | | _ n  | | f S(   Ni   (   t   NoneR   R    t   ndarrayt   ndimt   flattent   shapeR*   R   t   dotR/   (   R   R%   R&   R   R   R   R   R6   t   inpt   matrixR   t   at   b(    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyt   evaluateV   s    !	c         C` s   i t  j d 6t  j d 6S(   u    Input units. u   alphau   delta(   R   t   deg(   R   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyt   input_unitsi   s    c         C` s   i t  j d 6t  j d 6S(   u    Output units. u   alphau   delta(   R   R=   (   R   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyt   return_unitsn   s    (   t   __name__t
   __module__t   __doc__R   t   staticmethodR*   R/   R
   R1   R<   t   Truet   input_units_strictt   input_units_allow_dimensionlesst   propertyR>   R?   (    (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyR   )   s   	
			t   EulerAngleRotationc           B` s†   e  Z d  Z d
 Z d Z e d d d e d e ƒ Z e d d d e d e ƒ Z	 e d d d e d e ƒ Z
 d „  Z d „  Z d	 „  Z RS(   u'  
    Implements Euler angle intrinsic rotations.

    Rotates one coordinate system into another (fixed) coordinate system.
    All coordinate systems are right-handed. The sign of the angles is
    determined by the right-hand rule..

    Parameters
    ----------
    phi, theta, psi : float or `~astropy.units.Quantity`
        "proper" Euler angles in deg.
        If floats, they should be in deg.
    axes_order : str
        A 3 character string, a combination of 'x', 'y' and 'z',
        where each character denotes an axis in 3D space.
    u   alphau   deltat   defaulti    t   gettert   setterc   	      K` s  d d d g |  _  t | ƒ d k r< t d j | ƒ ƒ ‚ n  t | ƒ j |  j  ƒ } | rx t d j | |  j  ƒ ƒ ‚ n  | |  _ g  | | | g D] } t | t	 j
 ƒ ^ q‘ } t | ƒ r× t | ƒ r× t d ƒ ‚ n  t t |  ƒ j d | d	 | d
 | |  d  S(   Nu   xu   yu   zi   uB   Expected axes_order to be a character sequence of length 3,got {0}u2   Unrecognized axis label {0}; should be one of {1} u>   All parameters should be of the same type - float or Quantity.R   R   R   (   t   axest   lent	   TypeErrort   formatt   sett
   differencet
   ValueErrorR   R   R   R   t   anyt   allt   superRH   t   __init__(	   R   R   R   R   R   t   kwargst   unrecognizedt   part   qs(    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyRV      s    		.c         C` s>   |  j  d |  j d |  j d |  j d |  j d  d  d … ƒ S(   NR   R   R   R   iÿÿÿÿ(   t	   __class__R   R   R   R   (   R   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyt   inversež   s    

c         C` s:   t  t |  ƒ j | | | | | |  j ƒ \ } } | | f S(   N(   RU   RH   R<   R   (   R   R%   R&   R   R   R   R:   R;   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyR<   ¤   s    0(   u   alphau   delta(   u   alphau   delta(   R@   RA   RB   t   inputst   outputsR   R   R   R   R   R   RV   R\   R<   (    (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyRH   t   s   		t   _SkyRotationc           B` sq   e  Z d  Z e d d d e d e ƒ Z e d d d e d e ƒ Z e d d d e d e ƒ Z d „  Z	 d „  Z
 RS(   uK   
    Base class for RotateNative2Celestial and RotateCelestial2Native.
    RI   i    RJ   RK   c         K` s‚   g  | | | g D] } t  | t j ƒ ^ q } t | ƒ rV t | ƒ rV t d ƒ ‚ n  t t |  ƒ j | | | |  d |  _	 d  S(   Nu>   All parameters should be of the same type - float or Quantity.u   zxz(
   R   R   R   RS   RT   RN   RU   R_   RV   R   (   R   t   lont   latt   lon_poleRW   RY   RZ   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyRV   ²   s
    .c   	      C` su   t  t |  ƒ j | | | | | |  j ƒ \ } } | d k  } t | t j ƒ ra | | c d 7<n
 | d 7} | | f S(   Ni    ih  (   RU   R_   R<   R   R   R    R3   (	   R   R   R   R`   Ra   Rb   R%   R&   t   mask(    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyt	   _evaluate¹   s    
(   R@   RA   RB   R   R   R   R`   Ra   Rb   RV   Rd   (    (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyR_   ©   s   	t   RotateNative2Celestialc           B` sY   e  Z d  Z d
 Z d Z e d „  ƒ Z e d „  ƒ Z d „  Z d „  Z	 e d	 „  ƒ Z
 RS(   u  
    Transform from Native to Celestial Spherical Coordinates.

    Parameters
    ----------
    lon : float or or `~astropy.units.Quantity`
        Celestial longitude of the fiducial point.
    lat : float or or `~astropy.units.Quantity`
        Celestial latitude of the fiducial point.
    lon_pole : float or or `~astropy.units.Quantity`
        Longitude of the celestial pole in the native system.

    Notes
    -----
    If ``lon``, ``lat`` and ``lon_pole`` are numerical values they should be in units of deg.
    u   phi_Nu   theta_Nu   alpha_Cu   delta_Cc         C` s   i t  j d 6t  j d 6S(   u    Input units. u   phi_Nu   theta_N(   R   R=   (   R   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyR>   Ü   s    c         C` s   i t  j d 6t  j d 6S(   u    Output units. u   alpha_Cu   delta_C(   R   R=   (   R   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyR?   á   s    c         K` s#   t  t |  ƒ j | | | |  d  S(   N(   RU   Re   RV   (   R   R`   Ra   Rb   RW   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyRV   æ   s    c         C` s™   t  | t j ƒ r0 | j } | j } | j } n  | t j d } t j d | } t j d | } t t |  ƒ j | | | | | ƒ \ }	 }
 |	 |
 f S(   u¼  
        Parameters
        ----------
        phi_N, theta_N : float (deg) or `~astropy.units.Quantity`
            Angles in the Native coordinate system.
        lon, lat, lon_pole : float (in deg) or `~astropy.units.Quantity`
            Parameter values when the model was initialized.

        Returns
        -------
        alpha_C, delta_C : float (deg) or `~astropy.units.Quantity`
            Angles on the Celestial sphere.
        i   (	   R   R   R   R   R    t   piRU   Re   Rd   (   R   t   phi_Nt   theta_NR`   Ra   Rb   R   R   R   t   alpha_Ct   delta_C(    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyR<   é   s    		c         C` s   t  |  j |  j |  j ƒ S(   N(   t   RotateCelestial2NativeR`   Ra   Rb   (   R   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyR\     s    (   u   phi_Nu   theta_N(   u   alpha_Cu   delta_C(   R@   RA   RB   R]   R^   RG   R>   R?   RV   R<   R\   (    (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyRe   Ä   s   		Rk   c           B` sY   e  Z d  Z d
 Z d Z e d „  ƒ Z e d „  ƒ Z d „  Z d „  Z	 e d	 „  ƒ Z
 RS(   u  
    Transform from Celestial to Native Spherical Coordinates.

    Parameters
    ----------
    lon : float or or `~astropy.units.Quantity`
        Celestial longitude of the fiducial point.
    lat : float or or `~astropy.units.Quantity`
        Celestial latitude of the fiducial point.
    lon_pole : float or or `~astropy.units.Quantity`
        Longitude of the celestial pole in the native system.

    Notes
    -----
    If ``lon``, ``lat`` and ``lon_pole`` are numerical values they should be in units of deg.
    u   alpha_Cu   delta_Cu   phi_Nu   theta_Nc         C` s   i t  j d 6t  j d 6S(   u    Input units. u   alpha_Cu   delta_C(   R   R=   (   R   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyR>   "  s    c         C` s   i t  j d 6t  j d 6S(   u    Output units. u   phi_Nu   theta_N(   R   R=   (   R   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyR?   '  s    c         K` s#   t  t |  ƒ j | | | |  d  S(   N(   RU   Rk   RV   (   R   R`   Ra   Rb   RW   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyRV   ,  s    c         C` s˜   t  | t j ƒ r0 | j } | j } | j } n  t j d | } t j d | } | t j d } t t |  ƒ j | | | | | ƒ \ }	 }
 |	 |
 f S(   u¹  
        Parameters
        ----------
        alpha_C, delta_C : float (deg) or `~astropy.units.Quantity`
            Angles in the Celestial coordinate frame.
        lon, lat, lon_pole : float (deg) or `~astropy.units.Quantity`
            Parameter values when the model was initialized.

        Returns
        -------
        phi_N, theta_N : float (deg) or `~astropy.units.Quantity`
            Angles on the Native sphere.

        i   (	   R   R   R   R   R    Rf   RU   Rk   Rd   (   R   Ri   Rj   R`   Ra   Rb   R   R   R   Rg   Rh   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyR<   /  s    		c         C` s   t  |  j |  j |  j ƒ S(   N(   Re   R`   Ra   Rb   (   R   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyR\   K  s    (   u   alpha_Cu   delta_C(   u   phi_Nu   theta_N(   R@   RA   RB   R]   R^   RG   R>   R?   RV   R<   R\   (    (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyRk   
  s   		t
   Rotation2Dc           B` sn   e  Z d  Z d
 Z d Z e d d d e d e ƒ Z e	 Z
 e	 Z e d „  ƒ Z e d „  ƒ Z e d	 „  ƒ Z RS(   u  
    Perform a 2D rotation given an angle.

    Positive angles represent a counter-clockwise rotation and vice-versa.

    Parameters
    ----------
    angle : float or `~astropy.units.Quantity`
        Angle of rotation (if float it should be in deg).
    u   xu   yRI   g        RJ   RK   c         C` s   |  j  d |  j ƒ S(   u   Inverse rotation.R   (   R[   R   (   R   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyR\   e  s    c         C` s  | j  | j  k r! t d ƒ ‚ n  | j  p- d } t | t j ƒ rN | j } n d } t j | j	 ƒ  | j	 ƒ  g ƒ } t | t j ƒ r“ | j
 } n  t j |  j | ƒ | ƒ } | d | d } } | | _  | _  | d k	 rt j | d | ƒt j | d | ƒf S| | f Sd S(   uê   
        Rotate (x, y) about ``angle``.

        Parameters
        ----------
        x, y : ndarray-like
            Input quantities
        angle : float (deg) or `~astropy.units.Quantity`
            Angle of rotations.

        u,   Expected input arrays to have the same shapei   i    R   N(   i   (   R6   RR   R   R   R   R   R2   R    R$   R5   R   R7   t   _compute_matrix(   t   clsR'   R(   R   t
   orig_shapeR   t   inarrR   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyR<   k  s    !(c         C` sM   t  j t j |  ƒ t j |  ƒ g t j |  ƒ t j |  ƒ g g d t  j ƒS(   Nt   dtype(   R    R$   R0   R"   R#   t   float64(   R   (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyRm   Ž  s    "!(   u   xu   y(   u   xu   y(   R@   RA   RB   R]   R^   R   R   R   R   RD   RE   RF   RG   R\   t   classmethodR<   RC   Rm   (    (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyRl   P  s   
#("   RB   t
   __future__R    R   R   R   R0   t   numpyR    t   coreR   t
   parametersR   t   extern.six.movesR   t   coordinates.matrix_utilitiesR   R   t    R	   R   t   utils.decoratorsR
   t   utilsR   R   t   __all__t   objectR   RH   R_   Re   Rk   Rl   (    (    (    s9   lib/python2.7/site-packages/astropy/modeling/rotations.pyt   <module>   s$   "		K5FF