scanpy.pp.hashsolo#
- scanpy.pp.hashsolo(adata, hashes, *, priors=(0.01, 0.8, 0.19), pre_existing_clusters=None, n_noise_barcodes=None, out=False)[source]#
Probabilistic demultiplexing of cell hashing data using HashSolo [Bernstein et al., 2020].
Array type support# Array type
supported
… experimentally in dask
Array✅
❌
✅
❌
- 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 inobsorA.X[:, ["Hash1", "Hash2"]]for hashing barcodes among thevar_names. AMultiAccsuch asA.obsm["hto"]refers to all columns of what it points to, named after theDataFrame’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.- out
AdRef[Idx2D|int,AnnData] |str|HashsoloOut|bool(default:False) Where to write the outputs. A single accessor writes
classificationto it and names the others after its keyk:kin kinds of places no other output goes to, elsek_{name}, e.g..obsp['k_distances']next to.obsp['k']. Outputs that aren’t written by default stay unwritten. A mapping from output names to accessors writes only the outputs it names, each to a different place, e.g.{'classification': A.obs['hto']}.strs areanndata.acc.AdAcc.resolve()d. IfTrue, they are returned as aHashsoloResultinstead of written. IfFalse, they are written to their default locations. The outputs are:classificationClassification of each cell. By default written to
A.obs['hashsolo'].probabilitiesProbabilities of each hypothesis. By default written to
A.obsm['hashsolo'].
- adata
- Return type:
- Returns:
Returns the outputs as a
HashsoloResultifout=True, elseNone. By default sets the following fields (seeoutfor others):adata.obs['hashsolo']Categorical(shape(n_obs,))Classification of each cell: the name of one of the
hashes,"Negative", or"Doublet".adata.obsm['hashsolo']DataFrame(shape(n_obs, 3))Probability of the
negative,singlet, anddoublethypothesis.
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
MultiAccdemultiplexes 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
obscolumns (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"]], out=A.obs["hs2"]) >>> adata.obs["hs2"].cat.categories.astype("string") Index(['Hash1', 'Hash2', 'Hash3'], dtype='string')