U
    Åmœd3  ã                   @   sÐ  d Z ddl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mZ ddlmZ dd	lmZmZ edddddd
dœeeee	jejf  ee ee ee ee eee	jef dœdd„ƒZedd�e	je	je	je	je	jee	jedœdd„ƒZedd�e	je	je	je	je	jedœdd„ƒZeddd�e	je	je	je	jedœdd„ƒZeddd�e	je	je	je	je	jdœdd„ƒZeddd�e	je	je	je	je	je	je e	jdœdd „ƒZ!e "ej#¡e	jd!œd"d#„ƒZ$dS )$z)Moran's I global spatial autocorrelation.é    )ÚUnionÚOptional)Úsingledispatch)ÚAnnDataN)Úsparse)ÚnjitÚprange)Ú_get_obs_rep)Ú_resolve_valsÚ_check_valsF)ÚvalsÚ	use_graphÚlayerÚobsmÚobspÚuse_raw)Úadatar   r   r   r   r   r   Úreturnc                C   sx   |dkrLt | dƒr(d| jkr(| jd }qRd| jkrB| jd d }qRtdƒ‚ntƒ ‚|dkrnt| ||||d�j}t||ƒS )uc  
    Calculate Moranâ€™s I Global Autocorrelation Statistic.

    Moranâ€™s I is a global autocorrelation statistic for some measure on a graph. It is commonly used in
    spatial data analysis to assess autocorrelation on a 2D grid. It is closely related to Geary's C,
    but not identical. More info can be found `here <https://en.wikipedia.org/wiki/Moran%27s_I>`_.

    .. math::

        I =
            \frac{
                N \sum_{i, j} w_{i, j} z_{i} z_{j}
            }{
                S_{0} \sum_{i} z_{i}^{2}
            }

    Params
    ------
    adata
    vals
        Values to calculate Moran's I for. If this is two dimensional, should
        be of shape `(n_features, n_cells)`. Otherwise should be of shape
        `(n_cells,)`. This matrix can be selected from elements of the anndata
        object by using key word arguments: `layer`, `obsm`, `obsp`, or
        `use_raw`.
    use_graph
        Key to use for graph in anndata object. If not provided, default
        neighbors connectivities will be used instead.
    layer
        Key for `adata.layers` to choose `vals`.
    obsm
        Key for `adata.obsm` to choose `vals`.
    obsp
        Key for `adata.obsp` to choose `vals`.
    use_raw
        Whether to use `adata.raw.X` for `vals`.


    This function can also be called on the graph and values directly. In this case
    the signature looks like:

    Params
    ------
    g
        The graph
    vals
        The values


    See the examples for more info.

    Returns
    -------
    If vals is two dimensional, returns a 1 dimensional ndarray array. Returns
    a scalar if `vals` is 1d.


    Examples
    --------

    Calculate Morans I for each components of a dimensionality reduction:

    .. code:: python

        import scanpy as sc, numpy as np

        pbmc = sc.datasets.pbmc68k_processed()
        pc_c = sc.metrics.morans_i(pbmc, obsm="X_pca")


    It's equivalent to call the function directly on the underlying arrays:

    .. code:: python

        alt = sc.metrics.morans_i(pbmc.obsp["connectivities"], pbmc.obsm["X_pca"].T)
        np.testing.assert_array_equal(pc_c, alt)
    Nr   ZconnectivitiesZ	neighborszMust run neighbors first.)r   r   r   r   )Úhasattrr   ZunsÚ
ValueErrorÚNotImplementedErrorr	   ÚTÚmorans_i)r   r   r   r   r   r   r   Úg© r   úQ/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/scanpy/metrics/_morans_i.pyr      s    X

r   T)Úcache)Úg_dataÚ	g_indicesÚg_indptrÚx_dataÚ	x_indicesÚNÚWr   c                 C   s(   t j||jd�}|||< t| ||||ƒS )N©Údtype)ÚnpÚzerosr%   Ú_morans_i_vec_W)r   r   r   r    r!   r"   r#   Úxr   r   r   Ú_morans_i_vec_W_sparse{   s    
r*   )r   r   r   r)   r#   r   c                 C   sˆ   ||  ¡  }||  ¡ }t|ƒ}d}t|ƒD ]F}	t||	 ||	d  ƒ}
||
 }| |
 }||||   ¡ ||	  7 }q,t|ƒ| | | S )Ng        é   )ZmeanÚsumÚlenr   Úslice)r   r   r   r)   r#   ÚzZz2ssr"   ZinumÚiÚsZ	i_indicesZi_datar   r   r   r(   Š   s    r(   )r   Úparallel)r   r   r   r)   r   c                 C   s   |   ¡ }t| ||||ƒS )N)r,   r(   )r   r   r   r)   r#   r   r   r   Ú_morans_i_vec    s    r3   )r   r   r   ÚXr   c           
      C   sl   |j \}}|t|ƒd kst‚|  ¡ }tj|tjd�}t|ƒD ](}||d d …f }	t| |||	|ƒ||< q>|S )Nr+   r$   )	Úshaper-   ÚAssertionErrorr,   r&   r'   Úfloat_r   r(   )
r   r   r   r4   ÚMr"   r#   ÚoutÚkr)   r   r   r   Ú_morans_i_mtx«   s    
r;   )r   r   r   ÚX_dataÚ	X_indicesÚX_indptrÚX_shaper   c              	   C   sz   |\}}|   ¡ }	tj|tjd�}
t ||dd… ¡}t ||dd… ¡}t|ƒD ]$}t| |||| || ||	ƒ|
|< qP|
S )Nr$   r+   éÿÿÿÿ)r,   r&   r'   r7   Úsplitr   r*   )r   r   r   r<   r=   r>   r?   r8   r"   r#   r9   Zx_data_listZx_indices_listr:   r   r   r   Ú_morans_i_mtx_csr¼   s     ù
	rB   )r   c                 C   sV  | j d | j d kstdƒ‚t|ƒ}| jjtjdd�}t|tj	ƒr | j d |j d ksZt‚t
|ƒ\}}}t|| j| j|jjtjdd�|j|j|j ƒ}|||< |S t|tjƒrà|jdkrà| j d |j d ksÎt‚t|| j| j|ƒS t|tjƒ�rL|jdk�rL| j d |j d k�st‚t
|ƒ\}}}t|| j| j|jtjdd�ƒ}|||< |S tƒ ‚d S )Nr   r+   z'`g` should be a square adjacency matrixF)Úcopyé   )r5   r6   r
   ÚdataZastyper&   r7   Ú
isinstancer   Ú
csr_matrixr   rB   ÚindicesZindptrÚndarrayÚndimr3   r;   r   )r   r   r   Únew_valsZidxerZfull_resultÚresultr   r   r   Ú	_morans_ià   s@    ù	ürM   )%Ú__doc__Útypingr   r   Ú	functoolsr   Zanndatar   Únumpyr&   Zscipyr   Znumbar   r   Z
scanpy.getr	   Zscanpy.metrics._gearys_cr
   r   rI   ZspmatrixÚstrÚboolÚfloatr   Úintr7   r*   r(   r3   r;   ÚtuplerB   ÚregisterrG   rM   r   r   r   r   Ú<module>   s�   ø÷løú
û

ûþø 
