a
    ߙfb%                     @   sx   d dl Z d dlZd dlmZ d dlmZmZ d dl	m
Z
 d dlmZ d dlmZ dgZdd	 Zdddddd
ddZdS )    N)units)Time	TimeDelta)AstropyUserWarning)
TimeSeries)BinnedTimeSeriesaggregate_downsamplec              	   C   s   t |dkrtg S t|dr2t|| |S g }tt |d D ]V}||d  || d krz||| ||   qF||| || ||d    qF||| |d d  t|S dS )z
    Manual reduceat functionality for cases where Numpy functions don't have a reduceat.
    It will check if the input function has a reduceat and call that if it does.
    r   reduceat   N)lennparrayhasattrr	   rangeappend)r   indicesZfunctionresulti r   <lib/python3.9/site-packages/astropy/timeseries/downsample.pyr	      s    

$r	   )time_bin_sizetime_bin_starttime_bin_endn_binsaggregate_funcc             
   C   s  t | tstd|dur2t |tjtfs2td|durPt |ttfsPt|}|durnt |ttfsnt|}| jdd }|du r|jd }|j	r|jd | j
}|du r|du r|j	r|du rtdq|| tj }nt|jd |d }|j	rt|dur6|j	rt|du rt|tj}tt|| }n>|durt|j	st|}	|jdd}|	|d< |dd |d	d< |dur|j	s|j	st|d	d |dd k rtd
t t||||d}
|du rtj}|
j}|
j}|du s|j	s t|}|j|d k|j|d k@ }t|d	 D ]8}tt|j|| k|j||d	  k }d||< q(|| }t||j| }t|rt|d	d |dd krt|j|||jd k }t t|||< t|rt!dt"t#|d d	 g}n
t$g }t%|}|j&D ]}|dkr.q|| }t |tj'tjfsZtdt qt |tjrtjt(tj)||j*d}tjt+|j,|||j*dd||< n2tj-j.||j/d}d	|_0t+|||||< d|j0|< ||
|< q|
S )aZ
  
    Downsample a time series by binning values into bins with a fixed size or
    custom sizes, using a single function to combine the values in the bin.

    Parameters
    ----------
    time_series : :class:`~astropy.timeseries.TimeSeries`
        The time series to downsample.
    time_bin_size : `~astropy.units.Quantity` or `~astropy.time.TimeDelta` ['time'], optional
        The time interval for the binned time series - this is either a scalar
        value (in which case all time bins will be assumed to have the same
        duration) or as an array of values (in which case each time bin can
        have a different duration). If this argument is provided,
        ``time_bin_end`` should not be provided.
    time_bin_start : `~astropy.time.Time` or iterable, optional
        The start time for the binned time series - this can be either given
        directly as a `~astropy.time.Time` array or as any iterable that
        initializes the `~astropy.time.Time` class. This can also be a scalar
        value if ``time_bin_size`` or ``time_bin_end`` is provided.
        Defaults to the first time in the sampled time series.
    time_bin_end : `~astropy.time.Time` or iterable, optional
        The times of the end of each bin - this can be either given directly as
        a `~astropy.time.Time` array or as any iterable that initializes the
        `~astropy.time.Time` class. This can only be given if ``time_bin_start``
        is provided or its default is used. If ``time_bin_end`` is scalar and
        ``time_bin_start`` is an array, time bins are assumed to be contiguous;
        the end of each bin is the start of the next one, and ``time_bin_end`` gives
        the end time for the last bin.  If ``time_bin_end`` is an array and
        ``time_bin_start`` is scalar, bins will be contiguous. If both ``time_bin_end``
        and ``time_bin_start`` are arrays, bins do not need to be contiguous.
        If this argument is provided, ``time_bin_size`` should not be provided.
    n_bins : int, optional
        The number of bins to use. Defaults to the number needed to fit all
        the original points. If both ``time_bin_start`` and ``time_bin_size``
        are provided and are scalar values, this determines the total bins
        within that interval. If ``time_bin_start`` is an iterable, this
        parameter will be ignored.
    aggregate_func : callable, optional
        The function to use for combining points in the same bin. Defaults
        to np.nanmean.

    Returns
    -------
    binned_time_series : :class:`~astropy.timeseries.BinnedTimeSeries`
        The downsampled time series.
    z"time_series should be a TimeSeriesNz3'time_bin_size' should be a Quantity or a TimeDeltar   r   z_With single 'time_bin_start' either 'n_bins', 'time_bin_size' or time_bin_end' must be providedT)copyr
   zaOverlapping bins should be avoided since they can lead to double-counting of data during binning.)r   r   r   r   Ftimez.Skipping column {0} since it has a mix-in type)unit)dtype)1
isinstancer   	TypeErroruZQuantityr   r   Zilocr   ZisscalarZsecsr   ZmaximumZto_valueintZceilZ	replicateanywarningswarnr   r   Znanmeanr   r   r   r   whereZlogical_andZsearchsortedallZarangeZhstackZnonzeroZdiffr   uniqueZcolnamesZndarrayrepeatnanr   r	   valueZmaZzerosr   mask)Ztime_seriesr   r   r   r   r   Z	ts_sortedZtime_durationZbin_size_secZscalar_start_timeZbinnedZ	bin_startZbin_endZkeepZindZdelete_indicesZsubsetr   Zindices_startgroupsZunique_indicesZcolnamevaluesdatar   r   r   r   $   s    1







*
$




)r&   Znumpyr   Zastropyr   r"   Zastropy.timer   r   Zastropy.utils.exceptionsr   Zastropy.timeseries.sampledr   Zastropy.timeseries.binnedr   __all__r	   r   r   r   r   r   <module>   s   