<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def downsample_counts( adata: AnnData, counts_per_cell: Optional[Union[int, Collection[int]]] = None, total_counts: Optional[int] = None, random_state: Optional[int] = 0, replace: bool = False, copy: bool = False, ) -> Optional[AnnData]: """Downsample counts from count matrix. If `counts_per_cell` is specified, each cell will downsampled. If `total_counts` is specified, expression matrix will be downsampled to contain at most `total_counts`. Parameters adata Annotated data matrix. counts_per_cell Target total counts per cell. If a cell has more than 'counts_per_cell', it will be downsampled to this number. Resulting counts can be specified on a per cell basis by passing an array.Should be an integer or integer ndarray with same length as number of obs. total_counts Target total counts. If the count matrix has more than `total_counts` it will be downsampled to have this number. random_state Random seed for subsampling. replace Whether to sample the counts with replacement. copy If an :class:`~anndata.AnnData` is passed, determines whether a copy is returned. Returns ------- Depending on `copy` returns or updates an `adata` with downsampled `.X`. """

    # This logic is all dispatch
    total_counts_call = total_counts is not None
    counts_per_cell_call = counts_per_cell is not None
    if total_counts_call is counts_per_cell_call:
        raise ValueError("Must specify exactly one of `total_counts` or `counts_per_cell`.")
    if copy:
        adata = adata.copy()
    adata.X = adata.X.astype(np.integer)  # Numba doesn't want floats
    if total_counts_call:
        adata.X = _downsample_total_counts(adata.X, total_counts, random_state, replace)
    elif counts_per_cell_call:
        adata.X = _downsample_per_cell(adata.X, counts_per_cell, random_state, replace)
    if copy:
        return adata