OmicVerse Single-Cell Batch Integration
Goal
Turn the notebook's post-preprocessing batch integration workflow into one reusable skill. Assume QC, normalization, HVG selection, and base PCA preparation are already handled upstream; this skill starts from a preprocessed AnnData with a batch column and focuses on integration backend selection, optional embedding visualization, and optional integration benchmarking.
Quick Workflow
- Confirm that preprocessing is already done and that
adata.obs contains the batch labels.
- Choose an integration backend explicitly with
methods=....
- Validate the backend-specific prerequisites before calling
ov.single.batch_correction(...).
- Check which integrated embedding key was written to
adata.obsm, and keep model/object returns when the backend returns more than adata.
- Run optional embedding visualization only after the integrated embedding exists.
- Run benchmarking only when at least one non-integrated reference embedding and one or more integrated embeddings are present.
Interface Summary
ov.single.batch_correction(adata, batch_key, use_rep='scaled|original|X_pca', methods='harmony', n_pcs=50, **kwargs) dispatches across the notebook's integration backends.
methods='harmony' writes both X_pca_harmony and X_harmony.
methods='combat' runs ComBat on a copy, rescales, recomputes PCA, and writes X_combat.
methods='scanorama' splits by categorical batch, runs Scanorama per batch list, concatenates the integrated coordinates, and writes X_scanorama.
methods='scVI' calls scvi.model.SCVI.setup_anndata(..., layer='counts', batch_key=batch_key), trains a model, writes X_scVI, and returns the trained model object instead of returning adata.
methods='CellANOVA' expects a control_dict, computes denoised, runs PCA on that layer, and writes X_cellanova.
methods='Concord' or methods='concord' constructs a concord.Concord object, runs fit_transform(output_key='X_concord'), writes X_concord, and returns the Concord object.
ov.pp.mde(...) can be used for optional low-dimensional visualization once an embedding key exists.
scib_metrics.benchmark.Benchmarker(...) benchmarks one or more embedding keys against batch and label annotations.
Stage Selection
- Keep this as one skill because the notebook's integration and benchmarking stages share one tight input contract: a preprocessed
AnnData with batch labels and integrated embedding outputs.
- Use the integration stage when the user wants a corrected latent space or wants to compare backends.
- Use the visualization stage only after a concrete integrated embedding key exists.
- Use the benchmarking stage only after integration outputs exist; it is downstream evaluation, not an independent upstream job.
- Do not re-run generic preprocessing here; reuse the existing single-cell preprocessing skill first when needed.
Backend Selection
- Use
harmony as the default CPU-friendly backend when you already have PCA and want the notebook's primary integration path.
- Use
combat when you want a simple expression-level correction path and can accept a recomputed PCA output.
- Use
scanorama when pairwise manifold stitching is explicitly requested and its extra dependencies are available.
- Use
scVI when the environment has scvi-tools, raw counts are present in adata.layers['counts'], and a heavier latent-variable model is acceptable.
- Use
CellANOVA when you have a defensible control pool and explicitly want signal recovery with control_dict.
- Use
Concord when the environment has Concord installed and the user wants its self-supervised latent space.
Input Contract
- Start from a preprocessed
AnnData that already has a batch column in adata.obs.
- Preserve raw counts in
adata.layers['counts'] before scVI.
- Keep or create a PCA representation before
harmony when you want to control use_rep explicitly.
- Convert the batch column to categorical before
scanorama so the per-batch split is stable.
- Ensure
control_dict is provided for CellANOVA and that it names valid batch groups.
- Keep a non-integrated reference embedding such as
X_pca if benchmarking will follow.
Minimal Execution Patterns
import omicverse as ov
ov.single.batch_correction(
adata,
batch_key="batch",
methods="harmony",
n_pcs=50,
use_gpu=False,
)
ov.single.batch_correction(
adata,
batch_key="batch",
methods="combat",
n_pcs=50,
)
model = ov.single.batch_correction(
adata,
batch_key="batch",
methods="scVI",
n_layers=2,
n_latent=30,
gene_likelihood="nb",
)
control_dict = {
"pool1": ["batch_a", "batch_b"],
}
ov.single.batch_correction(
adata,
batch_key="batch",
methods="CellANOVA",
n_pcs=50,
control_dict=control_dict,
)
from scib_metrics.benchmark import Benchmarker
bm = Benchmarker(
adata,
batch_key="batch",
label_key="cell_type",
embedding_obsm_keys=["X_pca", "X_pca_harmony", "X_combat"],
pre_integrated_embedding_obsm_key="X_pca",
n_jobs=1,
progress_bar=False,
)
bm.benchmark()
results = bm.get_results(min_max_scale=False)
Constraints
- Do not treat this as a preprocessing skill.
- Do not leave
methods implicit.
- Do not assume every backend returns
adata; keep the returned object for scVI and Concord.
- Do not claim that all backends are equally cheap;
scVI and Concord are materially heavier than harmony or combat.
- Do not benchmark embeddings that were never written to
adata.obsm.
- Keep smoke commands shell-agnostic.
Validation
- After
harmony, check X_pca_harmony and X_harmony.
- After
combat, check X_combat.
- After
scanorama, check X_scanorama.
- After
scVI, check that a model object was returned and that X_scVI exists.
- After
CellANOVA, check denoised plus X_cellanova.
- After
Concord, check that a Concord object was returned and that X_concord exists.
- Before benchmarking, confirm that the batch and label columns both exist.
- After benchmarking, confirm that the results table is non-empty and includes the requested embedding keys.
- If only a representative smoke path was executed, state which backends and which benchmark subset were run empirically.
Resource Map
- Use the source grounding notes for backend-specific outputs, return types, and prerequisite details.
- Use the backend selection notes when choosing among CPU, GPU, or control-pool branches.
- Use the notebook mapping notes to align notebook sections with the stage boundaries in this skill.
- Use the compatibility notes for dependency-sensitive and long-running backends.
1---2name: omicverse-single-cell-batch-integration3description: Run OmicVerse single-cell batch integration as a reusable, triggerable skill after preprocessing is already complete. Use when choosing a batch correction backend such as harmony, combat, scanorama, scVI, CellANOVA, or Concord on a preprocessed AnnData with batch labels, or when benchmarking integrated embeddings from one of those backends.4---56# OmicVerse Single-Cell Batch Integration78## Goal910Turn the notebook's post-preprocessing batch integration workflow into one reusable skill. Assume QC, normalization, HVG selection, and base PCA preparation are already handled upstream; this skill starts from a preprocessed `AnnData` with a batch column and focuses on integration backend selection, optional embedding visualization, and optional integration benchmarking.1112## Quick Workflow13141. Confirm that preprocessing is already done and that `adata.obs` contains the batch labels.152. Choose an integration backend explicitly with `methods=...`.163. Validate the backend-specific prerequisites before calling `ov.single.batch_correction(...)`.174. Check which integrated embedding key was written to `adata.obsm`, and keep model/object returns when the backend returns more than `adata`.185. Run optional embedding visualization only after the integrated embedding exists.196. Run benchmarking only when at least one non-integrated reference embedding and one or more integrated embeddings are present.2021## Interface Summary2223- `ov.single.batch_correction(adata, batch_key, use_rep='scaled|original|X_pca', methods='harmony', n_pcs=50, **kwargs)` dispatches across the notebook's integration backends.24- `methods='harmony'` writes both `X_pca_harmony` and `X_harmony`.25- `methods='combat'` runs ComBat on a copy, rescales, recomputes PCA, and writes `X_combat`.26- `methods='scanorama'` splits by categorical batch, runs Scanorama per batch list, concatenates the integrated coordinates, and writes `X_scanorama`.27- `methods='scVI'` calls `scvi.model.SCVI.setup_anndata(..., layer='counts', batch_key=batch_key)`, trains a model, writes `X_scVI`, and returns the trained model object instead of returning `adata`.28- `methods='CellANOVA'` expects a `control_dict`, computes `denoised`, runs PCA on that layer, and writes `X_cellanova`.29- `methods='Concord'` or `methods='concord'` constructs a `concord.Concord` object, runs `fit_transform(output_key='X_concord')`, writes `X_concord`, and returns the Concord object.30- `ov.pp.mde(...)` can be used for optional low-dimensional visualization once an embedding key exists.31- `scib_metrics.benchmark.Benchmarker(...)` benchmarks one or more embedding keys against batch and label annotations.3233## Stage Selection3435- Keep this as one skill because the notebook's integration and benchmarking stages share one tight input contract: a preprocessed `AnnData` with batch labels and integrated embedding outputs.36- Use the integration stage when the user wants a corrected latent space or wants to compare backends.37- Use the visualization stage only after a concrete integrated embedding key exists.38- Use the benchmarking stage only after integration outputs exist; it is downstream evaluation, not an independent upstream job.39- Do not re-run generic preprocessing here; reuse the existing single-cell preprocessing skill first when needed.4041## Backend Selection4243- Use `harmony` as the default CPU-friendly backend when you already have PCA and want the notebook's primary integration path.44- Use `combat` when you want a simple expression-level correction path and can accept a recomputed PCA output.45- Use `scanorama` when pairwise manifold stitching is explicitly requested and its extra dependencies are available.46- Use `scVI` when the environment has `scvi-tools`, raw counts are present in `adata.layers['counts']`, and a heavier latent-variable model is acceptable.47- Use `CellANOVA` when you have a defensible control pool and explicitly want signal recovery with `control_dict`.48- Use `Concord` when the environment has Concord installed and the user wants its self-supervised latent space.4950## Input Contract5152- Start from a preprocessed `AnnData` that already has a batch column in `adata.obs`.53- Preserve raw counts in `adata.layers['counts']` before `scVI`.54- Keep or create a PCA representation before `harmony` when you want to control `use_rep` explicitly.55- Convert the batch column to categorical before `scanorama` so the per-batch split is stable.56- Ensure `control_dict` is provided for `CellANOVA` and that it names valid batch groups.57- Keep a non-integrated reference embedding such as `X_pca` if benchmarking will follow.5859## Minimal Execution Patterns6061```python62import omicverse as ov6364ov.single.batch_correction(65 adata,66 batch_key="batch",67 methods="harmony",68 n_pcs=50,69 use_gpu=False,70)71```7273```python74ov.single.batch_correction(75 adata,76 batch_key="batch",77 methods="combat",78 n_pcs=50,79)80```8182```python83model = ov.single.batch_correction(84 adata,85 batch_key="batch",86 methods="scVI",87 n_layers=2,88 n_latent=30,89 gene_likelihood="nb",90)91```9293```python94control_dict = {95 "pool1": ["batch_a", "batch_b"],96}9798ov.single.batch_correction(99 adata,100 batch_key="batch",101 methods="CellANOVA",102 n_pcs=50,103 control_dict=control_dict,104)105```106107```python108from scib_metrics.benchmark import Benchmarker109110bm = Benchmarker(111 adata,112 batch_key="batch",113 label_key="cell_type",114 embedding_obsm_keys=["X_pca", "X_pca_harmony", "X_combat"],115 pre_integrated_embedding_obsm_key="X_pca",116 n_jobs=1,117 progress_bar=False,118)119bm.benchmark()120results = bm.get_results(min_max_scale=False)121```122123## Constraints124125- Do not treat this as a preprocessing skill.126- Do not leave `methods` implicit.127- Do not assume every backend returns `adata`; keep the returned object for `scVI` and `Concord`.128- Do not claim that all backends are equally cheap; `scVI` and `Concord` are materially heavier than `harmony` or `combat`.129- Do not benchmark embeddings that were never written to `adata.obsm`.130- Keep smoke commands shell-agnostic.131132## Validation133134- After `harmony`, check `X_pca_harmony` and `X_harmony`.135- After `combat`, check `X_combat`.136- After `scanorama`, check `X_scanorama`.137- After `scVI`, check that a model object was returned and that `X_scVI` exists.138- After `CellANOVA`, check `denoised` plus `X_cellanova`.139- After `Concord`, check that a Concord object was returned and that `X_concord` exists.140- Before benchmarking, confirm that the batch and label columns both exist.141- After benchmarking, confirm that the results table is non-empty and includes the requested embedding keys.142- If only a representative smoke path was executed, state which backends and which benchmark subset were run empirically.143144## Resource Map145146- Use the source grounding notes for backend-specific outputs, return types, and prerequisite details.147- Use the backend selection notes when choosing among CPU, GPU, or control-pool branches.148- Use the notebook mapping notes to align notebook sections with the stage boundaries in this skill.149- Use the compatibility notes for dependency-sensitive and long-running backends.