U
    vIÀdd  ã                   @  s  d dl m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 dlZdd	lmZ d d
lmZmZ e ej¡jdkZddddœdd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZG dd „ d eƒZ d!d"„ Z!d#d$„ Z"d%d&„ Z#d'd(œd)d*d*d+d,œd-d.„Z$dS )/é    )Úannotations)ÚEnum)ÚwrapsÚsingledispatch)ÚCallable)Úwarn)ÚversionNé   )ÚSparseDataset)ÚH5GroupÚ	ZarrGroupé   ÚtupleÚint)ÚshapeÚaxisÚ
chunk_sizec                 c  sp   | | }d}dd„ t t| ƒƒD ƒ}|| |k rTt||| ƒ||< t|ƒV  ||7 }q"t|dƒ||< t|ƒV  dS )a.      Gives indexer tuples chunked along an axis.

    Params
    ------
    shape
        Shape of array to be chunked
    axis
        Axis to chunk along
    chunk_size
        Size of chunk along axis

    Returns
    -------
    An iterator of tuples for indexing into an array of passed shape.
    r   c                 S  s   g | ]}t d ƒ‘qS )N)Úslice)Ú.0Úi© r   úJ/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/anndata/_io/utils.pyÚ
<listcomp>+   s     z)idx_chunks_along_axis.<locals>.<listcomp>N)ÚrangeÚlenr   r   )r   r   r   ÚtotalÚcurZmutable_idxr   r   r   Úidx_chunks_along_axis   s    

r   c                 C  s*   zt | ƒ W dS  tk
r$   Y dS X dS )z©    Check whether string is float.

    See also
    --------
    http://stackoverflow.com/questions/736043/checking-if-a-string-can-be-converted-to-float-in-python
    TFN)ÚfloatÚ
ValueError©Ústringr   r   r   Úis_float4   s
    r"   c                 C  s*   zt | ƒ W dS  tk
r$   Y dS X dS )z Check whether string is integer.TFN)r   r   r    r   r   r   Úis_intC   s
    r#   c                 C  s    | dkrdS | dkrdS dS dS )z Check whether string is boolean.ÚTrue)TTÚFalse)TF)FFNr   r    r   r   r   Úconvert_boolL   s
    r&   c                 C  sL   t | ƒrt| ƒS t| ƒr t| ƒS t| ƒd r8t| ƒd S | dkrDdS | S dS )z%Convert string to int, float or bool.r   é   ÚNoneN)r#   r   r"   r   r&   r    r   r   r   Úconvert_stringV   s    r)   c                 C  s2   t | ƒ}t|tƒrt| ƒS t| › d|› d�ƒ‚dS )z‚Checks that passed value is a valid h5py key.

    Should convert it if there is an obvious conversion path, error otherwise.
    ú	 of type z" is an invalid key. Should be str.N)ÚtypeÚ
issubclassÚstrÚ	TypeError)ÚkeyÚtypr   r   r   Ú	check_keyd   s    
r1   c                  O  s    ddl m} tdtƒ || |ŽS )Nr'   )Ú	read_elemzHThis internal function has been deprecated, please use read_elem instead)Úspecsr2   r   ÚDeprecationWarning)ÚargsÚkwargsr2   r   r   r   Úread_attributey   s    þr7   c                  O  s    ddl m} tdtƒ || |ŽS )Nr'   )Ú
write_elemzIThis internal function has been deprecated, please use write_elem instead)r3   r8   r   r4   )r5   r6   r8   r   r   r   Úwrite_attributeƒ   s    þr9   c                   @  s   e Zd ZdZdS )ÚAnnDataReadErrorz-Error caused while trying to read in AnnData.N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r:   ”   s   r:   c                 C  sf   zdd l }W n tk
r$   d }Y nX |rDt| |j|jfƒrD| j}nt| tƒrZ| jjj	}n| jj	}|S )Nr   )
ÚzarrÚImportErrorÚ
isinstanceÚGroupZArrayÚstorer
   ÚgroupÚfileÚname)Úelemr?   Úparentr   r   r   Ú_get_parentš   s    

rI   c                   s"   dd„ ‰t ˆ ƒ‡ ‡fdd„ƒ}|S )a[      A decorator for zarr element reading which makes keys involved in errors get reported.

    Example
    -------
    >>> import zarr
    >>> @report_read_key_on_error
    ... def read_arr(group):
    ...     raise NotImplementedError()
    >>> z = zarr.open("tmp.zarr")
    >>> z["X"] = [1, 2, 3]
    >>> read_arr(z["X"])  # doctest: +SKIP
    c                 S  s@   t | tƒr| ‚n,t|ƒ}td|j›dt|ƒ› d|› d�ƒ| ‚d S )Nz%Above error raised while reading key r*   z from Ú.)rA   r:   rI   rF   r+   )ÚerG   rH   r   r   r   Úre_raise_error·   s    
ÿýz0report_read_key_on_error.<locals>.re_raise_errorc               
     sb   ddl m} | D ]}t||ƒs q$qzˆ | |ŽW S  tk
r\ } zˆ||ƒ W 5 d }~X Y nX d S )Nr   )ÚReader)Úanndata._io.specsrM   rA   Ú	Exception)r5   r6   rM   rG   rK   ©ÚfuncrL   r   r   Úfunc_wrapperÁ   s    
z.report_read_key_on_error.<locals>.func_wrapper©r   ©rQ   rR   r   rP   r   Úreport_read_key_on_error¨   s    
rU   c                   s"   dd„ ‰t ˆ ƒ‡ ‡fdd„ƒ}|S )af      A decorator for zarr element reading which makes keys involved in errors get reported.

    Example
    -------
    >>> import zarr
    >>> @report_write_key_on_error
    ... def write_arr(group, key, val):
    ...     raise NotImplementedError()
    >>> z = zarr.open("tmp.zarr")
    >>> X = [1, 2, 3]
    >>> write_arr(z, "X", X)  # doctest: +SKIP
    c                 S  sD   dt | ƒkr‚ n0t|ƒ}t| ƒ| › d|›dt|ƒ› d|› �ƒ| ‚d S )Nz$Above error raised while writing keyz'

Above error raised while writing key z of z to )ÚformatrI   r+   )rK   rG   r/   rH   r   r   r   rL   à   s    ÿüz1report_write_key_on_error.<locals>.re_raise_errorc               
     s€   ddl m} tt| ƒƒD ]&}| | }| |d  }t||ƒs q@qzˆ | |ŽW S  tk
rz } zˆ|||ƒ W 5 d }~X Y nX d S )Nr   )ÚWriterr'   )rN   rW   r   r   rA   rO   )r5   r6   rW   r   rG   r/   rK   rP   r   r   rR   ë   s    
z/report_write_key_on_error.<locals>.func_wrapperrS   rT   r   rP   r   Úreport_write_key_on_errorÑ   s    rX   )ÚXÚvarÚvarm)ÚattrszZarrGroup | H5Groupr   Údict)ÚfÚread_dfÚ	read_attrÚreturnc                C  sª   |rBt dd„ | D ƒƒr>t| dƒr,d| j› �nd}t|› d�ƒ‚|S i }d|krfd| krf|| d ƒ|d< d	|kr†d
| kr†|| d
 ƒ|d	< d|kr¦d| kr¦|| d ƒ|d< |S )z|    Backwards compat for reading legacy raw.
    Makes sure that no modern raw group coexists with legacy raw.* groups.
    c                 s  s   | ]}|  d ¡V  qdS )zraw.N)Ú
startswith)r   Úkr   r   r   Ú	<genexpr>  s     z#_read_legacy_raw.<locals>.<genexpr>ÚfilenamezFile ÚStorez) has both legacy and current raw formats.rY   zraw.XrZ   zraw.varr[   zraw.varm)ÚanyÚhasattrre   r   )r^   Z
modern_rawr_   r`   r\   ÚwhatÚrawr   r   r   Ú_read_legacy_raw  s    rk   )%Ú
__future__r   Úenumr   Ú	functoolsr   r   Útypingr   Úwarningsr   Ú	packagingr   Zh5pyZ_core.sparse_datasetr
   Zanndata.compatr   r   ÚparseÚ__version__ÚmajorZH5PY_V3r   r"   r#   r&   r)   r1   r7   r9   ÚOSErrorr:   rI   rU   rX   rk   r   r   r   r   Ú<module>   s.   	

)7ú