U
    mdb                     @   s  d 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m	Z	 ddl
mZ ddlmZ ddlmZmZ ddlmZmZ dd	lmZmZmZmZmZmZmZ ddlZ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+m,Z, ddl-m.Z/ ddl0m1Z1 G dd deZ2e2j3Z4ede5ej6f Z7dZ8dd Z9eee:f ee; dddZ<ee;e;f dddZ=e;d d!d"Z>dbee;d#d$d%Z?ee;d#d&d'Z@d(d) ZAd*d+ ZBe"edeCf eCd,d-d.ZDdcd/d0ZEddd1d2ZFdee"e;e;e,d5 eGee5 d6d7d8ZHd9d: ZIdfd<d=ZJd>d? ZKd@dA ZLejMe5dBdCdDZNdgee;ef ee;ef ee;ef dEdFdGZOeejMe jPf dHdIdJZQdhdMdNZRdidOdPZSdjejMe5e5eejMejMf dQdRdSZTdkejMe5e5eejMejMf dTdUdVZUe	dWdXdYZVdZd[ ZWd\d] ZXG d^d_ d_ZYd`da ZZdS )lzUtility functions and classes

This file largely consists of the old _utils.py file. Over time, these functions
should be moved of this file.
    N)Enum)Path)WeakSet)
namedtuple)partialwraps)
ModuleType
MethodType)UnionCallableOptionalMappingAnyDictTuple)random)sparse)AnnData__version__)dedent)version   )settings)Literal)logging   )is_constantc                   @   s   e Zd ZdZdS )Emptyr   N)__name__
__module____qualname__token r"   r"   O/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/scanpy/_utils/__init__.pyr       s   r   gV瞯<c                  C   s   ddl m}  | d}tttdk rJddlm} td| dt d|td	k r|d
dlm} t	d| d| d d S )Nr   )pkg_versionz
umap-learnz0.6.10)r   zScanpy z% needs anndata version >=0.6.10, not z).
Run `pip install anndata -U --no-deps`.z0.3.0r   z! needs umap version >=0.3.0, not .)
_compatr$   r   parseanndata_version r   ImportErrorloggwarning)r$   Zumap_versionr   r"   r"   r#   check_versions,   s    r-   )c_or_freturnc                    s|   t | dd d krd S t| }t| tr@t| dr@t| j n
t|  td fddd	 fdd|
dD S )	N__doc____init__)namec                    sD    j |  }t|jdt|j}|j|jk	r<| d|jdS |S d S )Nr    z, optional (default: ))
parametersgetattr
annotationreprdefaultempty)r2   paramcls)sigr"   r#   type_docL   s
    
zgetdoc.<locals>.type_doc
c                 3   s2   | ]*}|   jkr&| d | n|V  qdS )z : N)stripr4   ).0liner<   r=   r"   r#   	<genexpr>T   s   zgetdoc.<locals>.<genexpr>)r5   inspectgetdoc
isinstancetypehasattr	signaturer1   strjoinsplit)r.   docr"   rB   r#   rE   C   s    

rE   arg_mappingc                    s    fdd}|S )aX  
    Decorator which marks a functions keyword arguments as deprecated. It will
    result in a warning being emitted when the deprecated keyword argument is
    used, and the function being called with the new argument.

    Parameters
    ----------
    arg_mapping
        Mapping from deprecated argument name to current argument name.
    c                    s   t   fdd}|S )Nc               	      sr   t dt   D ]F\}}||krt jd| d| d| dtdd ||}|||< qt dt | |S )	NalwayszKeyword argument 'z$' has been deprecated in favour of 'z'. 'z&' will be removed in a future version.r   )category
stacklevelr8   )warningssimplefilterDeprecationWarningitemswarnpop)argskwargsoldnewval)rO   funcr"   r#   func_wrapperg   s    

z=deprecated_arg_names.<locals>.decorator.<locals>.func_wrapper)r   )r^   r_   rN   )r^   r#   	decoratorf   s    z'deprecated_arg_names.<locals>.decoratorr"   )rO   r`   r"   rN   r#   deprecated_arg_namesZ   s    ra   )rootc                 C   s>   t | do<| jdd d o<t| dt| d| j|S )Nr   r%   _r   r    )rH   r   rL   
startswithr5   )objrb   r"   r"   r#   _one_of_ours~   s    
  rg   )modrb   c                 c   s   |d krt  }t|  D ]}t||s*qt|rxt|tsx|V  t|trt| D ]}t|rXt||rX|V  qXqt|tr||kr|j	
drq|| t|||E d H  qd S )Nzscanpy.tests)r   varsvaluesrg   callablerF   r	   rG   r   r   re   adddescend_classes_and_funcs)rh   rb   Zencounteredrf   mr"   r"   r#   rm      s     



rm   c                 C   s    t | |D ]}tt||_q
d S N)rm   r   rE   )rh   rb   r.   r"   r"   r#   annotate_doc_types   s    rp   c                     s    fdd}|S )zQ    Docstrings should start with "" in the first line for proper formatting.
    c                    s   | j | _t| j  | _ | S ro   )r0   Z__orig_doc__r   
format_map)rf   kwdsr"   r#   dec   s    z_doc_params.<locals>.decr"   )rs   rt   r"   rr   r#   _doc_params   s    ru   c                  K   s2   dd |   D }t|dkr.td| ddS )zChecks for invalid arguments when an array is passed.

    Helper for functions that work on either AnnData objects or array-likes.
    c                 S   s   g | ]\}}|d k	r|qS ro   r"   )r@   kvr"   r"   r#   
<listcomp>   s      z3_check_array_function_arguments.<locals>.<listcomp>r   z
Arguments z/ are only valid if an AnnData object is passed.N)rV   len	TypeError)rZ   Zinvalid_argsr"   r"   r#   _check_array_function_arguments   s
    
r{   )adatause_rawr/   c                 C   s"   |dk	r|S | j dk	rdS dS dS )z
    Normalize checking `use_raw`.

    My intentention here is to also provide a single place to throw a deprecation warning from in future.
    NTF)raw)r|   r}   r"   r"   r#   _check_use_raw   s
    
r   c                 C   s   ddl }|  \}}| ||f }t|tjr2|j}|j|d}|| jd  |	t
t|| z||jd< W n tk
r   Y nX | | jd krtd|  d |S )z'Get igraph graph from adjacency matrix.r   N)directedweightzThe constructed graph has only z8 nodes. Your adjacency matrix contained redundant nodes.)ZigraphZnonzerorF   npmatrixA1ZGraphZadd_verticesshapeZ	add_edgeslistzipesKeyErrorvcountr+   r,   )Z	adjacencyr   Zigsourcestargetsweightsgr"   r"   r#   get_igraph_from_adjacency   s"    r   c                 C   s   ddl m} |  }|d kr,dgt| }n
| j| }|  s\|dd |D  || |  }||f}t|dkr||t| f|dS ||S d S )Nr   )
csr_matrixr   c                 S   s   g | ]\}}||fqS r"   r"   )r@   urw   r"   r"   r#   rx      s     z*get_sparse_from_igraph.<locals>.<listcomp>)r   )	Zscipy.sparser   Zget_edgelistry   r   Zis_directedextendr   r   )graphZweight_attrr   edgesr   r   r"   r"   r#   get_sparse_from_igraph   s    

r   
prediction{Gz?)r   	reference)r|   r   r   normalization	thresholdmax_n_namesc                    s  |dkrt dt|  | j| jjD ] }|tjkr*td|d q*g }g  t	| j| jjD ]\}}	d|	krt
|}	| j| j|	k}
|
tj} g g7  | j| jjD ]}| j| j|ktj}| }d||
< |dkrt|t||  t| }n"t|t||  t| } d  |g7  < q fd	d
t d ddd D }|d|d| g7 }qftdddg}||t dS )ay  Compute overlaps between groups.

    See ``identify_groups`` for identifying the groups.

    Parameters
    ----------
    adata
    prediction
        Field name of adata.obs.
    reference
        Field name of adata.obs.
    normalization
        Whether to normalize with respect to the predicted groups or the
        reference groups.
    threshold
        Do not consider associations whose overlap is below this fraction.
    max_n_names
        Control how many reference names you want to be associated with per
        predicted name. Set to `None`, if you want all.

    Returns
    -------
    asso_names
        List of associated reference names
        (`max_n_names` for each predicted name).
    asso_matrix
        Matrix where rows correspond to the predicted labels and columns to the
        reference labels, entries are proportional to degree of association.
    >   r   r   z?`normalization` needs to be either "prediction" or "reference".zIgnoring category u.    as it’s in `settings.categories_to_ignore`.?r   r   rc   c                    s6   g | ].} d  | kr| t jkr.| ndqS )rc   r)   )r   categories_to_ignore)r@   iasso_matrixZcatsr   r"   r#   rx   K  s   z8compute_association_matrix_of_groups.<locals>.<listcomp>Nr>   $compute_association_matrix_of_groups
asso_namesr   )r   r   )
ValueErrorsanitize_anndataobscat
categoriesr   r   r+   info	enumeraterJ   rj   astyper   Zint8copysumargsortrK   r   array)r|   r   r   r   r   r   r   r   Zipred_groupZ
pred_groupZ	mask_predZmask_pred_intZ	ref_groupZmask_refZmask_ref_or_predZratio_containedZname_list_predResultr"   r   r#   r      sP    %



 r   c                    s    fddt  jd D S )Nc                    s,   g | ]$  fd dt jd D qS )c                    s   i | ]}|  |f qS r"   r"   )r@   Zi_ref)r   i_predreference_colorsr"   r#   
<dictcomp>Y  s    z>get_associated_colors_of_groups.<locals>.<listcomp>.<dictcomp>r   ranger   )r@   r   r   )r   r#   rx   X  s   z3get_associated_colors_of_groups.<locals>.<listcomp>r   r   )r   r   r"   r   r#   get_associated_colors_of_groupsW  s    r   Fc                    s   t j| dd\}}tt||t j|dd\}}tt|| i }i }|D ]t j|| k dd\}	 fddt|	D }
fddt|	D }t j|
|f }t j|dd}t |ddd	 }|	| |< || |< qL|r||fS |S dS )
a  Which predicted label explains which reference label?

    A predicted label explains the reference label which maximizes the minimum
    of ``relative_overlaps_pred`` and ``relative_overlaps_ref``.

    Compare this with ``compute_association_matrix_of_groups``.

    Returns
    -------
    A dictionary of length ``len(np.unique(ref_labels))`` that stores for each
    reference label the predicted label that best explains it.

    If ``return_overlaps`` is ``True``, this will in addition return the overlap
    of the reference group with the predicted group; normalized with respect to
    the reference group size and the predicted group size, respectively.
    T)Zreturn_countsc                    s    g | ]\}}|  |  qS r"   r"   r@   r   n)	pred_dictsub_pred_countsr"   r#   rx   |  s    z#identify_groups.<locals>.<listcomp>c                    s    g | ]\}}|    qS r"   r"   r   )ref_dict	ref_labelr   r"   r#   rx     s   r   )ZaxisNrc   )r   uniquedictr   r   Zc_minr   )Z
ref_labelsZpred_labelsZreturn_overlapsZ
ref_uniqueZ
ref_countsZpred_uniqueZpred_countsZassociated_predictionsZassociated_overlapsZsub_pred_uniqueZrelative_overlaps_predZrelative_overlaps_refZrelative_overlapsZrelative_overlaps_minZpred_best_indexr"   )r   r   r   r   r#   identify_groupsa  s2    
 
r   c                 C   s   |    dS )z-Transform string annotations to categoricals.N)	_sanitizer|   r"   r"   r#   r     s    r   c                 C   s&   | j r"tjddd | |   d S )Nz-Received a view of an AnnData. Making a copy.r   )rR   )Zis_viewrS   rW   Z_init_as_actualr   r   r"   r"   r#   view_to_actual  s    r   )ar   c                 C   sD   t j| td}||d |d|   ||d< ||d d | S )a-  Moving average over one-dimensional array.

    Parameters
    ----------
    a
        One-dimensional array.
    n
        Number of entries to average over. n=2 means averaging over the currrent
        the previous entry.

    Returns
    -------
    An array view storing the moving average.
    dtypeNr   )r   Zcumsumfloat)r   r   retr"   r"   r#   moving_average  s    "r   )
old_params
new_paramsr/   c                 C   sb   t | }|r^| D ]H\}}|| krL|rLtd| d d tt|   |dk	r|||< q|S )aX      Update old_params with new_params.

    If check==False, this merely adds and overwrites the content of old_params.

    If check==True, this only allows updating of parameters that are already
    present in old_params.

    Parameters
    ----------
    old_params
    new_params
    check

    Returns
    -------
    updated_params
    'z ' is not a valid parameter key, zconsider one of 
N)r   rV   r   rJ   r   keys)r   r   checkZupdated_paramskeyr]   r"   r"   r#   update_params  s$    
r   )Xc                 C   sn   ddl m} t| tjr| n| j}t| r4dS t|j	j
|rFdS ttt|dd rfdS dS dS )z-Checks values of X to ensure it is count datar   )IntegralFTr   N)numbersr   rF   r   ndarraydataZsignbitany
issubclassr   rG   equalrh   )r   r   r   r"   r"   r#   check_nonnegative_integers  s    r   allgroupsc           
   	   C   s  | j | jj}|d | jkr,| j|d  }ntjt| j | jj| j | jjft	d}t
| j | jjD ]b\}}| j | jj| | j | jkr| j | jj| | j | jk}nt|| j | jk}|||< qhttt|}|dkrg }|D ],}|t| j | jjj|kd d  qt|dkr`tttt| j | jjtt|d }t|dkrtt| d| j | jj  ddlm}	 |	d || }| j | jj| j}n|j}||fS )z'Get subset of groups in adata.obs[key].Z_masksr   r   r   z7 invalid! specify valid groups_order (or indices) from )exit)r   r   r   unsr   Zzerosry   rj   sizeboolr   rJ   r   r   appendwhereZin1daranger   r   r+   debugsysr   )
r|   Zgroups_order_subsetr   Zgroups_orderZgroups_masksZinamer2   maskZ
groups_idsr   r"   r"   r#   select_groups  sL      

 r   c              	   C   s@   ddl }|  t|dr|ntj}tt| |||| dS )zGet full tracebacks when warning is raised by setting

    warnings.showwarning = warn_with_traceback

    See also
    --------
    http://stackoverflow.com/questions/22373927/get-traceback-of-warnings
    r   Nwrite)		tracebackprint_stackrH   r   stderrr   r   rS   formatwarning)messagerQ   filenamelinenofilerA   r   logr"   r"   r#   warn_with_traceback&  s
    	r   )r   	subsampleseedr/   c                 C   s   |dkr(|dkr(| t j| jd tdfS |dkr^t jd| jd |td}|j}t | | }nD|dk rttd| t| jd | }t j| t	| |d\}}t
d| d| jd  d ||fS )	a|      Subsample a fraction of 1/subsample samples from the rows of X.

    Parameters
    ----------
    X
        Data array.
    subsample
        1/subsample is the fraction of data sampled, n = X.shape[0]/subsample.
    seed
        Seed for sampling.

    Returns
    -------
    Xsampled
        Subsampled X.
    rows
        Indices of rows that are stored in Xsampled.
    r   r   r   zInvalid seed value < 0: )r   z... subsampled to z of z data points)r   r   r   intr   r   r   r   r   subsample_nr+   r   )r   r   r   rowsr   Xsampledr"   r"   r#   r   8  s    r   )r   r   r   r/   c                 C   sh   |dk rt dtj| |dks2|| jd kr<| jd n|}tjj| jd |dd}| | }||fS )a  Subsample n samples from rows of array.

    Parameters
    ----------
    X
        Data array.
    n
        Sample size.
    seed
        Seed for sampling.

    Returns
    -------
    Xsampled
        Subsampled X.
    rows
        Indices of rows that are stored in Xsampled.
    r   zn must be greater 0F)r   replace)r   r   r   r   r   choice)r   r   r   r   r   r"   r"   r#   r   b  s    $r   )r   c                 C   s"   |   sddlm} |||  dS )z,Check if file is present otherwise download.r   )	_downloadN)is_fileZ	readwriter   )r   Z
backup_urlr   r"   r"   r#   check_presence_download  s    r   c                 C   sZ   zt j|  W S  tk
rT   tj| }tj|}tj|j}|	| | Y S X dS )uD   Imports a module in a way that it’s only executed on member accessN)
r   modulesr   	importlibutil	find_specmodule_from_spec
LazyLoaderloaderexec_module)Z	full_namespecmoduler  r"   r"   r#   lazy_import  s    
r  c                 C   s8   |d kr|| kr| | }|d kr0|| kr0| | }||fS ro   r"   )dctZconnsdistsZ	conns_keyZ	dists_keyr"   r"   r#   _fallback_to_uns  s
    r
  c                   @   s*   e Zd ZdZd	ddZdd Zdd ZdS )
NeighborsViewa  Convenience class for accessing neighbors graph representations.

    Allows to access neighbors distances, connectivities and settings
    dictionary in a uniform manner.

    Parameters
    ----------

    adata
        AnnData object.
    key
        This defines where to look for neighbors dictionary,
        connectivities, distances.

        neigh = NeighborsView(adata, key)
        neigh['distances']
        neigh['connectivities']
        neigh['params']
        'connectivities' in neigh
        'params' in neigh

        is the same as

        adata.obsp[adata.uns[key]['distances_key']]
        adata.obsp[adata.uns[key]['connectivities_key']]
        adata.uns[key]['params']
        adata.uns[key]['connectivities_key'] in adata.obsp
        'params' in adata.uns[key]
    Nc                 C   s   d | _ d | _|d ks|dkrHd|jkr.td|jd | _d| _d| _n>||jkrbtd| d|j| | _| jd | _| jd | _| j|jkr|j| j | _ | j|jkr|j| j | _t| j| j | j| j| j\| _ | _d S )	N	neighborszNo "neighbors" in .unsconnectivities	distancesNo "z	" in .unsZconnectivities_keyZdistances_key)	_connectivities
_distancesr   r   _neighbors_dict
_conns_key
_dists_keyobspr
  )selfr|   r   r"   r"   r#   r1     s0    

zNeighborsView.__init__c                 C   s^   |dkr(d| kr"t d| j d| jS |dkrPd| krJt d| j d| jS | j| S d S )Nr  r  z
" in .obspr  )r   r  r  r  r  r  r  r   r"   r"   r#   __getitem__  s    zNeighborsView.__getitem__c                 C   s2   |dkr| j d k	S |dkr$| jd k	S || jkS d S )Nr  r  )r  r  r  r  r"   r"   r#   __contains__  s
    

zNeighborsView.__contains__)N)r   r   r    r0   r1   r  r  r"   r"   r"   r#   r    s   
r  c                 C   sP   |dk	r|dk	rt d|dk	r*| j| S t| |}d|krDt d|d S dS )z<Choose connectivities from neighbbors or another obsp columnNzCYou can't specify both obsp, neighbors_key. Please select only one.r  zEYou need to run `pp.neighbors` first to compute a neighborhood graph.)r   r  r  )r|   r  Zneighbors_keyr  r"   r"   r#   _choose_graph  s    

r  )N)N)N)r   r   r   )F)F)r   r   )NN)r   r   )r   r   )[r0   r   rD   rS   importlib.utilr   enumr   pathlibr   weakrefr   collectionsr   	functoolsr   r   typesr   r	   typingr
   r   r   r   r   r   r   numpyr   r   Zscipyr   Zanndatar   r   r(   textwrapr   	packagingr   Z	_settingsr   r&   r   r)   r   r+   Zcompute.is_constantr   r   r!   _emptyr   ZRandomStateZ	AnyRandomZEPSr-   rG   rJ   rE   ra   rg   rm   rp   ru   r{   r   r   r   r   r   r   r   r   r   r   r   r   r   Zspmatrixr   r   r   r   r   r   r  r
  r  r  r"   r"   r"   r#   <module>   s   $$


   Y

3	 


,
.
  +     	S