コード例 #1
0
def pcr_noise(
    read_counts: np.ndarray,
    pcr_betas: Union[float, np.ndarray],
    n_cycles: int,
    copy: bool = True,
) -> np.ndarray:
    """PCR noise model: every read has an affinity for PCR, and for every round
    of PCR we do a ~binomial doubling of each count.

    :param read_counts: array of shape (n_samples, n_features) representing unique
                        molecules (e.g. genes or gene fragments). If a sparse matrix
                        is provided, the output will be sparse
    :param pcr_betas: PCR efficiency for each feature, either constant or per-feature
    :param n_cycles: number of rounds of PCR to simulate
    :param copy: if True, return a copy of the read_counts array, else modify in-place
    :return: int array of shape (n_samples, n_features) with amplified counts
    """
    if np.any(pcr_betas < 0):
        raise ValueError("pcr_betas must be non-negative")

    if copy:
        read_counts = read_counts.copy()

    pcr_betas = np.broadcast_to(pcr_betas, (1, read_counts.shape[1]))

    if sp.issparse(read_counts):
        d = read_counts.data[None, :]
        pcr_betas = pcr_betas[:, read_counts.nonzero()[1]]
    else:
        d = read_counts

    # for each round of pcr, each gene increases according to its affinity factor
    for i in range(n_cycles):
        d += np.random.binomial(n=d, p=pcr_betas, size=d.shape)

    if sp.issparse(read_counts):
        read_counts.data = d.flatten()

    return read_counts