Goal
Map labels from a reference AnnData onto a query AnnData by building a shared integrated space, training a weighted kNN transfer model, and writing predicted labels plus uncertainty scores back to the query object.
Treat harmony, scVI, and scanorama as alternative integration branches. They share the same query/reference contract, so keep them in one skill rather than splitting into thin wrappers.
Quick Workflow
- Start from a query
AnnDataand a referenceAnnDatathat share gene names. - Make sure the reference has a cell-type column such as
celltypeinadata_ref.obs. - If the data are already log-normalized, recover or restore counts before concatenating.
- Construct
ov.single.AnnotationRef(adata_query, adata_ref, celltype_key=...). - Run
preprocess(mode=...)on the combined object. - Choose one integration backend with
train(method=...). - Transfer labels with
predict(method=...). - Validate the method-specific prediction keys before plotting or writing outputs.
Interface Summary
AnnotationRef(adata_query, adata_ref, celltype_key='celltype')checks shared genes, concatenates query and reference, and stores the integrated object onself.adata_new.AnnotationRef.preprocess(mode='shiftlog|pearson', n_HVGs=3000, batch_key='integrate_batch')prepares the concatenated object for transfer.AnnotationRef.train(method='harmony', **kwargs)computes the integrated latent space used for transfer.AnnotationRef.predict(method='harmony', n_neighbors=15, pred_key=None, uncert_key=None)transfers labels with weighted kNN.- The current source also exposes
batch_correction(..., methods='harmony')with additional methods such ascombat,scanorama,scVI,CellANOVA, andConcord; the notebook uses only theharmonyandscVItransfer path.
Read references/source-grounding.md before documenting narrower parameter behavior than the live source supports.
Branch Selection
- Use
harmonywhen you want the notebook's default transfer path and a fast, interpretable integration backend. - Use
scVIwhen you want the scVI latent-space branch and the environment hasscvi-tools. - Use
scanoramawhen you explicitly want Scanorama integration and its dependencies are available. - Keep
harmonyas the default unless the user asks for a different integration backend. - Keep
mode='shiftlog|pearson'as the default preprocessing choice unless the user wants a different normalization/HVG strategy.
Input Contract
- Query and reference must share feature names before
AnnotationRefcan concatenate them. - The reference must carry a cell-type label column in
adata_ref.obs. - If the notebook reference was stored with a
feature_namecolumn, alignadata_ref.var_namesfirst. - If
adata_query.X.max()oradata_ref.X.max()suggests the data are already log-normalized, recover counts before transfer. AnnotationRef.preprocess(...)uses the combined query/reference object, so treat the pair as one integrated preprocessing unit.
Minimal Execution Patterns
For harmony-based transfer:
import omicverse as ov
ref_anno = ov.single.AnnotationRef(adata_query, adata_ref, celltype_key="celltype")
ref_anno.preprocess(mode="shiftlog|pearson", n_HVGs=3000, batch_key="integrate_batch")
ref_anno.train(method="harmony", n_pcs=50)
ad_pred = ref_anno.predict(method="harmony", n_neighbors=15)
ov.pp.mde(ad_pred, use_rep="X_pca_harmony_anno")
ov.pl.embedding(ad_pred, basis="X_mde", color="harmony_prediction")
For scVI-based transfer:
import omicverse as ov
ref_anno = ov.single.AnnotationRef(adata_query, adata_ref, celltype_key="celltype")
ref_anno.preprocess(mode="shiftlog|pearson", n_HVGs=3000, batch_key="integrate_batch")
ref_anno.train(method="scVI", n_layers=2, n_latent=30, gene_likelihood="nb")
ad_pred = ref_anno.predict(method="scVI", n_neighbors=15)
ov.pl.embedding(ad_pred, basis="X_mde", color="scVI_prediction")
For prompt-driven label transfer around the reference selection step, keep the notebook's reference selection logic separate from the transfer logic; this skill starts once you already have the paired query/reference objects.
Validation
After preprocess(...), check:
self.adata_newhasintegrate_batchinobsself.adata_new.obsm["X_pca"]existsself.adata_new.var["highly_variable_features"]exists
After train(method="harmony"), check:
self.adata_query.obsm["X_pca_harmony_anno"]existsself.adata_ref.obsm["X_pca_harmony_anno"]exists
After train(method="scVI"), check:
self.adata_query.obsm["X_scVI_anno"]existsself.adata_ref.obsm["X_scVI_anno"]exists
After train(method="scanorama"), check:
self.adata_query.obsm["X_scanorama_anno"]existsself.adata_ref.obsm["X_scanorama_anno"]exists
After predict(...), check:
harmony_predictionandharmony_uncertaintyfor the harmony branchscVI_predictionandscVI_uncertaintyfor the scVI branchscanorama_predictionandscanorama_uncertaintyfor the Scanorama branch
Before any plotting, check:
- the prediction columns are present in
ad_pred.obs - the integrated embedding key you pass to
ov.pp.mde(...)exists
Constraints
- Do not bake notebook-specific download URLs, file names, or absolute paths into the reusable workflow.
- Do not assume the reference dataset is already in the correct gene-name convention; align feature names first when needed.
- Do not treat
scVIas free: it depends onscvi-toolsand can be materially heavier than the harmony path. - Do not collapse the notebook into one monolithic "load data and run" step; the reusable spine is query/reference construction, preprocessing, backend selection, prediction, and validation.
- Treat
scanoramaas a source-present branch even though the notebook focuses on harmony and scVI.
Resource Map
- Read
references/integration-method-selection.mdwhen choosing betweenharmony,scVI, andscanorama. - Read
references/source-notebook-map.mdto trace notebook sections into this reusable skill. - Read
references/source-grounding.mdfor inspected signatures, source-level branch behavior, and compatibility notes. - Read
references/compatibility.mdwhen notebook prose, input assumptions, or current runtime behavior diverge.