U
    vIdC                     @   s  d dl mZmZ d dlmZ d dlmZmZmZ d dl	m
Z
mZ d dlZd dlZd dlZd dlZd dlmZ d dlZd dlmZ d dl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!m"Z" d dl#m$Z$m%Z% e&ej'ej(ej)e%fej'ej(ej)e%fej'ej(ej)e%fdZ*dXddZ+dYddZ,dd Z-ej.fddZ/dZej)dddZ0ej'ej1ej'ej(ej)e$fej'ej(ej)e$fej'ej(ej)ffee2e2f dddedddZ3d[dd Z4d\d!d"Z5d]d#d$Z6d^d%d&Z7d_d'd(Z8d`d)d*Z9d+d, Z:ej;e7e9e:e8e4e5e6gd-d.d/ Z<d0d1 Z=d2d3 Z>e>d4d5 Z?edad7d8Z@e@Aej(dbd9d:ZBe@Aedcd;d<ZCe@Aee@AejDddd=d>ZEe@AejFded?d@ZGe@Ae%dfdAdBZHe@Aej)dgdCdDZIe@Ae$dhdEdFZJe@Ae
didGdHZKe@Ae djdIdJZLe@AejMdkdKdLZNe@AejOjPjQdldMdNZRe@AedmdOdPZSe@AedneeeTeeU dQdRdSZVedTdU ZWeWAejDdVdW ZXdS )o    )singledispatchwraps)ascii_letters)TupleOptionalType)Mapping
CollectionN)is_numeric_dtype)sparse)AnnDataRaw)	ArrayView)SparseDataset)AlignedMapping)asarray)AwkArray	DaskArray)
obsm_types
varm_typeslayers_typesc                    s|   | | }t jdd|}t ttfdd t  fdd|D | |}tj| fddt	|D dj
d	|d
S )N      c                    s   d tj | S )N )joinnprandomchoice)l)letters N/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/anndata/tests/helpers.py<lambda>'       z#gen_vstr_recarray.<locals>.<lambda>c                    s   g | ]} |qS r    r    ).0r   gen_wordr    r!   
<listcomp>(   s     z%gen_vstr_recarray.<locals>.<listcomp>c                    s   g | ]} d qS )r   r    r$   ir%   r    r!   r'   )   s     )columnsF)indexZcolumn_dtypes)r   r   randintarraylistr   reshapepd	DataFramerangeZ
to_records)mndtypesizelengthsarrr    )r&   r   r!   gen_vstr_recarray#   s       r9   c                 C   s   t ttd}| t|kr,|d | d  }tjtt j	|| tjt j	|| ddt j
dd| t j| t jj
d| dd	t jj
d
d| td	tjjt jj
d
d| td	t jj
d
d| td	dtjjt jj
d
d| t jd	t jj
d
d| td	dd|dS )NZU1   T)Zorderedi2      uint8)r6   r5   r   )mask  )catZcat_orderedZint64Zfloat64r=   boolznullable-boolznullable-intr+   )r   Zfromiteriterr   lenr0   r1   ZCategoricalr   r   r,   rA   ZarraysZBooleanArrayZIntegerArrayint32)r4   r+   r   r    r    r!   gen_typed_df.   s*    
rF   c                 C   sh   d}t | s||dS | d }g }|d kr8||}t|D ]}|t| dd  || q@|S d S )N   r?   r      )rD   	randranger2   append_gen_awkward_inner)shaperngr5   ZMAX_RAGGED_DIM_LENZcurr_dim_lenlil_r    r    r!   rK   H   s    
rK   c           	      C   s   ddl }| d dkrtdtd}t| } t| dkrdd t| D }dd | D } |tj	| |d}|D ]}|j
||d	 d
}qv|S t| ||}|t||}t| D ]\}}|dk	r|||}q|S )ah  Function to generate an awkward array with random values.

    Awkward array dimensions can either be fixed-length ("regular") or variable length ("ragged")
    (the first dimension is always fixed-length).


    Parameters
    ----------
    shape
        shape of the array to be generated. Any dimension specified as `None` will be simulated as ragged.
    r   Nz)The first dimension must be fixed-length.{   c                 S   s   g | ]\}}|d kr|qS Nr    )r$   r)   sr    r    r!   r'   q   s      zgen_awkward.<locals>.<listcomp>c                 S   s   g | ]}|d k	r|qS rQ   r    )r$   rR   r    r    r!   r'   r   s      r5   rH   )Zaxis)awkward
ValueErrorr   Randomr   r-   any	enumerateZArrayemptyZ
singletonsrK   Zvalues_astyper   Z
to_regular)	rL   r5   akrM   Zvar_dimsr8   drN   r)   r    r    r!   gen_awkward[   s$    

r\   )returnc                 C   s   d}t  }t| }|||jd  k rZt| |d}|jd t| |_|||j< |d7 }q|jd | d |f  }|d k	r||_|S )Nr   rH   rB   rO   )r0   r1   rF   rL   r*   strZiloccopy)r3   r4   r+   r*   rR   dfnew_valsr    r    r!   gen_typed_df_t2_size   s    

rb   zCollection[Type])rL   r   r   r   r]   c                    sL  ddl m} | \}}tdd t| d D }	tdd t| d D }
t||	}t||
}|jtddd	d
 |jtddd	d
 |dkrd}n|tj	
dd||f|}ttj		|dftj	|dddt||	t|df|j		|dfd}fdd| D }ttj		|dftj	|dddt||
t|df|j		|dfd}fdd| D }ttj		||ftj	||dd|j		||fd} fdd| D }ttj		||ftj	||ddd}ttj		||ftj	||ddd}tt|dtdddttdddtdtdd }t|||||||||d!	}|S )"a      Helper function to generate a random AnnData for testing purposes.

    Note: For `obsm_types`, `varm_types`, and `layers_types` these currently
    just filter already created objects.
    In future, these should choose which objects are created.

    Params
    ------
    shape
        What shape you want the anndata to be.
    X_type
        What kind of container should `X` be? This will be called on a randomly
        generated 2d array.
    X_dtype
        What should the dtype of the `.X` container be?
    obsm_types
        What kinds of containers should be in `.obsm`?
    varm_types
        What kinds of containers should be in `.varm`?
    layers_types
        What kinds of containers should be in `.layers`?
    r   Nc                 s   s   | ]}d | V  qdS )cellNr    r(   r    r    r!   	<genexpr>   s     zgen_adata.<locals>.<genexpr>c                 s   s   | ]}d | V  qdS )ZgeneNr    r(   r    r    r!   rd      s     rH   Zobs_cat)r@   T)r*   ZinplaceZvar_catd   g{Gzt?r;   Zcsr)format)r-   r   r`   Zawk_2d_raggeddac                    s"   i | ]\}}t | kr||qS r    typer$   kv)r   r    r!   
<dictcomp>   s       zgen_adata.<locals>.<dictcomp>c                    s"   i | ]\}}t | kr||qS r    rh   rj   )r   r    r!   rm      s       )r-   r   rg   c                    s"   i | ]\}}t | kr||qS r    rh   rj   )r   r    r!   rm      s       )r-   r   r   r^   *   g      @)r-   )Z
scalar_strZ
scalar_intZscalar_floatZnested_further)
   r   )   NN)Z
O_recarraynestedZawkward_regularZawkward_ragged)	Xobsvarobsmvarmlayersobspvarpuns)
dask.arrayr-   r0   Indexr2   rF   renamedictr   r   ZbinomialZastyper   r\   itemsr9   aranger   )rL   ZX_typeZX_dtyper   r   r   rg   MN	obs_names	var_namesrs   rt   rr   ru   rv   rw   rx   ry   rz   Zadatar    )r   r   r   r!   	gen_adata   s    +



  r   r:   c                 C   sH   t jt| td}t jjtt| t j|t| ddd}d||< |S )NrS   r    Fr6   replaceT)r   ZzerosrD   rA   r   r   r2   r,   )r+   min_sizebselectedr    r    r!   array_bool_subset  s    
r   c              	   C   sB   t  0 t dt tt| |dt| d}W 5 Q R X |S )Nignorer   rH   )	warningscatch_warningssimplefilterPendingDeprecationWarningr   matrixr   r/   rD   )r+   r   Zindexerr    r    r!   matrix_bool_subset  s    
r   c                 C   s   t t| |dt| dS )Nr   rH   )r   
csr_matrixr   r/   rD   r+   r   r    r    r!   spmatrix_bool_subset  s    r   c                 C   sF   t | |k r$td| dt |  tjj| tj|t | dddS Nzmin_size (=z$) must be smaller than len(index) (=r    Fr   )rD   rU   r   r   r   r,   r   r    r    r!   array_subset  s      r   c                 C   sP   t | |k r$td| dt |  tjjtt | tj|t | dddS r   )rD   rU   r   r   r   r   r,   r   r    r    r!   array_int_subset'  s    r   c                 C   sN   t jjt t| d ddd}tt| }tt|t|  |kr qJq |S )NrH   r:   Fr   )	r   r   r   r   rD   slicesortedr2   indices)r+   r   ZpointsrR   r    r    r!   slice_subset3  s
     r   c                 C   s   | t jdt|  S Nr   )r   r   r,   rD   rB   r    r    r!   single_subset<  s    r   )paramsc                 C   s   | j S rQ   )param)requestr    r    r!   subset_func@  s    r   c                 C   s   | d k	rd| dS dS d S )NzError raised from element .r   r    	elem_namer    r    r!   
format_msgT  s    r   c                    s   t  dd fdd
}|S )z2Report name of element being tested if test fails.N
_elem_namec              
      s   z ||W S  t k
r } zf| d k	r|t|ds|t| }t|j}t|dkrV|g}n|d  d| |d< t||_d|_|W 5 d }~X Y nX d S )N_name_attachedr   z

T)	Exceptionhasattrr   r.   argsrD   tupler   )r   r   kwargsemsgfuncr    r!   func_wrapper_  s    

z!report_name.<locals>.func_wrapper)r   )r   r   r    r   r!   report_name\  s    r   c                 C   s   | |kst dS )z0Allows reporting elem name for simple assertion.NAssertionError)ar   r    r    r!   _assert_equalr  s    r   Fc                 C   s   t | ||d d S )Nr   )r   r   r   exactr   r    r    r!   assert_equalx  s    r   c                 C   s   t |}|sRt| rRt|rR| j|jks4tt|tj| |ddstt|nj|st| drt|drt| j	dkrt|j	dkrt
t| t||| nt| |kstt|d S )NT)Z	equal_nanr5   rH   r   )r   r
   rL   r   r   r   Zallcloser   rD   r5   r   r0   r1   allr   r    r    r!   assert_equal_ndarray}  s     r   c                 C   s   t t| t|||d d S Nr   r   )r   r   r   r    r    r!   assert_equal_arrayview  s    r   c                 C   s   t | } t|| ||d d S Nr   r   r   r   r    r    r!   assert_equal_sparse  s    r   c                 C   s   t | } t|| ||d d S r   r   r   r    r    r!   assert_equal_h5py_dataset  s    r   c                 C   s:   ddl m} |r$|| |dddd n|| |dddd d S )Nr   )	assert_eqTF)check_dtypeZ
check_typeZcheck_graph)Zdask.array.utilsr   )r   r   r   r   r   r    r    r!   assert_equal_dask_array  s    r   c                 C   s:   t |tjst|| || ttjj| ||||dd d S )NF)Zcheck_index_typecheck_exactr   Zcheck_frame_type)
isinstancer0   r1   r   r   testingZassert_frame_equalr   r    r    r!   are_equal_dataframe  s    
r   c                 C   s\   dd l }|r8| j|jks8t| j d|j dt| || ||ksXtt|d S )Nr   z != z, )rT   ri   r   r   Zto_list)r   r   r   r   rZ   r    r    r!   assert_equal_awkarray  s    ,r   c                 C   sb   t |  t | ks$tt||  D ]0}|d kr<d}t| | || || d|  q,d S )Nr   /)setkeysr   r   r   )r   r   r   r   rk   r    r    r!   assert_equal_mapping  s
    $r   c                 C   sp   | j j| j jf}|j j|j jf}| jD ]}t|| || ||d q&| j|jks\tt|t| |||d d S r   )	parentr   r   Zaxesr   attrnamer   r   r   )r   r   r   r   Z	a_indicesZ	b_indicesZaxis_idxr    r    r!   assert_equal_aligned_mapping  s    
   r   c                 C   s:   |s t tjj| |dd|d nt tjj| ||d d S )NF)Zcheck_namesZcheck_categoricalr   r   )r   r0   r   Zassert_index_equalr   r    r    r!   assert_equal_index  s    
    r   c                 C   s   t tjj| ||||d d S )N)r   r   r   )r   r0   r   Zassert_extension_array_equalr   r    r    r!   assert_equal_extension_array  s    
r   c                 C   sL   dd }t |||d dD ]*}tt| |t|||| d| d qd S )Nc                 S   s   | d k	st d S rQ   r   xr    r    r!   assert_is_not_none  s    z,assert_equal_raw.<locals>.assert_is_not_noner   )rr   rt   rv   r   r   r   )r   r   getattr)r   r   r   r   r   attrr    r    r!   assert_equal_raw  s    r   r   c                    s    fdd}t | j|j||dd t | j|j||dd |stdtdg}d}t| j|jkst| j|d< d	}t| j|jks| j|d
< d	}|r|t|  }dD ]$}t t| |t|||||d qdS )u'      Check whether two AnnData objects are equivalent,
    raising an AssertionError if they aren’t.

    Params
    ------
    a
    b
    exact
        Whether comparisons should be exact or not. This has a somewhat flexible
        meaning and should probably get refined in the future.
    c                    s    d kr| S   d|  S d S )Nr   r    r   r   r    r!   fmt_name  s    z$assert_adata_equal.<locals>.fmt_namer   r   r   NFr   TrH   )
rr   rs   rt   ru   rv   rw   rz   rx   ry   raw)	r   r   r   r   r   r   r   r_   r   )r   r   r   r   r   idxZchange_flagr   r    r   r!   assert_adata_equal  s*    

r   c                 C   s   dd l m} || S r   )r{   r-   r   )r   rg   r    r    r!   as_dense_dask_array9  s    r   c                 C   s   t |  S rQ   )r   Ztoarray)r   r    r    r!   rO   @  s    rO   )N)N)NN)r:   )r:   )r:   )r:   )r:   )r:   )FN)FN)FN)FN)FN)FN)FN)FN)FN)FN)FN)FN)FN)FN)Y	functoolsr   r   stringr   typingr   r   r   collections.abcr   r	   r   Zh5pynumpyr   Zpandasr0   Zpandas.api.typesr
   ZpytestZscipyr   r   Zanndatar   r   Zanndata._core.viewsr   Zanndata._core.sparse_datasetr   Zanndata._core.aligned_mappingr   Zanndata.utilsr   Zanndata.compatr   r   r~   r   Zndarrayr1   ZGEN_ADATA_DASK_ARGSr9   rF   rK   rE   r\   rb   Zfloat32intr   r   r   r   r   r   r   r   Zfixturer   r   r   r   r   registerr   r   Zspmatrixr   ZDatasetr   r   r   r   r   r   r|   r   api
extensionsZExtensionArrayr   r   rA   r^   r   r   rO   r    r    r    r!   <module>   s   

(
p

	




	
	






	
      ;

