scanpy.pp.hashsolo

Contents

scanpy.pp.hashsolo#

scanpy.pp.hashsolo(adata, hashes, *, priors=(0.01, 0.8, 0.19), pre_existing_clusters=None, n_noise_barcodes=None, key_added='hashsolo', copy=False)[source]#

Probabilistic demultiplexing of cell hashing data using HashSolo [Bernstein et al., 2020].

Array type support#

Array type

supported

… experimentally in dask Array

numpy.ndarray

scipy.sparse.{csr,csc}_{array,matrix}

Parameters:
adata AnnData

The (annotated) data matrix of shape n_obs × n_vars. Rows correspond to cells and columns to genes.

hashes MultiAcc | Collection[AdRef] | Collection[str]

References to the vectors holding the cell hashing counts, e.g. A.obs[["Hash1", "Hash2"]] for columns in obs or A.X[:, ["Hash1", "Hash2"]] for hashing barcodes among the var_names. A MultiAcc such as A.obsm["hto"] refers to all columns of what it points to, named after the DataFrame’s columns or, for a plain array, its column positions.

priors tuple[float, float, float] (default: (0.01, 0.8, 0.19))

Prior probabilities of each hypothesis, in the order [negative, singlet, doublet]. The default is set to [0.01, 0.8, 0.19] assuming barcode counts are from cells that have passed QC in the transcriptome space, e.g. UMI counts, pct mito reads, etc.

pre_existing_clusters AdRef | str | None (default: None)

Reference to a vector of pre-existing cluster assignments (e.g. Leiden clusters or cell types, but not batch assignments). If provided, demultiplexing is performed separately for each cluster.

n_noise_barcodes int | None (default: None)

The number of barcodes used to create the noise distribution. Defaults to len(hashes) - 2.

key_added str (default: 'hashsolo')

Key under which to add the demultiplexing results.

copy bool (default: False)

Whether to modify a copy of adata instead of adata itself.

Return type:

AnnData | None

Returns:

Returns None if copy=False, else the modified adata. Sets the following fields:

adata.obs[key_added]Categorical (shape (n_obs,))

Classification of each cell: the name of one of the hashes, "Negative", or "Doublet".

adata.obsm[key_added]DataFrame (shape (n_obs, 3))

Probability of the negative, singlet, and doublet hypothesis.

Examples

Simulate 300 cells, each carrying one of 3 hashtag oligos:

>>> import numpy as np
>>> import scanpy as sc
>>> from anndata import AnnData
>>> from anndata.acc import A
>>>
>>> rng = np.random.default_rng(0)
>>> hto = rng.poisson(20, size=(300, 3))  # ambient background
>>> hto[np.arange(300), np.arange(300) % 3] = rng.poisson(1000, 300)  # signal
>>> adata = AnnData(rng.poisson(1, (300, 5)).astype("f4"), obsm=dict(hto=hto))

A MultiAcc demultiplexes using every column it points to. A plain array has no column names, so the barcodes are named after their positions:

>>> sc.pp.hashsolo(adata, A.obsm["hto"])
>>> adata.obs["hashsolo"].cat.categories.astype("string")
Index(['0', '1', '2'], dtype='string')
>>> adata.obs["hashsolo"].value_counts().tolist()
[100, 100, 100]

The same counts as obs columns (as in a Cell Ranger run’s “Multiplexing Capture” features), referenced one by one:

>>> adata.obs[["Hash1", "Hash2", "Hash3"]] = hto
>>> sc.pp.hashsolo(adata, A.obs[["Hash1", "Hash2", "Hash3"]], key_added="hs2")
>>> adata.obs["hs2"].cat.categories.astype("string")
Index(['Hash1', 'Hash2', 'Hash3'], dtype='string')