ó
›ßÈ[c        	   @` s)  d  d l  m Z m Z m Z m Z d  d l Z d d l m Z	 d d l
 m Z d d l m Z m Z d g Z d	 d
 d d d d d d d g	 Z d „  Z d „  Z e g g Z d e f d „  ƒ  YZ d „  Z d „  Z d „  Z d d „ Z d „  Z d „  Z d „  Z d  d d „ Z d  d d d „ Z d S(    i    (   t   absolute_importt   divisiont   print_functiont   unicode_literalsNi   (   t   units(   t   rangei   (   t   WCSSUB_LONGITUDEt   WCSSUB_LATITUDEu   wcs_to_celestial_frameu   add_stokes_axis_to_wcsu   custom_frame_mappingsu   proj_plane_pixel_scalesu   proj_plane_pixel_areau   is_proj_plane_distortedu   non_celestial_pixel_scalesu   skycoord_to_pixelu   pixel_to_skycoordc         C` sl   g  t  |  j j ƒ D] } | d ^ q } | j | d ƒ |  j | ƒ } d | j j | <d | j j | <| S(   u¸  
    Add a new Stokes axis that is uncorrelated with any other axes.

    Parameters
    ----------
    wcs : `~astropy.wcs.WCS`
        The WCS to add to
    add_before_ind : int
        Index of the WCS to insert the new Stokes axis in front of.
        To add at the end, do add_before_ind = wcs.wcs.naxis
        The beginning is at position 0.

    Returns
    -------
    A new `~astropy.wcs.WCS` instance with an additional axis
    i   i    u   STOKES(   R   t   wcst   naxist   insertt   subt   ctypet   cname(   R   t   add_before_indt   it   indst   newwcs(    (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pyt   add_stokes_axis_to_wcs   s    )c         C` s-  d d l  m } m } m } m } m } d d l m } |  j t	 t
 g ƒ }  |  j j d k sq |  j j d k ru d  S|  j j } t j |  j j ƒ rŸ d  } n |  j j } |  j j d d  }	 |  j j d d  }
 | d k r*|	 d	 k r*|
 d
 k r*| d  k rd } q*| d k  r!d } q*d } n  | d k ri| d  k	 rW| | d d ƒ} n  | d | ƒ } nÀ | d k r¨| d  k	 r–| | d d ƒ} n  | d | ƒ } n | d k rç| d  k	 rÕ| | d d ƒ} n  | d | ƒ } nB | d k rÿ| ƒ  } n* |	 d k r#|
 d k r#| ƒ  } n d  } | S(   Ni   (   t   FK4t   FK4NoETermst   FK5t   ICRSt   Galactic(   t   Timeiÿÿÿÿi    i   i   u    u   RA--u   DEC-u   ICRSg      Ÿ@u   FK4u   FK5t   formatu   byeart   equinoxu   FK4-NO-Eu   jyearu   GLONu   GLAT(   t   coordinatesR   R   R   R   R   t   timeR   R   R   R   R   t   lngt   latt   Nonet   radesyst   npt   isnanR   R   (   R   R   R   R   R   R   R   R    R   t   xcoordt   ycoordt   frame(    (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pyt   _wcs_to_celestial_frame_builtin.   sF    ($	$			t   custom_frame_mappingsc           B` s&   e  Z g  d  „ Z d „  Z d „  Z RS(   c         C` s,   t  | d ƒ r | g } n  t j | ƒ d  S(   Nu   __call__(   t   hasattrt   WCS_FRAME_MAPPINGSt   append(   t   selft   mappings(    (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pyt   __init__g   s    c         C` s   d  S(   N(    (   R+   (    (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pyt	   __enter__l   s    c         C` s   t  j ƒ  d  S(   N(   R)   t   pop(   R+   t   typet   valuet   tb(    (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pyt   __exit__o   s    (   t   __name__t
   __module__R-   R.   R3   (    (    (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pyR'   f   s   	c         C` sN   x; t  D]3 } x* | D]" } | |  ƒ } | d k	 r | Sq Wq Wt d ƒ ‚ d S(   uï  
    For a given WCS, return the coordinate frame that matches the celestial
    component of the WCS.

    Parameters
    ----------
    wcs : :class:`~astropy.wcs.WCS` instance
        The WCS to find the frame for

    Returns
    -------
    frame : :class:`~astropy.coordinates.baseframe.BaseCoordinateFrame` subclass instance
        An instance of a :class:`~astropy.coordinates.baseframe.BaseCoordinateFrame`
        subclass instance that best matches the specified WCS.

    Notes
    -----

    To extend this function to frames not defined in astropy.coordinates, you
    can write your own function which should take a :class:`~astropy.wcs.WCS`
    instance and should return either an instance of a frame, or `None` if no
    matching frame was found. You can register this function temporarily with::

        >>> from astropy.wcs.utils import wcs_to_celestial_frame, custom_frame_mappings
        >>> with custom_frame_mappings(my_function):
        ...     wcs_to_celestial_frame(...)

    uM   Could not determine celestial frame corresponding to the specified WCS objectN(   R)   R   t
   ValueError(   R   t   mapping_sett   funcR%   (    (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pyt   wcs_to_celestial_frames   s    c         C` s)   t  j |  j d j d d d t  j ƒ ƒ S(   u1  
    For a WCS returns pixel scales along each axis of the image pixel at
    the ``CRPIX`` location once it is projected onto the
    "plane of intermediate world coordinates" as defined in
    `Greisen & Calabretta 2002, A&A, 395, 1061 <http://adsabs.harvard.edu/abs/2002A%26A...395.1061G>`_.

    .. note::
        This function is concerned **only** about the transformation
        "image plane"->"projection plane" and **not** about the
        transformation "celestial sphere"->"projection plane"->"image plane".
        Therefore, this function ignores distortions arising due to
        non-linear nature of most projections.

    .. note::
        In order to compute the scales corresponding to celestial axes only,
        make sure that the input `~astropy.wcs.WCS` object contains
        celestial axes only, e.g., by passing in the
        `~astropy.wcs.WCS.celestial` WCS object.

    Parameters
    ----------
    wcs : `~astropy.wcs.WCS`
        A world coordinate system object.

    Returns
    -------
    scale : `~numpy.ndarray`
        A vector (`~numpy.ndarray`) of projection plane increments
        corresponding to each pixel side (axis). The units of the returned
        results are the same as the units of `~astropy.wcs.Wcsprm.cdelt`,
        `~astropy.wcs.Wcsprm.crval`, and `~astropy.wcs.Wcsprm.cd` for
        the celestial WCS and can be obtained by inquiring the value
        of `~astropy.wcs.Wcsprm.cunit` property of the input
        `~astropy.wcs.WCS` WCS object.

    See Also
    --------
    astropy.wcs.utils.proj_plane_pixel_area

    i   t   axisi    t   dtype(   R!   t   sqrtt   pixel_scale_matrixt   sumt   float(   R   (    (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pyt   proj_plane_pixel_scales™   s    )c         C` sC   |  j  j } | j d k r* t d ƒ ‚ n  t j t j j | ƒ ƒ S(   uZ  
    For a **celestial** WCS (see `astropy.wcs.WCS.celestial`) returns pixel
    area of the image pixel at the ``CRPIX`` location once it is projected
    onto the "plane of intermediate world coordinates" as defined in
    `Greisen & Calabretta 2002, A&A, 395, 1061 <http://adsabs.harvard.edu/abs/2002A%26A...395.1061G>`_.

    .. note::
        This function is concerned **only** about the transformation
        "image plane"->"projection plane" and **not** about the
        transformation "celestial sphere"->"projection plane"->"image plane".
        Therefore, this function ignores distortions arising due to
        non-linear nature of most projections.

    .. note::
        In order to compute the area of pixels corresponding to celestial
        axes only, this function uses the `~astropy.wcs.WCS.celestial` WCS
        object of the input ``wcs``.  This is different from the
        `~astropy.wcs.utils.proj_plane_pixel_scales` function
        that computes the scales for the axes of the input WCS itself.

    Parameters
    ----------
    wcs : `~astropy.wcs.WCS`
        A world coordinate system object.

    Returns
    -------
    area : float
        Area (in the projection plane) of the pixel at ``CRPIX`` location.
        The units of the returned result are the same as the units of
        the `~astropy.wcs.Wcsprm.cdelt`, `~astropy.wcs.Wcsprm.crval`,
        and `~astropy.wcs.Wcsprm.cd` for the celestial WCS and can be
        obtained by inquiring the value of `~astropy.wcs.Wcsprm.cunit`
        property of the `~astropy.wcs.WCS.celestial` WCS object.

    Raises
    ------
    ValueError
        Pixel area is defined only for 2D pixels. Most likely the
        `~astropy.wcs.Wcsprm.cd` matrix of the `~astropy.wcs.WCS.celestial`
        WCS is not a square matrix of second order.

    Notes
    -----

    Depending on the application, square root of the pixel area can be used to
    represent a single pixel scale of an equivalent square pixel
    whose area is equal to the area of a generally non-square pixel.

    See Also
    --------
    astropy.wcs.utils.proj_plane_pixel_scales

    i   u)   Pixel area is defined only for 2D pixels.(   i   i   (   t	   celestialR=   t   shapeR6   R!   t   abst   linalgt   det(   R   t   psm(    (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pyt   proj_plane_pixel_areaÅ   s    7gñhãˆµøä>c         C` s&   |  j  } t | j | ƒ p% t | ƒ S(   u–  
    For a WCS returns `False` if square image (detector) pixels stay square
    when projected onto the "plane of intermediate world coordinates"
    as defined in
    `Greisen & Calabretta 2002, A&A, 395, 1061 <http://adsabs.harvard.edu/abs/2002A%26A...395.1061G>`_.
    It will return `True` if transformation from image (detector) coordinates
    to the focal plane coordinates is non-orthogonal or if WCS contains
    non-linear (e.g., SIP) distortions.

    .. note::
        Since this function is concerned **only** about the transformation
        "image plane"->"focal plane" and **not** about the transformation
        "celestial sphere"->"focal plane"->"image plane",
        this function ignores distortions arising due to non-linear nature
        of most projections.

    Let's denote by *C* either the original or the reconstructed
    (from ``PC`` and ``CDELT``) CD matrix. `is_proj_plane_distorted`
    verifies that the transformation from image (detector) coordinates
    to the focal plane coordinates is orthogonal using the following
    check:

    .. math::
        \left \| \frac{C \cdot C^{\mathrm{T}}}
        {| det(C)|} - I \right \|_{\mathrm{max}} < \epsilon .

    Parameters
    ----------
    wcs : `~astropy.wcs.WCS`
        World coordinate system object

    maxerr : float, optional
        Accuracy to which the CD matrix, **normalized** such
        that :math:`|det(CD)|=1`, should be close to being an
        orthogonal matrix as described in the above equation
        (see :math:`\epsilon`).

    Returns
    -------
    distorted : bool
        Returns `True` if focal (projection) plane is distorted and `False`
        otherwise.

    (   RA   t   _is_cd_orthogonalR=   t   _has_distortion(   R   t   maxerrt   cwcs(    (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pyt   is_proj_plane_distorted  s    -	c         C` sÀ   |  j  } t | ƒ d k o, | d | d k s> t d ƒ ‚ n  t j t j j |  ƒ ƒ } | d k rt t d ƒ ‚ n  t j |  |  j ƒ | } t j	 t j | t j
 | d ƒ ƒ ƒ } | | k  S(   Ni   i    i   u-   CD (or PC) matrix must be a 2D square matrix.g        u   CD (or PC) matrix is singular.(   RB   t   lenR6   R!   RC   RD   RE   t   dott   Tt   amaxt   eye(   t   cdRJ   RB   t   pixareat   It   cd_unitary_err(    (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pyRH   4  s    	&)c         C` s|   |  j  r t d ƒ ‚ n  |  j } t j t j d t j | j Œ  | ƒ d ƒ rl t j t j	 | ƒ ƒ t
 j St d ƒ ‚ d S(   uM  
    Calculate the pixel scale along each axis of a non-celestial WCS,
    for example one with mixed spectral and spatial axes.

    Parameters
    ----------
    inwcs : `~astropy.wcs.WCS`
        The world coordinate system object.

    Returns
    -------
    scale : `numpy.ndarray`
        The pixel scale along each axis.
    u4   WCS is celestial, use celestial_pixel_scales insteadi   i    u8   WCS is rotated, cannot determine consistent pixel scalesN(   t   is_celestialR6   R=   R!   t   allcloset   extractRQ   RB   RC   t   diagonalt   ut   deg(   t   inwcst   pccd(    (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pyt   non_celestial_pixel_scalesE  s    		.c         ` s)   t  ‡  f d †  d d d d d g Dƒ ƒ S(   uD   
    `True` if contains any SIP or image distortion components.
    c         3` s$   |  ] } t  ˆ  | ƒ d  k	 Vq d  S(   N(   t   getattrR   (   t   .0t	   dist_attr(   R   (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pys	   <genexpr>d  s   u   cpdis1u   cpdis2u   det2im1u   det2im2u   sip(   t   any(   R   (    (   R   s0   lib/python2.7/site-packages/astropy/wcs/utils.pyRI   `  s    u   allc         C` s¬  d d l  m } d d l  m } t | ƒ rJ | j d k rJ t d ƒ ‚ n  | j t t g ƒ } | j d k r} t d ƒ ‚ n  t	 | ƒ } | j
 | j j d ƒ } | j
 | j j d ƒ } |  j | ƒ }  y. |  j j j | ƒ }	 |  j j j | ƒ }
 Wn; t k
 r5|  j j j | ƒ }	 |  j j j | ƒ }
 n X| d k rf| j |	 j |
 j | ƒ \ } } n< | d	 k r–| j |	 j |
 j | ƒ \ } } n t d
 ƒ ‚ | | f S(   uƒ  
    Convert a set of SkyCoord coordinates into pixels.

    Parameters
    ----------
    coords : `~astropy.coordinates.SkyCoord`
        The coordinates to convert.
    wcs : `~astropy.wcs.WCS`
        The WCS transformation to use.
    origin : int
        Whether to return 0 or 1-based pixel coordinates.
    mode : 'all' or 'wcs'
        Whether to do the transformation including distortions (``'all'``) or
        only including only the core WCS transformation (``'wcs'``).

    Returns
    -------
    xp, yp : `numpy.ndarray`
        The pixel coordinates

    See Also
    --------
    astropy.coordinates.SkyCoord.from_pixel
    i   (   R   i   (   t   WCSSUB_CELESTIALu:   Can only handle WCS with distortions for 2-dimensional WCSu&   WCS should contain celestial componenti    u   allu   wcsu$   mode should be either 'all' or 'wcs'(   t    R   Rc   RI   R	   R6   R   R   R   R9   t   UnitR   t   cunitt   transform_tot   datat   lont   toR   t   AttributeErrort	   sphericalt   all_world2pixR1   t   wcs_world2pix(   t   coordsR   t   origint   modeRZ   Rc   R%   t   xw_unitt   yw_unitRi   R   t   xpt   yp(    (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pyt   skycoord_to_pixelk  s.    $$c         C` sˆ  d d l  m } d d l  m } d d l m } m }	 | d k rK | } n  t | ƒ ru | j d k ru t	 d ƒ ‚ n  | j
 t t g ƒ } | j d k r¨ t	 d ƒ ‚ n  t | ƒ }
 | j | j j d ƒ } | j | j j d ƒ } | d	 k r| j |  | | ƒ \ } } n6 | d
 k r:| j |  | | ƒ \ } } n t	 d ƒ ‚ | | } | | } |	 d | d | ƒ } | |
 j | ƒ ƒ } | S(   u˜  
    Convert a set of pixel coordinates into a `~astropy.coordinates.SkyCoord`
    coordinate.

    Parameters
    ----------
    xp, yp : float or `numpy.ndarray`
        The coordinates to convert.
    wcs : `~astropy.wcs.WCS`
        The WCS transformation to use.
    origin : int
        Whether to return 0 or 1-based pixel coordinates.
    mode : 'all' or 'wcs'
        Whether to do the transformation including distortions (``'all'``) or
        only including only the core WCS transformation (``'wcs'``).
    cls : class or None
        The class of object to create.  Should be a
        `~astropy.coordinates.SkyCoord` subclass.  If None, defaults to
        `~astropy.coordinates.SkyCoord`.

    Returns
    -------
    coords : Whatever ``cls`` is (a subclass of `~astropy.coordinates.SkyCoord`)
        The celestial coordinates

    See Also
    --------
    astropy.coordinates.SkyCoord.from_pixel
    i   (   R   i   (   Rc   (   t   SkyCoordt   UnitSphericalRepresentationu:   Can only handle WCS with distortions for 2-dimensional WCSu&   WCS should contain celestial componenti    u   allu   wcsu$   mode should be either 'all' or 'wcs'Ri   R   N(   Rd   R   Rc   R   Rw   Rx   R   RI   R	   R6   R   R   R   R9   Re   R   Rf   t   all_pix2worldt   wcs_pix2worldt   realize_frame(   Rt   Ru   R   Rp   Rq   t   clsRZ   Rc   Rw   Rx   R%   t   lon_unitt   lat_unitRi   R   Rh   Ro   (    (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pyt   pixel_to_skycoord²  s.    	

(    t
   __future__R    R   R   R   t   numpyR!   Rd   R   RZ   t   extern.six.movesR   R   R   R   t   __doctest_skip__t   __all__R   R&   R)   t   objectR'   R9   R@   RG   RL   RH   R^   RI   Rv   R   R   (    (    (    s0   lib/python2.7/site-packages/astropy/wcs/utils.pyt   <module>   s0   "				5	&	,	=2			G