U
    e»{j*  ã                   @   s²   d dl Zd dlmZmZ ddgZG dd„ deƒZG dd„ deƒZdd	„ Z	d
d„ Z
dd„ Zdd„ Zd#dd„Zdd„ Zdd„ Zdd„ Zdd„ Zd$dd„Zd%dd„Zdd „ Zd!d"„ ZdS )&é    N)ÚModelÚcustom_modelÚdiscretize_modelÚKernelSizeErrorc                   @   s   e Zd ZdZdS )ÚDiscretizationErrorz:
    Called when discretization of models goes wrong.
    N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   úX/var/www/html/bwave/python/venv/lib/python3.8/site-packages/astropy/convolution/utils.pyr   	   s   r   c                   @   s   e Zd ZdZdS )r   z.
    Called when size of kernels is even.
    Nr   r   r   r   r   r      s   c                 C   s4   t | ttfƒrt| ƒd  S tdd„ | jD ƒƒS d S )Né   c                 s   s   | ]}|d   V  qdS )r   Nr   ©Ú.0Z	axes_sizer   r   r   Ú	<genexpr>   s     z has_even_axis.<locals>.<genexpr>)Ú
isinstanceÚlistÚtupleÚlenÚanyÚshape)Úarrayr   r   r   Úhas_even_axis   s    r   c                   C   s   t dƒ‚d S )Nz$Kernel size must be odd in all axes.)r   r   r   r   r   Úraise_even_kernel_exception   s    r   c                 C   s°   | j |j krT|  ¡ }| j d }t||j d  ||j d  d ƒ}||  |7  < |S |j | j kr¨| ¡ }|j d }t|| j d  || j d  d ƒ}||  | 7  < |S ||  S )zw
    Add two 1D kernel arrays of different size.

    The arrays are added with the centers lying upon each other.
    r   é   )ÚsizeÚcopyÚslice)Úarray_1Úarray_2Ú	new_arrayÚcenterZslice_r   r   r   Úadd_kernel_arrays_1D    s    
"
"r#   c                 C   sJ  | j |j kr |  ¡ }dd„ | jD ƒ}t|d |jd d  |d |jd d  d ƒ}t|d |jd d  |d |jd d  d ƒ}|||f  |7  < |S |j | j k�rB| ¡ }dd„ |jD ƒ}t|d | jd d  |d | jd d  d ƒ}t|d | jd d  |d | jd d  d ƒ}|||f  | 7  < |S ||  S )zw
    Add two 2D kernel arrays of different size.

    The arrays are added with the centers lying upon each other.
    c                 S   s   g | ]}|d  ‘qS ©r   r   r   r   r   r   Ú
<listcomp>=   s     z(add_kernel_arrays_2D.<locals>.<listcomp>r   r   r   c                 S   s   g | ]}|d  ‘qS r$   r   r   r   r   r   r%   H   s     )r   r   r   r   )r   r    r!   r"   Zslice_xZslice_yr   r   r   Úadd_kernel_arrays_2D5   s6     ÿ ÿ ÿ ÿr&   r"   é
   c                 C   s‚  t | ƒstdƒ‚t| tƒs$t| ƒƒ } | j}|dkr:tdƒ‚tt 	|¡ƒ 
¡ sTtdƒ‚|rrtt 	|¡ƒ 
¡ srtdƒ‚|dkrŠ|dkrŠtdƒ‚|dkr¢|dk	r¢td	ƒ‚|d
krÒ|dkr¼t| |ƒS |dkrÐt| ||ƒS n¬|dk�r|dkrît| |ƒS |dk�r~t| ||ƒS nx|dk�r@|dk�r&t| ||ƒS |dk�r~t| |||ƒS n>|dk�rv|dk�r^t| |ƒS |dk�r~t| ||ƒS ntdƒ‚dS )aº
  
    Function to evaluate analytical model functions on a grid.

    So far the function can only deal with pixel coordinates.

    Parameters
    ----------
    model : `~astropy.modeling.Model` or callable.
        Analytic model function to be discretized. Callables, which are not an
        instances of `~astropy.modeling.Model` are passed to
        `~astropy.modeling.custom_model` and then evaluated.
    x_range : tuple
        x range in which the model is evaluated. The difference between the
        upper an lower limit must be a whole number, so that the output array
        size is well defined.
    y_range : tuple, optional
        y range in which the model is evaluated. The difference between the
        upper an lower limit must be a whole number, so that the output array
        size is well defined. Necessary only for 2D models.
    mode : str, optional
        One of the following modes:
            * ``'center'`` (default)
                Discretize model by taking the value
                at the center of the bin.
            * ``'linear_interp'``
                Discretize model by linearly interpolating
                between the values at the corners of the bin.
                For 2D models interpolation is bilinear.
            * ``'oversample'``
                Discretize model by taking the average
                on an oversampled grid.
            * ``'integrate'``
                Discretize model by integrating the model
                over the bin using `scipy.integrate.quad`.
                Very slow.
    factor : float or int
        Factor of oversampling. Default = 10.

    Returns
    -------
    array : `numpy.array`
        Model value array

    Notes
    -----
    The ``oversample`` mode allows to conserve the integral on a subpixel
    scale. Here is the example of a normalized Gaussian1D:

    .. plot::
        :include-source:

        import matplotlib.pyplot as plt
        import numpy as np
        from astropy.modeling.models import Gaussian1D
        from astropy.convolution.utils import discretize_model
        gauss_1D = Gaussian1D(1 / (0.5 * np.sqrt(2 * np.pi)), 0, 0.5)
        y_center = discretize_model(gauss_1D, (-2, 3), mode='center')
        y_corner = discretize_model(gauss_1D, (-2, 3), mode='linear_interp')
        y_oversample = discretize_model(gauss_1D, (-2, 3), mode='oversample')
        plt.plot(y_center, label='center sum = {0:3f}'.format(y_center.sum()))
        plt.plot(y_corner, label='linear_interp sum = {0:3f}'.format(y_corner.sum()))
        plt.plot(y_oversample, label='oversample sum = {0:3f}'.format(y_oversample.sum()))
        plt.xlabel('pixels')
        plt.ylabel('value')
        plt.legend()
        plt.show()


    zModel must be callable.r   z2discretize_model only supports 1-d and 2-d models.zUThe difference between the upper and lower limit of 'x_range' must be a whole number.zUThe difference between the upper and lower limit of 'y_range' must be a whole number.Nz'y range not specified, but model is 2-dr   z)y range specified, but model is only 1-d.r"   Zlinear_interpZ
oversampleZ	integratezInvalid mode.)ÚcallableÚ	TypeErrorr   r   r   Zn_inputsÚ
ValueErrorÚfloatÚnpÚdiffÚ
is_integerÚdiscretize_center_1DÚdiscretize_center_2DÚdiscretize_linear_1DÚdiscretize_bilinear_2DÚdiscretize_oversample_1DÚdiscretize_oversample_2DÚdiscretize_integrate_1DÚdiscretize_integrate_2Dr   )ÚmodelÚx_rangeÚy_rangeÚmodeÚfactorÚndimr   r   r   r   T   sR    F

ÿÿ










c                 C   s   t j|Ž }| |ƒS )zH
    Discretize model by taking the value at the center of the bin.
    ©r,   Úarange)r7   r8   Úxr   r   r   r/   Ë   s    
r/   c                 C   s.   t j|Ž }t j|Ž }t  ||¡\}}| ||ƒS )zJ
    Discretize model by taking the value at the center of the pixel.
    ©r,   r>   Úmeshgrid)r7   r8   r9   r?   Úyr   r   r   r0   Ó   s    

r0   c                 C   s@   t  |d d |d d ¡}| |ƒ}d|dd… |dd…   S )z@
    Discretize model by performing a linear interpolation.
    r   ç      à?r   Néÿÿÿÿr=   )r7   r8   r?   Úvalues_intermediate_gridr   r   r   r1   Ý   s    r1   c                 C   s®   t  |d d |d d ¡}t  |d d |d d ¡}t  ||¡\}}| ||ƒ}d|dd…dd…f |dd…dd…f   }d|dd…dd…f |dd…dd…f   }|S )zB
    Discretize model by performing a bilinear interpolation.
    r   rC   r   NrD   r@   )r7   r8   r9   r?   rB   rE   Úvaluesr   r   r   r2   ç   s    
,,r2   c                 C   sv   t j|d ddd|    |d ddd|    t|d |d  | ƒd�}| |ƒ}t  ||j| |f¡}|jdd�S )úH
    Discretize model by taking the average on an oversampled grid.
    r   rC   r   ©Únum©Zaxis)r,   ÚlinspaceÚintÚreshaper   Úmean)r7   r8   r;   r?   rF   r   r   r   r3   ø   s    ýr3   c           
      C   sê   t j|d ddd|    |d ddd|    t|d |d  | ƒd�}t j|d ddd|    |d ddd|    t|d |d  | ƒd�}t  ||¡\}}| ||ƒ}|j| ||j| |f}	t  ||	¡}|jdd�jdd�S )rG   r   rC   r   rH   é   rJ   )r,   rK   rL   rA   r   rM   rN   )
r7   r8   r9   r;   r?   rB   Zx_gridZy_gridrF   r   r   r   r   r4   
  s    ýý
r4   c              
   C   sn   ddl m} t |d d |d d ¡}t g ¡}t|jd ƒD ](}t ||| || ||d  ƒd ¡}q@|S )zM
    Discretize model by integrating numerically the model over the bin.
    r   )ÚquadrC   r   )Úscipy.integraterP   r,   r>   r   Úranger   Úappend)r7   r8   rP   r?   rF   Úir   r   r   r5   #  s    
&r5   c              
      sÐ   ddl m} t |d d |d d ¡}t |d d |d d ¡‰t ˆjd |jd f¡}t|jd ƒD ]^}tˆjd ƒD ]J‰ |‡fdd„|| ||d  ‡ ‡fdd„‡ ‡fdd„d	�d |ˆ |f< q~ql|S )
zC
    Discretize model by integrating the model over the pixel.
    r   )ÚdblquadrC   r   c                    s
   ˆ || ƒS ©Nr   )rB   r?   )r7   r   r   Ú<lambda>B  ó    z)discretize_integrate_2D.<locals>.<lambda>c                    s   ˆˆ  S rV   r   ©r?   ©ÚjrB   r   r   rW   E  rX   c                    s   ˆˆ d  S )Nr   r   rY   rZ   r   r   rW   F  rX   )ÚfuncÚaÚbZgfunZhfun)rQ   rU   r,   r>   Úemptyr   rR   )r7   r8   r9   rU   r?   rF   rT   r   )r[   r7   rB   r   r6   3  s     

ûúr6   )Nr"   r'   )r'   )r'   )Únumpyr,   Zastropy.modeling.corer   r   Ú__all__Ú	Exceptionr   r   r   r   r#   r&   r   r/   r0   r1   r2   r3   r4   r5   r6   r   r   r   r   Ú<module>   s"   
w



