Goal
Turn notebook-style OmicVerse differential cell-type abundance analysis into a reusable execution spine. Keep this skill separate from DEG because DCT has a different constructor, different branch-specific prerequisites, and different result shapes.
Quick Workflow
- Inspect the input
AnnData, the condition column, the cell-type column, and whether sample IDs and a usable embedding already exist. - Choose a backend before running anything:
sccodafor the scCODA branch,milopyfor the native Python Milo-like branch, ormilofor the pertpy Milo branch. - For
milopyandmilo, make suresample_keyexists anduse_reppoints to an embedding already stored inobsm. - Construct
ov.single.DCT(...)with explicit branch arguments, then runrun(...). - For
sccoda, do any posterior-specific follow-up such asset_fdr(...)only after the model has finished. - Collect results with
get_results(...)and verify the branch-specific output columns before plotting or exporting.
Interface Summary
ov.single.DCT(adata, condition, ctrl_group, test_group, cell_type_key, method='sccoda', sample_key=None, use_rep=None)initializes the wrapper.methodbranches aresccoda,milopy, andmilo.sample_keyis operationally required for the Milo-family branches because neighborhood counts are aggregated per sample.use_repis required formilopy; current code also uses it formilo, even though only themilopybranch validates it eagerly.- The constructor filters to the control and test labels immediately and reorders the condition categories.
DCT.run(**kwargs)forwards kwargs only to thesccodabranch viarun_nuts(...).milopyandmiloignore extra kwargs in current wrapper code and instead run fixed neighborhood-testing logic.DCT.get_results(mix_threshold=0.6)returns a scCODA effect table forsccoda, or neighborhood-level Milo tables formilopyandmilo.mix_thresholdonly affects the Milo-family branches by relabeling low-purity neighborhoods asMixed.
Stage Selection
- Use
method='sccoda'when the user wants compositional Bayesian inference and is prepared for posterior sampling and FDR tuning. - Use
method='milopy'when the user wants the native Python Milo-like path and already has a valid embedding such as PCA or Harmony. - Use
method='milo'only when the pertpy Milo branch is specifically required. - Keep diagnostic plots and beeswarm visualizations optional; they are downstream reporting on top of the DCT results, not the reusable contract itself.
Input Contract
- Start from an
AnnDataobject with condition labels and cell-type annotations inobs. - Provide control and test labels that exist in the condition column.
- For
sccoda, provide a sample identifier because the scCODA preparation step loads cell-level data into a sample-aware modality. - For
milopyandmilo, provide bothsample_keyanduse_rep. - Ensure the embedding named by
use_repalready exists inadata.obsm.
Minimal Execution Patterns
import omicverse as ov
dct = ov.single.DCT(
adata,
condition="condition",
ctrl_group="Control",
test_group="Salmonella",
cell_type_key="cell_label",
method="sccoda",
sample_key="batch",
)
dct.run(num_samples=5000, num_warmup=500)
res = dct.get_results()
dct = ov.single.DCT(
adata,
condition="condition",
ctrl_group="Control",
test_group="Salmonella",
cell_type_key="cell_label",
method="milopy",
sample_key="batch",
use_rep="X_harmony",
)
dct.run()
res = dct.get_results(mix_threshold=0.6)
Constraints
- Do not assume one abundance backend can replace another without changing the input contract.
- Do not hide
method,sample_key, oruse_rep; those choices control materially different code paths. - Do not pass
num_samplesornum_warmupas if they affect the Milo-family branches; current wrapper code only forwards kwargs tosccoda. - Do not claim that neighborhood purity relabeling matters for
sccoda;mix_thresholdonly changes the Milo-family result table. - Keep smoke and acceptance commands shell-agnostic. Do not rely on
zsh-specific syntax, shell startup files, or shell-only features when a direct${PYTHON} script.pycommand is enough. - Do not put local paths or environment names into the reusable instructions.
Validation
- Check that the control and test labels both remain after constructor filtering.
- For
sccoda, check thatget_results()returns an effect table and that any FDR adjustment is applied after model fitting. - For
milopyormilo, check that the result table includes neighborhood annotation columns and abundance statistics such as FDR-like outputs. - Check that the embedding named by
use_repexisted before construction. - If only one representative branch was run as a smoke test, say which branch was validated and which branches were source-grounded only.
Resource Map
- Use the branch selection notes when choosing between scCODA and the Milo-family branches.
- Use the source grounding notes when you need live signatures, current branching behavior, or branch-specific caveats.
- Use the notebook map when tracing which tutorial cells became which reusable instruction.
- Use the compatibility notes when notebook prose and current wrapper behavior differ.