
    HR-e .                         d dl Zd dlmZmZ ddgZ G d de          Z G d de          Zd Z	d	 Z
d
 Zd ZddZd Zd Zd Zd ZddZddZd Zd ZdS )    N)Modelcustom_modeldiscretize_modelKernelSizeErrorc                       e Zd ZdZdS )DiscretizationErrorz:
    Called when discretization of models goes wrong.
    N__name__
__module____qualname____doc__     9lib/python3.11/site-packages/astropy/convolution/utils.pyr   r   	              r   r   c                       e Zd ZdZdS )r   z.
    Called when size of kernels is even.
    Nr	   r   r   r   r   r      r   r   c                     t          | t          t          f          rt          |           dz   S t	          d | j        D                       S )N   c              3   "   K   | ]
}|d z   V  dS )r   Nr   .0	axes_sizes     r   	<genexpr>z has_even_axis.<locals>.<genexpr>   s)      BBy1}$BBBBBBr   )
isinstancelisttuplelenanyshape)arrays    r   has_even_axisr!      sK    %$'' Cu::>!!BBekBBBBBBr   c                       t          d          )Nz$Kernel size must be odd in all axes.)r   r   r   r   raise_even_kernel_exceptionr#      s    
@
A
AAr   c                    | j         |j         k    rY|                                 }| j         dz  }t          ||j         dz  z
  ||j         dz  z   dz             }||xx         |z  cc<   |S |j         | j         k    rY|                                }|j         dz  }t          || j         dz  z
  || j         dz  z   dz             }||xx         | z  cc<   |S || z   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centerslice_s        r   add_kernel_arrays_1Dr.       s     |gl""LLNN	"v 116GLA<M3MPQ3QRR&W$		$	$LLNN	"v 116GLA<M3MPQ3QRR&W$Wr   c                 8   | j         |j         k    r|                                 }d | j        D             }t          |d         |j        d         dz  z
  |d         |j        d         dz  z   dz             }t          |d         |j        d         dz  z
  |d         |j        d         dz  z   dz             }|||fxx         |z  cc<   |S |j         | j         k    r|                                }d |j        D             }t          |d         | j        d         dz  z
  |d         | j        d         dz  z   dz             }t          |d         | j        d         dz  z
  |d         | j        d         dz  z   dz             }|||fxx         | z  cc<   |S || z   S )zw
    Add two 2D kernel arrays of different size.

    The arrays are added with the centers lying upon each other.
    c                     g | ]}|d z  S r   r   r   s     r   
<listcomp>z(add_kernel_arrays_2D.<locals>.<listcomp>=       @@@Y)q.@@@r   r%   r   r   c                     g | ]}|d z  S r1   r   r   s     r   r2   z(add_kernel_arrays_2D.<locals>.<listcomp>H   r3   r   )r&   r'   r   r(   )r)   r*   r+   r,   slice_xslice_ys         r   add_kernel_arrays_2Dr7   5   s    |gl""LLNN	@@'-@@@1Ia(A--vay7=;Kq;P/PST/T
 
 1Ia(A--vay7=;Kq;P/PST/T
 
 	'7"###w.###		$	$LLNN	@@'-@@@1Ia(A--vay7=;Kq;P/PST/T
 
 1Ia(A--vay7=;Kq;P/PST/T
 
 	'7"###w.###Wr   r,   
   c                    t          |           st          d          t          | t                    s t	          |                       } | j        }|dk    rt          d          t          j        |          d         }|t          |          k    rt          d          |r<t          j        |          d         }|t          |          k    rt          d          |dk    r|t          d          |d	k    r|t          d
          |dk    r/|d	k    rt          | |          S |dk    rt          | ||          S dS |dk    r/|d	k    rt          | |          S |dk    rt          | ||          S dS |dk    r1|d	k    rt          | ||          S |dk    rt          | |||          S dS |dk    r/|d	k    rt!          | |          S |dk    rt#          | ||          S dS t%          d          )a  
    Evaluate an analytical model function on a pixel grid.

    Parameters
    ----------
    model : `~astropy.modeling.Model` or callable.
        Analytical model function to be discretized. A callable that is
        not a `~astropy.modeling.Model` instance is converted to a model
        using `~astropy.modeling.custom_model`.
    x_range : 2-tuple
        Lower and upper bounds of x pixel values at which the model is
        evaluated. The upper bound is non-inclusive. A ``x_range`` of
        ``(0, 3)`` means the model will be evaluated at x pixels 0, 1,
        and 2. The difference between the upper and lower bound must be
        a whole number so that the output array size is well defined.
    y_range : 2-tuple or `None`, optional
        Lower and upper bounds of y pixel values at which the model is
        evaluated. The upper bound is non-inclusive. A ``y_range`` of
        ``(0, 3)`` means the model will be evaluated at y pixels of 0,
        1, and 2. The difference between the upper and lower bound must
        be a whole number so that the output array size is well defined.
        ``y_range`` is necessary only for 2D models.
    mode : {'center', 'linear_interp', 'oversample', 'integrate'}, optional
        One of the following modes:
            * ``'center'`` (default)
                Discretize model by taking the value at the center of
                the pixel bins.
            * ``'linear_interp'``
                Discretize model by linearly interpolating between the
                values at the edges (1D) or corners (2D) of the pixel
                bins. For 2D models, the interpolation is bilinear.
            * ``'oversample'``
                Discretize model by taking the average of model values
                on an oversampled grid.
            * ``'integrate'``
                Discretize model by integrating the model over the pixel
                bins using `scipy.integrate.quad`. This mode conserves
                the model integral on a subpixel scale, but is very
                slow.
    factor : int, optional
        The oversampling factor used when ``mode='oversample'``. Ignored
        otherwise.

    Returns
    -------
    array : `numpy.ndarray`
        The discretized model array.

    Examples
    --------
    In this example, we define a
    `~astropy.modeling.functional_models.Gaussian1D` model that has been
    normalized so that it sums to 1.0. We then discretize this model
    using the ``'center'``, ``'linear_interp'``, and ``'oversample'``
    (with ``factor=10``) modes.

    .. plot::
        :show-source-link:

        import matplotlib.pyplot as plt
        import numpy as np
        from astropy.convolution.utils import discretize_model
        from astropy.modeling.models import Gaussian1D

        gauss_1D = Gaussian1D(1 / (0.5 * np.sqrt(2 * np.pi)), 0, 0.5)
        x_range = (-2, 3)
        x = np.arange(*x_range)
        y_center = discretize_model(gauss_1D, x_range, mode='center')
        y_edge = discretize_model(gauss_1D, x_range, mode='linear_interp')
        y_oversample = discretize_model(gauss_1D, x_range, mode='oversample')

        fig, ax = plt.subplots(figsize=(8, 6))
        label = f'center (sum={y_center.sum():.3f})'
        ax.plot(x, y_center, '.-', label=label)
        label = f'linear_interp (sum={y_edge.sum():.3f})'
        ax.plot(x, y_edge, '.-', label=label)
        label = f'oversample (sum={y_oversample.sum():.3f})'
        ax.plot(x, y_oversample, '.-', label=label)
        ax.set_xlabel('x')
        ax.set_ylabel('Value')
        plt.legend()
    zModel must be callable.r   z0discretize_model supports only 1D and 2D models.r   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 must be specified for a 2D modelr%   z*y_range should not be input for a 1D modelr,   linear_interp
oversample	integratezInvalid mode.)callable	TypeErrorr   r   r   n_inputs
ValueErrornpdiffint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ndimdxrangedyranges           r   r   r   T   sQ   f E?? 31222eU## &#U##%%>DaxxKLLLggq!G#g,,1
 
 	

  ''""1%c'll""5  
 qyyW_CDDDqyyW(EFFFx199'w777QYY'w@@@ Y		 	 199'w777199)%'BBB 9			199+E7FCCC199+E7GVLLL 9			199*5':::199*5'7CCC 9 "/222r   c                 4    t          j        | } | |          S )zH
    Discretize model by taking the value at the center of the bin.
    rA   arange)rL   rM   xs      r   rD   rD      s     		7A588Or   c                     t          j        | }t          j        | }t          j        ||          \  }} | ||          S )zJ
    Discretize model by taking the value at the center of the pixel.
    rA   rV   meshgrid)rL   rM   rN   rW   ys        r   rE   rE      sA     		7A
	7A;q!DAq5A;;r   c                     t          j        |d         dz
  |d         dz             } | |          }d|dd         |dd         z   z  S )z@
    Discretize model by performing a linear interpolation.
    r         ?r%   NrU   )rL   rM   rW   values_intermediate_grids       r   rF   rF      sY    
 		'!*s"GAJ$455A$uQxx*122.1I#2#1NNOOr   c                 j   t          j        |d         dz
  |d         dz             }t          j        |d         dz
  |d         dz             }t          j        ||          \  }} | ||          }d|ddddf         |ddddf         z   z  }d|ddddf         |ddddf         z   z  }|S )zB
    Discretize model by performing a bilinear interpolation.
    r   r]   r%   Nr^   rY   )rL   rM   rN   rW   r[   r_   valuess          r   rG   rG      s    
 		'!*s"GAJ$455A
	'!*s"GAJ$455A;q!DAq$uQ{{ ,QRRU36NsPRsTUTUTUv6VVWFF111abb5MF111crc6N23FMr   c           	      6   t          j        |d         ddd|z  z
  z  z
  |d         ddd|z  z   z  z
  t          |d         |d         z
  |z                      } | |          }t          j        ||j        |z  |f          }|                    d          S )H
    Discretize model by taking the average on an oversampled grid.
    r   r]   r%   numaxis)rA   linspacerC   reshaper&   mean)rL   rM   rP   rW   ra   s        r   rH   rH     s    
 	
SAF
N++
SAF
N++gaj(F233	 	 	A U1XXF Z6!16 :;;F;;A;r   c           	      \   t          j        |d         ddd|z  z
  z  z
  |d         ddd|z  z   z  z
  t          |d         |d         z
  |z                      }t          j        |d         ddd|z  z
  z  z
  |d         ddd|z  z   z  z
  t          |d         |d         z
  |z                      }t          j        ||          \  }} | ||          }|j        |z  ||j        |z  |f}	t          j        ||	          }|                    d                              d          S )rc   r   r]   r%   rd      rf   )rA   rh   rC   rZ   r&   ri   rj   )
rL   rM   rN   rP   rW   r[   x_gridy_gridra   r   s
             r   rI   rI     sL   
 	
SAF
N++
SAF
N++gaj(F233	 	 	A
 	
SAF
N++
SAF
N++gaj(F233	 	 	A [A&&NFFU66""F Vvvqv'7@EZ&&F;;A;###+++r   c                 &   ddl m} t          j        |d         dz
  |d         dz             }t          j        g           }t          |j        dz
            D ]7}t          j        | || ||         ||dz                      d                   }8|S )zM
    Discretize model by integrating numerically the model over the bin.
    r   )quadr]   r%   )scipy.integraterp   rA   rV   r    ranger&   append)rL   rM   rp   rW   ra   is         r   rJ   rJ   2  s     %$$$$$ 		'!*s"GAJ$455AXb\\F 16A: C C644qtQq1uX#>#>q#ABBMr   c           
          ddl m} t          j        |d         dz
  |d         dz             }t          j        |d         dz
  |d         dz             t          j        j        dz
  |j        dz
  f          }t          |j        dz
            D ]Q}t          j        dz
            D ]7 | fd||         ||dz            fdfd          d         ||f<   8R|S )	zC
    Discretize model by integrating the model over the pixel.
    r   )dblquadr]   r%   c                      ||           S Nr   )r[   rW   rL   s     r   <lambda>z)discretize_integrate_2D.<locals>.<lambda>Q  s    %%1++ r   c                              S rx   r   rW   jr[   s    r   ry   z)discretize_integrate_2D.<locals>.<lambda>T  s    qt r   c                     dz            S )Nr%   r   r{   s    r   ry   z)discretize_integrate_2D.<locals>.<lambda>U  s    qQx r   )funcabgfunhfun)rq   rv   rA   rV   emptyr&   rr   )	rL   rM   rN   rv   rW   ra   rt   r|   r[   s	   `      @@r   rK   rK   B  s+    (''''' 		'!*s"GAJ$455A
	'!*s"GAJ$455AXqvz16A:.//F 16A:  qvz"" 	 	A"7----A$AE(#^^^^'''''   F1a4LL	 Mr   )Nr,   r8   )r8   )numpyrA   astropy.modeling.corer   r   __all__	Exceptionr   r   r!   r#   r.   r7   r   rD   rE   rF   rG   rH   rI   rJ   rK   r   r   r   <module>r      sr       5 5 5 5 5 5 5 50
1    )       i   C C CB B B  *  >C3 C3 C3 C3L    P P P  "   $, , , ,2       r   