We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
normalize_total throws ValueError when passed a large view
When I run sc.pp.normalize_total(adata, target_sum=1e4),I got the error:ValueError: could not convert integer scalar,and How can I fixed this issue?

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `scanpy/preprocessing/_normalization.py`
Content:
```
1 from typing import Optional, Union, Iterable, Dict
2 
3 import numpy as np
4 from anndata import AnnData
5 from scipy.sparse import issparse
6 from sklearn.utils import sparsefuncs
7 
8 from .. import logging as logg
9 from .._compat import Literal
10 
11 
12 def _normalize_data(X, counts, after=None, copy=False):
13     X = X.copy() if copy else X
14     if issubclass(X.dtype.type, (int, np.integer)):
15         X = X.astype(np.float32)  # TODO: Check if float64 should be used
16     counts = np.asarray(counts)  # dask doesn't do medians
17     after = np.median(counts[counts>0], axis=0) if after is None else after
18     counts += (counts == 0)
19     counts = counts / after
20     if issparse(X):
21         sparsefuncs.inplace_row_scale(X, 1/counts)
22     else:
23         np.divide(X, counts[:, None], out=X)
24     return X
25 
26 
27 def normalize_total(
28     adata: AnnData,
29     target_sum: Optional[float] = None,
30     exclude_highly_expressed: bool = False,
31     max_fraction: float = 0.05,
32     key_added: Optional[str] = None,
33     layers: Union[Literal['all'], Iterable[str]] = None,
34     layer_norm: Optional[str] = None,
35     inplace: bool = True,
36 ) -> Optional[Dict[str, np.ndarray]]:
37     """\
38     Normalize counts per cell.
39 
40     If choosing `target_sum=1e6`, this is CPM normalization.
41 
42     If `exclude_highly_expressed=True`, very highly expressed genes are excluded
43     from the computation of the normalization factor (size factor) for each
44     cell. This is meaningful as these can strongly influence the resulting
45     normalized values for all other genes [Weinreb17]_.
46 
47     Similar functions are used, for example, by Seurat [Satija15]_, Cell Ranger
48     [Zheng17]_ or SPRING [Weinreb17]_.
49 
50     Params
51     ------
52     adata
53         The annotated data matrix of shape `n_obs` × `n_vars`.
54         Rows correspond to cells and columns to genes.
55     target_sum
56         If `None`, after normalization, each observation (cell) has a total
57         count equal to the median of total counts for observations (cells)
58         before normalization.
59     exclude_highly_expressed
60         Exclude (very) highly expressed genes for the computation of the
61         normalization factor (size factor) for each cell. A gene is considered
62         highly expressed, if it has more than `max_fraction` of the total counts
63         in at least one cell. The not-excluded genes will sum up to
64         `target_sum`.
65     max_fraction
66         If `exclude_highly_expressed=True`, consider cells as highly expressed
67         that have more counts than `max_fraction` of the original total counts
68         in at least one cell.
69     key_added
70         Name of the field in `adata.obs` where the normalization factor is
71         stored.
72     layers
73         List of layers to normalize. Set to `'all'` to normalize all layers.
74     layer_norm
75         Specifies how to normalize layers:
76 
77         * If `None`, after normalization, for each layer in *layers* each cell
78           has a total count equal to the median of the *counts_per_cell* before
79           normalization of the layer.
80         * If `'after'`, for each layer in *layers* each cell has
81           a total count equal to `target_sum`.
82         * If `'X'`, for each layer in *layers* each cell has a total count
83           equal to the median of total counts for observations (cells) of
84           `adata.X` before normalization.
85 
86     inplace
87         Whether to update `adata` or return dictionary with normalized copies of
88         `adata.X` and `adata.layers`.
89 
90     Returns
91     -------
92     Returns dictionary with normalized copies of `adata.X` and `adata.layers`
93     or updates `adata` with normalized version of the original
94     `adata.X` and `adata.layers`, depending on `inplace`.
95 
96     Example
97     --------
98     >>> from anndata import AnnData
99     >>> import scanpy as sc
100     >>> sc.settings.verbosity = 2
101     >>> np.set_printoptions(precision=2)
102     >>> adata = AnnData(np.array([
103     ...    [3, 3, 3, 6, 6],
104     ...    [1, 1, 1, 2, 2],
105     ...    [1, 22, 1, 2, 2],
106     ... ]))
107     >>> adata.X
108     array([[ 3.,  3.,  3.,  6.,  6.],
109            [ 1.,  1.,  1.,  2.,  2.],
110            [ 1., 22.,  1.,  2.,  2.]], dtype=float32)
111     >>> X_norm = sc.pp.normalize_total(adata, target_sum=1, inplace=False)['X']
112     >>> X_norm
113     array([[0.14, 0.14, 0.14, 0.29, 0.29],
114            [0.14, 0.14, 0.14, 0.29, 0.29],
115            [0.04, 0.79, 0.04, 0.07, 0.07]], dtype=float32)
116     >>> X_norm = sc.pp.normalize_total(
117     ...     adata, target_sum=1, exclude_highly_expressed=True,
118     ...     max_fraction=0.2, inplace=False
119     ... )['X']
120     The following highly-expressed genes are not considered during normalization factor computation:
121     ['1', '3', '4']
122     >>> X_norm
123     array([[ 0.5,  0.5,  0.5,  1. ,  1. ],
124            [ 0.5,  0.5,  0.5,  1. ,  1. ],
125            [ 0.5, 11. ,  0.5,  1. ,  1. ]], dtype=float32)
126     """
127     if max_fraction < 0 or max_fraction > 1:
128         raise ValueError('Choose max_fraction between 0 and 1.')
129 
130     if layers == 'all':
131         layers = adata.layers.keys()
132     elif isinstance(layers, str):
133         raise ValueError(
134             f"`layers` needs to be a list of strings or 'all', not {layers!r}"
135         )
136 
137     gene_subset = None
138     msg = 'normalizing counts per cell'
139     if exclude_highly_expressed:
140         counts_per_cell = adata.X.sum(1)  # original counts per cell
141         counts_per_cell = np.ravel(counts_per_cell)
142 
143         # at least one cell as more than max_fraction of counts per cell
144         gene_subset = (adata.X > counts_per_cell[:, None]*max_fraction).sum(0)
145         gene_subset = (np.ravel(gene_subset) == 0)
146 
147         msg += (
148             ' The following highly-expressed genes are not considered during '
149             f'normalization factor computation:\n{adata.var_names[~gene_subset].tolist()}'
150         )
151     start = logg.info(msg)
152 
153     # counts per cell for subset, if max_fraction!=1
154     X = adata.X if gene_subset is None else adata[:, gene_subset].X
155     counts_per_cell = X.sum(1)
156     # get rid of adata view
157     counts_per_cell = np.ravel(counts_per_cell).copy()
158 
159     cell_subset = counts_per_cell > 0
160     if not np.all(cell_subset):
161         logg.warning('Some cells have total count of genes equal to zero')
162 
163     if layer_norm == 'after':
164         after = target_sum
165     elif layer_norm == 'X':
166         after = np.median(counts_per_cell[cell_subset])
167     elif layer_norm is None:
168         after = None
169     else:
170         raise ValueError('layer_norm should be "after", "X" or None')
171     del cell_subset
172 
173     if inplace:
174         if key_added is not None:
175             adata.obs[key_added] = counts_per_cell
176         adata.X = _normalize_data(adata.X, counts_per_cell, target_sum)
177     else:
178         # not recarray because need to support sparse
179         dat = dict(
180             X=_normalize_data(adata.X, counts_per_cell, target_sum, copy=True),
181             norm_factor=counts_per_cell,
182         )
183 
184     for layer_name in (layers or ()):
185         layer = adata.layers[layer_name]
186         counts = np.ravel(layer.sum(1))
187         if inplace:
188             adata.layers[layer_name] = _normalize_data(layer, counts, after)
189         else:
190             dat[layer_name] = _normalize_data(layer, counts, after, copy=True)
191 
192     logg.info(
193         '    finished ({time_passed})',
194         time=start,
195     )
196     if key_added is not None:
197         logg.debug(f'and added {key_added!r}, counts per cell before normalization (adata.obs)')
198 
199     return dat if not inplace else None
200
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/scanpy/preprocessing/_normalization.py b/scanpy/preprocessing/_normalization.py
--- a/scanpy/preprocessing/_normalization.py
+++ b/scanpy/preprocessing/_normalization.py
@@ -7,6 +7,7 @@
 
 from .. import logging as logg
 from .._compat import Literal
+from .._utils import view_to_actual
 
 
 def _normalize_data(X, counts, after=None, copy=False):
@@ -134,6 +135,8 @@
             f"`layers` needs to be a list of strings or 'all', not {layers!r}"
         )
 
+    view_to_actual(adata)
+
     gene_subset = None
     msg = 'normalizing counts per cell'
     if exclude_highly_expressed:

{"golden_diff": "diff --git a/scanpy/preprocessing/_normalization.py b/scanpy/preprocessing/_normalization.py\n--- a/scanpy/preprocessing/_normalization.py\n+++ b/scanpy/preprocessing/_normalization.py\n@@ -7,6 +7,7 @@\n \n from .. import logging as logg\n from .._compat import Literal\n+from .._utils import view_to_actual\n \n \n def _normalize_data(X, counts, after=None, copy=False):\n@@ -134,6 +135,8 @@\n             f\"`layers` needs to be a list of strings or 'all', not {layers!r}\"\n         )\n \n+    view_to_actual(adata)\n+\n     gene_subset = None\n     msg = 'normalizing counts per cell'\n     if exclude_highly_expressed:\n", "issue": "normalize_total throws ValueError when passed a large view\nWhen I run sc.pp.normalize_total(adata, target_sum=1e4),I got the error:ValueError: could not convert integer scalar,and How can I fixed this issue?\n", "before_files": [{"content": "from typing import Optional, Union, Iterable, Dict\n\nimport numpy as np\nfrom anndata import AnnData\nfrom scipy.sparse import issparse\nfrom sklearn.utils import sparsefuncs\n\nfrom .. import logging as logg\nfrom .._compat import Literal\n\n\ndef _normalize_data(X, counts, after=None, copy=False):\n    X = X.copy() if copy else X\n    if issubclass(X.dtype.type, (int, np.integer)):\n        X = X.astype(np.float32)  # TODO: Check if float64 should be used\n    counts = np.asarray(counts)  # dask doesn't do medians\n    after = np.median(counts[counts>0], axis=0) if after is None else after\n    counts += (counts == 0)\n    counts = counts / after\n    if issparse(X):\n        sparsefuncs.inplace_row_scale(X, 1/counts)\n    else:\n        np.divide(X, counts[:, None], out=X)\n    return X\n\n\ndef normalize_total(\n    adata: AnnData,\n    target_sum: Optional[float] = None,\n    exclude_highly_expressed: bool = False,\n    max_fraction: float = 0.05,\n    key_added: Optional[str] = None,\n    layers: Union[Literal['all'], Iterable[str]] = None,\n    layer_norm: Optional[str] = None,\n    inplace: bool = True,\n) -> Optional[Dict[str, np.ndarray]]:\n    \"\"\"\\\n    Normalize counts per cell.\n\n    If choosing `target_sum=1e6`, this is CPM normalization.\n\n    If `exclude_highly_expressed=True`, very highly expressed genes are excluded\n    from the computation of the normalization factor (size factor) for each\n    cell. This is meaningful as these can strongly influence the resulting\n    normalized values for all other genes [Weinreb17]_.\n\n    Similar functions are used, for example, by Seurat [Satija15]_, Cell Ranger\n    [Zheng17]_ or SPRING [Weinreb17]_.\n\n    Params\n    ------\n    adata\n        The annotated data matrix of shape `n_obs` \u00d7 `n_vars`.\n        Rows correspond to cells and columns to genes.\n    target_sum\n        If `None`, after normalization, each observation (cell) has a total\n        count equal to the median of total counts for observations (cells)\n        before normalization.\n    exclude_highly_expressed\n        Exclude (very) highly expressed genes for the computation of the\n        normalization factor (size factor) for each cell. A gene is considered\n        highly expressed, if it has more than `max_fraction` of the total counts\n        in at least one cell. The not-excluded genes will sum up to\n        `target_sum`.\n    max_fraction\n        If `exclude_highly_expressed=True`, consider cells as highly expressed\n        that have more counts than `max_fraction` of the original total counts\n        in at least one cell.\n    key_added\n        Name of the field in `adata.obs` where the normalization factor is\n        stored.\n    layers\n        List of layers to normalize. Set to `'all'` to normalize all layers.\n    layer_norm\n        Specifies how to normalize layers:\n\n        * If `None`, after normalization, for each layer in *layers* each cell\n          has a total count equal to the median of the *counts_per_cell* before\n          normalization of the layer.\n        * If `'after'`, for each layer in *layers* each cell has\n          a total count equal to `target_sum`.\n        * If `'X'`, for each layer in *layers* each cell has a total count\n          equal to the median of total counts for observations (cells) of\n          `adata.X` before normalization.\n\n    inplace\n        Whether to update `adata` or return dictionary with normalized copies of\n        `adata.X` and `adata.layers`.\n\n    Returns\n    -------\n    Returns dictionary with normalized copies of `adata.X` and `adata.layers`\n    or updates `adata` with normalized version of the original\n    `adata.X` and `adata.layers`, depending on `inplace`.\n\n    Example\n    --------\n    >>> from anndata import AnnData\n    >>> import scanpy as sc\n    >>> sc.settings.verbosity = 2\n    >>> np.set_printoptions(precision=2)\n    >>> adata = AnnData(np.array([\n    ...    [3, 3, 3, 6, 6],\n    ...    [1, 1, 1, 2, 2],\n    ...    [1, 22, 1, 2, 2],\n    ... ]))\n    >>> adata.X\n    array([[ 3.,  3.,  3.,  6.,  6.],\n           [ 1.,  1.,  1.,  2.,  2.],\n           [ 1., 22.,  1.,  2.,  2.]], dtype=float32)\n    >>> X_norm = sc.pp.normalize_total(adata, target_sum=1, inplace=False)['X']\n    >>> X_norm\n    array([[0.14, 0.14, 0.14, 0.29, 0.29],\n           [0.14, 0.14, 0.14, 0.29, 0.29],\n           [0.04, 0.79, 0.04, 0.07, 0.07]], dtype=float32)\n    >>> X_norm = sc.pp.normalize_total(\n    ...     adata, target_sum=1, exclude_highly_expressed=True,\n    ...     max_fraction=0.2, inplace=False\n    ... )['X']\n    The following highly-expressed genes are not considered during normalization factor computation:\n    ['1', '3', '4']\n    >>> X_norm\n    array([[ 0.5,  0.5,  0.5,  1. ,  1. ],\n           [ 0.5,  0.5,  0.5,  1. ,  1. ],\n           [ 0.5, 11. ,  0.5,  1. ,  1. ]], dtype=float32)\n    \"\"\"\n    if max_fraction < 0 or max_fraction > 1:\n        raise ValueError('Choose max_fraction between 0 and 1.')\n\n    if layers == 'all':\n        layers = adata.layers.keys()\n    elif isinstance(layers, str):\n        raise ValueError(\n            f\"`layers` needs to be a list of strings or 'all', not {layers!r}\"\n        )\n\n    gene_subset = None\n    msg = 'normalizing counts per cell'\n    if exclude_highly_expressed:\n        counts_per_cell = adata.X.sum(1)  # original counts per cell\n        counts_per_cell = np.ravel(counts_per_cell)\n\n        # at least one cell as more than max_fraction of counts per cell\n        gene_subset = (adata.X > counts_per_cell[:, None]*max_fraction).sum(0)\n        gene_subset = (np.ravel(gene_subset) == 0)\n\n        msg += (\n            ' The following highly-expressed genes are not considered during '\n            f'normalization factor computation:\\n{adata.var_names[~gene_subset].tolist()}'\n        )\n    start = logg.info(msg)\n\n    # counts per cell for subset, if max_fraction!=1\n    X = adata.X if gene_subset is None else adata[:, gene_subset].X\n    counts_per_cell = X.sum(1)\n    # get rid of adata view\n    counts_per_cell = np.ravel(counts_per_cell).copy()\n\n    cell_subset = counts_per_cell > 0\n    if not np.all(cell_subset):\n        logg.warning('Some cells have total count of genes equal to zero')\n\n    if layer_norm == 'after':\n        after = target_sum\n    elif layer_norm == 'X':\n        after = np.median(counts_per_cell[cell_subset])\n    elif layer_norm is None:\n        after = None\n    else:\n        raise ValueError('layer_norm should be \"after\", \"X\" or None')\n    del cell_subset\n\n    if inplace:\n        if key_added is not None:\n            adata.obs[key_added] = counts_per_cell\n        adata.X = _normalize_data(adata.X, counts_per_cell, target_sum)\n    else:\n        # not recarray because need to support sparse\n        dat = dict(\n            X=_normalize_data(adata.X, counts_per_cell, target_sum, copy=True),\n            norm_factor=counts_per_cell,\n        )\n\n    for layer_name in (layers or ()):\n        layer = adata.layers[layer_name]\n        counts = np.ravel(layer.sum(1))\n        if inplace:\n            adata.layers[layer_name] = _normalize_data(layer, counts, after)\n        else:\n            dat[layer_name] = _normalize_data(layer, counts, after, copy=True)\n\n    logg.info(\n        '    finished ({time_passed})',\n        time=start,\n    )\n    if key_added is not None:\n        logg.debug(f'and added {key_added!r}, counts per cell before normalization (adata.obs)')\n\n    return dat if not inplace else None\n", "path": "scanpy/preprocessing/_normalization.py"}], "after_files": [{"content": "from typing import Optional, Union, Iterable, Dict\n\nimport numpy as np\nfrom anndata import AnnData\nfrom scipy.sparse import issparse\nfrom sklearn.utils import sparsefuncs\n\nfrom .. import logging as logg\nfrom .._compat import Literal\nfrom .._utils import view_to_actual\n\n\ndef _normalize_data(X, counts, after=None, copy=False):\n    X = X.copy() if copy else X\n    if issubclass(X.dtype.type, (int, np.integer)):\n        X = X.astype(np.float32)  # TODO: Check if float64 should be used\n    counts = np.asarray(counts)  # dask doesn't do medians\n    after = np.median(counts[counts>0], axis=0) if after is None else after\n    counts += (counts == 0)\n    counts = counts / after\n    if issparse(X):\n        sparsefuncs.inplace_row_scale(X, 1/counts)\n    else:\n        np.divide(X, counts[:, None], out=X)\n    return X\n\n\ndef normalize_total(\n    adata: AnnData,\n    target_sum: Optional[float] = None,\n    exclude_highly_expressed: bool = False,\n    max_fraction: float = 0.05,\n    key_added: Optional[str] = None,\n    layers: Union[Literal['all'], Iterable[str]] = None,\n    layer_norm: Optional[str] = None,\n    inplace: bool = True,\n) -> Optional[Dict[str, np.ndarray]]:\n    \"\"\"\\\n    Normalize counts per cell.\n\n    If choosing `target_sum=1e6`, this is CPM normalization.\n\n    If `exclude_highly_expressed=True`, very highly expressed genes are excluded\n    from the computation of the normalization factor (size factor) for each\n    cell. This is meaningful as these can strongly influence the resulting\n    normalized values for all other genes [Weinreb17]_.\n\n    Similar functions are used, for example, by Seurat [Satija15]_, Cell Ranger\n    [Zheng17]_ or SPRING [Weinreb17]_.\n\n    Params\n    ------\n    adata\n        The annotated data matrix of shape `n_obs` \u00d7 `n_vars`.\n        Rows correspond to cells and columns to genes.\n    target_sum\n        If `None`, after normalization, each observation (cell) has a total\n        count equal to the median of total counts for observations (cells)\n        before normalization.\n    exclude_highly_expressed\n        Exclude (very) highly expressed genes for the computation of the\n        normalization factor (size factor) for each cell. A gene is considered\n        highly expressed, if it has more than `max_fraction` of the total counts\n        in at least one cell. The not-excluded genes will sum up to\n        `target_sum`.\n    max_fraction\n        If `exclude_highly_expressed=True`, consider cells as highly expressed\n        that have more counts than `max_fraction` of the original total counts\n        in at least one cell.\n    key_added\n        Name of the field in `adata.obs` where the normalization factor is\n        stored.\n    layers\n        List of layers to normalize. Set to `'all'` to normalize all layers.\n    layer_norm\n        Specifies how to normalize layers:\n\n        * If `None`, after normalization, for each layer in *layers* each cell\n          has a total count equal to the median of the *counts_per_cell* before\n          normalization of the layer.\n        * If `'after'`, for each layer in *layers* each cell has\n          a total count equal to `target_sum`.\n        * If `'X'`, for each layer in *layers* each cell has a total count\n          equal to the median of total counts for observations (cells) of\n          `adata.X` before normalization.\n\n    inplace\n        Whether to update `adata` or return dictionary with normalized copies of\n        `adata.X` and `adata.layers`.\n\n    Returns\n    -------\n    Returns dictionary with normalized copies of `adata.X` and `adata.layers`\n    or updates `adata` with normalized version of the original\n    `adata.X` and `adata.layers`, depending on `inplace`.\n\n    Example\n    --------\n    >>> from anndata import AnnData\n    >>> import scanpy as sc\n    >>> sc.settings.verbosity = 2\n    >>> np.set_printoptions(precision=2)\n    >>> adata = AnnData(np.array([\n    ...    [3, 3, 3, 6, 6],\n    ...    [1, 1, 1, 2, 2],\n    ...    [1, 22, 1, 2, 2],\n    ... ]))\n    >>> adata.X\n    array([[ 3.,  3.,  3.,  6.,  6.],\n           [ 1.,  1.,  1.,  2.,  2.],\n           [ 1., 22.,  1.,  2.,  2.]], dtype=float32)\n    >>> X_norm = sc.pp.normalize_total(adata, target_sum=1, inplace=False)['X']\n    >>> X_norm\n    array([[0.14, 0.14, 0.14, 0.29, 0.29],\n           [0.14, 0.14, 0.14, 0.29, 0.29],\n           [0.04, 0.79, 0.04, 0.07, 0.07]], dtype=float32)\n    >>> X_norm = sc.pp.normalize_total(\n    ...     adata, target_sum=1, exclude_highly_expressed=True,\n    ...     max_fraction=0.2, inplace=False\n    ... )['X']\n    The following highly-expressed genes are not considered during normalization factor computation:\n    ['1', '3', '4']\n    >>> X_norm\n    array([[ 0.5,  0.5,  0.5,  1. ,  1. ],\n           [ 0.5,  0.5,  0.5,  1. ,  1. ],\n           [ 0.5, 11. ,  0.5,  1. ,  1. ]], dtype=float32)\n    \"\"\"\n    if max_fraction < 0 or max_fraction > 1:\n        raise ValueError('Choose max_fraction between 0 and 1.')\n\n    if layers == 'all':\n        layers = adata.layers.keys()\n    elif isinstance(layers, str):\n        raise ValueError(\n            f\"`layers` needs to be a list of strings or 'all', not {layers!r}\"\n        )\n\n    view_to_actual(adata)\n\n    gene_subset = None\n    msg = 'normalizing counts per cell'\n    if exclude_highly_expressed:\n        counts_per_cell = adata.X.sum(1)  # original counts per cell\n        counts_per_cell = np.ravel(counts_per_cell)\n\n        # at least one cell as more than max_fraction of counts per cell\n        gene_subset = (adata.X > counts_per_cell[:, None]*max_fraction).sum(0)\n        gene_subset = (np.ravel(gene_subset) == 0)\n\n        msg += (\n            ' The following highly-expressed genes are not considered during '\n            f'normalization factor computation:\\n{adata.var_names[~gene_subset].tolist()}'\n        )\n    start = logg.info(msg)\n\n    # counts per cell for subset, if max_fraction!=1\n    X = adata.X if gene_subset is None else adata[:, gene_subset].X\n    counts_per_cell = X.sum(1)\n    # get rid of adata view\n    counts_per_cell = np.ravel(counts_per_cell).copy()\n\n    cell_subset = counts_per_cell > 0\n    if not np.all(cell_subset):\n        logg.warning('Some cells have total count of genes equal to zero')\n\n    if layer_norm == 'after':\n        after = target_sum\n    elif layer_norm == 'X':\n        after = np.median(counts_per_cell[cell_subset])\n    elif layer_norm is None:\n        after = None\n    else:\n        raise ValueError('layer_norm should be \"after\", \"X\" or None')\n    del cell_subset\n\n    if inplace:\n        if key_added is not None:\n            adata.obs[key_added] = counts_per_cell\n        adata.X = _normalize_data(adata.X, counts_per_cell, target_sum)\n    else:\n        # not recarray because need to support sparse\n        dat = dict(\n            X=_normalize_data(adata.X, counts_per_cell, target_sum, copy=True),\n            norm_factor=counts_per_cell,\n        )\n\n    for layer_name in (layers or ()):\n        layer = adata.layers[layer_name]\n        counts = np.ravel(layer.sum(1))\n        if inplace:\n            adata.layers[layer_name] = _normalize_data(layer, counts, after)\n        else:\n            dat[layer_name] = _normalize_data(layer, counts, after, copy=True)\n\n    logg.info(\n        '    finished ({time_passed})',\n        time=start,\n    )\n    if key_added is not None:\n        logg.debug(f'and added {key_added!r}, counts per cell before normalization (adata.obs)')\n\n    return dat if not inplace else None\n", "path": "scanpy/preprocessing/_normalization.py"}]}