B
    Ù‹d¶ ã               @   s¬  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dl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 d dlmZ d dlmZ d d	lmZ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!gZd"gZ edk	rej! "d#¡Z#e$e#d  ƒd$kr@e$e#d ƒd%k r@e%d&ƒ‚e &¡ sRe'd'ƒ‚ej(Z)ej*Z*ej+Z+ej,Z,ej-Z-ej.Z.ej/Z/ej0Z0ej1Z1ej2Z2ej3Z3ej4Z4ej5Z5ej6Z6ej7Z7ej8Z8ej9Z9x8ej: ;¡ D ]*\Z<Z=e< >d(¡rÄe=e?ƒ e<< e @e<¡ qÄW d)d*„ ZAe BeA¡ n@eCZ)eCZ,eCZ*eCZ+eCZ.eCZ/dZ0dZ1dZ2dZ3dZ4dZ5dZ6dZ7dZ8dZ9d+ZDe Ed,¡ZFd-d.„ ZGG d/d„ deHƒZIG d0d„ deƒZJG d1d„ dee)ƒZKd2d3„ ZLd8d6d„ZMd7d„ ZNdS )9é    N)Úlog)Úfitsé   )Ú
docstrings)Ú_wcs)Úunits)Úpossible_filename)ÚAstropyWarningÚAstropyUserWarningÚAstropyDeprecationWarning)Údeprecated_renamed_argument)ÚFITSWCSAPIMixinÚSlicedFITSWCSÚFITSFixedWarningÚWCSÚfind_all_wcsÚDistortionLookupTableÚSipÚTabprmÚWcsprmÚAuxprmÚWtbarrÚWCSBaseÚvalidateÚWcsErrorÚSingularMatrixErrorÚInconsistentAxisTypesErrorÚInvalidTransformErrorÚInvalidCoordinateErrorÚNoSolutionErrorÚ!InvalidSubimageSpecificationErrorÚNoConvergenceÚ)NonseparableSubimageCoordinateSystemErrorÚNoWcsKeywordsFoundErrorÚInvalidTabularParametersErrorzWCS.all_world2pixÚ.é   é   z¦astropy.wcs is built with wcslib {0}, but only versions 5.8 and later on the 5.x series are known to work.  The version of wcslib that ships with astropy may be used.zJastropy.wcs did not pass its sanity check for your build on your platform.)ZWCSSUB_ZWCSHDR_ZWCSHDO_ZWCSCOMPARE_c       	      C   s^   | ||f j | |d  }|j|krN|dkrF|dkrF| |jdf¡}ntdƒ‚tj|tjdS )Nr   Úcé   zBad TDIM)Údtype)ÚdataÚndimÚreshapeÚsizeÚ
ValueErrorÚnpZascontiguousarrayÚdouble)	ÚhdulistZextnamZextverZextlevÚkindÚttypeÚrowr,   Zarr© r6   ú\/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/astropy/wcs/wcs.pyÚ_load_tab_bintablem   s    
r8   i   z^[AB]P?_1?[0-9]_1?[0-9][A-Z]?$c             C   st   d}| d k	rlxb| D ]T}|  ¡ dkr.|tjO }q|  ¡ dkrF|tjO }q|  ¡ dkr^|tjO }qtdƒ‚qW nd}|S )Nr   ÚimageÚbinaryZpixelz9keysel must be a list of 'image', 'binary' and/or 'pixel'éÿÿÿÿ)Úlowerr   ZWCSHDR_IMGHEADZWCSHDR_BIMGARRZWCSHDR_PIXLISTr/   )ÚkeyselÚkeysel_flagsÚelementr6   r6   r7   Ú_parse_keysel—   s    
r@   c                   s.   e Zd ZdZddddddœ‡ fdd„
Z‡  ZS )r!   a‡  
    An error class used to report non-convergence and/or divergence
    of numerical methods. It is used to report errors in the
    iterative solution used by
    the :py:meth:`~astropy.wcs.WCS.all_world2pix`.

    Attributes
    ----------

    best_solution : `numpy.ndarray`
        Best solution achieved by the numerical method.

    accuracy : `numpy.ndarray`
        Accuracy of the ``best_solution``.

    niter : `int`
        Number of iterations performed by the numerical method
        to compute ``best_solution``.

    divergent : None, `numpy.ndarray`
        Indices of the points in ``best_solution`` array
        for which the solution appears to be divergent. If the
        solution does not diverge, ``divergent`` will be set to `None`.

    slow_conv : None, `numpy.ndarray`
        Indices of the solutions in ``best_solution`` array
        for which the solution failed to converge within the
        specified maximum number of iterations. If there are no
        non-converging solutions (i.e., if the required accuracy
        has been achieved for all input data points)
        then ``slow_conv`` will be set to `None`.

    N)Úbest_solutionÚaccuracyÚniterÚ	divergentÚ	slow_convc               sH   t ƒ j|Ž  || _|| _|| _|| _|| _|rDt d 	t
|ƒ¡t¡ d S )NzhFunction received unexpected arguments ({}) these are ignored but will raise an Exception in the future.)ÚsuperÚ__init__rA   rB   rC   rD   rE   ÚwarningsÚwarnÚformatÚlistr   )ÚselfrA   rB   rC   rD   rE   ÚargsÚkwargs)Ú	__class__r6   r7   rG   Î   s    zNoConvergence.__init__)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rG   Ú__classcell__r6   r6   )rO   r7   r!   «   s   !c               @   s   e Zd ZdZdS )r   zs
    The warning raised when the contents of the FITS header have been
    modified to be standards compliant.
    N)rP   rQ   rR   rS   r6   r6   r6   r7   r   ß   s   c               @   s„  e Zd ZdZd—dd„Zd	d
„ Zdd„ Zdd„ Zdd„ Zd˜dd„Z	e
dk	rTe
jj	je	_dd„ Zd™dd„Zdšdd„Zd›dd„Zdd„ Zdd„ Zdœd d!„Zdd"d#„Zd$d%„ Zdžd&d'„Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/œd0d1„Zd2d3„ Zd4 e d5d6¡e d6¡e d7d6¡¡e_d8d9„ Z d: e d5d6¡e d6¡e d;d6¡¡e _d<d=„ Z!e"d>d?d@ƒdAdBd.dd.dCœdDdE„ƒZ#dF e d5d6¡e d6¡e dGd6¡¡e#_dHdI„ Z$dJ e d5d6¡e d6¡e dGd6¡¡e$_dKdL„ Z%dM e dNd6¡e dOd6¡¡e%_dPdQ„ Z&dR e dNd6¡e dOd6¡¡e&_dSdT„ Z'dU e dNd6¡e dGd6¡¡e'_dVdW„ Z(dX e dNd6¡e dOd6¡¡e(_dYdZ„ Z)d[ e dNd6¡e dGd6¡¡e)_d\d]„ Z*d^d_„ Z+dŸd`da„Z,d dbdc„Z-d¡ddde„Z.d¢dfdg„Z/d£dkdl„Z0d¤dmdn„Z1dodp„ Z2dqdr„ Z3dsdt„ Z4dudv„ Z5dwdx„ Z6dydz„ Z7d{d|„ Z8d¥d}d~„Z9dd€„ Z:dd‚„ Z;e<dƒd„„ ƒZ=e<d…d†„ ƒZ>e<d‡dˆ„ ƒZ?e<d‰dŠ„ ƒZ@e<d‹dŒ„ ƒZAe<ddŽ„ ƒZBe<dd„ ƒZCe<d‘d’„ ƒZDe<d“d”„ ƒZEd•d–„ ZFdS )¦r   aæ  WCS objects perform standard WCS transformations, and correct for
    `SIP`_ and `distortion paper`_ table-lookup transformations, based
    on the WCS keywords and supplementary data read from a FITS file.

    See also: https://docs.astropy.org/en/stable/wcs/

    Parameters
    ----------
    header : `~astropy.io.fits.Header`, `~astropy.io.fits.hdu.image.PrimaryHDU`, `~astropy.io.fits.hdu.image.ImageHDU`, str, dict-like, or None, optional
        If *header* is not provided or None, the object will be
        initialized to default values.

    fobj : `~astropy.io.fits.HDUList`, optional
        It is needed when header keywords point to a `distortion
        paper`_ lookup table stored in a different extension.

    key : str, optional
        The name of a particular WCS transform to use.  This may be
        either ``' '`` or ``'A'``-``'Z'`` and corresponds to the
        ``"a"`` part of the ``CTYPEia`` cards.  *key* may only be
        provided if *header* is also provided.

    minerr : float, optional
        The minimum value a distortion correction must have in order
        to be applied. If the value of ``CQERRja`` is smaller than
        *minerr*, the corresponding distortion is not applied.

    relax : bool or int, optional
        Degree of permissiveness:

        - `True` (default): Admit all recognized informal extensions
          of the WCS standard.

        - `False`: Recognize only FITS keywords defined by the
          published WCS standard.

        - `int`: a bit field selecting specific extensions to accept.
          See :ref:`relaxread` for details.

    naxis : int or sequence, optional
        Extracts specific coordinate axes using
        :meth:`~astropy.wcs.Wcsprm.sub`.  If a header is provided, and
        *naxis* is not ``None``, *naxis* will be passed to
        :meth:`~astropy.wcs.Wcsprm.sub` in order to select specific
        axes from the header.  See :meth:`~astropy.wcs.Wcsprm.sub` for
        more details about this parameter.

    keysel : sequence of str, optional
        A sequence of flags used to select the keyword types
        considered by wcslib.  When ``None``, only the standard image
        header keywords are considered (and the underlying wcspih() C
        function is called).  To use binary table image array or pixel
        list keywords, *keysel* must be set.

        Each element in the list should be one of the following
        strings:

        - 'image': Image header keywords

        - 'binary': Binary table image array keywords

        - 'pixel': Pixel list keywords

        Keywords such as ``EQUIna`` or ``RFRQna`` that are common to
        binary table image arrays and pixel lists (including
        ``WCSNna`` and ``TWCSna``) are selected by both 'binary' and
        'pixel'.

    colsel : sequence of int, optional
        A sequence of table column numbers used to restrict the WCS
        transformations considered to only those pertaining to the
        specified columns.  If `None`, there is no restriction.

    fix : bool, optional
        When `True` (default), call `~astropy.wcs.Wcsprm.fix` on
        the resulting object to fix any non-standard uses in the
        header.  `FITSFixedWarning` Warnings will be emitted if any
        changes were made.

    translate_units : str, optional
        Specify which potentially unsafe translations of non-standard
        unit strings to perform.  By default, performs none.  See
        `WCS.fix` for more information about this parameter.  Only
        effective when ``fix`` is `True`.

    Raises
    ------
    MemoryError
         Memory allocation failed.

    ValueError
         Invalid key.

    KeyError
         Key not found in FITS header.

    ValueError
         Lookup table distortion present in the header but *fobj* was
         not provided.

    Notes
    -----

    1. astropy.wcs supports arbitrary *n* dimensions for the core WCS
       (the transformations handled by WCSLIB).  However, the
       `distortion paper`_ lookup table and `SIP`_ distortions must be
       two dimensional.  Therefore, if you try to create a WCS object
       where the core WCS has a different number of dimensions than 2
       and that object also contains a `distortion paper`_ lookup
       table or `SIP`_ distortion, a `ValueError`
       exception will be raised.  To avoid this, consider using the
       *naxis* kwarg to select two dimensions from the core WCS.

    2. The number of coordinate axes in the transformation is not
       determined directly from the ``NAXIS`` keyword but instead from
       the highest of:

           - ``NAXIS`` keyword

           - ``WCSAXESa`` keyword

           - The highest axis number in any parameterized WCS keyword.
             The keyvalue, as well as the keyword, must be
             syntactically valid otherwise it will not be considered.

       If none of these keyword types is present, i.e. if the header
       only contains auxiliary WCS keywords for a particular
       coordinate representation, then no coordinate description is
       constructed for it.

       The number of axes, which is set as the ``naxis`` member, may
       differ for different coordinate representations of the same
       image.

    3. When the header includes duplicate keywords, in most cases the
       last encountered is used.

    4. `~astropy.wcs.Wcsprm.set` is called immediately after
       construction, so any invalid keywords or transformations will
       be raised by the constructor, not when subsequently calling a
       transformation method.

    Nú ç        TÚ c             C   sn  g }|d krB|d krd}t jd |||d}|j| _d}d}d }n”t|ƒ}t|ttfƒrÂyt|ƒoltj	 
|¡}W n ttfk
rŒ   d}Y nX |rÀ|d k	r¢tdƒ‚t |¡}| |¡ |d j}nvt|tjjjƒrÚ|j}n^t|tjƒs8y0|}t ¡ }x| ¡ D ]}|| ||< q W W n tk
r6   tdƒ‚Y nX t|tjƒrT| ¡  ¡ }n|}t|tƒrt| d¡}|}n|}| d¡}|d ks¢t|tjƒs¢td	ƒ‚d}y–tj |¡}|  |¡ | ¡  ¡ }t|tƒrà| d¡}t j|||||d|d
}|d k	r:y| |¡}W n tk
r&   Y nX |jr6|jnd}W n t j k
rT   Y nX || _tj |¡}| j!|||d}| j"||d|d}| j#||d}|  |¡ | ¡ }| $dd¡}t|tƒrÒ| d¡}|}n|}| d¡}yt j||||||d}W n< t j k
r6   |d kr0t jd |||||d}n‚ Y nX |d k	rL| |¡}|j| _|jdkrž|d sŽ|d sŽ|d sŽ|d sŽ|ržtd %|j¡ƒ‚| &dd ¡}|d k	rÖ||jk rÖt' (d %|j|¡t)¡ |  *|¡ t+ ,| ||||¡ |	r<|d kr0t' -¡  t' .dt)¡ | j/|
d W d Q R X n| j/|
d |rL| j0 1¡  x|D ]}| 2¡  qRW d | _3d S )Nr)   )ÚheaderÚkeyÚrelaxÚnaxis)NNFzWCan not provide both a FITS filename to argument 1 and a FITS file object to argument 2r   zPheader must be a string, an astropy.io.fits.Header object, or a dict-like objectÚasciiz@'fobj' must be either None or an astropy.io.fits.HDUList object.)rX   rY   rZ   r=   ÚcolselrH   r2   )ÚerrÚCPDIS)Údistr^   )ÚwcskeyzPEND                                                                             rW   )rX   rY   rZ   r=   r]   r2   r   aE  
FITS WCS distortion paper lookup tables and SIP distortions only work
in 2 dimensions.  However, WCSLIB has detected {} dimensions in the
core WCS keywords.  To use core WCS in conjunction with FITS WCS
distortion paper lookup tables or SIP distortion, you must select or
reduce these to 2 dimensions using the naxis kwarg.
ÚNAXISzWThe WCS transformation has more axes ({:d}) than the image it is associated with ({:d})Úignore)Útranslate_units)4r   r   r[   r@   Ú
isinstanceÚstrÚbytesr   ÚosÚpathÚexistsÚOSErrorr/   r   ÚopenÚappendrX   Úhdur9   Z_ImageBaseHDUÚHeaderÚkeysÚ	TypeErrorÚtostringÚrstripÚencodeÚdecodeÚHDUListÚAssertionErrorÚ
fromstringÚ_remove_sip_kwÚsubr#   Ú_read_det2im_kwÚ_read_distortion_kwÚ_read_sip_kwÚreplacerJ   ÚgetrH   rI   r   Ú
_get_naxisr   rG   Úcatch_warningsÚsimplefilterÚfixÚwcsÚsetÚcloseZ_pixel_bounds)rL   rX   ÚfobjrY   ZminerrrZ   r[   r=   r]   rƒ   rd   Ú_do_setÚ	close_fdsÚwcsprmÚdet2imÚcpdisÚsipr>   Zis_pathZorig_headerZdict_keyÚheader_stringÚheader_bytesZ	est_naxisZ
tmp_headerZtmp_header_bytesZ
tmp_wcsprmZheader_naxisÚfdr6   r6   r7   rG   x  sâ    














.




zWCS.__init__c             C   s@   |   ¡ }t || j| j| jf| j| j| jf¡ |j	 
| j	¡ |S )N)rO   r   rG   r   Úcpdis1Úcpdis2r„   Údet2im1Údet2im2Ú__dict__Úupdate)rL   Únew_copyr6   r6   r7   Ú__copy__  s    

zWCS.__copy__c          
   C   s˜   ddl m} |  ¡ }|| j|ƒ|_t ||| j|ƒ|| j|ƒ|| j|ƒf|| j	|ƒ|| j
|ƒ|| j|ƒf¡ x&| j ¡ D ]\}}|||ƒ|j|< qxW |S )Nr   )Údeepcopy)Úcopyr™   rO   r[   r   rG   r   r‘   r’   r„   r“   r”   r•   Úitems)rL   Úmemor™   r—   rY   Úvalr6   r6   r7   Ú__deepcopy__#  s    


zWCS.__deepcopy__c             C   s
   t   | ¡S )a  
        Return a shallow copy of the object.

        Convenience method so user doesn't have to import the
        :mod:`copy` stdlib module.

        .. warning::
            Use `deepcopy` instead of `copy` unless you know why you need a
            shallow copy.
        )rš   )rL   r6   r6   r7   rš   2  s    zWCS.copyc             C   s
   t  | ¡S )z•
        Return a deep copy of the object.

        Convenience method so user doesn't have to import the
        :mod:`copy` stdlib module.
        )rš   r™   )rL   r6   r6   r7   r™   ?  s    zWCS.deepcopyc                s¦   ˆ  ¡ }dd„ t|jjƒD ƒ‰ ˆ |j_|j |¡|_|jj|_‡ fdd„|jjD ƒ}‡fdd„|D ƒ|j_ˆjrˆt‡fdd„|D ƒƒ|_ˆjr¢‡fdd„|D ƒ|_|S )Nc             S   s   g | ]}t t ¡ ƒ‘qS r6   )rf   ÚuuidÚuuid4)Ú.0Úir6   r6   r7   ú
<listcomp>P  s    zWCS.sub.<locals>.<listcomp>c                s"   g | ]}|ˆ krˆ   |¡nd ‘qS )N)Úindex)r¡   Úcname)Ú
cname_uuidr6   r7   r£   Y  s   c                s$   g | ]}|d krdn
ˆ j j| ‘qS )NrW   )r„   r¥   )r¡   r¢   )rL   r6   r7   r£   ]  s    c                s"   g | ]}|d krd nˆ j | ‘qS )N)Úpixel_shape)r¡   r¢   )rL   r6   r7   r£   a  s    c                s"   g | ]}|d krd nˆ j | ‘qS )N)Úpixel_bounds)r¡   r¢   )rL   r6   r7   r£   c  s    )	r™   Úranger„   r[   r¥   rz   r§   Útupler¨   )rL   Úaxesrš   Zkeepr6   )r¦   rL   r7   rz   H  s    

zWCS.subc             C   sÄ   | j dkrdS | j  ¡ }|s dS | jdkr.dS t |¡}xnt|dd…df ƒD ]V}t|dd…df |dd…df |k ƒ}t|ƒ}x dD ]}||k rˆ||krˆdS qˆW qNW | j  g ¡ t 	dt
¡ dS )až  
        Remove SCAMP's PVi_m distortion parameters if SIP distortion parameters
        are also present. Some projects (e.g., Palomar Transient Factory)
        convert SCAMP's distortion parameters (which abuse the PVi_m cards) to
        SIP. However, wcslib gets confused by the presence of both SCAMP and
        SIP distortion parameters.

        See https://github.com/astropy/astropy/issues/299.
        Nr   r   )é   é   é   é'   zURemoved redundant SCAMP distortion parameters because SIP parameters are also present)r„   Zget_pvr   r0   Úasarrayr…   ÚmaxZset_pvrH   rI   r   )rL   Úpvr¢   ÚjsZmax_jÚjr6   r6   r7   Ú
_fix_scampj  s"    



(
zWCS._fix_scampc             C   sv   | j dk	rr|  ¡  | j  ||¡}xP| ¡ D ]D\}}|dkr*|dkrZd|krZt | j j¡sZq*t d 	||¡t
¡ q*W dS )a=  
        Perform the fix operations from wcslib, and warn about any
        changes it has made.

        Parameters
        ----------
        translate_units : str, optional
            Specify which potentially unsafe translations of
            non-standard unit strings to perform.  By default,
            performs none.

            Although ``"S"`` is commonly used to represent seconds,
            its translation to ``"s"`` is potentially unsafe since the
            standard recognizes ``"S"`` formally as Siemens, however
            rarely that may be used.  The same applies to ``"H"`` for
            hours (Henry), and ``"D"`` for days (Debye).

            This string controls what to do in such cases, and is
            case-insensitive.

            - If the string contains ``"s"``, translate ``"S"`` to
              ``"s"``.

            - If the string contains ``"h"``, translate ``"H"`` to
              ``"h"``.

            - If the string contains ``"d"``, translate ``"D"`` to
              ``"d"``.

            Thus ``''`` doesn't do any unsafe translations, whereas
            ``'shd'`` does all of them.

        naxis : int array, optional
            Image axis lengths.  If this array is set to zero or
            ``None``, then `~astropy.wcs.Wcsprm.cylfix` will not be
            invoked.
        Nz	No changeZdatfixz
1858-11-17z'{0}' made the change '{1}'.)r„   rµ   rƒ   r›   r0   Zcount_nonzeroZmjdrefrH   rI   rJ   r   )rL   rd   r[   ÚfixesrY   r   r6   r6   r7   rƒ   •  s    &
zWCS.fixc          	   C   s  |dk	r|\}}nV|dkrPy| j \}}W qh ttfk
rL   t dt¡ dS X n| dd¡}| dd¡}|dksx|dkr€tdƒ‚|r®tj	ddgd|g||g|dggtj
d}n8tj	ddgd|d g|d |d g|d dggtj
d}|rö|  |d¡S |  |d¡S dS )	at  
        Calculates the footprint of the image on the sky.

        A footprint is defined as the positions of the corners of the
        image on the sky after all available distortions have been
        applied.

        Parameters
        ----------
        header : `~astropy.io.fits.Header` object, optional
            Used to get ``NAXIS1`` and ``NAXIS2``
            header and axes are mutually exclusive, alternative ways
            to provide the same information.

        undistort : bool, optional
            If `True`, take SIP and distortion lookup table into
            account

        axes : (int, int), optional
            If provided, use the given sequence as the shape of the
            image.  Otherwise, use the ``NAXIS1`` and ``NAXIS2``
            keywords from the header that was used to create this
            `WCS` object.

        center : bool, optional
            If `True` use the center of the pixel, otherwise use the corner.

        Returns
        -------
        coord : (4, 2) array of (*x*, *y*) coordinates.
            The order is clockwise starting with the bottom left corner.
        Nz4Need a valid header in order to calculate footprint
ZNAXIS1ZNAXIS2z#Image size could not be determined.r   )r*   g      à?)r§   ÚAttributeErrorrq   rH   rI   r
   r   r/   r0   ÚarrayZfloat64Úall_pix2worldÚwcs_pix2world)rL   rX   Z	undistortr«   ÚcenterZnaxis1Znaxis2Zcornersr6   r6   r7   Úcalc_footprintÈ  s4    !



zWCS.calc_footprintc             C   s2  |dkrdS t |tjƒsdS y|d }|  |||¡}|S  tk
rJ   Y nX d}d}d}i }	x°td| jd ƒD ]š}
| |t|
ƒ d¡}||k rœd|	|
< qp|t|
ƒ }||kr||  	¡ }|d	krÌ||= t |tjƒsât
d
ƒ‚|t|
ƒ  ¡ }|d }||kr|| }||= nd}|d|
d› }|
|| krF|d|f j}n|d|f j ¡ }||= |d|f j}| dd¡| dd¡f}| dd¡| dd¡f}| dd¡| dd¡f}t||||ƒ}||	|
< nt dt¡ x2t|ƒD ]}| |d ¡râ||= qâW qpd|	|
< qpW |	sdS |	 d¡|	 d¡fS dS )zp
        Create a `distortion paper`_ type lookup table for detector to
        image plane correction.
        N)NNZAXISCORRÚD2IMDISÚD2IMZD2IMERRr   g        ÚlookupzBAn astropy.io.fits.HDUListis required for Lookup table distortion.z.EXTVERz.AXIS.ÚdÚD2IMARRÚCRPIX1ÚCRPIX2ÚCRVAL1ÚCRVAL2ÚCDELT1g      ð?ÚCDELT2z*Polynomial distortion is not implemented.
r%   r)   )re   r   rv   Ú_read_d2im_old_formatÚKeyErrorr©   r[   r   rf   r<   rw   Ústripr+   Ú	transposerX   r   rH   rI   r
   r…   Ú
startswith)rL   rX   r‡   r^   ÚaxiscorrZd2imdisr`   Úd_kwÚerr_kwÚtablesr¢   Úd_errorÚ
distortionÚdisÚdpÚdp_extver_keyÚd_extverÚdp_axis_keyÚd_dataÚd_headerÚd_crpixÚd_crvalÚd_cdeltÚd_lookuprY   r6   r6   r7   r{     sh    



zWCS._read_det2im_kwc             C   s2  t  dt¡ d d g}ddg}ddg}ddg}y|d j}W n& tk
rN   dS  tk
r`   dS X t |g¡}|d j}	|	d }
xjt	d|
d ƒD ]X}|	 
dt|ƒ d¡||d < |	 
d	t|ƒ d¡||d < |	 
d
t|ƒ d¡||d < qW t||||ƒ}|dkr|d fS |dkrd |fS t  dt¡ dS d S )Nz¦The use of ``AXISCORR`` for D2IM correction has been deprecated.`~astropy.wcs` will read in files with ``AXISCORR`` but ``to_fits()`` will write out files without it.g        g      ð?)rÁ   r   )NNrb   r   ÚCRPIXÚCRVALÚCDELTr)   zExpected AXISCORR to be 1 or 2)rH   rI   r   r+   rÉ   r·   r0   r¸   rX   r©   r   rf   r   r
   )rL   rX   r‡   rÍ   rŒ   ÚcrpixÚcrvalÚcdeltZ	d2im_dataZd2im_hdrr[   r¢   r6   r6   r7   rÈ   P  s6    
 

zWCS._read_d2im_old_formatc                sL   | j dkr| jdkrdS d‰d‰ ‡ ‡‡fdd„}|d| j ƒ |d| jƒ dS )zq
        Writes a `distortion paper`_ type lookup table to the given
        `~astropy.io.fits.HDUList`.
        Nr½   r¾   c                s„  |d krd S dˆd j ˆ› | d›< | dfˆd j ˆ › | d›d< t|jjƒdfˆd j ˆ › | d›d< xjt|jjƒD ]Z}dd	d
dœ |d |d › d¡}|d d|› dfˆd j ˆ › | d›d|d d›< qvW tj|jdd}|j }|j	d df|d< |j	d df|d< |j
d df|d< |j
d df|d< |jd df|d< |jd df|d< tˆd j ˆ › | d›d ƒ|_ˆ |¡ d S )N)ÚLOOKUPz!Detector to image correction typer   rÀ   z$Version number of WCSDVARR extensionz.EXTVERz0Number of independent variables in D2IM functionz.NAXESÚ1stÚ2ndÚ3rd)r   r)   r¬   r   ÚthzAxis number of the z variable in a D2IM functionz.AXIS.rÁ   )Únamez!Coordinate system reference pixelrÂ   rÃ   z*Coordinate system value at reference pixelrÄ   rÅ   zCoordinate increment along axisrÆ   rÇ   )rX   Úlenr+   Úshaper©   r,   r   r   ÚImageHDUrá   râ   rã   ÚintÚverrm   )Únumr‹   r¢   Újthr9   rX   )rÎ   r`   r2   r6   r7   Ú	write_d2i  s0    &"8





 z$WCS._write_det2im.<locals>.write_d2ir   r)   )r“   r”   )rL   r2   rñ   r6   )rÎ   r`   r2   r7   Ú_write_det2imt  s    !zWCS._write_det2imr_   c             C   s  t |ttfƒrdS |dkr$d}d}nd}d}i }xÂtd| jd ƒD ]¬}|t|ƒ }	|	|krn||	 }
||	= nd}
|
|k r„d	||< qD|t|ƒ }||krê||  ¡ }||= |d
krÜt |tjƒsÊtdƒ‚|t|ƒ  	¡ }|d }||krú|| }||= nd}|d|d› }||| kr,|d|f j
}n|d|f j
 ¡ }||= |d|f j}| dd¡| dd¡f}| dd¡| dd¡f}| dd¡| dd¡f}t||||ƒ}|||< x6t|ƒD ]}| |d ¡rº||= qºW nt dt¡ qDd	||< qDW |s dS | d¡| d¡fS d	S )zÿ
        Reads `distortion paper`_ table-lookup keywords and data, and
        returns a 2-tuple of `~astropy.wcs.DistortionLookupTable`
        objects.

        If no `distortion paper`_ keywords are found, ``(None, None)``
        is returned.
        )NNr_   ÚDPZCPERRÚDQZCQERRr   g        Nr¿   zCan astropy.io.fits.HDUList is required for Lookup table distortion.z.EXTVERz.AXIS.rÀ   ÚWCSDVARRrÂ   rÃ   rÄ   rÅ   rÆ   g      ð?rÇ   r%   z*Polynomial distortion is not implemented.
r)   )re   rf   rg   r©   r[   r<   r   rv   r/   rÊ   r+   rË   rX   r   r   r…   rÌ   rH   rI   r
   )rL   rX   r‡   r`   r^   rÎ   rÏ   rÐ   r¢   Zd_error_keyrÑ   rÒ   rÓ   rÔ   rÕ   rÖ   r×   rØ   rÙ   rÚ   rÛ   rÜ   rÝ   rY   r6   r6   r7   r|   £  sh    	




zWCS._read_distortion_kwc                sV   | j dkr| jdkrdS ˆdkr&d‰ nd‰ ‡ ‡‡fdd„}|d| j ƒ |d| jƒ dS )	zi
        Write out `distortion paper`_ keywords to the given
        `~astropy.io.fits.HDUList`.
        Nr_   ró   rô   c                s’  |d krd S dˆd j ˆ› | d›< | dfˆd j ˆ › | d›d< t|jjƒdˆ› dfˆd j ˆ › | d›d< xpt|jjƒD ]`}d	d
ddœ |d |d › d¡}|d d|› dˆ› dfˆd j ˆ › | d›d|d d›< q~W tj|jdd}|j }|j	d df|d< |j	d df|d< |j
d df|d< |j
d df|d< |jd df|d< |jd df|d< tˆd j ˆ › | d›d ƒ|_ˆ |¡ d S )N)rä   zPrior distortion function typer   rÀ   z$Version number of WCSDVARR extensionz.EXTVERz#Number of independent variables in z	 functionz.NAXESrå   ræ   rç   )r   r)   r¬   r   rè   zAxis number of the z variable in a z.AXIS.rõ   )ré   z!Coordinate system reference pixelrÂ   rÃ   z*Coordinate system value at reference pixelrÄ   rÅ   zCoordinate increment along axisrÆ   rÇ   )rX   rê   r+   rë   r©   r,   r   r   rì   rá   râ   rã   rí   rî   rm   )rï   rŒ   r¢   rð   r9   rX   )rÎ   r`   r2   r6   r7   Ú
write_distú  s&    ."8 z,WCS._write_distortion_kw.<locals>.write_distr   r)   )r‘   r’   )rL   r2   r`   rö   r6   )rÎ   r`   r2   r7   Ú_write_distortion_kwí  s    zWCS._write_distortion_kwc             C   s2   x,t dd„ ttjt|ƒƒD ƒƒD ]
}||= q W dS )z7
        Remove SIP information from a header.
        c             s   s   | ]}|d k	r|  ¡ V  qd S )N)Úgroup)r¡   Úmr6   r6   r7   ú	<genexpr>   s    z%WCS._remove_sip_kw.<locals>.<genexpr>N)r…   ÚmapÚSIP_KWÚmatchrK   )rL   rX   rY   r6   r6   r7   ry     s    $zWCS._remove_sip_kwc                sæ  t ˆ ttfƒrdS dˆ krªˆ d dkrªdˆ kr:tdƒ‚tˆ d ƒ}t |d |d ftj¡}x\t|d ƒD ]L}xFt|| d ƒD ]2}d|› d|› }|ˆ kr„ˆ | |||f< ˆ |= q„W qnW tˆ d ƒ}|dkrRt |d |d ftj¡}xjt|d ƒD ]P}xJt|| d ƒD ]6}d|› d|› }|ˆ krˆ | |||f< ˆ |= qW qüW nd}d}ˆ d= ˆ d= ‡ ‡fd	d
„td| j	d ƒD ƒ}	t
dd„ |	D ƒƒrÔd}
t |
¡ n*dˆ krÌˆ d dkrÌtdƒ‚nd}d}dˆ kr4ˆ d dkr4dˆ krþtdƒ‚tˆ d ƒ}t |d |d ftj¡}xbt|d ƒD ]R}xJt|| d ƒD ]6}d|› d|› }|ˆ krHˆ | |||f< ˆ |= qHW q2W tˆ d ƒ}|dkrt |d |d ftj¡}xlt|d ƒD ]R}xJt|| d ƒD ]6}d|› d|› }|ˆ krÜˆ | |||f< ˆ |= qÜW qÆW nd}d}ˆ d= ˆ d= n*dˆ krVˆ d dkrVtdƒ‚nd}d}|dkrŠ|dkrŠ|dkrŠ|dkrŠdS dˆ› ˆ ksªdˆ› ˆ kr²tdƒ‚ˆ  dˆ› ¡}ˆ  dˆ› ¡}t||||||fƒS )z¦
        Reads `SIP`_ header keywords and returns a `~astropy.wcs.Sip`
        object.

        If no `SIP`_ header keywords are found, ``None`` is returned.
        NZA_ORDERr   ZB_ORDERzIA_ORDER provided without corresponding B_ORDER keyword for SIP distortionZA_Ú_ZB_c                s   g | ]}ˆ d |› ˆ›  ‘qS )ÚCTYPEr6   )r¡   Znax)rX   ra   r6   r7   r£   N  s    z$WCS._read_sip_kw.<locals>.<listcomp>c             s   s   | ]}|  d ¡ V  qdS )z-SIPN)Úendswith)r¡   Úctypr6   r6   r7   rú   O  s    z#WCS._read_sip_kw.<locals>.<genexpr>a»  
                Inconsistent SIP distortion information is present in the FITS header and the WCS object:
                SIP coefficients were detected, but CTYPE is missing a "-SIP" suffix.
                astropy.wcs is using the SIP distortion coefficients,
                therefore the coordinates calculated here might be incorrect.

                If you do not want to apply the SIP distortion coefficients,
                please remove the SIP coefficients from the FITS header or the
                WCS object.  As an example, if the image is already distortion-corrected
                (e.g., drizzled) then distortion components should not apply and the SIP
                coefficients should be removed.

                While the SIP distortion coefficients are being applied here, if that was indeed the intent,
                for consistency please append "-SIP" to the CTYPE in the FITS header or the WCS object.

                zIB_ORDER provided without corresponding A_ORDER keyword for SIP distortionZAP_ORDERZBP_ORDERzKAP_ORDER provided without corresponding BP_ORDER keyword for SIP distortionZAP_ZBP_zKBP_ORDER provided without corresponding AP_ORDER keyword for SIP distortionrÂ   rÃ   z.Header has SIP keywords without CRPIX keywords)re   rf   rg   r/   rí   r0   Úzerosr1   r©   r[   Úanyr   Úinfor   r   )rL   rX   ra   rù   Úar¢   r´   rY   ÚbÚctypeÚmessageÚapÚbpZcrpix1Zcrpix2r6   )rX   ra   r7   r}   $  s”    

 



( zWCS._read_sip_kwc                sZ   | j dkri S i ‰ ‡ fdd„}|d| j jƒ |d| j jƒ |d| j jƒ |d| j jƒ ˆ S )z[
        Write out SIP keywords.  Returns a dictionary of key-value
        pairs.
        Nc          
      sÄ   |d krd S |j d }| d dkr&dnd}d t| d ƒtdƒ |¡}|d |fˆ | › d	< d
}x^t|ƒD ]R}xLt|| ƒD ]<}|||f dkr||||f |fˆ | › d|d›d|d›< q|W qjW d S )Nr   r;   ÚPzsky to detectorzdetector to skyz%SIP polynomial order, axis {:d}, {:s}ÚAr   Z_ORDERzSIP distortion coefficientg        rþ   rÀ   )rë   rJ   Úordr©   )ré   r  r.   ZtrdirÚcommentr¢   r´   )Úkeywordsr6   r7   Úwrite_array¥  s    
z&WCS._write_sip_kw.<locals>.write_arrayr  ÚBZAPZBP)r   r  r  r	  r
  )rL   r  r6   )r  r7   Ú_write_sip_kw›  s    
zWCS._write_sip_kwc             C   s  | j jdkrtdƒ‚| j jdkr(tdƒ‚| j jdkrˆ| j jdkrP| j jdkrP|S | j jdkr~| j jdkr~|d d …d d d…f S td	ƒ‚n|| j jdk s | j jdk r¨td
ƒ‚t |j	d | j jf¡}|d d …df |d d …| j jf< |d d …df |d d …| j jf< |S d S )NÚRAz[WCS does not have longitude type of 'RA', therefore (ra, dec) data can not be used as inputÚDECz\WCS does not have longitude type of 'DEC', therefore (ra, dec) data can not be used as inputr)   r   r   r;   zjWCS does not have longitude and latitude celestial axes, therefore (ra, dec) data can not be used as inputzoWCS does not have both longitude and latitude celestial axes, therefore (ra, dec) data can not be used as input)
r„   Úlngtypr/   Úlattypr[   ÚlngÚlatr0   r  rë   )rL   ÚskyÚoutr6   r6   r7   Ú_denormalize_sky¼  s(      zWCS._denormalize_skyc             C   s  | j jdkrtdƒ‚| j jdkr(tdƒ‚| j jdkrˆ| j jdkrP| j jdkrP|S | j jdkr~| j jdkr~|d d …d d d…f S td	ƒ‚nx| j jdk s | j jdk r¨td
ƒ‚t |j	d df¡}|d d …| j jf |d d …df< |d d …| j jf |d d …df< |S d S )Nr  zVWCS does not have longitude type of 'RA', therefore (ra, dec) data can not be returnedr  zWWCS does not have longitude type of 'DEC', therefore (ra, dec) data can not be returnedr)   r   r   r;   zeWCS does not have longitude and latitude celestial axes, therefore (ra, dec) data can not be returnedzjWCS does not have both longitude and latitude celestial axes, therefore (ra, dec) data can not be returned)
r„   r  r/   r  r[   r  r  r0   Úemptyrë   )rL   r  r  r6   r6   r7   Ú_normalize_skyÚ  s(      zWCS._normalize_skyF)Úra_dec_orderc      
         s0  ‡ ‡‡‡fdd„}‡ ‡‡‡fdd„}t |ƒdkr¢y|\}}t |¡}t|ƒ}W n$ tk
rr   td ˆj¡ƒ‚Y nX |jdksŒt |jƒdkr˜||g|ƒS |||ƒS t |ƒˆjd kr|d	d
… }	|d
 }ydd„ |	D ƒ}	t|ƒ}W n tk
r   tdƒ‚Y nX ||	|ƒS td ˆjˆjd t |ƒ¡ƒ‚d	S )zm
        A helper function to support reading either a pair of arrays
        or a single Nx2 array.
        c                sâ   t dd„ ˆ D ƒƒrˆ S ytjˆ Ž ‰ W n tk
r@   tdƒ‚Y nX t dd„ ˆ D ƒ¡}ˆrlˆdkrlˆ |¡}ˆ||ƒ‰ˆrÄˆdkrÄˆ ˆ¡‰ˆd d …df  ˆ d j¡ˆd d …df  ˆ d j¡fS ‡ ‡fd	d„t	ˆjd ƒD ƒS )
Nc             S   s   g | ]}|j d k‘qS )r   )r.   )r¡   Úxr6   r6   r7   r£   þ  s    zHWCS._array_converter.<locals>._return_list_of_arrays.<locals>.<listcomp>z5Coordinate arrays are not broadcastable to each otherc             S   s   g | ]}|  |jd f¡‘qS )r   )r-   r.   )r¡   r  r6   r6   r7   r£     s    ÚinputÚoutputr   r   c                s(   g | ] }ˆd d …|f   ˆ d j¡‘qS )Nr   )r-   rë   )r¡   r¢   )r«   r!  r6   r7   r£     s   )
r  r0   Zbroadcast_arraysr/   Zhstackr  r  r-   rë   r©   )r«   ÚoriginÚxy)Úfuncr  rL   r  )r«   r!  r7   Ú_return_list_of_arraysý  s"    


z4WCS._array_converter.<locals>._return_list_of_arraysc                sh   | j d ˆjkr td ˆj¡ƒ‚d| j kr.| S ˆrDˆdkrDˆ | ¡} ˆ | |ƒ}ˆrdˆdkrdˆ |¡}|S )Nr;   z@When providing two arguments, the array must be of shape (N, {})r   r   r!  )rë   r[   r/   rJ   r  r  )r#  r"  Úresult)r$  r  rL   r  r6   r7   Ú_return_single_array  s    




z2WCS._array_converter.<locals>._return_single_arrayr)   zBWhen providing two arguments, they must be (coords[N][{}], origin)r6   r   Nr;   c             S   s   g | ]}t  |¡‘qS r6   )r0   r°   )r¡   r  r6   r6   r7   r£   2  s    z(WCS._array_converter.<locals>.<listcomp>zfWhen providing more than two arguments, they must be a 1-D array for each axis, followed by an origin.zÈWCS projection has {0} dimensions, so expected 2 (an Nx{0} array and the origin argument) or {1} arguments (the position in each dimension, and the origin argument). Instead, {2} arguments were given.)	rê   r0   r°   rí   Ú	Exceptionrq   rJ   r[   rë   )
rL   r$  r  r  rM   r%  r'  r#  r"  r«   r6   )r$  r  rL   r  r7   Ú_array_converter÷  s6    


zWCS._array_converterc             O   s   | j | jdf|ž|ŽS )Nr!  )r)  Z_all_pix2world)rL   rM   rN   r6   r6   r7   r¹   B  s    zWCS.all_pix2worldaÞ  
        Transforms pixel coordinates to world coordinates.

        Performs all of the following in series:

            - Detector to image plane correction (if present in the
              FITS file)

            - `SIP`_ distortion correction (if present in the FITS
              file)

            - `distortion paper`_ table-lookup correction (if present
              in the FITS file)

            - `wcslib`_ "core" WCS transformation

        Parameters
        ----------
        {}

            For a transformation that is not two-dimensional, the
            two-argument form must be used.

        {}

        Returns
        -------

        {}

        Notes
        -----
        The order of the axes for the result is determined by the
        ``CTYPEia`` keywords in the FITS header, therefore it may not
        always be of the form (*ra*, *dec*).  The
        `~astropy.wcs.Wcsprm.lat`, `~astropy.wcs.Wcsprm.lng`,
        `~astropy.wcs.Wcsprm.lattyp` and `~astropy.wcs.Wcsprm.lngtyp`
        members can be used to determine the order of the axes.

        Raises
        ------
        MemoryError
            Memory allocation failed.

        SingularMatrixError
            Linear transformation matrix is singular.

        InconsistentAxisTypesError
            Inconsistent or unrecognized coordinate axis types.

        ValueError
            Invalid parameter value.

        ValueError
            Invalid coordinate transformation parameters.

        ValueError
            x- and y-coordinate arrays are not the same size.

        InvalidTransformError
            Invalid coordinate transformation parameters.

        InvalidTransformError
            Ill-conditioned coordinate transformation parameters.
        r[   r'   zsky coordinates, in degreesc                s.   ˆ j d krtdƒ‚ˆ j‡ fdd„df|ž|ŽS )Nz#No basic WCS settings were created.c                s   ˆ j  | |¡d S )NÚworld)r„   Zp2s)r#  Úo)rL   r6   r7   Ú<lambda>  ó    z#WCS.wcs_pix2world.<locals>.<lambda>r!  )r„   r/   r)  )rL   rM   rN   r6   )rL   r7   rº   ‰  s
    

zWCS.wcs_pix2worlda«  
        Transforms pixel coordinates to world coordinates by doing
        only the basic `wcslib`_ transformation.

        No `SIP`_ or `distortion paper`_ table lookup correction is
        applied.  To perform distortion correction, see
        `~astropy.wcs.WCS.all_pix2world`,
        `~astropy.wcs.WCS.sip_pix2foc`, `~astropy.wcs.WCS.p4_pix2foc`,
        or `~astropy.wcs.WCS.pix2foc`.

        Parameters
        ----------
        {}

            For a transformation that is not two-dimensional, the
            two-argument form must be used.

        {}

        Returns
        -------

        {}

        Raises
        ------
        MemoryError
            Memory allocation failed.

        SingularMatrixError
            Linear transformation matrix is singular.

        InconsistentAxisTypesError
            Inconsistent or unrecognized coordinate axis types.

        ValueError
            Invalid parameter value.

        ValueError
            Invalid coordinate transformation parameters.

        ValueError
            x- and y-coordinate arrays are not the same size.

        InvalidTransformError
            Invalid coordinate transformation parameters.

        InvalidTransformError
            Ill-conditioned coordinate transformation parameters.

        Notes
        -----
        The order of the axes for the result is determined by the
        ``CTYPEia`` keywords in the FITS header, therefore it may not
        always be of the form (*ra*, *dec*).  The
        `~astropy.wcs.Wcsprm.lat`, `~astropy.wcs.Wcsprm.lng`,
        `~astropy.wcs.Wcsprm.lattyp` and `~astropy.wcs.Wcsprm.lngtyp`
        members can be used to determine the order of the axes.

        zworld coordinates, in degreesc             C   sÎ  |   ||¡}| js|S | ¡ }	|  |	|¡| }
|	|
8 }	tj|
|
 dd}| ¡ }|d }d}d }d }t ¡ d }t ¡ d }tjddd |sŒxút |¡|krŠ||k rŠ|  |	|¡| }
tj|
|
 dd}|rx||k}t 	|¡rt||k}t 
||@ ¡\}|jd dkrt||k }t 
|¡}|
| }|	|  |8  < ||
|< t 
||@ ¡\}|| }|| ||< |d7 }d	}P |}|	|
8 }	|d7 }q’W |rº|d kr¾t 
t |	¡jdd¡\}|| }xú|jd dkr¸||k r¸|  |	| |¡| }tjt |¡dd}||  ¡ ||< |||< |rt||| k }t 
|¡}|| }|| }|	|  |8  < ||
|< t 
||k|@ ¡\}n(|	|  |8  < ||
|< t 
||k¡\}|| }|| }|d7 }qÀW tjt |	¡dd tjt |¡dd@ }t 
||k||k@ |B ¡\}|jd dkrd }||krRt 
||k||k @ | @ ¡\}|jd dkrVd }nd }tj||d |d k	sx|d k	rÊ|sÊ|d krªtd
 |¡|	t |
¡||d d‚n td |¡|	t |
¡|||d‚|	S )Nr   )Zaxisr)   ÚinvalidÚoverrc   )r.  r/  r   TzW'WCS.all_world2pix' failed to converge to the requested accuracy after {:d} iterations.)rA   rB   rC   rE   rD   z'WCS.all_world2pix' failed to converge to the requested accuracy.
After {:d} iterations, the solution is diverging at least for one input point.)Úwcs_world2pixÚhas_distortionrš   Úpix2focr0   ÚsumZgeterrZseterrZnanmaxr  Úwhererë   ÚisfiniteÚallZsquarer!   rJ   Úabs)rL   r*  r"  Ú	toleranceÚmaxiterÚadaptiveÚdetect_divergenceÚquietZpix0ZpixZdpixÚdnZdnprevZtol2ÚkÚindZinddivZold_invalidZold_overrD   ZslowconvÚconvZiconvZdpixgoodZdpixnewZdnnewZiiconvZsubindr.  r6   r6   r7   Ú_all_world2pixÎ  s®     R







zWCS._all_world2pixrB   r8  z4.3g-Cëâ6?é   )r8  r9  r:  r;  r<  c               s8   ˆj d krtdƒ‚ˆj‡ ‡‡‡‡‡fdd„df|ž|ŽS )Nz#No basic WCS settings were created.c                 s   ˆj | ˆˆˆ ˆˆdœŽS )N)r8  r9  r:  r;  r<  )rA  )rM   rN   )r:  r;  r9  r<  rL   r8  r6   r7   r,  a  s    z#WCS.all_world2pix.<locals>.<lambda>r   )r„   r/   r)  )rL   r8  r9  r:  r;  r<  rM   rN   r6   )r:  r;  r9  r<  rL   r8  r7   Úall_world2pixZ  s
    
zWCS.all_world2pixa09  
        all_world2pix(*arg, tolerance=1.0e-4, maxiter=20,
        adaptive=False, detect_divergence=True, quiet=False)

        Transforms world coordinates to pixel coordinates, using
        numerical iteration to invert the full forward transformation
        `~astropy.wcs.WCS.all_pix2world` with complete
        distortion model.


        Parameters
        ----------
        {0}

            For a transformation that is not two-dimensional, the
            two-argument form must be used.

        {1}

        tolerance : float, optional (default = 1.0e-4)
            Tolerance of solution. Iteration terminates when the
            iterative solver estimates that the "true solution" is
            within this many pixels current estimate, more
            specifically, when the correction to the solution found
            during the previous iteration is smaller
            (in the sense of the L2 norm) than ``tolerance``.

        maxiter : int, optional (default = 20)
            Maximum number of iterations allowed to reach a solution.

        quiet : bool, optional (default = False)
            Do not throw :py:class:`NoConvergence` exceptions when
            the method does not converge to a solution with the
            required accuracy within a specified number of maximum
            iterations set by ``maxiter`` parameter. Instead,
            simply return the found solution.

        Other Parameters
        ----------------
        adaptive : bool, optional (default = False)
            Specifies whether to adaptively select only points that
            did not converge to a solution within the required
            accuracy for the next iteration. Default is recommended
            for HST as well as most other instruments.

            .. note::
               The :py:meth:`all_world2pix` uses a vectorized
               implementation of the method of consecutive
               approximations (see ``Notes`` section below) in which it
               iterates over *all* input points *regardless* until
               the required accuracy has been reached for *all* input
               points. In some cases it may be possible that
               *almost all* points have reached the required accuracy
               but there are only a few of input data points for
               which additional iterations may be needed (this
               depends mostly on the characteristics of the geometric
               distortions for a given instrument). In this situation
               it may be advantageous to set ``adaptive`` = `True` in
               which case :py:meth:`all_world2pix` will continue
               iterating *only* over the points that have not yet
               converged to the required accuracy. However, for the
               HST's ACS/WFC detector, which has the strongest
               distortions of all HST instruments, testing has
               shown that enabling this option would lead to a about
               50-100% penalty in computational time (depending on
               specifics of the image, geometric distortions, and
               number of input points to be converted). Therefore,
               for HST and possibly instruments, it is recommended
               to set ``adaptive`` = `False`. The only danger in
               getting this setting wrong will be a performance
               penalty.

            .. note::
               When ``detect_divergence`` is `True`,
               :py:meth:`all_world2pix` will automatically switch
               to the adaptive algorithm once divergence has been
               detected.

        detect_divergence : bool, optional (default = True)
            Specifies whether to perform a more detailed analysis
            of the convergence to a solution. Normally
            :py:meth:`all_world2pix` may not achieve the required
            accuracy if either the ``tolerance`` or ``maxiter`` arguments
            are too low. However, it may happen that for some
            geometric distortions the conditions of convergence for
            the the method of consecutive approximations used by
            :py:meth:`all_world2pix` may not be satisfied, in which
            case consecutive approximations to the solution will
            diverge regardless of the ``tolerance`` or ``maxiter``
            settings.

            When ``detect_divergence`` is `False`, these divergent
            points will be detected as not having achieved the
            required accuracy (without further details). In addition,
            if ``adaptive`` is `False` then the algorithm will not
            know that the solution (for specific points) is diverging
            and will continue iterating and trying to "improve"
            diverging solutions. This may result in ``NaN`` or
            ``Inf`` values in the return results (in addition to a
            performance penalties). Even when ``detect_divergence``
            is `False`, :py:meth:`all_world2pix`, at the end of the
            iterative process, will identify invalid results
            (``NaN`` or ``Inf``) as "diverging" solutions and will
            raise :py:class:`NoConvergence` unless the ``quiet``
            parameter is set to `True`.

            When ``detect_divergence`` is `True`,
            :py:meth:`all_world2pix` will detect points for which
            current correction to the coordinates is larger than
            the correction applied during the previous iteration
            **if** the requested accuracy **has not yet been
            achieved**. In this case, if ``adaptive`` is `True`,
            these points will be excluded from further iterations and
            if ``adaptive`` is `False`, :py:meth:`all_world2pix` will
            automatically switch to the adaptive algorithm. Thus, the
            reported divergent solution will be the latest converging
            solution computed immediately *before* divergence
            has been detected.

            .. note::
               When accuracy has been achieved, small increases in
               current corrections may be possible due to rounding
               errors (when ``adaptive`` is `False`) and such
               increases will be ignored.

            .. note::
               Based on our testing using HST ACS/WFC images, setting
               ``detect_divergence`` to `True` will incur about 5-20%
               performance penalty with the larger penalty
               corresponding to ``adaptive`` set to `True`.
               Because the benefits of enabling this
               feature outweigh the small performance penalty,
               especially when ``adaptive`` = `False`, it is
               recommended to set ``detect_divergence`` to `True`,
               unless extensive testing of the distortion models for
               images from specific instruments show a good stability
               of the numerical method for a wide range of
               coordinates (even outside the image itself).

            .. note::
               Indices of the diverging inverse solutions will be
               reported in the ``divergent`` attribute of the
               raised :py:class:`NoConvergence` exception object.

        Returns
        -------

        {2}

        Notes
        -----
        The order of the axes for the input world array is determined by
        the ``CTYPEia`` keywords in the FITS header, therefore it may
        not always be of the form (*ra*, *dec*).  The
        `~astropy.wcs.Wcsprm.lat`, `~astropy.wcs.Wcsprm.lng`,
        `~astropy.wcs.Wcsprm.lattyp`, and
        `~astropy.wcs.Wcsprm.lngtyp`
        members can be used to determine the order of the axes.

        Using the method of fixed-point iterations approximations we
        iterate starting with the initial approximation, which is
        computed using the non-distortion-aware
        :py:meth:`wcs_world2pix` (or equivalent).

        The :py:meth:`all_world2pix` function uses a vectorized
        implementation of the method of consecutive approximations and
        therefore it is highly efficient (>30x) when *all* data points
        that need to be converted from sky coordinates to image
        coordinates are passed at *once*. Therefore, it is advisable,
        whenever possible, to pass as input a long array of all points
        that need to be converted to :py:meth:`all_world2pix` instead
        of calling :py:meth:`all_world2pix` for each data point. Also
        see the note to the ``adaptive`` parameter.

        Raises
        ------
        NoConvergence
            The method did not converge to a
            solution to the required accuracy within a specified
            number of maximum iterations set by the ``maxiter``
            parameter. To turn off this exception, set ``quiet`` to
            `True`. Indices of the points for which the requested
            accuracy was not achieved (if any) will be listed in the
            ``slow_conv`` attribute of the
            raised :py:class:`NoConvergence` exception object.

            See :py:class:`NoConvergence` documentation for
            more details.

        MemoryError
            Memory allocation failed.

        SingularMatrixError
            Linear transformation matrix is singular.

        InconsistentAxisTypesError
            Inconsistent or unrecognized coordinate axis types.

        ValueError
            Invalid parameter value.

        ValueError
            Invalid coordinate transformation parameters.

        ValueError
            x- and y-coordinate arrays are not the same size.

        InvalidTransformError
            Invalid coordinate transformation parameters.

        InvalidTransformError
            Ill-conditioned coordinate transformation parameters.

        Examples
        --------
        >>> import astropy.io.fits as fits
        >>> import astropy.wcs as wcs
        >>> import numpy as np
        >>> import os

        >>> filename = os.path.join(wcs.__path__[0], 'tests/data/j94f05bgq_flt.fits')
        >>> hdulist = fits.open(filename)
        >>> w = wcs.WCS(hdulist[('sci',1)].header, hdulist)
        >>> hdulist.close()

        >>> ra, dec = w.all_pix2world([1,2,3], [1,1,1], 1)
        >>> print(ra)  # doctest: +FLOAT_CMP
        [ 5.52645627  5.52649663  5.52653698]
        >>> print(dec)  # doctest: +FLOAT_CMP
        [-72.05171757 -72.05171276 -72.05170795]
        >>> radec = w.all_pix2world([[1,1], [2,1], [3,1]], 1)
        >>> print(radec)  # doctest: +FLOAT_CMP
        [[  5.52645627 -72.05171757]
         [  5.52649663 -72.05171276]
         [  5.52653698 -72.05170795]]
        >>> x, y = w.all_world2pix(ra, dec, 1)
        >>> print(x)  # doctest: +FLOAT_CMP
        [ 1.00000238  2.00000237  3.00000236]
        >>> print(y)  # doctest: +FLOAT_CMP
        [ 0.99999996  0.99999997  0.99999997]
        >>> xy = w.all_world2pix(radec, 1)
        >>> print(xy)  # doctest: +FLOAT_CMP
        [[ 1.00000238  0.99999996]
         [ 2.00000237  0.99999997]
         [ 3.00000236  0.99999997]]
        >>> xy = w.all_world2pix(radec, 1, maxiter=3,
        ...                      tolerance=1.0e-10, quiet=False)
        Traceback (most recent call last):
        ...
        NoConvergence: 'WCS.all_world2pix' failed to converge to the
        requested accuracy. After 3 iterations, the solution is
        diverging at least for one input point.

        >>> # Now try to use some diverging data:
        >>> divradec = w.all_pix2world([[1.0, 1.0],
        ...                             [10000.0, 50000.0],
        ...                             [3.0, 1.0]], 1)
        >>> print(divradec)  # doctest: +FLOAT_CMP
        [[  5.52645627 -72.05171757]
         [  7.15976932 -70.8140779 ]
         [  5.52653698 -72.05170795]]

        >>> # First, turn detect_divergence on:
        >>> try:  # doctest: +FLOAT_CMP
        ...   xy = w.all_world2pix(divradec, 1, maxiter=20,
        ...                        tolerance=1.0e-4, adaptive=False,
        ...                        detect_divergence=True,
        ...                        quiet=False)
        ... except wcs.wcs.NoConvergence as e:
        ...   print("Indices of diverging points: {{0}}"
        ...         .format(e.divergent))
        ...   print("Indices of poorly converging points: {{0}}"
        ...         .format(e.slow_conv))
        ...   print("Best solution:\n{{0}}".format(e.best_solution))
        ...   print("Achieved accuracy:\n{{0}}".format(e.accuracy))
        Indices of diverging points: [1]
        Indices of poorly converging points: None
        Best solution:
        [[  1.00000238e+00   9.99999965e-01]
         [ -1.99441636e+06   1.44309097e+06]
         [  3.00000236e+00   9.99999966e-01]]
        Achieved accuracy:
        [[  6.13968380e-05   8.59638593e-07]
         [  8.59526812e+11   6.61713548e+11]
         [  6.09398446e-05   8.38759724e-07]]
        >>> raise e
        Traceback (most recent call last):
        ...
        NoConvergence: 'WCS.all_world2pix' failed to converge to the
        requested accuracy.  After 5 iterations, the solution is
        diverging at least for one input point.

        >>> # This time turn detect_divergence off:
        >>> try:  # doctest: +FLOAT_CMP
        ...   xy = w.all_world2pix(divradec, 1, maxiter=20,
        ...                        tolerance=1.0e-4, adaptive=False,
        ...                        detect_divergence=False,
        ...                        quiet=False)
        ... except wcs.wcs.NoConvergence as e:
        ...   print("Indices of diverging points: {{0}}"
        ...         .format(e.divergent))
        ...   print("Indices of poorly converging points: {{0}}"
        ...         .format(e.slow_conv))
        ...   print("Best solution:\n{{0}}".format(e.best_solution))
        ...   print("Achieved accuracy:\n{{0}}".format(e.accuracy))
        Indices of diverging points: [1]
        Indices of poorly converging points: None
        Best solution:
        [[ 1.00000009  1.        ]
         [        nan         nan]
         [ 3.00000009  1.        ]]
        Achieved accuracy:
        [[  2.29417358e-06   3.21222995e-08]
         [             nan              nan]
         [  2.27407877e-06   3.13005639e-08]]
        >>> raise e
        Traceback (most recent call last):
        ...
        NoConvergence: 'WCS.all_world2pix' failed to converge to the
        requested accuracy.  After 6 iterations, the solution is
        diverging at least for one input point.

        zpixel coordinatesc                s.   ˆ j d krtdƒ‚ˆ j‡ fdd„df|ž|ŽS )Nz#No basic WCS settings were created.c                s   ˆ j  | |¡d S )NZpixcrd)r„   Zs2p)r#  r+  )rL   r6   r7   r,  ³  r-  z#WCS.wcs_world2pix.<locals>.<lambda>r   )r„   r/   r)  )rL   rM   rN   r6   )rL   r7   r0  ¯  s
    

zWCS.wcs_world2pixaô  
        Transforms world coordinates to pixel coordinates, using only
        the basic `wcslib`_ WCS transformation.  No `SIP`_ or
        `distortion paper`_ table lookup transformation is applied.

        Parameters
        ----------
        {}

            For a transformation that is not two-dimensional, the
            two-argument form must be used.

        {}

        Returns
        -------

        {}

        Notes
        -----
        The order of the axes for the input world array is determined by
        the ``CTYPEia`` keywords in the FITS header, therefore it may
        not always be of the form (*ra*, *dec*).  The
        `~astropy.wcs.Wcsprm.lat`, `~astropy.wcs.Wcsprm.lng`,
        `~astropy.wcs.Wcsprm.lattyp` and `~astropy.wcs.Wcsprm.lngtyp`
        members can be used to determine the order of the axes.

        Raises
        ------
        MemoryError
            Memory allocation failed.

        SingularMatrixError
            Linear transformation matrix is singular.

        InconsistentAxisTypesError
            Inconsistent or unrecognized coordinate axis types.

        ValueError
            Invalid parameter value.

        ValueError
            Invalid coordinate transformation parameters.

        ValueError
            x- and y-coordinate arrays are not the same size.

        InvalidTransformError
            Invalid coordinate transformation parameters.

        InvalidTransformError
            Ill-conditioned coordinate transformation parameters.
        c             G   s   | j | jd f|žŽ S )N)r)  Z_pix2foc)rL   rM   r6   r6   r7   r2  î  s    zWCS.pix2foca  
        Convert pixel coordinates to focal plane coordinates using the
        `SIP`_ polynomial distortion convention and `distortion
        paper`_ table-lookup correction.

        The output is in absolute pixel coordinates, not relative to
        ``CRPIX``.

        Parameters
        ----------

        {}

        Returns
        -------

        {}

        Raises
        ------
        MemoryError
            Memory allocation failed.

        ValueError
            Invalid coordinate transformation parameters.
        Ú2zfocal coordinatesc             G   s   | j | jd f|žŽ S )N)r)  Z_p4_pix2foc)rL   rM   r6   r6   r7   Ú
p4_pix2foc	  s    zWCS.p4_pix2focaá  
        Convert pixel coordinates to focal plane coordinates using
        `distortion paper`_ table-lookup correction.

        The output is in absolute pixel coordinates, not relative to
        ``CRPIX``.

        Parameters
        ----------

        {}

        Returns
        -------

        {}

        Raises
        ------
        MemoryError
            Memory allocation failed.

        ValueError
            Invalid coordinate transformation parameters.
        c             G   s   | j | jd f|žŽ S )N)r)  Z_det2im)rL   rM   r6   r6   r7   r‹   )	  s    z
WCS.det2imaä  
        Convert detector coordinates to image plane coordinates using
        `distortion paper`_ table-lookup correction.

        The output is in absolute pixel coordinates, not relative to
        ``CRPIX``.

        Parameters
        ----------

        {}

        Returns
        -------

        {}

        Raises
        ------
        MemoryError
            Memory allocation failed.

        ValueError
            Invalid coordinate transformation parameters.
        c             G   sT   | j d kr>t|ƒdkr|d S t|ƒdkr6|d d… S tdƒ‚| j| j jd f|žŽ S )Nr)   r   r¬   zWrong number of arguments)r   rê   rq   r)  r2  )rL   rM   r6   r6   r7   Úsip_pix2focF	  s    
zWCS.sip_pix2focaû  
        Convert pixel coordinates to focal plane coordinates using the
        `SIP`_ polynomial distortion convention.

        The output is in pixel coordinates, relative to ``CRPIX``.

        FITS WCS `distortion paper`_ table lookup correction is not
        applied, even if that information existed in the FITS file
        that initialized this :class:`~astropy.wcs.WCS` object.  To
        correct for that, use `~astropy.wcs.WCS.pix2foc` or
        `~astropy.wcs.WCS.p4_pix2foc`.

        Parameters
        ----------

        {}

        Returns
        -------

        {}

        Raises
        ------
        MemoryError
            Memory allocation failed.

        ValueError
            Invalid coordinate transformation parameters.
        c             G   sT   | j d kr>t|ƒdkr|d S t|ƒdkr6|d d… S tdƒ‚| j| j jd f|žŽ S )Nr)   r   r¬   zWrong number of arguments)r   rê   rq   r)  Zfoc2pix)rL   rM   r6   r6   r7   Úsip_foc2pixo	  s    
zWCS.sip_foc2pixaT  
        Convert focal plane coordinates to pixel coordinates using the
        `SIP`_ polynomial distortion convention.

        FITS WCS `distortion paper`_ table lookup distortion
        correction is not applied, even if that information existed in
        the FITS file that initialized this `~astropy.wcs.WCS` object.

        Parameters
        ----------

        {}

        Returns
        -------

        {}

        Raises
        ------
        MemoryError
            Memory allocation failed.

        ValueError
            Invalid coordinate transformation parameters.
        c             C   s:   ddl m} || ƒ}dd„ | jjD ƒ}dd„ t||ƒD ƒS )ad  
        Calculate 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 <https://ui.adsabs.harvard.edu/abs/2002A%26A...395.1061G>`_.

        .. note::
            This method 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::
            This method only returns sensible answers if the WCS contains
            celestial axes, i.e., the `~astropy.wcs.WCS.celestial` WCS object.

        Returns
        -------
        scale : list of `~astropy.units.Quantity`
            A vector of projection plane increments corresponding to each
            pixel side (axis).

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

        r   )Úproj_plane_pixel_scalesc             S   s   g | ]}t  |¡‘qS r6   )ÚuÚUnit)r¡   r  r6   r6   r7   r£   ³	  s    z/WCS.proj_plane_pixel_scales.<locals>.<listcomp>c             S   s   g | ]\}}|| ‘qS r6   r6   )r¡   ÚvalueÚunitr6   r6   r7   r£   ´	  s    )Úastropy.wcs.utilsrH  r„   ÚcunitÚzip)rL   rH  Úvaluesr   r6   r6   r7   rH  ”	  s    zWCS.proj_plane_pixel_scalesc             C   s@   ddl m} || ƒ}t | jjd ¡t | jjd ¡ }|| S )ag  
        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 <https://ui.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::
            This method only returns sensible answers if the WCS contains
            celestial axes, i.e., the `~astropy.wcs.WCS.celestial` WCS object.

        Returns
        -------
        area : `~astropy.units.Quantity`
            Area (in the projection plane) of the pixel at ``CRPIX`` location.

        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_area

        r   )Úproj_plane_pixel_arear   )rM  rQ  rI  rJ  r„   rN  )rL   rQ  rK  rL  r6   r6   r7   rQ  ¶	  s    *$zWCS.proj_plane_pixel_areac             C   s<   | j ||d}tj|d}t |¡}|  |¡ |  |¡ |S )a  
        Generate an `~astropy.io.fits.HDUList` object with all of the
        information stored in this object.  This should be logically identical
        to the input FITS file, but it will be normalized in a number of ways.

        See `to_header` for some warnings about the output produced.

        Parameters
        ----------

        relax : bool or int, optional
            Degree of permissiveness:

            - `False` (default): Write all extensions that are
              considered to be safe and recommended.

            - `True`: Write all recognized informal extensions of the
              WCS standard.

            - `int`: a bit field selecting specific extensions to
              write.  See :ref:`relaxwrite` for details.

        key : str
            The name of a particular WCS transform to use.  This may be
            either ``' '`` or ``'A'``-``'Z'`` and corresponds to the ``"a"``
            part of the ``CTYPEia`` cards.

        Returns
        -------
        hdulist : `~astropy.io.fits.HDUList`
        )rZ   rY   )rX   )Ú	to_headerr   Z
PrimaryHDUrv   rò   r÷   )rL   rZ   rY   rX   rn   r2   r6   r6   r7   Úto_fitså	  s    !


zWCS.to_fitsc             C   sä  t }d}|dkrd}d}|dkr4|t@ }|t M }n|}|dkrDtnt}||B }| jdk	r”|dk	rt| jj}|| j_| j |¡}tj 	|¡}dddg}	x|	D ]}
|
|krœ||
= qœW t
td ƒd	 t
td
 ƒ dk r x¼| ¡ D ]<\}
}|
dd… dkrÞ|dkrÞt d|
› dtj› dt¡ qÞW nrt
td ƒd	 t
td
 ƒ dk rœxX| ¡ D ]B\}
}|
dd… dkrL|dkrLt d|
› dtj› dt¡ qLW nt ¡ }|r| jdk	r| jdk	ràtdd„ | jjD ƒƒrà| j|dd x"|  ¡  ¡ D ]\}
}|||
< qîW |s>| jdk	r>t| jjƒr>| jdk	r>| j|dd}|rÎ| jd|d}g }x*| ¡ D ]\}
}|
|kr`| |
¡ q`W t|ƒr¤t d d |¡¡t¡ t| jjƒrÎ| jdk	rÎ| j|ddd}|dk	rà|| j_|S )aà
  Generate an `astropy.io.fits.Header` object with the basic WCS
        and SIP information stored in this object.  This should be
        logically identical to the input FITS file, but it will be
        normalized in a number of ways.

        .. warning::

          This function does not write out FITS WCS `distortion
          paper`_ information, since that requires multiple FITS
          header data units.  To get a full representation of
          everything in this object, use `to_fits`.

        Parameters
        ----------
        relax : bool or int, optional
            Degree of permissiveness:

            - `False` (default): Write all extensions that are
              considered to be safe and recommended.

            - `True`: Write all recognized informal extensions of the
              WCS standard.

            - `int`: a bit field selecting specific extensions to
              write.  See :ref:`relaxwrite` for details.

            If the ``relax`` keyword argument is not given and any
            keywords were omitted from the output, an
            `~astropy.utils.exceptions.AstropyWarning` is displayed.
            To override this, explicitly pass a value to ``relax``.

        key : str
            The name of a particular WCS transform to use.  This may be
            either ``' '`` or ``'A'``-``'Z'`` and corresponds to the ``"a"``
            part of the ``CTYPEia`` cards.

        Returns
        -------
        header : `astropy.io.fits.Header`

        Notes
        -----
        The output header will almost certainly differ from the input in a
        number of respects:

          1. The output header only contains WCS-related keywords.  In
             particular, it does not contain syntactically-required
             keywords such as ``SIMPLE``, ``NAXIS``, ``BITPIX``, or
             ``END``.

          2. Deprecated (e.g. ``CROTAn``) or non-standard usage will
             be translated to standard (this is partially dependent on
             whether ``fix`` was applied).

          3. Quantities will be converted to the units used internally,
             basically SI with the addition of degrees.

          4. Floating-point quantities may be given to a different decimal
             precision.

          5. Elements of the ``PCi_j`` matrix will be written if and
             only if they differ from the unit matrix.  Thus, if the
             matrix is unity then no elements will be written.

          6. Additional keywords such as ``WCSAXES``, ``CUNITia``,
             ``LONPOLEa`` and ``LATPOLEa`` may appear.

          7. The original keycomments will be lost, although
             `to_header` tries hard to write meaningful comments.

          8. Keyword order may be changed.

        FNT)TFrW   rU   ÚCOMMENTr   é
   r   éG   r&   )r_   ZCQDISZTPDz'WCS contains a TPD distortion model in z	. WCSLIB zq is writing this in a format incompatible with current versions - please update to 7.4 or use the bundled WCSLIB.éJ   zG, which requires WCSLIB 7.4 or later to store in a FITS header (having z).c             s   s   | ]}|  d ¡ V  qdS )z-SIPN)r   )r¡   r  r6   r6   r7   rú   ˆ
  s    z WCS.to_header.<locals>.<genexpr>)Úadd_sip)rZ   rY   zYSome non-standard WCS keywords were excluded: {} Use the ``relax`` kwarg to control this.z, )rX  Úlog_message)Z
WCSHDO_P14Ú
WCSHDO_SIPZ
WCSHDO_allZWCSHDO_safer„   ÚaltrR  r   ro   rx   rí   Ú_parsed_versionr›   rH   rI   r   Ú__version__r	   r   r  r  Ú
_fix_ctyper  rm   rê   rJ   Újoin)rL   rZ   rY   Ú	precisionZdisplay_warningZdo_sipÚorig_keyrŽ   rX   Zkeys_to_removeÚkwr   Zfull_headerZmissing_keysr6   r6   r7   rR  
  sr    K


""$,



zWCS.to_headerc             C   s„   d}|r|rt  |¡ xhtd| jd ƒD ]T}d|› | jj›  ¡ }||kr(|rb||  d¡d }n||  d¡}|||< q(q(q(W |S )a…  
        Parameters
        ----------
        header : `~astropy.io.fits.Header`
            FITS header.
        add_sip : bool
            Flag indicating whether "-SIP" should be added or removed from CTYPE keywords.

            Remove "-SIP" from CTYPE when writing out a header with relax=False.
            This needs to be done outside ``to_header`` because ``to_header`` runs
            twice when ``relax=False`` and the second time ``relax`` is set to ``True``
            to display the missing keywords.

            If the user requested SIP distortion to be written out add "-SIP" to
            CTYPE if it is missing.
        a#  
        Inconsistent SIP distortion information is present in the current WCS:
        SIP coefficients were detected, but CTYPE is missing "-SIP" suffix,
        therefore the current WCS is internally inconsistent.

        Because relax has been set to True, the resulting output WCS will have
        "-SIP" appended to CTYPE in order to make the header internally consistent.

        However, this may produce incorrect astrometry in the output WCS, if
        in fact the current WCS is already distortion-corrected.

        Therefore, if current WCS is already distortion-corrected (eg, drizzled)
        then SIP distortion components should not apply. In that case, for a WCS
        that is already distortion-corrected, please remove the SIP coefficients
        from the header.

        r   rÿ   z-SIP)r   r  r©   r[   r„   r[  rÊ   )rL   rX   rX  rY  Z_add_sip_to_ctyper¢   rb  r   r6   r6   r7   r^  ©
  s    "

zWCS._fix_ctypec             C   s   t |  |¡ƒS )ze
        Identical to `to_header`, but returns a string containing the
        header cards.
        )rf   rR  )rL   rZ   r6   r6   r7   Úto_header_stringÜ
  s    zWCS.to_header_stringúfootprint.regÚgreenr)   c          	   C   sž   d}|p| j j}|dkr&td |¡ƒ‚t|ddb}| |¡ | |› d¡ | d¡ |  ¡ }|dk	r|j|d	d
 | d|› d|d›d¡ W dQ R X dS )aj  
        Writes out a `ds9`_ style regions file. It can be loaded
        directly by `ds9`_.

        Parameters
        ----------
        filename : str, optional
            Output file name - default is ``'footprint.reg'``

        color : str, optional
            Color to use when plotting the line.

        width : int, optional
            Width of the region line.

        coordsys : str, optional
            Coordinate system. If not specified (default), the ``radesys``
            value is used. For all possible values, see
            http://ds9.si.edu/doc/ref/region.html#RegionFileFormat

        z˜# Region file format: DS9 version 4.0 
# global color=green font="helvetica 12 bold select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source
)ZPHYSICALZIMAGEZFK4ZB1950ZFK5ZJ2000ZGALACTICZECLIPTICZICRSZLINEARZ	AMPLIFIERZDETECTORz_Coordinate system '{}' is not supported. A valid one can be given with the 'coordsys' argument.Úw)ÚmodeÚ
zpolygon(Nú,)Úsepz
) # color=z, width=rÀ   z 
)r„   Zradesysr/   rJ   rl   Úwriter¼   Útofile)rL   ÚfilenameÚcolorÚwidthZcoordsysÚcommentsÚfZftprr6   r6   r7   Úfootprint_to_fileã
  s    

zWCS.footprint_to_filec          	   C   s”   g }|d k	r^t |ttfƒs^xBt d¡D ]4}y| |d|›  ¡ W q& tk
rX   P Y q&X q&W t|ƒdkrtddg}nt|ƒdkrŠ| d¡ || _d S )Nr   rb   r   )	re   rf   rg   Ú	itertoolsÚcountrm   rÉ   rê   Ú_naxis)rL   rX   ru  r[   r6   r6   r7   r€     s    

zWCS._get_naxisc             C   s   t t| ƒƒ d S )N)ÚprintÚrepr)rL   r6   r6   r7   Úprintwcs   s    zWCS.printwcsc       
      C   sÈ  dd| j ›g}dd dd„ t| j ƒD ƒ¡ }ddd	g}| jj| jj| jjg}x*t||ƒD ]\}}| ||j	|Ž  ¡ qZW t
| jd
ƒrxrt| j ƒD ]d}d}x:t| j ƒD ],}	|d dt|d ƒdt|	d ƒdg¡7 }q¨W ||7 }| |j	| jj| Ž ¡ q”W d| }| |j	| jjŽ ¡ n†t
| jdƒr xvt| j ƒD ]h}d}x<t| j ƒD ].}	|d dt|d ƒdt|	d ƒdg¡7 }qHW ||7 }| |j	| jj| Ž ¡ q4W | dd tt| jƒ¡› ¡ d |¡S )zo
        Return a short description. Simply porting the behavior from
        the `printwcs()` method.
        zWCS Keywords
zNumber of WCS axes: z : rW   c             S   s   g | ]}d |›  d ‘qS )Ú{z!r}  r6   )r¡   r¢   r6   r6   r7   r£   *  s    z WCS.__repr__.<locals>.<listcomp>rÿ   rß   rÞ   ÚpcÚPCr   rþ   rU   rà   ÚcdZCDzNAXIS : z  rh  )r[   r_  r©   r„   r  râ   rá   rO  rm   rJ   Úhasattrrf   rz  rã   r|  rû   ru  )
rL   ÚdescriptionZsfmtr  rP  ÚkeywordrK  r¢   Úsr´   r6   r6   r7   Ú__repr__#  s2    
,.zWCS.__repr__c       
      C   s®   | j dkrtdƒ‚dddddœ}ddd	d
dddœ}g }xr| j jD ]f}i }|d d }|| |d< |d d }|| |d< |d d }||d< |d }	|	|d< | |¡ q@W |S )aå  
        Similar to `self.wcsprm.axis_types <astropy.wcs.Wcsprm.axis_types>`
        but provides the information in a more Python-friendly format.

        Returns
        -------
        result : list of dict

            Returns a list of dictionaries, one for each axis, each
            containing attributes about the type of that axis.

            Each dictionary has the following keys:

            - 'coordinate_type':

              - None: Non-specific coordinate type.

              - 'stokes': Stokes coordinate.

              - 'celestial': Celestial coordinate (including ``CUBEFACE``).

              - 'spectral': Spectral coordinate.

            - 'scale':

              - 'linear': Linear axis.

              - 'quantized': Quantized axis (``STOKES``, ``CUBEFACE``).

              - 'non-linear celestial': Non-linear celestial axis.

              - 'non-linear spectral': Non-linear spectral axis.

              - 'logarithmic': Logarithmic axis.

              - 'tabular': Tabular axis.

            - 'group'

              - Group number, e.g. lookup table number

            - 'number'

              - For celestial axes:

                - 0: Longitude coordinate.

                - 1: Latitude coordinate.

                - 2: ``CUBEFACE`` number.

              - For lookup tables:

                - the axis number in a multidimensional table.

            ``CTYPEia`` in ``"4-3"`` form with unrecognized algorithm code will
            generate an error.
        Nz.This WCS object does not have a wcsprm object.ZstokesÚ	celestialÚspectral)r   r   r)   r¬   ZlinearZ	quantizedznon-linear celestialznon-linear spectralZlogarithmicZtabular)r   r   r)   r¬   é   r&   iè  rU  Úcoordinate_typeéd   Úscalerø   Únumber)r„   r·   Z
axis_typesrm   )
rL   Zcoordinate_type_mapZ	scale_mapr&  Z	axis_typeÚ	subresultr…  r‡  rø   rˆ  r6   r6   r7   Úget_axis_typesE  s4    ;
zWCS.get_axis_typesc             C   s4   | j dd}t ¡ }| |¡ t| j| j| ¡ ffS )z
        Support pickling of WCS objects.  This is done by serializing
        to an in-memory FITS file and dumping that as a string.
        T)rZ   )rS  ÚioÚBytesIOZwritetoÚ__WCS_unpickle__rO   r•   Úgetvalue)rL   r2   Úbufferr6   r6   r7   Ú
__reduce__¦  s
    
zWCS.__reduce__c             C   s.   t t| jjƒƒ}| |¡ |  dd„ |D ƒ¡S )a¶  
        Remove an axis from the WCS.

        Parameters
        ----------
        wcs : `~astropy.wcs.WCS`
            The WCS with naxis to be chopped to naxis-1
        dropax : int
            The index of the WCS to drop, counting from 0 (i.e., python convention,
            not FITS convention)

        Returns
        -------
        `~astropy.wcs.WCS`
            A new `~astropy.wcs.WCS` instance with one axis fewer
        c             S   s   g | ]}|d  ‘qS )r   r6   )r¡   r¢   r6   r6   r7   r£   Ë  s    z WCS.dropaxis.<locals>.<listcomp>)rK   r©   r„   r[   Úpoprz   )rL   ZdropaxÚindsr6   r6   r7   Údropaxis´  s    
zWCS.dropaxisc             C   s>   t t| jjƒƒ}|| ||  ||< ||< |  dd„ |D ƒ¡S )aß  
        Swap axes in a WCS.

        Parameters
        ----------
        wcs : `~astropy.wcs.WCS`
            The WCS to have its axes swapped
        ax0 : int
        ax1 : int
            The indices of the WCS to be swapped, counting from 0 (i.e., python
            convention, not FITS convention)

        Returns
        -------
        `~astropy.wcs.WCS`
            A new `~astropy.wcs.WCS` instance with the same number of axes,
            but two swapped
        c             S   s   g | ]}|d  ‘qS )r   r6   )r¡   r¢   r6   r6   r7   r£   ã  s    z WCS.swapaxes.<locals>.<listcomp>)rK   r©   r„   r[   rz   )rL   Zax0Zax1r’  r6   r6   r7   ÚswapaxesÍ  s    zWCS.swapaxesc             C   s   |   tttg¡S )z¾
        Reorient the WCS such that the celestial axes are first, followed by
        the spectral axis, followed by any others.
        Assumes at least celestial axes are present.
        )rz   ÚWCSSUB_CELESTIALÚWCSSUB_SPECTRALZWCSSUB_STOKES)rL   r6   r6   r7   Úreorient_celestial_firstå  s    zWCS.reorient_celestial_firstc             C   sB  t |dƒr$t|ƒ| jjkr$tdƒ‚nt |dƒs4|g}tdd„ |D ƒƒsPt| |ƒS |  ¡ }|jdk	rn|jj	 
¡ }xžt|ƒD ]\}}|jdk	r |jdk r tdƒ‚|r¶| jjd | }n|}|jdk	rÞ|jdkrÞtd|j|jƒ}|jdk	rœ|jd	krh| jj	| }| jj| }	||j d
 |j d d
|j d  }
|
|jj	|< |jdk	rT|
||< |	|j |jj|< n4|jj	|  |j8  < |jdk	rœ||  |j8  < ytt | j| ¡| ƒ}W nH tk
r  } z(dt|ƒkrÜ‚ t d ||¡t¡ W dd}~X Y qzX ||j|< qzW |jdk	r>t| jj| jj| jj| jj|ƒ|_|S )ao  
        Slice a WCS instance using a Numpy slice. The order of the slice should
        be reversed (as for the data) compared to the natural WCS order.

        Parameters
        ----------
        view : tuple
            A tuple containing the same number of slices as the WCS system.
            The ``step`` method, the third argument to a slice, is not
            presently supported.
        numpy_order : bool
            Use numpy order, i.e. slice the WCS so that an identical slice
            applied to a numpy array will slice the array and WCS in the same
            way. If set to `False`, the WCS will be sliced in FITS order,
            meaning the first slice will be applied to the *last* numpy index
            but the *first* WCS axis.

        Returns
        -------
        wcs_new : `~astropy.wcs.WCS`
            A new resampled WCS axis
        Ú__len__z&Must have # of slices <= # of WCS axesc             s   s   | ]}t |tƒV  qd S )N)re   Úslice)r¡   r  r6   r6   r7   rú   	  s    zWCS.slice.<locals>.<genexpr>Nr   z%Reversing an axis is not implemented.r   )Nr   g      ð?g      à?g       @zindices must be integerszQNAXIS{} attribute is not updated because at least one index ('{}') is no integer.) r}  rê   r„   r[   r/   r6  r   r™   r   rá   ÚtolistÚ	enumerateÚstepÚNotImplementedErrorÚstartr™  Ústoprã   Úbuiltinsr©   ru  rq   rf   rH   rI   rJ   r
   r   r  r  r	  r
  )rL   ÚviewZnumpy_orderZwcs_newZ	sip_crpixr¢   ZiviewZ	wcs_indexrá   rã   ZcrpZnitemsÚexcr6   r6   r7   r™  í  sR    



&z	WCS.slicec             C   s
   |   |¡S )N)r™  )rL   Úitemr6   r6   r7   Ú__getitem__M  s    zWCS.__getitem__c             C   s   t d| jj› dƒ‚d S )Nú'z' object is not iterable)rq   rO   rP   )rL   r6   r6   r7   Ú__iter__T  s    zWCS.__iter__c             C   sV   t | jjƒ}| jj}x<tt|ƒƒD ],}t|| ƒdkr8q"||  d¡d ||< q"W |S )z˜
        World names for each coordinate axis

        Returns
        -------
        list of str
            A list of names along each axis.
        r   ú-)rK   r„   r¥   r  r©   rê   Úsplit)rL   ÚnamesÚtypesr¢   r6   r6   r7   Úaxis_type_namesZ  s    
zWCS.axis_type_namesc             C   s   |   tg¡S )zQ
        A copy of the current WCS with only the celestial axes included
        )rz   r•  )rL   r6   r6   r7   r‚  l  s    zWCS.celestialc             C   s   | j o| jdkS )Nr)   )Úhas_celestialr[   )rL   r6   r6   r7   Úis_celestials  s    zWCS.is_celestialc             C   s2   y| j jdko| j jdkS  tk
r,   dS X d S )Nr   F)r„   r  r  r   )rL   r6   r6   r7   r¬  w  s    zWCS.has_celestialc             C   s   |   tg¡S )zP
        A copy of the current WCS with only the spectral axes included
        )rz   r–  )rL   r6   r6   r7   rƒ  ~  s    zWCS.spectralc             C   s   | j o| jdkS )Nr   )Úhas_spectralr[   )rL   r6   r6   r7   Úis_spectral…  s    zWCS.is_spectralc             C   s&   y| j jdkS  tk
r    dS X d S )Nr   F)r„   Úspecr   )rL   r6   r6   r7   r®  ‰  s    zWCS.has_spectralc             C   s2   | j dk	p0| jdk	p0| jdk	p0| jdk	o0| jdk	S )zE
        Returns `True` if any distortion terms are present.
        N)r   r‘   r’   r“   r”   )rL   r6   r6   r7   r1    s    
zWCS.has_distortionc             C   sÎ   yt  | j ¡ ¡}| j ¡ }W nž tk
r¼   y@t ¡ . t ddt	¡ t  
| jjt  | jj¡¡}W d Q R X W n" tk
r   t  | jj¡}Y nX y| jj}W n tk
r¶   d}Y nX Y nX t  
||¡}|S )Nrc   z)cdelt will be ignored since cd is presentr   )r0   Zdiagr„   Z	get_cdeltZget_pcr   rH   r   ÚfilterwarningsÚRuntimeWarningÚdotr|  rã   r·   rz  )rL   rã   rz  Zpccdr6   r6   r7   Úpixel_scale_matrix™  s"    

(zWCS.pixel_scale_matrixc             K   s   |j | f|ŽS )aì  
        Determines if a given SkyCoord is contained in the wcs footprint.

        Parameters
        ----------
        coord : `~astropy.coordinates.SkyCoord`
            The coordinate to check if it is within the wcs coordinate.
        **kwargs :
           Additional arguments to pass to `~astropy.coordinates.SkyCoord.to_pixel`

        Returns
        -------
        response : bool
           True means the WCS footprint contains the coordinate, False means it does not.
        )Zcontained_by)rL   ZcoordrN   r6   r6   r7   Úfootprint_contains²  s    zWCS.footprint_contains)NNrU   rV   TNNNTrW   T)N)rW   N)NTNT)rV   )r_   rV   )r_   )rW   )FN)NN)TT)N)rd  re  r)   N)N)T)GrP   rQ   rR   rS   rG   r˜   rž   rš   r™   rz   r   r   rµ   rƒ   r¼   r{   rÈ   rò   r|   r÷   ry   r}   r  r  r  r)  r¹   rJ   r   ZTWO_OR_MORE_ARGSZRA_DEC_ORDERZRETURNSrº   rA  r   rC  r0  r2  rE  r‹   rF  rG  rH  rQ  rS  rR  r^  rc  rr  r€   rx  r  rŠ  r  r“  r”  r—  r™  r¤  r¦  Úpropertyr«  r‚  r­  r¬  rƒ  r¯  r®  r1  r´  rµ  r6   r6   r6   r7   r   ç   sÀ      
 !		
+
3
E
C$/
J
-

w!KCA   
  Q;&""/
+
 
3
 
-
"a
`	c             C   sB   |   | ¡}|j |¡ t |¡}t |¡}t ||d j	|¡ |S )z?
    Unpickles a WCS object from a serialized FITS string.
    r   )
Ú__new__r•   r–   r‹  rŒ  r   rl   r   rG   rX   )ÚclsÚdctZ	fits_datarL   r  r2   r6   r6   r7   r  Æ  s    


r  TrW   c             C   s°   t | ttfƒr| }nt | tjƒr*|  ¡ }ntdƒ‚t|ƒ}t |tƒrP| d¡}n|}t	 
|||¡}	g }
xD|	D ]<}tddd}||_|
 |¡ |rš| |¡ |rl|j ¡  qlW |
S )au  
    Find all the WCS transformations in the given header.

    Parameters
    ----------
    header : str or `~astropy.io.fits.Header` object.

    relax : bool or int, optional
        Degree of permissiveness:

        - `True` (default): Admit all recognized informal extensions of the
          WCS standard.

        - `False`: Recognize only FITS keywords defined by the
          published WCS standard.

        - `int`: a bit field selecting specific extensions to accept.
          See :ref:`relaxread` for details.

    keysel : sequence of str, optional
        A list of flags used to select the keyword types considered by
        wcslib.  When ``None``, only the standard image header
        keywords are considered (and the underlying wcspih() C
        function is called).  To use binary table image array or pixel
        list keywords, *keysel* must be set.

        Each element in the list should be one of the following strings:

            - 'image': Image header keywords

            - 'binary': Binary table image array keywords

            - 'pixel': Pixel list keywords

        Keywords such as ``EQUIna`` or ``RFRQna`` that are common to
        binary table image arrays and pixel lists (including
        ``WCSNna`` and ``TWCSna``) are selected by both 'binary' and
        'pixel'.

    fix : bool, optional
        When `True` (default), call `~astropy.wcs.Wcsprm.fix` on
        the resulting objects to fix any non-standard uses in the
        header.  `FITSFixedWarning` warnings will be emitted if any
        changes were made.

    translate_units : str, optional
        Specify which potentially unsafe translations of non-standard
        unit strings to perform.  By default, performs none.  See
        `WCS.fix` for more information about this parameter.  Only
        effective when ``fix`` is `True`.

    Returns
    -------
    wcses : list of `WCS`
    z8header must be a string or astropy.io.fits.Header objectr\   F)rƒ   rˆ   )re   rf   rg   r   ro   rr   rq   r@   rt   r   r   r   r„   rm   rƒ   r…   )rX   rZ   r=   rƒ   rd   rˆ   rŽ   r>   r   Zwcsprmsr&  rŠ   r‰  r6   r6   r7   r   Ö  s*    ;




c             C   sŽ  G dd„ dt ƒ}G dd„ dt ƒ}G dd„ dt ƒ}t| tjƒrB| }n
t | ¡}|ƒ }x4t|ƒD ]&\}}|||jƒ}| |¡ tj	dd}	t
|jtjd	d	d
}
W dQ R X xÚ|
D ]Ò}||jjƒ}| |¡ ybW n tk
rä   Y nX tj	ddŠ}	t ¡  tjdtdd y$t|j|jjp dtjdd	d W n2 tk
rb } z| t|ƒ¡ W dd}~X Y nX | dd„ |	D ƒ¡ W dQ R X q°W q^W |S )a  
    Prints a WCS validation report for the given FITS file.

    Parameters
    ----------
    source : str or file-like or `~astropy.io.fits.HDUList`
        The FITS file to validate.

    Returns
    -------
    results : list subclass instance
        The result is returned as nested lists.  The first level
        corresponds to the HDUs in the given file.  The next level has
        an entry for each WCS found in that header.  The special
        subclass of list will pretty-print the results as a table when
        printed.

    c               @   s   e Zd Zdd„ Zdd„ ZdS )z'validate.<locals>._WcsValidateWcsResultc             S   s
   || _ d S )N)Ú_key)rL   rY   r6   r6   r7   rG   E  s    z0validate.<locals>._WcsValidateWcsResult.__init__c          	   S   s‚   d| j p
d› dg}t| ƒrnxZ| D ]F}x@t| ¡ ƒD ]0\}}|dkrJd}nd}| tj||dd¡ q4W q"W n
| d¡ d	 |¡S )
Nz  WCS key 'rU   z':r   z    - z      )Úinitial_indentÚsubsequent_indentz    No issues.rh  )	rº  rê   r›  Ú
splitlinesÚextendÚtextwrapÚwraprm   r_  )rL   r&  Úentryr¢   Úliner»  r6   r6   r7   r  H  s    

z0validate.<locals>._WcsValidateWcsResult.__repr__N)rP   rQ   rR   rG   r  r6   r6   r6   r7   Ú_WcsValidateWcsResultD  s   rÃ  c               @   s   e Zd Zdd„ Zdd„ ZdS )z'validate.<locals>._WcsValidateHduResultc             S   s   || _ || _t | ¡ d S )N)Ú
_hdu_indexÚ	_hdu_namerK   rG   )rL   Z	hdu_indexÚhdu_namer6   r6   r7   rG   [  s    z0validate.<locals>._WcsValidateHduResult.__init__c             S   s`   t | ƒr\| jrd| j› d}nd}d| j› |› dg}x| D ]}| t|ƒ¡ q<W d |¡S dS )Nz (ú)rW   zHDU ú:rh  )rê   rÅ  rÄ  rm   rw  r_  )rL   rÆ  r&  r„   r6   r6   r7   r  `  s    

z0validate.<locals>._WcsValidateHduResult.__repr__N)rP   rQ   rR   rG   r  r6   r6   r6   r7   Ú_WcsValidateHduResultZ  s   rÉ  c               @   s   e Zd Zdd„ ZdS )z%validate.<locals>._WcsValidateResultsc             S   s6   g }x&| D ]}t |ƒ}t|ƒr
| |¡ q
W d |¡S )Nz

)rw  rê   rm   r_  )rL   r&  rn   Úcontentr6   r6   r7   r  m  s    
z.validate.<locals>._WcsValidateResults.__repr__N)rP   rQ   rR   r  r6   r6   r6   r7   Ú_WcsValidateResultsl  s   rË  T)ÚrecordF)rZ   rƒ   rˆ   NÚalways)rm   rU   )rY   rZ   rƒ   rˆ   c             S   s   g | ]}t |jƒ‘qS r6   )rf   r  )r¡   r  r6   r6   r7   r£     s    zvalidate.<locals>.<listcomp>)rK   re   r   rv   rl   r›  ré   rm   rH   r   r   rX   r   ZWCSHDR_rejectr„   r[  Ú__warningregistry__Ú	NameErrorÚresetwarningsr‚   r   r   r   rf   r¾  )ÚsourcerÃ  rÉ  rË  r2   Úresultsr¢   rn   Zhdu_resultsZwarning_linesZwcsesr„   Zwcs_resultsÚer6   r6   r7   r   1  sD    



 &)TNTrW   T)Orš   rŸ   r‹  rs  rh   Úrer¿  rH   r   Únumpyr0   Zastropyr   Z
astropy.ior   rW   r   r   r   rI  Zastropy.utils.compatr   Zastropy.utils.exceptionsr	   r
   r   Zastropy.utils.decoratorsr   Zwcsapi.fitswcsr   r   Ú__all__Z__doctest_skip__r]  r¨  r\  rí   ÚImportErrorÚ_sanity_checkÚRuntimeErrorZ_Wcsr   r   r   r   r   r   r   r   r   r   r   r   r   r    r"   r#   r$   r•   r›   rY   r   rÌ   Úlocalsrm   r8   Zset_wtbarr_fitsio_callbackÚobjectrZ  Úcompilerü   r@   r(  r!   r   r   r  r   r   r6   r6   r6   r7   Ú<module>   sØ   


$


4                       v  
Y