a
    tDf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 s
0    Y  ej'Z'e$e% ej(Z(W d   n1 sB0    Y  ej)Z)e$e% ej*Z*W d   n1 sz0    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 )0z- 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 r8t | j}t|tttfsN|g}t }t | jD ]$}||v rt|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 ]/nfs/NAS7/SABIOD/METHODE/ermites/ermites_venv/lib/python3.9/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
|rHt 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<   | ]4\}}| |  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>       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r8 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(      r)   ztrim.<locals>.<listcomp>c                 s  s"   | ]}t ||r| nd V  qd S r   r   )r    axr   r   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rPt| 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  s"   | ]}| 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   r3   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  s*   | ]"}| krt d d dnt d V  qd S Nr   r&   r2   r   r   r$      s   z!topk_aggregate.<locals>.<genexpr>)r:   r5   sortr   r   r   r7   r   r2   r   topk_aggregate   s    r>   c                 C  s   | |fS )z^Preparatory step for argtopk

    Put data together with its original indices in a tuple.
    r   )r8   idxr   r   r   argtopk_preprocess   s    r@   c                   s   |du sJ  d  t | trXtt| } tdd | D  }tdd | D  }n| \}}t||j  krv| S tj||  d}|dkrt| 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(      r)   zargtopk.<locals>.<listcomp>c                 S  s   g | ]\}}t ||jqS r   )r5   Zbroadcast_tor%   )r    rA   Zidxir   r   r   r(      r)   r2   Nc                 3  s"   | ]}| krnt d V  qd S r   r   r&   r3   r   r   r$      r)   zargtopk.<locals>.<genexpr>)r   listr
   r5   Zconcatenater4   r%   Zargpartitionr   r   r   r   take_along_axisZ
a_plus_idxr9   r   r   r8   r?   Zidx2r   r3   r   argtopk   s    
"rF   c                   s   |du sJ t | dkr| n| d } t| | |\}} d  tj| d}t|| }|dk rf|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  s*   | ]"}| krt d d dnt d V  qd S r;   r   r&   r2   r   r   r$      s   z$argtopk_aggregate.<locals>.<genexpr>)lenrF   r5   ZargsortrD   r   r   r   rE   r   r2   r   argtopk_aggregate   s    rH   c                 C  s:   ddl m} || ||||d}t||kr6|d d S |S )Nr   )arange_safeliker<   )dask.array.utilsrI   rG   )startstopsteplengthdtyperK   rI   resr   r   r   arange  s    rS   Tc                 C  sD   ddl m} t| |r|  } t||r0| }tj| ||||dS )Nr   )Array)endpointrQ   )Zdask.array.corerT   r   Zcomputer5   linspace)rM   rN   numrU   rQ   rT   r   r   r   rV   	  s    

rV   c                 K  s   | j |fi |S r   )astype)r   Zastype_dtyper   r   r   r   rX     s    rX   Cc                 C  s   |dkrBzt j| | d} W n ty6   t | } Y n0 | |S zt j| | d} W n typ   t | } Y n0 | j|jS d S )NrY   rJ   )r5   Zascontiguousarray	TypeErrorviewZasfortranarrayT)r   rQ   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_arrayrJ   c                 3  s"   | ]}| krnt d V  qd S r   r   r&   r   r?   r   r   r$   S  r)   z,slice_with_int_dask_array.<locals>.<genexpr>)rL   r^   r_   rX   r5   int64wherer%   r   r   r   )r   r?   offsetZx_sizer   r^   r_   
idx_filterr   r`   r   slice_with_int_dask_array(  s    re   c           	        s   |  tj} t| dk | t| | } d}d}t| |D ]Z}| |k| || k @ }t|}t||d | d7 ||7 }|jdkr<||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  s"   | ]}| krnt d V  qd S r   r   r&   r   Z	idx_finalr   r   r$     s   z6slice_with_int_dask_array_aggregate.<locals>.<genexpr>)rX   r5   ra   rb   sumZ
zeros_likeZcumsumsizer   r   r   )	r?   Zchunk_outputsZx_chunksr   Zx_chunk_offsetZchunk_output_offsetZx_chunkrd   Zidx_cumr   rf   r   #slice_with_int_dask_array_aggregateV  s"    


ri   c              
   C  sx   z| | }W n. t y: } ztd|W Y d}~n
d}~0 0 z$|jjs^| jd|j kr^| }W n tyr   Y n0 |S )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owndatarh   copyAttributeError)objindexresulter   r   r   getitem  s    rs   )F)N)N)TN)N)rY   )9__doc__
__future__r   
contextlibcollections.abcr   r   r   	functoolsr   Znumbersr   numpyr5   Ztlzr	   Z	dask.corer
   r   rg   prodminmaxZargminZ	nanargminZargmaxZ	nanargmaxanyallZnansumZnanprodZ
nancumprodZ	nancumsumZnanminZnanmaxmeansuppressrn   ZnanmeanvarZnanvarZstdZnanstdr-   r1   r:   r>   r@   rF   rH   rS   rV   rX   r[   re   ri   rs   r   r   r   r   <module>   s`   #



&&&
9




.8