code: def normalize_per_cell(data, counts_per_cell_after=None, counts_per_cell=None, key_n_counts=None,
                         max_proportion_per_cell=None, use_initial_size=True, layers=['spliced', 'unspliced'],
                         enforce=False, copy=False):
      adata = data.copy() if copy else data
      layers = adata.layers.keys() if layers is 'all' else [layers] if isinstance(layers, str) \
          else [layer for layer in layers if layer in adata.layers.keys()]
      layers = ['X'] + layers
      modified_layers = []
      for layer in layers:
          X = adata.X if layer is 'X' else adata.layers[layer]
          if not_yet_normalized(X) or enforce:
              counts = counts_per_cell if counts_per_cell is not None \
                  else get_initial_size(adata, layer) if use_initial_size else get_size(adata, layer)
              if max_proportion_per_cell is not None and (0 < max_proportion_per_cell < 1):
                  counts = counts_per_cell_quantile(X, max_proportion_per_cell, counts)
              counts_after = np.median(counts) if counts_per_cell_after is None else counts_per_cell_after
              counts /= counts_after + (counts_after == 0)
              counts += counts == 0
              if issparse(X):
                  sparsefuncs.inplace_row_scale(X, 1 / counts)
              else:
                  X /= np.array(counts[:, None])
              modified_layers.append(layer)
      adata.obs['n_counts' if key_n_counts is None else key_n_counts] = get_size(adata)
      if len(modified_layers) > 0:
          logg.info('Normalized count data:', ', '.join(modified_layers) + '.')
      return adata if copy else None