scanpy.pp.harmony_integrate#

scanpy.pp.harmony_integrate(adata, batch, *, use=None, out=False, dtype=<class 'numpy.float64'>, flavor='harmony2', n_clusters=None, max_iter_harmony=10, max_iter_clustering=None, tol_harmony=None, tol_clustering=None, sigma=0.1, theta=2.0, tau=0, ridge_lambda=1.0, alpha=0.2, batch_prune_threshold=1e-05, correction_method='fast', block_proportion=0.05, stop_rule='reference_record', seeding=None, seeding_lloyd_steps=0, seeding_cells_per_cluster=None, penalty_combine='product', recompute_counts=True, low_memory=False, rng=None)[source]#

Integrate different experiments using the Harmony algorithm [Korsunsky et al., 2019, Patikas et al., 2026].

Integration adjusts a PCA embedding to reduce experiment-specific technical variation, allowing cells from different experiments to be compared. This CPU implementation runs in parallel numba kernels. Multiple batch variables follow the per-covariate formulation described in the Harmony papers: each batch variable is modeled separately instead of combining them all into one joint category. As Harmony works by adjusting the principal components, this function should be run after performing PCA but before computing the neighbor graph.

By default, the Harmony2 algorithm is used, which includes a stabilized diversity penalty, dynamic per-cluster-per-batch ridge regularization, and automatic batch pruning. To revert to the original Harmony behavior:

sc.pp.harmony_integrate(adata, batch, flavor="harmony1")
Array type support#

Array type

supported

… experimentally in dask Array

numpy.ndarray

✅

❌

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

❌

❌

Array API

❌

❌

Parameters:
adata AnnData

The annotated data matrix.

batch AdRef | str | Sequence[AdRef | str]

The annotation(s) that differentiate(s) among experiments/batches, e.g. A.obs['batch'] or [A.obs['batch'], A.obs['donor']]. strs are anndata.acc.AdAcc.resolve()d, e.g. 'obs.batch'. Multiple keys are modeled as separate batch variables, with one active categorical level per variable and cell.

use MultiAcc | str | None (default: None)

Which embedding to adjust. By default, the one pca() wrote. Given by an accessor, e.g. A.X, A.layers['counts'] or A.obsm['pca']. strs are anndata.acc.AdAcc.resolve()d, e.g. 'layers.counts'.

out MultiAcc | str | bool (default: False)

Where to write the adjusted embedding. Given by an accessor, e.g. A.obsm['pca_harmony']. strs are anndata.acc.AdAcc.resolve()d. Accompanying uns entries are stored under the same key. If True, the adjusted embedding is returned instead of written. If False, it is written to .obsm['pca_harmony'].

dtype DTypeLike (default: <class 'numpy.float64'>)

The data type to use for Harmony computation, float32 or float64. If you use 32-bit you may experience numerical instability.

flavor Literal['harmony2', 'harmony1'] (default: 'harmony2')

Which version of the Harmony algorithm to use. "harmony2" (default) enables the stabilized diversity penalty, dynamic per-cluster-per-batch ridge regularization, and automatic batch pruning from [Patikas et al., 2026]. "harmony1" uses the original algorithm from [Korsunsky et al., 2019].

n_clusters int | None (default: None)

Number of clusters used for soft k-means in the Harmony algorithm. If None, uses min(100, N / 30). More clusters capture finer-grained structure but increase computation time.

max_iter_harmony int (default: 10)

Maximum number of outer Harmony iterations (each consisting of a clustering step followed by a correction step).

max_iter_clustering int | None (default: None)

Maximum iterations for the clustering step within each Harmony iteration. If None, uses the value of the reference implementation for the chosen flavor: 4 for "harmony2", 200 for "harmony1" (200 for both with the "paper" stop rules).

tol_harmony float | None (default: None)

Convergence tolerance for the Harmony objective function. The algorithm stops when the relative change in objective falls below this value. If None, 1e-2 for "harmony2" and 1e-4 for "harmony1" (1e-4 for both with the "paper" stop rules).

tol_clustering float | None (default: None)

Convergence tolerance for the clustering step within each Harmony iteration. If None, 1e-3 for "harmony2" and 1e-5 for "harmony1" (1e-5 for both with the "paper" stop rules).

sigma float (default: 0.1)

Width of the soft-clustering kernel. Controls the entropy of cluster assignments: smaller values produce harder assignments (cells assigned to fewer clusters), while larger values produce softer assignments (cells spread across more clusters).

theta float | Sequence[float] (default: 2.0)

Diversity penalty weight per batch variable. Controls how strongly Harmony encourages each cluster to contain a balanced representation of all batches. Higher values (e.g. 4) produce more aggressive mixing; lower values (e.g. 0.5) allow more batch-specific clusters. Set to 0 to disable the diversity penalty for a batch variable. A scalar is applied to every batch variable. A sequence may contain one value per variable, expanded over that variable’s categorical levels, or one value per categorical level across all keys.

tau int (default: 0)

Discounting factor on theta. When tau > 0, the diversity penalty is down-weighted for batches with fewer cells, preventing over-correction of small batches. By default (0), there is no discounting.

ridge_lambda float (default: 1.0)

Ridge regression regularization for the correction step. Larger values produce more conservative (smaller) corrections, preventing over-fitting. Must be finite and greater than zero. Only used with flavor="harmony1".

alpha float (default: 0.2)

Scaling factor for the dynamic per-cluster-per-batch ridge regularization. The effective regularization for each cluster-batch pair is alpha * E_kb where E_kb is the expected number of cells. Larger values produce more conservative corrections. Only used with flavor="harmony2".

batch_prune_threshold float | None (default: 1e-05)

Fraction threshold below which a batch-cluster pair is pruned (correction suppressed). When the fraction of a batch’s cells assigned to a cluster (O_kb / N_b) falls below this threshold, that batch-cluster pair receives no correction, preventing spurious adjustments. Only used with flavor="harmony2". Set to None to disable pruning.

correction_method Literal['fast'] (default: 'fast')

Method for the correction step. Only "fast" is supported: the ridge regression of every cluster is solved exactly, eliminating the batch variable with the most levels in closed form, for one or several batch keys.

block_proportion float (default: 0.05)

Proportion of cells updated per clustering sub-iteration. Smaller values produce more stochastic updates. Larger values are faster but may converge to different solutions.

stop_rule Literal['reference_record', 'reference', 'paper', 'paper_window3'] (default: 'reference_record')

When the clustering and the outer Harmony loop stop. "reference_record" (default) and "reference" use the iteration limits and tolerances listed under max_iter_clustering, tol_clustering and tol_harmony, and test clustering convergence over a window of 3 iterations. "reference_record" records every round’s objective for the outer test; "reference" records it only when the clustering converged. "paper" and "paper_window3" use the tolerances of Korsunsky et al. [2019] (200 clustering iterations, 1e-5 and 1e-4) for both flavors, testing clustering convergence on the last iteration or a window of 3.

seeding Literal['afkmc2', 'kmeans', 'kmeans++', 'paper_nearest'] | None (default: None)

How the initial cluster centroids are chosen. If None, "afkmc2" for "harmony2" and "kmeans" for "harmony1". "afkmc2" approximates k-means++ seeding with Markov chains [Bachem et al., 2016] and needs a single pass over the cells. "kmeans" runs KMeans (k-means++ and up to 25 Lloyd iterations). "kmeans++" is exact k-means++ seeding. "paper_nearest" follows the sampler of Patikas et al. [2026], taking the cell with the highest log(u) / D (the paper prints “lowest”), where D is the distance to the nearest centroid chosen so far: this draws cells with probability proportional to that distance.

seeding_lloyd_steps int (default: 0)

Hard spherical k-means iterations applied to the seeds before Harmony starts.

seeding_cells_per_cluster int | None (default: None)

If set, seeding="kmeans" and the seeding_lloyd_steps run on a random subsample of seeding_cells_per_cluster * n_clusters cells.

penalty_combine Literal['product', 'sum'] (default: 'product')

How the diversity penalties of several batch keys are combined in the soft assignment. "product" (default) multiplies the per-key penalty factors, as in Korsunsky et al. [2019]; "sum" adds them, as the assignment rule is printed in Patikas et al. [2026], leaving out levels with theta == 0. Identical for a single key.

recompute_counts bool (default: True)

Rebuild the per-batch cluster counts from the assignments after every clustering iteration. If False, the counts are only updated incrementally, which accumulates rounding error in float32.

low_memory bool (default: False)

Drop one cell x component buffer during the iterations at the cost of one extra pass at the end; the result is identical.

rng int | integer | Sequence[int] | SeedSequence | Generator | BitGenerator | None (default: None)

Random number generator or seed for deterministic behavior.

Return type:

ndarray | None

Returns:

Returns the adjusted embedding if out=True, else None. It contains the principal components adjusted by Harmony, such that different experiments are integrated.