a
    ߙfbm,                     @   s   d dl Z d dlmZmZ d dlZddlmZ ddgZdd Z	d	d
 Z
dd ZG dd de jdZdd Zdd ZG dd deZdS )    N)defaultdictOrderedDict   )deserialize_classBaseHighLevelWCSHighLevelWCSMixinc                 C   s   | dD ]}t| |} q
| S )N.)splitgetattr)objZatta r   @lib/python3.9/site-packages/astropy/wcs/wcsapi/high_level_api.pyrec_getattr   s    r   c                 C   s*   g }| D ]\}}}||vr| | q|S N)append)
componentsorderkey_r   r   r   default_order   s
    r   c                 C   s"   t jt t | d td}|S )a  
    Convert value to an int or an int array.
    Input coordinates converted to integers
    corresponding to the center of the pixel.
    The convention is that the center of the pixel is
    (0, 0), while the lower left corner is (-0.5, -0.5).
    The outputs are used to index the mask.
    Examples
    --------
    >>> _toindex(np.array([-0.5, 0.49999]))
    array([0, 0])
    >>> _toindex(np.array([0.5, 1.49999]))
    array([1, 1])
    >>> _toindex(np.array([1.5, 2.49999]))
    array([2, 2])
    g      ?)Zdtype)npZasarrayZfloorint)valueZindxr   r   r   _toindex   s    r   c                   @   sN   e Zd ZdZeejdd Zejdd Zdd Z	ejdd	 Z
d
d ZdS )r   z
    Abstract base class for the high-level WCS interface.

    This is described in `APE 14: A shared Python interface for World Coordinate
    Systems <https://doi.org/10.5281/zenodo.1188875>`_.
    c                 C   s   dS )zM
        Returns a reference to the underlying low-level WCS object.
        Nr   selfr   r   r   low_level_wcs6   s    zBaseHighLevelWCS.low_level_wcsc                 G   s   dS )a  
        Convert pixel coordinates to world coordinates (represented by
        high-level objects).

        If a single high-level object is used to represent the world coordinates
        (i.e., if ``len(wcs.world_axis_object_classes) == 1``), it is returned
        as-is (not in a tuple/list), otherwise a tuple of high-level objects is
        returned. See
        `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_to_world_values` for pixel
        indexing and ordering conventions.
        Nr   )r   pixel_arraysr   r   r   pixel_to_world=   s    zBaseHighLevelWCS.pixel_to_worldc                 G   s   | j |ddd  S )a  
        Convert array indices to world coordinates (represented by Astropy
        objects).

        If a single high-level object is used to represent the world coordinates
        (i.e., if ``len(wcs.world_axis_object_classes) == 1``), it is returned
        as-is (not in a tuple/list), otherwise a tuple of high-level objects is
        returned. See
        `~astropy.wcs.wcsapi.BaseLowLevelWCS.array_index_to_world_values` for
        pixel indexing and ordering conventions.
        N)r   )r   Zindex_arraysr   r   r   array_index_to_worldK   s    z%BaseHighLevelWCS.array_index_to_worldc                 G   s   dS )a  
        Convert world coordinates (represented by Astropy objects) to pixel
        coordinates.

        If `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_n_dim` is ``1``, this
        method returns a single scalar or array, otherwise a tuple of scalars or
        arrays is returned. See
        `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_to_pixel_values` for pixel
        indexing and ordering conventions.
        Nr   r   world_objectsr   r   r   world_to_pixelY   s    zBaseHighLevelWCS.world_to_pixelc                 G   s<   | j dkrt| j| S tt| j| ddd  S dS )a  
        Convert world coordinates (represented by Astropy objects) to array
        indices.

        If `~astropy.wcs.wcsapi.BaseLowLevelWCS.pixel_n_dim` is ``1``, this
        method returns a single scalar or array, otherwise a tuple of scalars or
        arrays is returned. See
        `~astropy.wcs.wcsapi.BaseLowLevelWCS.world_to_array_index_values` for
        pixel indexing and ordering conventions. The indices should be returned
        as rounded integers.
        r   Nr    )Zpixel_n_dimr   r$   tupletolistr"   r   r   r   world_to_array_indexf   s    
z%BaseHighLevelWCS.world_to_array_indexN)__name__
__module____qualname____doc__propertyabcabstractmethodr   r   r!   r$   r'   r   r   r   r   r   .   s   

)	metaclassc              	   G   s  | j }| j}t }t|D ],}| jr:t|| dd||< q|| ||< qt|t|krptdt|t|i }d}|D ]T}g }	|	 D ] \}^}
}t
||
r|	| qt|	dkr|||	d < q|d} qq|i }|r|	 D ]\}^}
}}}t|dkr|
}n t|dkr |d }ntdddlm} t
|| |rtd	|v rf|| |d	 ||< n|| ||< q||| g|R i |||< qnt|D ]\}}|| ^}
}}}t|dkr|
}n t|dkr|d }ntd|| }t
||
s td
ddd | D ddlm} t
||r`d	|v rV||d	 ||< n|||< n||g|R i |||< qg }|D ]>\}}}t|r||||  n|t|| | q|S )aq  
    Convert the input high level object to low level values.

    This function uses the information in ``wcs.world_axis_object_classes`` and
    ``wcs.world_axis_object_components`` to convert the high level objects
    (such as `~.SkyCoord`) to low level "values" `~.Quantity` objects.

    This is used in `.HighLevelWCSMixin.world_to_pixel`, but provided as a
    separate function for use in other places where needed.

    Parameters
    ----------
    *world_objects: object
        High level coordinate objects.

    low_level_wcs: `.BaseLowLevelWCS`
        The WCS object to use to interpret the coordinates.
    FZ	constructz8Number of world inputs ({}) does not match expected ({})Tr   r   =Tuples in world_axis_object_classes should have length 3 or 4)SkyCoordframez3Expected the following order of world arguments: {}z, c                 S   s   g | ]\}}}|j qS r   )r(   ).0kr   r   r   r   
<listcomp>       z0high_level_objects_to_values.<locals>.<listcomp>)world_axis_object_classesworld_axis_object_componentsr   r   serialized_classesr   len
ValueErrorformatitems
isinstancer   Zastropy.coordinatesr2   Ztransform_to	enumeratejoinvaluescallabler   )r   r#   r:   r   classesr   Zworld_by_keyZunique_matchwZmatchesklassr   Zobjectsargskwargsrest	klass_genr2   ZikeyZworldattrr   r   r   high_level_objects_to_valuesx   s|    


"



rL   c                 G   s4  | j }| j}| jr<i }| D ]\}}t|dd||< q|}tt}tt}t|D ]^\}	\}}
}t	|
t
r~||	 || |
< qT|
t|| d kr|| d q~||	 || |
< qTg }t|D ]n}|| ^}}}}t|dkr|}nt|dkr|d }ntd||g || |R i || | q|S )a  
    Convert low level values into high level objects.

    This function uses the information in ``wcs.world_axis_object_classes`` and
    ``wcs.world_axis_object_components`` to convert low level "values"
    `~.Quantity` objects, to high level objects (such as `~.SkyCoord).

    This is used in `.HighLevelWCSMixin.pixel_to_world`, but provided as a
    separate function for use in other places where needed.

    Parameters
    ----------
    *world_values: object
        Low level, "values" representations of the world coordinates.

    low_level_wcs: `.BaseLowLevelWCS`
        The WCS object to use to interpret the coordinates.
    Fr0   r   Nr   r1   )r9   r8   r:   r>   r   r   listdictr@   r?   strr;   r   r   r<   )r   world_valuesr   rD   Zclasses_newr   r   rG   rH   irK   r   resultrF   ZarkwrI   rJ   r   r   r   values_to_high_level_objects   s2    

,rT   c                   @   s,   e Zd ZdZedd Zdd Zdd ZdS )	r   z
    Mix-in class that automatically provides the high-level WCS API for the
    low-level WCS object given by the `~HighLevelWCSMixin.low_level_wcs`
    property.
    c                 C   s   | S r   r   r   r   r   r   r   /  s    zHighLevelWCSMixin.low_level_wcsc                 G   s    t |d| ji}| jj| }|S )Nr   )rL   r   Zworld_to_pixel_values)r   r#   rP   pixel_valuesr   r   r   r$   3  s    z HighLevelWCSMixin.world_to_pixelc                 G   sH   | j j| }| jdkr|f}t|d| j i}t|dkr@|d S |S d S )Nr   r   r   )r   Zpixel_to_world_valuesZworld_n_dimrT   r;   )r   r   rP   rU   r   r   r   r   <  s    
z HighLevelWCSMixin.pixel_to_worldN)r(   r)   r*   r+   r,   r   r$   r   r   r   r   r   r   (  s
   
	)r-   collectionsr   r   Znumpyr   Zutilsr   __all__r   r   r   ABCMetar   rL   rT   r   r   r   r   r   <module>   s   Jx8