def preprocess_data(self, div=<NUM_LIT:1>, downsample=<NUM_LIT:0>, sum_norm=None,<EOL>include_genes=None, exclude_genes=None,<EOL>include_cells=None, exclude_cells=None,<EOL>norm='<STR_LIT>', min_expression=<NUM_LIT:1>, thresh=<NUM_LIT>,<EOL>filter_genes=True):
<EOL>try:<EOL><INDENT>D= self.adata_raw.X<EOL>self.adata = self.adata_raw.copy()<EOL><DEDENT>except AttributeError:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>cell_names = np.array(list(self.adata_raw.obs_names))<EOL>idx_cells = np.arange(D.shape[<NUM_LIT:0>])<EOL>if(include_cells is not None):<EOL><INDENT>include_cells = np.array(list(include_cells))<EOL>idx2 = np.where(np.in1d(cell_names, include_cells))[<NUM_LIT:0>]<EOL>idx_cells = np.array(list(set(idx2) & set(idx_cells)))<EOL><DEDENT>if(exclude_cells is not None):<EOL><INDENT>exclude_cells = np.array(list(exclude_cells))<EOL>idx4 = np.where(np.in1d(cell_names, exclude_cells,<EOL>invert=True))[<NUM_LIT:0>]<EOL>idx_cells = np.array(list(set(idx4) & set(idx_cells)))<EOL><DEDENT>if downsample > <NUM_LIT:0>:<EOL><INDENT>numcells = int(D.shape[<NUM_LIT:0>] / downsample)<EOL>rand_ind = np.random.choice(np.arange(D.shape[<NUM_LIT:0>]),<EOL>size=numcells, replace=False)<EOL>idx_cells = np.array(list(set(rand_ind) & set(idx_cells)))<EOL><DEDENT>else:<EOL><INDENT>numcells = D.shape[<NUM_LIT:0>]<EOL><DEDENT>mask_cells = np.zeros(D.shape[<NUM_LIT:0>], dtype='<STR_LIT:bool>')<EOL>mask_cells[idx_cells] = True<EOL>self.adata = self.adata_raw[mask_cells,:].copy()<EOL>D = self.adata.X<EOL>if isinstance(D,np.ndarray):<EOL><INDENT>D=sp.csr_matrix(D,dtype='<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>D=D.astype('<STR_LIT>')<EOL>D.sort_indices()<EOL><DEDENT>if(D.getformat() == '<STR_LIT>'):<EOL><INDENT>D=D.tocsr();<EOL><DEDENT>if (sum_norm == '<STR_LIT>' and norm != '<STR_LIT>'):<EOL><INDENT>s = D.sum(<NUM_LIT:1>).A.flatten()<EOL>sum_norm = np.median(s)<EOL>D = D.multiply(<NUM_LIT:1> / s[:,None] * sum_norm).tocsr()<EOL><DEDENT>elif (sum_norm == '<STR_LIT>' and norm != '<STR_LIT>'):<EOL><INDENT>s = D.sum(<NUM_LIT:0>).A.flatten()<EOL>sum_norm = np.median(s)<EOL>s[s==<NUM_LIT:0>]=<NUM_LIT:1><EOL>D = D.multiply(<NUM_LIT:1> / s[None,:] * sum_norm).tocsr()<EOL><DEDENT>elif sum_norm is not None and norm != '<STR_LIT>':<EOL><INDENT>D = D.multiply(<NUM_LIT:1> / D.sum(<NUM_LIT:1>).A.flatten()[:,<EOL>None] * sum_norm).tocsr()<EOL><DEDENT>self.adata.X = D<EOL>if norm is None:<EOL><INDENT>D.data[:] = (D.data / div)<EOL><DEDENT>elif(norm.lower() == '<STR_LIT>'):<EOL><INDENT>D.data[:] = np.log2(D.data / div + <NUM_LIT:1>)<EOL><DEDENT>elif(norm.lower() == '<STR_LIT>'):<EOL><INDENT>D.data[:] = np.sqrt(D.data/div) + np.sqrt(D.data/div+<NUM_LIT:1>)<EOL><DEDENT>elif norm.lower() == '<STR_LIT>':<EOL><INDENT>ni = D.sum(<NUM_LIT:1>).A.flatten() <EOL>pj = (D.sum(<NUM_LIT:0>) / D.sum()).A.flatten() <EOL>col = D.indices<EOL>row=[]<EOL>for i in range(D.shape[<NUM_LIT:0>]):<EOL><INDENT>row.append(i*np.ones(D.indptr[i+<NUM_LIT:1>]-D.indptr[i]))                <EOL><DEDENT>row = np.concatenate(row).astype('<STR_LIT>')            <EOL>mu = sp.coo_matrix((ni[row]*pj[col], (row,col))).tocsr()<EOL>mu2 = mu.copy()            <EOL>mu2.data[:]=mu2.data**<NUM_LIT:2><EOL>mu2 = mu2.multiply(<NUM_LIT:1>/ni[:,None])  <EOL>mu.data[:] = (D.data - mu.data) / np.sqrt(mu.data - mu2.data)<EOL>self.adata.X = mu<EOL>if sum_norm is None:<EOL><INDENT>sum_norm = np.median(ni)<EOL><DEDENT>D = D.multiply(<NUM_LIT:1> / ni[:,None] * sum_norm).tocsr()            <EOL>D.data[:] = np.log2(D.data / div + <NUM_LIT:1>)<EOL><DEDENT>else:<EOL><INDENT>D.data[:] = (D.data / div)<EOL><DEDENT>idx = np.where(D.data <= min_expression)[<NUM_LIT:0>]<EOL>D.data[idx] = <NUM_LIT:0><EOL>gene_names = np.array(list(self.adata.var_names))<EOL>idx_genes = np.arange(D.shape[<NUM_LIT:1>])            <EOL>if(include_genes is not None):<EOL><INDENT>include_genes = np.array(list(include_genes))<EOL>idx = np.where(np.in1d(gene_names, include_genes))[<NUM_LIT:0>]<EOL>idx_genes = np.array(list(set(idx) & set(idx_genes)))<EOL><DEDENT>if(exclude_genes is not None):<EOL><INDENT>exclude_genes = np.array(list(exclude_genes))<EOL>idx3 = np.where(np.in1d(gene_names, exclude_genes,<EOL>invert=True))[<NUM_LIT:0>]<EOL>idx_genes = np.array(list(set(idx3) & set(idx_genes)))<EOL><DEDENT>if(filter_genes):                <EOL><INDENT>a, ct = np.unique(D.indices, return_counts=True)<EOL>c = np.zeros(D.shape[<NUM_LIT:1>])<EOL>c[a] = ct<EOL>keep = np.where(np.logical_and(c / D.shape[<NUM_LIT:0>] > thresh,<EOL>c / D.shape[<NUM_LIT:0>] <= <NUM_LIT:1> - thresh))[<NUM_LIT:0>]<EOL>idx_genes = np.array(list(set(keep) & set(idx_genes)))<EOL><DEDENT>mask_genes = np.zeros(D.shape[<NUM_LIT:1>], dtype='<STR_LIT:bool>')<EOL>mask_genes[idx_genes] = True<EOL>self.adata.X = self.adata.X.multiply(mask_genes[None, :]).tocsr()<EOL>self.adata.X.eliminate_zeros()<EOL>self.adata.var['<STR_LIT>']=mask_genes<EOL>if norm == '<STR_LIT>':<EOL><INDENT>self.adata.layers['<STR_LIT>'] = D.multiply(mask_genes[None, :]).tocsr()<EOL>self.adata.layers['<STR_LIT>'].eliminate_zeros()<EOL><DEDENT>else:<EOL><INDENT>self.adata.layers['<STR_LIT>'] = self.adata.X<EOL><DEDENT>
Log-normalizes and filters the expression data.

        Parameters
        ----------

        div : float, optional, default 1
            The factor by which the gene expression will be divided prior to
            log normalization.

        downsample : float, optional, default 0
            The factor by which to randomly downsample the data. If 0, the
            data will not be downsampled.

        sum_norm : str or float, optional, default None
            If a float, the total number of transcripts in each cell will be
            normalized to this value prior to normalization and filtering.
            Otherwise, nothing happens. If 'cell_median', each cell is
            normalized to have the median total read count per cell. If
            'gene_median', each gene is normalized to have the median total
            read count per gene.

        norm : str, optional, default 'log'
            If 'log', log-normalizes the expression data. If 'ftt', applies the
            Freeman-Tukey variance-stabilization transformation. If
            'multinomial', applies the Pearson-residual transformation (this is
            experimental and should only be used for raw, un-normalized UMI
            datasets). If None, the data is not normalized.

        include_genes : array-like of string, optional, default None
            A vector of gene names or indices that specifies the genes to keep.
            All other genes will be filtered out. Gene names are case-
            sensitive.

        exclude_genes : array-like of string, optional, default None
            A vector of gene names or indices that specifies the genes to
            exclude. These genes will be filtered out. Gene names are case-
            sensitive.

        include_cells : array-like of string, optional, default None
            A vector of cell names that specifies the cells to keep.
            All other cells will be filtered out. Cell names are
            case-sensitive.

        exclude_cells : array-like of string, optional, default None
            A vector of cell names that specifies the cells to exclude.
            Thses cells will be filtered out. Cell names are
            case-sensitive.

        min_expression : float, optional, default 1
            The threshold above which a gene is considered
            expressed. Gene expression values less than 'min_expression' are
            set to zero.

        thresh : float, optional, default 0.2
            Keep genes expressed in greater than 'thresh'*100 % of cells and
            less than (1-'thresh')*100 % of cells, where a gene is considered
            expressed if its expression value exceeds 'min_expression'.

        filter_genes : bool, optional, default True
            Setting this to False turns off filtering operations aside from
            removing genes with zero expression across all cells. Genes passed
            in exclude_genes or not passed in include_genes will still be
            filtered.