U
    vIdk/                     @   s  d dl Z d dlmZmZ d dlmZmZmZmZm	Z	 d dl
Z
d dlZd dlZd dlmZ ddlmZ ddlmZ eeZedd	 Zeejd
d Zeedd Zee
jdd ZeedddZeeedddZ eej!ej!dddZ"ee#dddddZ$edd Z%z@ddl&m'Z( dd Z)e%e(j*dd  Z+ee(j*d!d" Z,W n e-k
r   Y nX d8ej.e/d$d%d&Z0e/d'd(d)Z1ej2e/eej!ej3f d*d+d,Z4ee/ee f d-d.d/Z5e/d0d1d2Z6G d3d4 d4e#Z7e/e/e	d5d6d7Z8dS )9    N)wrapssingledispatch)MappingAnySequenceUnionCallable)sparse   )
get_logger)SparseDatasetc                 C   s
   t | S )zConvert x to a numpy array)npasarrayx r   F/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/anndata/utils.pyr      s    r   c                 C   s   |   S N)Ztoarrayr   r   r   r   asarray_sparse   s    r   c                 C   s
   t | jS r   )r   valuer   r   r   r   asarray_sparse_dataset   s    r   c                 C   s   | d S )N.r   r   r   r   r   asarray_h5py_dataset    s    r   )returnc                 C   s   t | S r   dictobjr   r   r   convert_to_dict%   s    r   r   c                 C   s   | S r   r   r   r   r   r   convert_to_dict_dict*   s    r   c                    s8    j jd krtd j  d fdd j j D S )NuN   Can only convert np.ndarray with compound dtypes to dict, passed array had “u   ”.c                    s   i | ]}| | qS r   r   ).0kr   r   r   
<dictcomp>6   s      z+convert_to_dict_ndarray.<locals>.<dictcomp>)dtypefields	TypeErrorkeysr   r   r   r   convert_to_dict_ndarray/   s
    r&   c                 C   s   t  S r   r   r   r   r   r   convert_to_dict_nonetype9   s    r'   c                 C   s
   | j | S )z    Return the size of an array in dimension `axis`.

    Returns None if `x` is an awkward array with variable length in the requested dimension.
    shape)r   axisr   r   r   dim_len>   s    r+   )awkwardc           	      K   s  | j rl| jrd}n| j}|d | d }d|  kr@t|k sVn td|d  d|| |d< tj S | jr||d kr| 	ddkrtd|d  d| j
r| j|d< nd	|d< tj S | jr||d krt| j|d< tj S | jr
td
|d  n| jrd}| jD ]Z}d|d i}tjt||d |dkrP|d }n$||d krd	|d< tj   S q||d< tj S dS )zNCallback function for dim_len_awkward, resolving the dim_len for a given level)r   r*   r
   zaxis=z is too deepoutZ	__array__)string
bytestringz.Cannot recurse into record type found at axis=Nlateral_context)Zis_numpyZ
is_unknownr)   lenr$   akcontentsZ
EmptyArrayZis_listZ	parameterZ
is_regularsizeZ	is_recordr#   Zis_union	transform_size_at_depth)	Zlayoutdepthr2   kwargsr)   Z
numpy_axisresultcontentcontextr   r   r   r8   K   sN    





r8   c                 C   sV   |dk rt dn@|dkr"t| S d|i}tjt| |d |d dkrJdS |d S dS )a  Get the length of an awkward array in a given dimension

        Returns None if the dimension is of variable length.

        Code adapted from @jpivarski's solution in https://github.com/scikit-hep/awkward/discussions/1654#discussioncomment-3521574
        r   zDoes not support negative axisr*   r1   r-   r0   N)NotImplementedErrorr3   r4   r7   r8   )arrayr*   r=   r   r   r   dim_len_awkward   s    
r@   c                 C   s   | S r   r   r   r   r   r   asarray_awkward   s    rA   -)indexjoinc                 C   s  | j r
| S ddlm} | j }| jdd}|| }t|}| }d}g }	t|D ]d\}
}||  d7  < || t||  }||kr|	| |||
< qRd}t
|	dk rZ|	| qZqR|rtd	| d
d d d d t|	  |||< tj|| jd} | S )a  
    Makes the index unique by appending a number string to each duplicate index element:
    '1', '2', etc.

    If a tentative name created by the algorithm already exists in the index, it tries
    the next integer in the sequence.

    The first occurrence of a non-unique value is ignored.

    Parameters
    ----------
    join
         The connecting string between name and integer.

    Examples
    --------
    >>> from anndata import AnnData
    >>> adata = AnnData(np.ones((2, 3)), var=pd.DataFrame(index=["a", "a", "b"]))
    >>> adata.var_names
    Index(['a', 'a', 'b'], dtype='object')
    >>> adata.var_names_make_unique()
    >>> adata.var_names
    Index(['a', 'a-1', 'b'], dtype='object')
    r   )Counterfirst)ZkeepFr
   T   zSuffix used (z3[0-9]+) to deduplicate index values may make index zGvalues difficult to interpret. There values with a similar suffixes in z;the index. Consider using a different delimiter by passing z`join={delimiter}`zEExample key collisions generated by the make_index_unique algorithm: )name)Z	is_uniquecollectionsrE   valuescopyZ
duplicatedset	enumeratestraddr3   appendwarningswarnpdIndexrH   )rC   rD   rE   rJ   Zindices_dupZ
values_dupZ
values_setcounterZissue_interpretation_warningZexample_colliding_valuesivZtentative_new_namer   r   r   make_index_unique   sJ    


rX   attrc                 C   s0   | dkrdnd}t j| d|  dtdd d S )NZobsZObservationVariablez3 names are not unique. To make them unique, call `.z_names_make_unique`.   )
stacklevel)rQ   rR   UserWarning)rZ   namesr   r   r   warn_names_duplicates   s    r`   )dfrH   r   c                 C   sT   t dd | jD r$| j  }n|  }| j dkrPt| d|j	  |S )Nc                 s   s   | ]}t |tjV  qd S r   )
isinstancerS   ZSparseDtype)r   dtr   r   r   	<genexpr>   s     z(ensure_df_homogeneous.<locals>.<genexpr>r
   z% converted to numpy array with dtype )
allZdtypesr	   Zto_cooZtocsrZto_numpyZnuniquerQ   rR   r"   )ra   rH   arrr   r   r   ensure_df_homogeneous   s    rg   )sourcec                 C   s   t |  }zdd |  D }W n tk
r>   tdY nX t t|dd |D dd |D }t|}tt	|d f|}t
|jD ]&\}}tj|| || d d||< q|S )	Nc                 S   s<   g | ]4}t |d  jjdkr(t |nt |dqS )r   >   USri   )r   r?   r"   charr   Zastype)r   colr   r   r   
<listcomp>  s   z:convert_dictionary_to_structured_array.<locals>.<listcomp>uV   Currently only support ascii strings. Don’t use “ö” etc. for sample annotation.c                 S   s   g | ]}t |jqS r   )rN   r"   r   cr   r   r   rm     s     c                 S   s   g | ]}|j d  fqS )r
   r(   rn   r   r   r   rm     s     r   r
   )r"   )listr%   rJ   UnicodeEncodeError
ValueErrorzipr   r"   Zzerosr3   rM   r_   r?   )rh   r_   colsZ
dtype_listr"   rf   rV   rH   r   r   r   &convert_dictionary_to_structured_array   s"    


 ru   new_namec                    s    fdd}|S )z    This is a decorator which can be used to mark functions
    as deprecated. It will result in a warning being emitted
    when the function is used.
    c                    s&   t   fdd}t|dd |S )Nc                     sJ   t dt t jd d j d j dtdd t dt  | |S )	NalwayszUse z instead of z, z will be removed in the future.r\   )categoryr]   default)rQ   simplefilterDeprecationWarningrR   __name__)argsr:   )funcrw   r   r   new_func-  s    z/deprecated.<locals>.decorator.<locals>.new_func__deprecatedT)r   setattr)r   r   rv   )r   r   	decorator,  s    zdeprecated.<locals>.decoratorr   )rw   r   r   rv   r   
deprecated%  s    r   c                   @   s   e Zd ZdZdd ZdS )DeprecationMixinMetazt    Use this as superclass so deprecated methods and properties
    do not appear in vars(MyClass)/dir(MyClass)
    c                    s"   dd  fddt  D S )Nc                 S   s   t | tr| j} t| ddS )Nr   F)rb   propertyfgetgetattrrY   r   r   r   is_deprecatedG  s    
z3DeprecationMixinMeta.__dir__.<locals>.is_deprecatedc                    s    g | ]}t  |d s|qS r   )r   )r   itemclsr   r   r   rm   L  s   z0DeprecationMixinMeta.__dir__.<locals>.<listcomp>)type__dir__)r   r   r   r   r   F  s    zDeprecationMixinMeta.__dir__N)r}   
__module____qualname____doc__r   r   r   r   r   r   @  s   r   )modulerH   r   c              
      s^   ddl m} z|| } t| |}W n6 ttfk
rX } z|  fdd}W 5 d}~X Y nX |S )a      Try to import function from module. If the module is not installed or
    function is not part of the module, it returns a dummy function that raises
    the respective import error once the function is called. This could be a
    ModuleNotFoundError if the module is missing or an AttributeError if the
    module is installed but the function is not exported by it.

    Params
    -------
    module
        Module to import from. Can be nested, e.g. "sklearn.utils".
    name
        Name of function to import from module.
    r   )import_modulec                     s    d S r   r   )___errorr   r   r   j  s    zimport_function.<locals>.funcN)	importlibr   r   ImportErrorAttributeError)r   rH   r   r   er   r   r   import_functionS  s    r   )rB   )9rQ   	functoolsr   r   typingr   r   r   r   r   Zh5pyZpandasrS   numpyr   Zscipyr	   loggingr   Z_core.sparse_datasetr   r}   loggerr   registerZspmatrixr   r   ZDatasetr   r   r   r   Zndarrayr&   r   r'   r+   compatr,   r4   r8   ZArrayr@   rA   r   rT   rN   rX   r`   Z	DataFrameZ
csr_matrixrg   ru   r   r   r   r   r   r   r   <module>   s\   






	
	>


> %