U
    mdU                     @   s   d dl mZ d dlm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eee eeeeeeeeeeeeee ee eeeee dddZdeeee eeeeeeeeee eeedddZdeeeeedddZdS )    )AnnData)OptionalN)sparse   )logging)preprocessing)_get_obs_rep       @皙?{Gz?      ?	euclideanTF   )adata	adata_sim	batch_keysim_doublet_ratioexpected_doublet_ratestdev_doublet_rate!synthetic_doublet_umi_subsamplingknn_dist_metricnormalize_variancelog_transformmean_centern_prin_compsuse_approx_neighborsget_doublet_neighbor_parentsn_neighbors	thresholdverbosecopyrandom_statereturnc                    sv  zddl }W n tk
r(   tdY nX |r6|  } td}|  d	
fdd	 dk	r| j krtdt	| j } fdd	|D }t
d
d	 |D }|j| jj | _i | jd< tt|dd	 |D | jd d< | jd d< n< }|d d | jd< |d d | jd< |d | jd< tjd|d |rn| S dS dS )u      Predict doublets using Scrublet [Wolock19]_.

    Predict cell doublets using a nearest-neighbor classifier of observed
    transcriptomes and simulated doublets. Works best if the input is a raw
    (unnormalized) counts matrix from a single sample or a collection of
    similar samples from the same experiment.
    This function is a wrapper around functions that pre-process using Scanpy
    and directly call functions of Scrublet(). You may also undertake your own
    preprocessing, simulate doublets with
    scanpy.external.pp.scrublet_simulate_doublets(), and run the core scrublet
    function scanpy.external.pp.scrublet.scrublet().

    .. note::
        More information and bug reports `here
        <https://github.com/swolock/scrublet>`__.

    Parameters
    ----------
    adata
        The annotated data matrix of shape ``n_obs`` × ``n_vars``. Rows
        correspond to cells and columns to genes. Expected to be un-normalised
        where adata_sim is not supplied, in which case doublets will be
        simulated and pre-processing applied to both objects. If adata_sim is
        supplied, this should be the observed transcriptomes processed
        consistently (filtering, transform, normalisaton, hvg) with adata_sim.
    adata_sim
        (Advanced use case) Optional annData object generated by
        sc.external.pp.scrublet_simulate_doublets(), with same number of vars
        as adata. This should have been built from adata_obs after
        filtering genes and cells and selcting highly-variable genes.
    batch_key
        Optional `adata.obs` column name discriminating between batches.
    sim_doublet_ratio
        Number of doublets to simulate relative to the number of observed
        transcriptomes.
    expected_doublet_rate
        Where adata_sim not suplied, the estimated doublet rate for the
        experiment.
    stdev_doublet_rate
        Where adata_sim not suplied, uncertainty in the expected doublet rate.
    synthetic_doublet_umi_subsampling
        Where adata_sim not suplied, rate for sampling UMIs when creating
        synthetic doublets. If 1.0, each doublet is created by simply adding
        the UMI counts from two randomly sampled observed transcriptomes. For
        values less than 1, the UMI counts are added and then randomly sampled
        at the specified rate.
    knn_dist_metric
        Distance metric used when finding nearest neighbors. For list of
        valid values, see the documentation for annoy (if `use_approx_neighbors`
        is True) or sklearn.neighbors.NearestNeighbors (if `use_approx_neighbors`
        is False).
    normalize_variance
        If True, normalize the data such that each gene has a variance of 1.
        `sklearn.decomposition.TruncatedSVD` will be used for dimensionality
        reduction, unless `mean_center` is True.
    log_transform
        Whether to use :func:``~scanpy.pp.log1p`` to log-transform the data
        prior to PCA.
    mean_center
        If True, center the data such that each gene has a mean of 0.
        `sklearn.decomposition.PCA` will be used for dimensionality
        reduction.
    n_prin_comps
        Number of principal components used to embed the transcriptomes prior
        to k-nearest-neighbor graph construction.
    use_approx_neighbors
        Use approximate nearest neighbor method (annoy) for the KNN
        classifier.
    get_doublet_neighbor_parents
        If True, return (in .uns) the parent transcriptomes that generated the
        doublet neighbors of each observed transcriptome. This information can
        be used to infer the cell states that generated a given doublet state.
    n_neighbors
        Number of neighbors used to construct the KNN graph of observed
        transcriptomes and simulated doublets. If ``None``, this is
        automatically set to ``np.round(0.5 * np.sqrt(n_obs))``.
    threshold
        Doublet score threshold for calling a transcriptome a doublet. If
        `None`, this is set automatically by looking for the minimum between
        the two modes of the `doublet_scores_sim_` histogram. It is best
        practice to check the threshold visually using the
        `doublet_scores_sim_` histogram and/or based on co-localization of
        predicted doublets in a 2-D embedding.
    verbose
        If True, print progress updates.
    copy
        If ``True``, return a copy of the input ``adata`` with Scrublet results
        added. Otherwise, Scrublet results are added in place.
    random_state
        Initial state for doublet simulation and nearest neighbors.

    Returns
    -------
    adata : anndata.AnnData
        if ``copy=True`` it returns or else adds fields to ``adata``. Those fields:

        ``.obs['doublet_score']``
            Doublet scores for each observed transcriptome

        ``.obs['predicted_doublets']``
            Boolean indicating predicted doublet status

        ``.uns['scrublet']['doublet_scores_sim']``
            Doublet scores for each simulated doublet transcriptome

        ``.uns['scrublet']['doublet_parents']``
            Pairs of ``.obs_names`` used to generate each simulated doublet
            transcriptome

        ``.uns['scrublet']['parameters']``
            Dictionary of Scrublet parameters

    See also
    --------
    :func:`~scanpy.external.pp.scrublet_simulate_doublets`: Run Scrublet's doublet
        simulation separately for advanced usage.
    :func:`~scanpy.external.pl.scrublet_score_distribution`: Plot histogram of doublet
        scores for observed transcriptomes and simulated doublets.
    r   NLPlease install scrublet: `pip install scrublet` or `conda install scrublet`.zRunning Scrubletc                    s   |d krt j| dd t j| dd | j | jd< t |  t j| dd}t | | d d |j	d f } t
| d	d}rt |  t | t j| d	d
 t j|d	d
 t| | 
d} | j| jd dS )Nr   )Z	min_cells)Z	min_genesrawT)r    Zhighly_variable)layerr   r   g    .A)Z
target_sum)	adata_obsr   r   r   r   r   r   r   r   r   r   r   r!   r   scrublet)obsuns)ppZfilter_genesZfilter_cellsXr    ZlayersZnormalize_totallog1pZhighly_variable_genesvarscrublet_simulate_doublets_scrublet_call_doubletsr(   r)   )Zad_obsZad_simZlogged)r   r   r   r   r   r   r   r   r!   r   r   r   r   r   r    U/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/scanpy/external/pp/_scrublet.py_run_scrublet   sH    



zscrublet.<locals>._run_scrubletzA`batch_key` must be a column of .obs in the input annData object.c                    s&   g | ]} j  |kf qS r0   r(   ).0batch)r2   r&   r   r   r0   r1   
<listcomp>   s   zscrublet.<locals>.<listcomp>c                 S   s   g | ]}|d  qS r3   r0   r4   scrubr0   r0   r1   r6      s     r'   c                 S   s   g | ]}|d  qS )r)   r0   r7   r0   r0   r1   r6     s     batchesZ
batched_byr(   doublet_scorepredicted_doubletr)   z    Scrublet finished)time)N)r'   ImportErrorr    logginfor(   keys
ValueErrornpuniquepdconcatlocZ	obs_namesvaluesr)   dictzip)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   slstartr9   ZscrubbedZscrubbed_obsr0   )r2   r&   r   r   r   r   r   r   r   r   r   r   r!   r   r   r   r   r   r   r1   r'      sH     

*=
	

r'   )r&   r   r   r   r   r   r   r   r   r   r   r   r!   r   r"   c                 C   s  zddl }W n tk
r(   tdY nX |dkrNttdt| jd  }|j| j||||d}t	
| j|_t	
|j|_|jd |_|r|r|| n|r|| n|r|| |rtd t|jtjrt|j|_t|jtjrt|j|_|j|||jd ntd	 |j|||jd |j||	|
d
 |j||d |j| jd< |j|jd ||j di  di  dd||dd| jd< t!|dr|j"| jd d< |j#| jd< n
d| jd< |
r|j$| jd d< | S )uQ      Core function for predicting doublets using Scrublet [Wolock19]_.

    Predict cell doublets using a nearest-neighbor classifier of observed
    transcriptomes and simulated doublets. This is a wrapper around the core
    functions of `Scrublet <https://github.com/swolock/scrublet>`__ to allow
    for flexibility in applying Scanpy filtering operations upstream. Unless
    you know what you're doing you should use the main scrublet() function.

    .. note::
        More information and bug reports `here
        <https://github.com/swolock/scrublet>`__.

    Parameters
    ----------
    adata_obs
        The annotated data matrix of shape ``n_obs`` × ``n_vars``. Rows
        correspond to cells and columns to genes. Should be normalised with
        scanpy.pp.normalize_total() and filtered to include only highly
        variable genes.
    adata_sim
        Anndata object generated by
        sc.external.pp.scrublet_simulate_doublets(), with same number of vars
        as adata_obs. This should have been built from adata_obs after
        filtering genes and cells and selcting highly-variable genes.
    n_neighbors
        Number of neighbors used to construct the KNN graph of observed
        transcriptomes and simulated doublets. If ``None``, this is
        automatically set to ``np.round(0.5 * np.sqrt(n_obs))``.
    expected_doublet_rate
        The estimated doublet rate for the experiment.
    stdev_doublet_rate
        Uncertainty in the expected doublet rate.
    mean_center
        If True, center the data such that each gene has a mean of 0.
        `sklearn.decomposition.PCA` will be used for dimensionality
        reduction.
    normalize_variance
        If True, normalize the data such that each gene has a variance of 1.
        `sklearn.decomposition.TruncatedSVD` will be used for dimensionality
        reduction, unless `mean_center` is True.
    n_prin_comps
        Number of principal components used to embed the transcriptomes prior
        to k-nearest-neighbor graph construction.
    use_approx_neighbors
        Use approximate nearest neighbor method (annoy) for the KNN
        classifier.
    knn_dist_metric
        Distance metric used when finding nearest neighbors. For list of
        valid values, see the documentation for annoy (if `use_approx_neighbors`
        is True) or sklearn.neighbors.NearestNeighbors (if `use_approx_neighbors`
        is False).
    get_doublet_neighbor_parents
        If True, return the parent transcriptomes that generated the
        doublet neighbors of each observed transcriptome. This information can
        be used to infer the cell states that generated a given
        doublet state.
    threshold
        Doublet score threshold for calling a transcriptome a doublet. If
        `None`, this is set automatically by looking for the minimum between
        the two modes of the `doublet_scores_sim_` histogram. It is best
        practice to check the threshold visually using the
        `doublet_scores_sim_` histogram and/or based on co-localization of
        predicted doublets in a 2-D embedding.
    random_state
        Initial state for doublet simulation and nearest neighbors.
    verbose
        If True, print progress updates.

    Returns
    -------
    adata : anndata.AnnData
        if ``copy=True`` it returns or else adds fields to ``adata``:

        ``.obs['doublet_score']``
            Doublet scores for each observed transcriptome

        ``.obs['predicted_doublets']``
            Boolean indicating predicted doublet status

        ``.uns['scrublet']['doublet_scores_sim']``
            Doublet scores for each simulated doublet transcriptome

        ``.uns['scrublet']['doublet_parents']``
            Pairs of ``.obs_names`` used to generate each simulated doublet transcriptome

        ``.uns['scrublet']['parameters']``
            Dictionary of Scrublet parameters
    r   Nr#   g      ?)r   r   r   r!   doublet_parentsz%Embedding transcriptomes using PCA...)r   r!   z/Embedding transcriptomes using Truncated SVD...)r   Zdistance_metricr   )r   r   r:   r'   
parametersr   )r   r   r   r!   )Zdoublet_scores_simrL   rM   
threshold_r   r;   FZdoublet_neighbor_parents)%r'   r=   introundrB   sqrtshapeScrubletr+   r   Z
csc_matrixZ_E_obs_normZ_E_sim_normobsmdoublet_parents_Zpipeline_zscoreZpipeline_mean_centerZpipeline_normalize_variancer>   r?   
isinstancematrixZasarrayZpipeline_pcar!   Zpipeline_truncated_svdZcalculate_doublet_scoresZcall_doubletsZdoublet_scores_obs_r(   Zdoublet_scores_sim_r)   gethasattrrN   Zpredicted_doublets_Zdoublet_neighbor_parents_)r&   r   r   r   r   r   r   r   r   r   r   r   r!   r   rJ   r8   r0   r0   r1   r/     s    i


  
    
r/   )r   r   r   random_seedr"   c           	      C   s   zddl }W n tk
r(   tdY nX t| |d}||}|j||d t|j}|j|jd< |j	|j
d< dd	|ii|jd
< |S )u      Simulate doublets by adding the counts of random observed transcriptome pairs.

    Parameters
    ----------
    adata
        The annotated data matrix of shape ``n_obs`` × ``n_vars``. Rows
        correspond to cells and columns to genes. Genes should have been
        filtered for expression and variability, and the object should contain
        raw expression of the same dimensions.
    layer
        Layer of adata where raw values are stored, or 'X' if values are in .X.
    sim_doublet_ratio
        Number of doublets to simulate relative to the number of observed
        transcriptomes. If `None`, self.sim_doublet_ratio is used.
    synthetic_doublet_umi_subsampling
        Rate for sampling UMIs when creating synthetic doublets. If 1.0,
        each doublet is created by simply adding the UMIs from two randomly
        sampled observed transcriptomes. For values less than 1, the
        UMI counts are added and then randomly sampled at the specified
        rate.

    Returns
    -------
    adata : anndata.AnnData with simulated doublets in .X
        Adds fields to ``adata``:

        ``.obsm['scrublet']['doublet_parents']``
            Pairs of ``.obs_names`` used to generate each simulated doublet transcriptome

        ``.uns['scrublet']['parameters']``
            Dictionary of Scrublet parameters

    See also
    --------
    :func:`~scanpy.external.pp.scrublet`: Main way of running Scrublet, runs
        preprocessing, doublet simulation (this function) and calling.
    :func:`~scanpy.external.pl.scrublet_score_distribution`: Plot histogram of doublet
        scores for observed transcriptomes and simulated doublets.
    r   Nr#   )r%   )r   r   Zn_countsrL   rM   r   r'   )r'   r=   r   rS   Zsimulate_doubletsr   Z_E_simZ_total_counts_simr(   rU   rT   r)   )	r   r%   r   r   rZ   rJ   r+   r8   r   r0   r0   r1   r.     s"    /


r.   )NNr	   r
   r   r   r   TFTr   TFNNTFr   )Nr
   r   TTr   Tr   FNr   T)Nr	   r   r   )Zanndatar   typingr   numpyrB   ZpandasrD   Zscipyr    r   r>   r   r*   rX   r   strfloatboolrO   r'   r/   r.   r0   r0   r0   r1   <module>   s                                    ^    