a
    ߙfb                     @   s   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 erpd dlZg d	Zd
d Zd!ddZd"ddZd#ddZd$ddZG dd dZd%ddZd&dd ZdS )'    N)normalize_axis_index)Quantity)
isiterable)AstropyUserWarning)_sigma_clip_fastmad_std)HAS_BOTTLENECK)	SigmaClip
sigma_clipsigma_clipped_statsc                    s`   t  } t fddt| jD 7  tt| j}t|  |}|d|j|d  }|S )z
    Bottleneck can only take integer axis, not tuple, so this function
    takes all the axes to be operated on and combines them into the
    first dimension of the array so that we can then use axis=0.
    c                 3   s   | ]}| vr|V  qd S N ).0iaxisr   ;lib/python3.9/site-packages/astropy/stats/sigma_clipping.py	<genexpr>        z)_move_tuple_axes_first.<locals>.<genexpr>N)lentuplerangendimnpZmoveaxisreshapeshape)arrayr   ZnaxisZdestinationZ	array_newr   r   r   _move_tuple_axes_first   s     r    c                 C   sJ   t |trt| |d} d}t | tr8| tj| |dS tj| |dS dS )z3Bottleneck nanmean function that handle tuple axis.r   r   N)
isinstancer   r    r   __array_wrap__
bottlenecknanmeanr   r   r   r   r   _nanmean0   s    

r&   c                 C   sJ   t |trt| |d} d}t | tr8| tj| |dS tj| |dS dS )z5Bottleneck nanmedian function that handle tuple axis.r   r   N)r!   r   r    r   r"   r#   	nanmedianr%   r   r   r   
_nanmedian=   s    

r(   c                 C   sN   t |trt| |d} d}t | tr:| tj| ||dS tj| ||dS dS )z2Bottleneck nanstd function that handle tuple axis.r   r   )r   ddofN)r!   r   r    r   r"   r#   nanstd)r   r   r)   r   r   r   _nanstdJ   s    

r+   c                 C   s   t | |ddS )z.mad_std function that ignores NaNs by default.T)r   Z
ignore_nanr   r%   r   r   r   
_nanmadstdX   s    r,   c                   @   st   e Zd ZdZddd	Zd
d Zdd Zedd Zedd Z	dddZ
dddZd ddZd!ddZd"ddZdS )#r
   a<  
    Class to perform sigma clipping.

    The data will be iterated over, each time rejecting values that are
    less or more than a specified number of standard deviations from a
    center value.

    Clipped (rejected) pixels are those where::

        data < center - (sigma_lower * std)
        data > center + (sigma_upper * std)

    where::

        center = cenfunc(data [, axis=])
        std = stdfunc(data [, axis=])

    Invalid data values (i.e., NaN or inf) are automatically clipped.

    For a functional interface to sigma clipping, see
    :func:`sigma_clip`.

    .. note::
        `scipy.stats.sigmaclip` provides a subset of the functionality
        in this class. Also, its input data cannot be a masked array
        and it does not handle data that contains invalid values (i.e.,
        NaN or inf). Also note that it uses the mean as the centering
        function. The equivalent settings to `scipy.stats.sigmaclip`
        are::

            sigclip = SigmaClip(sigma=4., cenfunc='mean', maxiters=None)
            sigclip(data, axis=None, masked=False, return_bounds=True)

    Parameters
    ----------
    sigma : float, optional
        The number of standard deviations to use for both the lower
        and upper clipping limit. These limits are overridden by
        ``sigma_lower`` and ``sigma_upper``, if input. The default is 3.

    sigma_lower : float or None, optional
        The number of standard deviations to use as the lower bound for
        the clipping limit. If `None` then the value of ``sigma`` is
        used. The default is `None`.

    sigma_upper : float or None, optional
        The number of standard deviations to use as the upper bound for
        the clipping limit. If `None` then the value of ``sigma`` is
        used. The default is `None`.

    maxiters : int or None, optional
        The maximum number of sigma-clipping iterations to perform or
        `None` to clip until convergence is achieved (i.e., iterate
        until the last iteration clips nothing). If convergence is
        achieved prior to ``maxiters`` iterations, the clipping
        iterations will stop. The default is 5.

    cenfunc : {'median', 'mean'} or callable, optional
        The statistic or callable function/object used to compute
        the center value for the clipping. If using a callable
        function/object and the ``axis`` keyword is used, then it must
        be able to ignore NaNs (e.g., `numpy.nanmean`) and it must have
        an ``axis`` keyword to return an array with axis dimension(s)
        removed. The default is ``'median'``.

    stdfunc : {'std', 'mad_std'} or callable, optional
        The statistic or callable function/object used to compute the
        standard deviation about the center value. If using a callable
        function/object and the ``axis`` keyword is used, then it must
        be able to ignore NaNs (e.g., `numpy.nanstd`) and it must have
        an ``axis`` keyword to return an array with axis dimension(s)
        removed. The default is ``'std'``.

    grow : float or `False`, optional
        Radius within which to mask the neighbouring pixels of those
        that fall outwith the clipping limits (only applied along
        ``axis``, if specified). As an example, for a 2D image a value
        of 1 will mask the nearest pixels in a cross pattern around each
        deviant pixel, while 1.5 will also reject the nearest diagonal
        neighbours and so on.

    See Also
    --------
    sigma_clip, sigma_clipped_stats

    Notes
    -----
    The best performance will typically be obtained by setting
    ``cenfunc`` and ``stdfunc`` to one of the built-in functions
    specified as as string. If one of the options is set to a string
    while the other has a custom callable, you may in some cases see
    better performance if you have the `bottleneck`_ package installed.

    .. _bottleneck:  https://github.com/pydata/bottleneck

    Examples
    --------
    This example uses a data array of random variates from a Gaussian
    distribution. We clip all points that are more than 2 sample
    standard deviations from the median. The result is a masked array,
    where the mask is `True` for clipped data::

        >>> from astropy.stats import SigmaClip
        >>> from numpy.random import randn
        >>> randvar = randn(10000)
        >>> sigclip = SigmaClip(sigma=2, maxiters=5)
        >>> filtered_data = sigclip(randvar)

    This example clips all points that are more than 3 sigma relative
    to the sample *mean*, clips until convergence, returns an unmasked
    `~numpy.ndarray`, and modifies the data in-place::

        >>> from astropy.stats import SigmaClip
        >>> from numpy.random import randn
        >>> from numpy import mean
        >>> randvar = randn(10000)
        >>> sigclip = SigmaClip(sigma=3, maxiters=None, cenfunc='mean')
        >>> filtered_data = sigclip(randvar, masked=False, copy=False)

    This example sigma clips along one axis::

        >>> from astropy.stats import SigmaClip
        >>> from numpy.random import normal
        >>> from numpy import arange, diag, ones
        >>> data = arange(5) + normal(0., 0.05, (5, 5)) + diag(ones(5))
        >>> sigclip = SigmaClip(sigma=2.3)
        >>> filtered_data = sigclip(data, axis=0)

    Note that along the other axis, no points would be clipped, as the
    standard deviation is higher.
          @N   medianstdFc           	      C   s   || _ |p|| _|p|| _|p"tj| _|| _|| _| || _	| 
|| _tj| _tj| _d| _|| _| jr~ddlm} || _d S )Nr   )binary_dilation)sigmasigma_lowersigma_upperr   infmaxiterscenfuncstdfunc_parse_cenfunc_cenfunc_parsed_parse_stdfunc_stdfunc_parsednan
_min_value
_max_value_niterationsgrowZscipy.ndimager1   _binary_dilation)	selfr2   r3   r4   r6   r7   r8   rA   r1   r   r   r   __init__   s    

zSigmaClip.__init__c              	   C   s,   d | j| j| j| jt| jt| j| jS )NzaSigmaClip(sigma={}, sigma_lower={}, sigma_upper={}, maxiters={}, cenfunc={}, stdfunc={}, grow={}))	formatr2   r3   r4   r6   reprr7   r8   rA   )rC   r   r   r   __repr__   s
    zSigmaClip.__repr__c              
   C   sN   d| j j d g}g d}|D ]$}|d| dtt| |  qd|S )N<>r2   r3   r4   r6   r7   r8   rA   z    z: 
)	__class____name__appendrF   getattrjoin)rC   linesattrsattrr   r   r   __str__   s
    "zSigmaClip.__str__c                 C   sP   t | trL| dkr$trt} qLtj} n(| dkr>tr6t} qLtj} nt|  d| S )Nr/   meanz is an invalid cenfunc.)	r!   strr	   r(   r   r'   r&   r$   
ValueError)r7   r   r   r   r9     s    
zSigmaClip._parse_cenfuncc                 C   sD   t | tr@| dkr$trt} q@tj} n| dkr2t} nt|  d| S )Nr0   r   z is an invalid stdfunc.)r!   rV   r	   r+   r   r*   r,   rW   )r8   r   r   r   r;     s    
zSigmaClip._parse_stdfuncc                 C   s~   t  b t jdtd | j||d| _| j||d}| j|| j  | _|  j|| j	 7  _W d    n1 sp0    Y  d S )Nignore)categoryr   )
warningscatch_warningssimplefilterRuntimeWarningr:   r?   r<   r3   r>   r4   )rC   datar   r0   r   r   r   _compute_bounds)  s    
zSigmaClip._compute_boundsTc              
      s  t trjj }nd}|du rB|du rBjjdkrBtd du rfjdkrXdntt	j t
 st j }d}njtfdd D  t fd	dt	jD   }	|	j}|	|djt   d
 }d |jjdks
|jjdkr|t}t| }
t|
r8tdt t |tjjr||
|jO }
tj|tj}t|
|j }
t ||
| j!dk| j"dkt#| j$rdn| j$| j%| j& d\}}tj'dd8 |
|t(| k O }
|
|t(| kO }
W d   n1 s0    Y  |durH|
|}
|
tfddt	jD }
|rbtjj)|
|d}n$|rxjtdd}n}tj*||
< |dur||> }||> }||> }|r|||fS |S dS )z=
        Fast C implementation for simple use cases.
        NFfzacannot mask non-floating-point array with NaN values, set copy=True or masked=True to avoid this.   r   c                 3   s   | ]}t | jV  qd S r   )r   r   r   Zax)r^   r   r   r   N  r   z,SigmaClip._sigmaclip_fast.<locals>.<genexpr>c                 3   s   | ]}| vr|V  qd S r   r   rb   r   r   r   r   O  s   r      TInput data contains invalid values (NaNs or infs), which were automatically clipped.r/   r   r   rX   Zinvalidc                 3   s   | ]}  |V  qd S r   )indexrb   )transposed_axesr   r   r   s  s   )maskcopyTri   )+r!   r   valueunitZdtypekind	Exceptionr   r   r   r   r   Z	transposer   r   r   itemsizeastypefloatr   isfiniteanyrZ   warnr   maMaskedArrayrh   ZviewZndarrayZbroadcast_tori   r   r7   r8   Zisinfr6   r3   r4   errstateZexpand_dimsr   r=   )rC   r^   r   maskedreturn_boundsri   rl   Zdata_reshapedZtransposed_shapeZdata_transposedrh   Zbound_loZbound_hiresultr   )r   r^   rg   r   _sigmaclip_fast3  sx    





4





zSigmaClip._sigmaclip_fastc           
      C   s0  |  }t|tjjr$|j|j  }t|}t| rN|| }t	
dt d}d}|dkr|| jk r|d7 }|j}	| j|dd ||| jk|| jk@  }|	|j }qV|| _|rtjj||d}tjdd2 | jt|| jk || jkO  _W d   n1 s
0    Y  |r(|| j| jfS |S dS )	z
        Sigma clip when ``axis`` is None and ``grow`` is not >0.

        In this simple case, we remove clipped elements from the
        flattened array during each iteration.
        rd   ra   r   Nr   rj   rX   re   )Zravelr!   r   ru   rv   r^   rh   rr   rs   rZ   rt   r   r6   sizer_   r>   r?   r@   masked_invalidrw   
logical_or)
rC   r^   rx   ry   ri   filtered_dataZ	good_masknchanged	iterationr|   r   r   r   _sigmaclip_noaxis  s>    
(zSigmaClip._sigmaclip_noaxisc                    s  | tt }t|r6tj|< tdt t	tj
jrbtj
 ttj durt sx f tfdd D  t fddtjD }| jr2t| jd d }tjtd|f|j  }	 durt|	D ]\}
}|
 vr|||k< qtfd	d|	D | jd k}~	d}d}|dkr || jk r |d7 }| j d
 t| js| j|| _| j|| _tjdd$ | jk | jkB }W d   n1 s0    Y  | jr| ||}tj|< t |}~q:|| _!|r|r.tj
j|t ddndtjddF tj
j|dd}tj
j"t#|| jk || jk|ddW d   n1 s0    Y  |r| j| jfS S dS )z
        Sigma clip the data when ``axis`` or ``grow`` is specified.

        In this case, we replace clipped values with NaNs as placeholder
        values.
        rd   Nc                 3   s$   | ]}|d k r j | n|V  qdS )r   N)r   )r   n)r   r   r   r     r   z0SigmaClip._sigmaclip_withaxis.<locals>.<genexpr>c                 3   s"   | ]\}}| v rd n|V  qdS )ra   Nr   )r   dimr|   r   r   r   r     s      ra   r   c                 3   s   | ]}|  d  V  qdS )r   Nr   )r   idx)cenidxr   r   r     r   r   rX   re   Trj   F)$rp   rq   r   rr   rs   r=   rZ   rt   r   r!   ru   rv   r}   Zfilledr   r   	enumerater   rA   intZmgridslicer   sumr6   r_   Zisscalarr>   r   r?   rw   rB   Zcount_nonzeror@   Zmasked_wherer~   )rC   r^   r   rx   ry   ri   Zbad_maskZmshaper|   indicesr   r   Zkernelr   r   Znew_maskoutr   )r   r   r   r   _sigmaclip_withaxis  s~    	




$



&zSigmaClip._sigmaclip_withaxisc                 C   s   t |}|jdkr@|r&t j|}n|}|r<|| j| jfS |S t|t jjr|j	 r|rb|}nt 
|jt j}|r|| j| jfS |S | jdv r| jdv r|dur| js| j|||||dS |du r| js| j||||dS | j|||||dS dS )a
  
        Perform sigma clipping on the provided data.

        Parameters
        ----------
        data : array-like or `~numpy.ma.MaskedArray`
            The data to be sigma clipped.

        axis : None or int or tuple of int, optional
            The axis or axes along which to sigma clip the data. If
            `None`, then the flattened data will be used. ``axis`` is
            passed to the ``cenfunc`` and ``stdfunc``. The default is
            `None`.

        masked : bool, optional
            If `True`, then a `~numpy.ma.MaskedArray` is returned, where
            the mask is `True` for clipped values. If `False`, then a
            `~numpy.ndarray` is returned. The default is `True`.

        return_bounds : bool, optional
            If `True`, then the minimum and maximum clipping bounds are
            also returned.

        copy : bool, optional
            If `True`, then the ``data`` array will be copied. If
            `False` and ``masked=True``, then the returned masked array
            data will contain the same array as the input ``data`` (if
            ``data`` is a `~numpy.ndarray` or `~numpy.ma.MaskedArray`).
            If `False` and ``masked=False``, the input data is modified
            in-place. The default is `True`.

        Returns
        -------
        result : array-like
            If ``masked=True``, then a `~numpy.ma.MaskedArray` is
            returned, where the mask is `True` for clipped values and
            where the input mask was `True`.

            If ``masked=False``, then a `~numpy.ndarray` is returned.

            If ``return_bounds=True``, then in addition to the masked
            array or array above, the minimum and maximum clipping
            bounds are returned.

            If ``masked=False`` and ``axis=None``, then the output
            array is a flattened 1D `~numpy.ndarray` where the clipped
            values have been removed. If ``return_bounds=True`` then the
            returned minimum and maximum thresholds are scalars.

            If ``masked=False`` and ``axis`` is specified, then the
            output `~numpy.ndarray` will have the same shape as the
            input ``data`` and contain ``np.nan`` where values were
            clipped. If the input ``data`` was a masked array, then the
            output `~numpy.ndarray` will also contain ``np.nan`` where
            the input mask was `True`. If ``return_bounds=True`` then
            the returned minimum and maximum clipping thresholds will be
            be `~numpy.ndarray`\s.
        r   )rU   r/   )r0   r   Nr   rx   ry   ri   )rx   ry   ri   )r   Z
asanyarrayr|   ru   rv   r>   r?   r!   rh   allZfullr   r=   r7   r8   rA   r{   r   r   )rC   r^   r   rx   ry   ri   rz   r   r   r   __call__  sF    <




zSigmaClip.__call__)r-   NNr.   r/   r0   F)N)NTFT)TFT)NTFT)NTFT)rM   
__module____qualname____doc__rD   rG   rT   staticmethodr9   r;   r_   r{   r   r   r   r   r   r   r   r
   ]   s2      




   
V  
2  
a  r
      r.   r/   r0   TFc              	   C   s(   t |||||||d}|| |||	|
dS )a5  
    Perform sigma-clipping on the provided data.

    The data will be iterated over, each time rejecting values that are
    less or more than a specified number of standard deviations from a
    center value.

    Clipped (rejected) pixels are those where::

        data < center - (sigma_lower * std)
        data > center + (sigma_upper * std)

    where::

        center = cenfunc(data [, axis=])
        std = stdfunc(data [, axis=])

    Invalid data values (i.e., NaN or inf) are automatically clipped.

    For an object-oriented interface to sigma clipping, see
    :class:`SigmaClip`.

    .. note::
        `scipy.stats.sigmaclip` provides a subset of the functionality
        in this class. Also, its input data cannot be a masked array
        and it does not handle data that contains invalid values (i.e.,
        NaN or inf). Also note that it uses the mean as the centering
        function. The equivalent settings to `scipy.stats.sigmaclip`
        are::

            sigma_clip(sigma=4., cenfunc='mean', maxiters=None, axis=None,
            ...        masked=False, return_bounds=True)

    Parameters
    ----------
    data : array-like or `~numpy.ma.MaskedArray`
        The data to be sigma clipped.

    sigma : float, optional
        The number of standard deviations to use for both the lower
        and upper clipping limit. These limits are overridden by
        ``sigma_lower`` and ``sigma_upper``, if input. The default is 3.

    sigma_lower : float or None, optional
        The number of standard deviations to use as the lower bound for
        the clipping limit. If `None` then the value of ``sigma`` is
        used. The default is `None`.

    sigma_upper : float or None, optional
        The number of standard deviations to use as the upper bound for
        the clipping limit. If `None` then the value of ``sigma`` is
        used. The default is `None`.

    maxiters : int or None, optional
        The maximum number of sigma-clipping iterations to perform or
        `None` to clip until convergence is achieved (i.e., iterate
        until the last iteration clips nothing). If convergence is
        achieved prior to ``maxiters`` iterations, the clipping
        iterations will stop. The default is 5.

    cenfunc : {'median', 'mean'} or callable, optional
        The statistic or callable function/object used to compute
        the center value for the clipping. If using a callable
        function/object and the ``axis`` keyword is used, then it must
        be able to ignore NaNs (e.g., `numpy.nanmean`) and it must have
        an ``axis`` keyword to return an array with axis dimension(s)
        removed. The default is ``'median'``.

    stdfunc : {'std', 'mad_std'} or callable, optional
        The statistic or callable function/object used to compute the
        standard deviation about the center value. If using a callable
        function/object and the ``axis`` keyword is used, then it must
        be able to ignore NaNs (e.g., `numpy.nanstd`) and it must have
        an ``axis`` keyword to return an array with axis dimension(s)
        removed. The default is ``'std'``.

    axis : None or int or tuple of int, optional
        The axis or axes along which to sigma clip the data. If `None`,
        then the flattened data will be used. ``axis`` is passed to the
        ``cenfunc`` and ``stdfunc``. The default is `None`.

    masked : bool, optional
        If `True`, then a `~numpy.ma.MaskedArray` is returned, where
        the mask is `True` for clipped values. If `False`, then a
        `~numpy.ndarray` and the minimum and maximum clipping thresholds
        are returned. The default is `True`.

    return_bounds : bool, optional
        If `True`, then the minimum and maximum clipping bounds are also
        returned.

    copy : bool, optional
        If `True`, then the ``data`` array will be copied. If `False`
        and ``masked=True``, then the returned masked array data will
        contain the same array as the input ``data`` (if ``data`` is a
        `~numpy.ndarray` or `~numpy.ma.MaskedArray`). If `False` and
        ``masked=False``, the input data is modified in-place. The
        default is `True`.

    grow : float or `False`, optional
        Radius within which to mask the neighbouring pixels of those
        that fall outwith the clipping limits (only applied along
        ``axis``, if specified). As an example, for a 2D image a value
        of 1 will mask the nearest pixels in a cross pattern around each
        deviant pixel, while 1.5 will also reject the nearest diagonal
        neighbours and so on.

    Returns
    -------
    result : array-like
        If ``masked=True``, then a `~numpy.ma.MaskedArray` is returned,
        where the mask is `True` for clipped values and where the input
        mask was `True`.

        If ``masked=False``, then a `~numpy.ndarray` is returned.

        If ``return_bounds=True``, then in addition to the masked array
        or array above, the minimum and maximum clipping bounds are
        returned.

        If ``masked=False`` and ``axis=None``, then the output array
        is a flattened 1D `~numpy.ndarray` where the clipped values
        have been removed. If ``return_bounds=True`` then the returned
        minimum and maximum thresholds are scalars.

        If ``masked=False`` and ``axis`` is specified, then the output
        `~numpy.ndarray` will have the same shape as the input ``data``
        and contain ``np.nan`` where values were clipped. If the input
        ``data`` was a masked array, then the output `~numpy.ndarray`
        will also contain ``np.nan`` where the input mask was `True`.
        If ``return_bounds=True`` then the returned minimum and maximum
        clipping thresholds will be be `~numpy.ndarray`\s.

    See Also
    --------
    SigmaClip, sigma_clipped_stats

    Notes
    -----
    The best performance will typically be obtained by setting
    ``cenfunc`` and ``stdfunc`` to one of the built-in functions
    specified as as string. If one of the options is set to a string
    while the other has a custom callable, you may in some cases see
    better performance if you have the `bottleneck`_ package installed.

    .. _bottleneck:  https://github.com/pydata/bottleneck

    Examples
    --------
    This example uses a data array of random variates from a Gaussian
    distribution. We clip all points that are more than 2 sample
    standard deviations from the median. The result is a masked array,
    where the mask is `True` for clipped data::

        >>> from astropy.stats import sigma_clip
        >>> from numpy.random import randn
        >>> randvar = randn(10000)
        >>> filtered_data = sigma_clip(randvar, sigma=2, maxiters=5)

    This example clips all points that are more than 3 sigma relative
    to the sample *mean*, clips until convergence, returns an unmasked
    `~numpy.ndarray`, and does not copy the data::

        >>> from astropy.stats import sigma_clip
        >>> from numpy.random import randn
        >>> from numpy import mean
        >>> randvar = randn(10000)
        >>> filtered_data = sigma_clip(randvar, sigma=3, maxiters=None,
        ...                            cenfunc=mean, masked=False, copy=False)

    This example sigma clips along one axis::

        >>> from astropy.stats import sigma_clip
        >>> from numpy.random import normal
        >>> from numpy import arange, diag, ones
        >>> data = arange(5) + normal(0., 0.05, (5, 5)) + diag(ones(5))
        >>> filtered_data = sigma_clip(data, sigma=2.3, axis=0)

    Note that along the other axis, no points would be clipped, as the
    standard deviation is higher.
    rJ   r   )r
   )r^   r2   r3   r4   r6   r7   r8   r   rx   ry   ri   rA   sigclipr   r   r   r     s     9r   r-   c              	   C   s   |durt j| |} |dur,t j| |} t| t jjrZ| j rZt jjt jjt jjfS t|||||||d}|| |
dddd}t	rt
||
d}t||
d}t||	|
d}n,t j||
d}t j||
d}t j||	|
d}|||fS )a#  
    Calculate sigma-clipped statistics on the provided data.

    Parameters
    ----------
    data : array-like or `~numpy.ma.MaskedArray`
        Data array or object that can be converted to an array.

    mask : `numpy.ndarray` (bool), optional
        A boolean mask with the same shape as ``data``, where a `True`
        value indicates the corresponding element of ``data`` is masked.
        Masked pixels are excluded when computing the statistics.

    mask_value : float, optional
        A data value (e.g., ``0.0``) that is ignored when computing the
        statistics. ``mask_value`` will be masked in addition to any
        input ``mask``.

    sigma : float, optional
        The number of standard deviations to use for both the lower
        and upper clipping limit. These limits are overridden by
        ``sigma_lower`` and ``sigma_upper``, if input. The default is 3.

    sigma_lower : float or None, optional
        The number of standard deviations to use as the lower bound for
        the clipping limit. If `None` then the value of ``sigma`` is
        used. The default is `None`.

    sigma_upper : float or None, optional
        The number of standard deviations to use as the upper bound for
        the clipping limit. If `None` then the value of ``sigma`` is
        used. The default is `None`.

    maxiters : int or None, optional
        The maximum number of sigma-clipping iterations to perform or
        `None` to clip until convergence is achieved (i.e., iterate
        until the last iteration clips nothing). If convergence is
        achieved prior to ``maxiters`` iterations, the clipping
        iterations will stop. The default is 5.

    cenfunc : {'median', 'mean'} or callable, optional
        The statistic or callable function/object used to compute
        the center value for the clipping. If using a callable
        function/object and the ``axis`` keyword is used, then it must
        be able to ignore NaNs (e.g., `numpy.nanmean`) and it must have
        an ``axis`` keyword to return an array with axis dimension(s)
        removed. The default is ``'median'``.

    stdfunc : {'std', 'mad_std'} or callable, optional
        The statistic or callable function/object used to compute the
        standard deviation about the center value. If using a callable
        function/object and the ``axis`` keyword is used, then it must
        be able to ignore NaNs (e.g., `numpy.nanstd`) and it must have
        an ``axis`` keyword to return an array with axis dimension(s)
        removed. The default is ``'std'``.

    std_ddof : int, optional
        The delta degrees of freedom for the standard deviation
        calculation. The divisor used in the calculation is ``N -
        std_ddof``, where ``N`` represents the number of elements. The
        default is 0.

    axis : None or int or tuple of int, optional
        The axis or axes along which to sigma clip the data. If `None`,
        then the flattened data will be used. ``axis`` is passed to the
        ``cenfunc`` and ``stdfunc``. The default is `None`.

    grow : float or `False`, optional
        Radius within which to mask the neighbouring pixels of those
        that fall outwith the clipping limits (only applied along
        ``axis``, if specified). As an example, for a 2D image a value
        of 1 will mask the nearest pixels in a cross pattern around each
        deviant pixel, while 1.5 will also reject the nearest diagonal
        neighbours and so on.

    Notes
    -----
    The best performance will typically be obtained by setting
    ``cenfunc`` and ``stdfunc`` to one of the built-in functions
    specified as as string. If one of the options is set to a string
    while the other has a custom callable, you may in some cases see
    better performance if you have the `bottleneck`_ package installed.

    .. _bottleneck:  https://github.com/pydata/bottleneck

    Returns
    -------
    mean, median, stddev : float
        The mean, median, and standard deviation of the sigma-clipped
        data.

    See Also
    --------
    SigmaClip, sigma_clip
    NrJ   FTr   r   )r)   r   )r   ru   rv   Zmasked_valuesr!   rh   r   rx   r
   r	   r&   r(   r+   r$   r'   r*   )r^   rh   Z
mask_valuer2   r3   r4   r6   r7   r8   Zstd_ddofr   rA   r   Zdata_clippedrU   r/   r0   r   r   r   r   G  s*    c
r   )N)N)Nr   )N)r   NNr.   r/   r0   NTFTF)NNr-   NNr.   r/   r0   r   NF)rZ   Znumpyr   Znumpy.core.multiarrayr   Zastropy.unitsr   Zastropy.utilsr   Zastropy.utils.exceptionsr   Zastropy.stats._fast_sigma_clipr   Zastropy.stats.funcsr   Z"astropy.utils.compat.optional_depsr	   r#   __all__r    r&   r(   r+   r,   r
   r   r   r   r   r   r   <module>   s>   



    .   
 A    