def normalize_per_cell(data, counts_per_cell_after=None, counts_per_cell=None, key_n_counts=None,<EOL>max_proportion_per_cell=None, use_initial_size=True, layers=['<STR_LIT>', '<STR_LIT>'],<EOL>enforce=False, copy=False):
adata = data.copy() if copy else data<EOL>layers = adata.layers.keys() if layers is '<STR_LIT:all>' else [layers] if isinstance(layers, str)else [layer for layer in layers if layer in adata.layers.keys()]<EOL>layers = ['<STR_LIT:X>'] + layers<EOL>modified_layers = []<EOL>for layer in layers:<EOL><INDENT>X = adata.X if layer is '<STR_LIT:X>' else adata.layers[layer]<EOL>if not_yet_normalized(X) or enforce:<EOL><INDENT>counts = counts_per_cell if counts_per_cell is not Noneelse get_initial_size(adata, layer) if use_initial_size else get_size(adata, layer)<EOL>if max_proportion_per_cell is not None and (<NUM_LIT:0> < max_proportion_per_cell < <NUM_LIT:1>):<EOL><INDENT>counts = counts_per_cell_quantile(X, max_proportion_per_cell, counts)<EOL><DEDENT>counts_after = np.median(counts) if counts_per_cell_after is None else counts_per_cell_after<EOL>counts /= counts_after + (counts_after == <NUM_LIT:0>)<EOL>counts += counts == <NUM_LIT:0>  <EOL>if issparse(X):<EOL><INDENT>sparsefuncs.inplace_row_scale(X, <NUM_LIT:1> / counts)<EOL><DEDENT>else:<EOL><INDENT>X /= np.array(counts[:, None])<EOL><DEDENT>modified_layers.append(layer)<EOL><DEDENT><DEDENT>adata.obs['<STR_LIT>' if key_n_counts is None else key_n_counts] = get_size(adata)<EOL>if len(modified_layers) > <NUM_LIT:0>:<EOL><INDENT>logg.info('<STR_LIT>', '<STR_LIT:U+002CU+0020>'.join(modified_layers) + '<STR_LIT:.>')<EOL><DEDENT>return adata if copy else None<EOL>
Normalize each cell by total counts over all genes.

    Parameters
    ----------
    data : :class:`~anndata.AnnData`, `np.ndarray`, `sp.sparse`
        The (annotated) data matrix of shape `n_obs` × `n_vars`. Rows correspond
        to cells and columns to genes.
    counts_per_cell_after : `float` or `None`, optional (default: `None`)
        If `None`, after normalization, each cell has a total count equal
        to the median of the *counts_per_cell* before normalization.
    counts_per_cell : `np.array`, optional (default: `None`)
        Precomputed counts per cell.
    key_n_counts : `str`, optional (default: `'n_counts'`)
        Name of the field in `adata.obs` where the total counts per cell are
        stored.
    max_proportion_per_cell : `int` (default: `None`)
        Exclude genes counts that account for more than a specific proportion of cell size, e.g. 0.05.
    use_initial_size : `bool` (default: `True`)
        Whether to use initial cell sizes oder actual cell sizes.
    layers : `str` or `list` (default: `{'spliced', 'unspliced'}`)
        Keys for layers to be also considered for normalization.
    copy : `bool`, optional (default: `False`)
        If an :class:`~anndata.AnnData` is passed, determines whether a copy
        is returned.

    Returns
    -------
    Returns or updates `adata` with normalized version of the original `adata.X`, depending on `copy`.