o
    Nrf0                     @  s  d Z ddlmZ ddlZddlmZmZmZ ddlm	Z	 ddl
mZ ddlZddlmZ ddlmZ d	d
 ZejZejZejZejZeejZeejZeejZeejZejZejZejZejZejZej Z ej!Z!ej"Z"ej#Z#e$e% ej&Z&W d   n1 sw   Y  ej'Z'e$e% ej(Z(W d   n1 sw   Y  ej)Z)e$e% ej*Z*W d   n1 sw   Y  d*ddZ+d+ddZ,dd Z-dd Z.dd Z/dd Z0dd Z1d+ddZ2d,ddZ3d+dd Z4d-d"d#Z5d$d% Z6d&d' Z7d(d) Z8dS ).z- A set of NumPy functions to apply per chunk     )annotationsN)	ContainerIterableSequencewraps)Integral)concat)flattenc                   s   t  d fdd	}|S )zU
    A wrapper for functions that don't provide keepdims to ensure that they do.
    Nc           	        s    | g|R d|i|}|s|S |}|d u rt | j}t|tttfs'|g}t }t | jD ]}||v r:|d7 }q/|td f7 }q/|| }|S )NaxisN)rangendim
isinstancer   r   r   tupleslice)	xr   keepdimsargskwargsraxesZr_sliceZ	each_axis
a_callable Y/var/www/html/software/conda/envs/catlas/lib/python3.10/site-packages/dask/array/chunk.pykeepdims_wrapped_callable   s   

z3keepdims_wrapper.<locals>.keepdims_wrapped_callable)NNr   )r   r   r   r   r   keepdims_wrapper   s   r   Fc                   s   t jD ]
}| vrd |< q|r$t fddtjD }| tt fddt jD }| |fdtt djd di|S )a  Coarsen array by applying reduction to fixed size neighborhoods

    Parameters
    ----------
    reduction: function
        Function like np.sum, np.mean, etc...
    x: np.ndarray
        Array to be coarsened
    axes: dict
        Mapping of axis to coarsening factor

    Examples
    --------
    >>> x = np.array([1, 2, 3, 4, 5, 6])
    >>> coarsen(np.sum, x, {0: 2})
    array([ 3,  7, 11])
    >>> coarsen(np.max, x, {0: 3})
    array([3, 6])

    Provide dictionary of scale per dimension

    >>> x = np.arange(24).reshape((4, 6))
    >>> x
    array([[ 0,  1,  2,  3,  4,  5],
           [ 6,  7,  8,  9, 10, 11],
           [12, 13, 14, 15, 16, 17],
           [18, 19, 20, 21, 22, 23]])

    >>> coarsen(np.min, x, {0: 2, 1: 3})
    array([[ 0,  3],
           [12, 15]])

    You must avoid excess elements explicitly

    >>> x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
    >>> coarsen(np.min, x, {0: 3}, trim_excess=True)
    array([1, 4])
       c                 3  s>    | ]\}}| |  rt d | |   nt ddV  qdS )r   Nr   ).0idr   r   r   	<genexpr>   s
    (
zcoarsen.<locals>.<genexpr>c                   s&   g | ]}j |  |   | fqS r   )shaper    r!   r   r   r   r   
<listcomp>   s   & zcoarsen.<locals>.<listcomp>r      )r   r   r   	enumerater%   r	   Zreshape)Z	reductionr   r   Ztrim_excessr   r!   indZnewshaper   r'   r   coarsenT   s   (",r,   c                   sN   t  tr g| j  t  tr fddt| jD  | tdd  D  S )aC  Trim boundaries off of array

    >>> x = np.arange(24).reshape((4, 6))
    >>> trim(x, axes={0: 0, 1: 1})
    array([[ 1,  2,  3,  4],
           [ 7,  8,  9, 10],
           [13, 14, 15, 16],
           [19, 20, 21, 22]])

    >>> trim(x, axes={0: 1, 1: 1})
    array([[ 7,  8,  9, 10],
           [13, 14, 15, 16]])
    c                   s   g | ]}  |d qS )r   )getr&   r#   r   r   r(      s    ztrim.<locals>.<listcomp>c                 s  s$    | ]}t ||r| nd V  qd S r   r   )r    axr   r   r   r$         " ztrim.<locals>.<genexpr>)r   r   r   dictr   r   )r   r   r   r#   r   trim   s
   

r1   c                   s|   |du sJ  d  t || j  kr| S tj| |  d} |dkr(t| dnt| | t fddt| jD  S )a  Chunk and combine function of topk

    Extract the k largest elements from a on the given axis.
    If k is negative, extract the -k smallest elements instead.
    Note that, unlike in the parent function, the returned elements
    are not sorted internally.
    Tr   r   Nc                 3  $    | ]}| kr
nt d V  qd S r   r   r&   r   Zk_slicer   r   r$      r/   ztopk.<locals>.<genexpr>)absr%   np	partitionr   r   r   r   akr   r   r   r4   r   topk   s   "r;   c                   s\   |du sJ t | | |}  d  tj|  d} |dk r| S | t fddt| jD  S )zmFinal aggregation function of topk

    Invoke topk one final time and then sort the results internally.
    Tr   r2   c                 3  ,    | ]}| krt d d dnt d V  qd S Nr   r&   r2   r   r   r$          
z!topk_aggregate.<locals>.<genexpr>)r;   r6   sortr   r   r   r8   r   r2   r   topk_aggregate   s   rA   c                 C  s   | |fS )z^Preparatory step for argtopk

    Put data together with its original indices in a tuple.
    r   )r9   idxr   r   r   argtopk_preprocess   s   rC   c                   s   |du sJ  d  t | tr,tt| } tdd | D  }tdd | D  }n| \}}t||j  kr;| S tj||  d}|dkrNt| dnt| |t	 fdd	t
|jD  }t|| t|| fS )
a)  Chunk and combine function of argtopk

    Extract the indices of the k largest elements from a on the given axis.
    If k is negative, extract the indices of the -k smallest elements instead.
    Note that, unlike in the parent function, the returned elements
    are not sorted internally.
    Tr   c                 S  s   g | ]\}}|qS r   r   )r    ai_r   r   r   r(      s    zargtopk.<locals>.<listcomp>c                 S  s   g | ]\}}t ||jqS r   )r6   Zbroadcast_tor%   )r    rD   Zidxir   r   r   r(      s    r2   Nc                 3  r3   r   r   r&   r4   r   r   r$      r/   zargtopk.<locals>.<genexpr>)r   listr
   r6   Zconcatenater5   r%   Zargpartitionr   r   r   r   take_along_axisZ
a_plus_idxr:   r   r   r9   rB   Zidx2r   r4   r   argtopk   s   
"rI   c                   s   |du sJ t | dkr| n| d } t| | |\}} d  tj| d}t|| }|dk r3|S |t fddt|jD  S )zFinal aggregation function of argtopk

    Invoke argtopk one final time, sort the results internally, drop the data
    and return the index only.
    Tr   r   r2   c                 3  r<   r=   r   r&   r2   r   r   r$      r?   z$argtopk_aggregate.<locals>.<genexpr>)lenrI   r6   ZargsortrG   r   r   r   rH   r   r2   r   argtopk_aggregate   s   rK   c                 C  s:   ddl m} || ||||d}t||kr|d d S |S )Nr   )arange_safeliker>   )dask.array.utilsrL   rJ   )startstopsteplengthdtyperN   rL   resr   r   r   arange  s   rV   Tc                 C  sD   ddl m} t| |r|  } t||r| }tj| ||||dS )Nr   )Array)endpointrT   )Zdask.array.corerW   r   Zcomputer6   linspace)rP   rQ   numrX   rT   rW   r   r   r   rY   	  s   

rY   c                 K  s   | j |fi |S r   )astype)r   Zastype_dtyper   r   r   r   r[     s   r[   Cc                 C  s   |dkr!z	t j| | d} W n ty   t | } Y nw | |S z	t j| | d} W n ty8   t | } Y nw | j|jS )Nr\   rM   )r6   Zascontiguousarray	TypeErrorviewZasfortranarrayT)r   rT   orderr   r   r   r^     s   
r^   c                   s   ddl m}m} ||| dtjtdk | | dk| j  k @ }| | t fddt	| j
D  S )a  Chunk function of `slice_with_int_dask_array_on_axis`.
    Slice one chunk of x by one chunk of idx.

    Parameters
    ----------
    x: ndarray, any dtype, any shape
        i-th chunk of x
    idx: ndarray, ndim=1, dtype=any integer
        j-th chunk of idx (cartesian product with the chunks of x)
    offset: ndarray, shape=(1, ), dtype=int64
        Index of the first element along axis of the current chunk of x
    x_size: int
        Total size of the x da.Array along axis
    axis: int
        normalized axis to take elements from (0 <= axis < x.ndim)

    Returns
    -------
    x sliced along axis, using only the elements of idx that fall inside the
    current chunk.
    r   )asarray_safemeta_from_arrayrM   c                 3  r3   r   r   r&   r   rB   r   r   r$   S  r/   z,slice_with_int_dask_array.<locals>.<genexpr>)rO   ra   rb   r[   r6   int64wherer%   r   r   r   )r   rB   offsetZx_sizer   ra   rb   
idx_filterr   rc   r   slice_with_int_dask_array(  s   "rh   c           	        s   |  tj} t| dk | t| | } d}d}t| |D ]-}| |k| || k @ }t|}t||d | d7 ||7 }|jdkrK||d 7 }q|t fddt	|j
D  S )aS  Final aggregation function of `slice_with_int_dask_array_on_axis`.
    Aggregate all chunks of x by one chunk of idx, reordering the output of
    `slice_with_int_dask_array`.

    Note that there is no combine function, as a recursive aggregation (e.g.
    with split_every) would not give any benefit.

    Parameters
    ----------
    idx: ndarray, ndim=1, dtype=any integer
        j-th chunk of idx
    chunk_outputs: ndarray
        concatenation along axis of the outputs of `slice_with_int_dask_array`
        for all chunks of x and the j-th chunk of idx
    x_chunks: tuple
        dask chunks of the x da.Array along axis, e.g. ``(3, 3, 2)``
    axis: int
        normalized axis to take elements from (0 <= axis < x.ndim)

    Returns
    -------
    Selection from all chunks of x for the j-th chunk of idx, in the correct
    order
    r   r   r>   c                 3  r3   r   r   r&   r   Z	idx_finalr   r   r$     s    
z6slice_with_int_dask_array_aggregate.<locals>.<genexpr>)r[   r6   rd   re   sumZ
zeros_likeZcumsumsizer   r   r   )	rB   Zchunk_outputsZx_chunksr   Zx_chunk_offsetZchunk_output_offsetZx_chunkrg   Zidx_cumr   ri   r   #slice_with_int_dask_array_aggregateV  s$   


rl   c              
   C  sx   z| | }W n t y } ztd|d}~ww z|jjs,| jd|j kr/| }W |S W |S W |S  ty;   Y |S w )af  Getitem function

    This function creates a copy of the desired selection for array-like
    inputs when the selection is smaller than half of the original array. This
    avoids excess memory usage when extracting a small portion from a large array.
    For more information, see
    https://numpy.org/doc/stable/reference/arrays.indexing.html#basic-slicing-and-indexing.

    Parameters
    ----------
    obj: ndarray, string, tuple, list
        Object to get item from.
    index: int, list[int], slice()
        Desired selection to extract from obj.

    Returns
    -------
    Selection obj[index]

    zTArray chunk size or shape is unknown. Possible solution with x.compute_chunk_sizes()Nr)   )
IndexError
ValueErrorflagsZowndatark   copyAttributeError)objindexresulter   r   r   getitem  s,   
rv   )Fr   )TN)r\   )9__doc__
__future__r   
contextlibcollections.abcr   r   r   	functoolsr   numbersr   numpyr6   Ztlzr	   Z	dask.corer
   r   rj   prodminmaxZargminZ	nanargminZargmaxZ	nanargmaxanyallZnansumZnanprodZ
nancumprodZ	nancumsumZnanminZnanmaxmeansuppressrq   ZnanmeanvarZnanvarZstdZnanstdr,   r1   r;   rA   rC   rI   rK   rV   rY   r[   r^   rh   rl   rv   r   r   r   r   <module>   sh    #





9



.8