name: dynamo-one-shot-total-rna-velocity
description: Run or adapt a one-shot total RNA velocity workflow in dynamo for metabolic-labeling or scNT-seq AnnData, including monocle preprocessing with an optional curated gene list, grouped moments by labeling time, Model-2 dynamics, calculate_velocity_alpha_minus_gamma_s, low-dimensional projection with cell_velocities, and optional streamline or phase-portrait plotting. Use when converting tutorials such as 301_tutorial_hsc_velocity.ipynb, or when choosing between one_shot_method branches like sci_fate and combined and projection method branches like cosine and pearson.
Dynamo One-Shot Total RNA Velocity
Goal
Run the stable execution spine behind the hematopoiesis scNT-seq tutorial: preprocess a one-shot labeling dataset, smooth by labeling time, force the Model-2 no-splicing branch for kinetics, compute total RNA velocity with alpha - gamma * s, then project that custom velocity to a low-dimensional embedding without treating the tutorial dataset as the workflow identity.
Quick Workflow
- Inspect the input
AnnDatafornew,total, andtime, plus any reusable helpers such asuns["genes_to_use"]andobsm["X_umap"]. - Preprocess with the monocle path. If a curated gene list exists, preserve it explicitly and use
Preprocessor(force_gene_list=...)plusconfig_monocle_recipe(..., n_top_genes=len(gene_list)). - Materialize grouped moments with
dyn.tl.moments(..., group='time')so the one-shot fit sees time-specific neighborhoods and createsM_n,M_t, andM_s. - Force the no-splicing Model-2 branch by setting
adata.uns["pp"]["has_splicing"] = False, then rundyn.tl.dynamics(..., group='time', one_shot_method='sci_fate', model='deterministic')unless the user explicitly wants another branch. - Convert the fitted kinetic parameters into total RNA velocity with
dyn.tl.calculate_velocity_alpha_minus_gamma_s(...). - Project the custom total RNA velocity with
dyn.tl.cell_velocities(..., X=adata.layers["M_t"], V=adata.layers["velocity_alpha_minus_gamma_s"], method='cosine'). - Treat
streamline_plotandphase_portraitsas optional visualization steps aftervelocity_umapalready exists.
Interface Summary
Preprocessor.config_monocle_recipe(adata, n_top_genes=2000)configures the notebook-style monocle preprocessing path.Preprocessor.preprocess_adata_monocle(adata, tkey=None, experiment_type=None)is the exact notebook entrypoint;Preprocessor.preprocess_adata(..., recipe='monocle', ...)is the higher-level wrapper.dyn.tl.moments(..., group=None, use_gaussian_kernel=False, use_mnn=False, layers='all')creates smoothed first and second moments and storesobsp["moments_con"].dyn.tl.dynamics(..., group=None, model='auto', est_method='auto', one_shot_method='combined', ...)estimates one-shot kinetic parameters and writes velocity-like layers such asvelocity_Nandvelocity_T.dyn.tl.calculate_velocity_alpha_minus_gamma_s(adata, gene_subset_key='use_for_pca', velocity_layer_name='velocity_alpha_minus_gamma_s')converts fitted rates plusM_nandM_sinto the total RNA velocity layer used in the notebook.dyn.tl.cell_velocities(..., X=None, V=None, basis='umap', method='pearson', adj_key='distances', enforce=False)projects the custom velocity to low-dimensional space and stores a kernel-specific transition matrix.dyn.pl.streamline_plot(..., basis='umap', method='gaussian')anddyn.pl.phase_portraits(...)are optional presentation entrypoints after the analytical path is complete.
Read references/source-grounding.md before documenting narrower parameter behavior than the live source currently supports.
Branch Selection
- Use the curated-gene-list branch when
uns["genes_to_use"]or a user-supplied marker/HVG list exists. Preserve that list explicitly before subsetting or concatenating becauseanndata.concat(...)can drop it. - Use
recipe='monocle'for this workflow family. Otherrecipebranches are real source-level options, but the total-RNA one-shot path here was empirically checked only on the monocle branch. - Use
group='time'onmoments(...)anddynamics(...)unless the user explicitly wants to smooth and fit without time-specific neighborhoods. - Use
one_shot_method='sci_fate'for notebook parity andone_shot_method='combined'when the user explicitly wants the steady-state-plus-absolute-gamma branch. Both were empirically checked. - Use
model='deterministic'by default for this total-RNA workflow. If the user wants a splicing-aware or stochastic branch, stop and switch to a different workflow instead of silently mixing models. - Use
cell_velocities(..., method='cosine')for notebook-style total-RNA projection. Usemethod='pearson'when the user wants the alternate kernel with a different transition-matrix key. Treatkmc,fp, andtransformas advanced branches with extra assumptions. - Use
streamline_plot(..., method='gaussian')for default streamline rendering. Switch tomethod='SparseVFC'only after a vector field has been reconstructed and the user explicitly wants that rendering path.
Read references/branch-selection.md before choosing non-default recipe, one_shot_method, model, method, or plotting branches.
Input Contract
- Expect a metabolic-labeling
AnnDatawith usablenewandtotallayers and a labeling-time column. - Expect the time column to be accessible as
adata.obs["time"]before callingcalculate_velocity_alpha_minus_gamma_s(...), or rename / copy the user's time key totime. - Treat
splicedandunsplicedas optional inputs for the raw object, not as the target model branch. The notebook-compatible total-RNA path forceshas_splicing=Falsebeforedynamics(...). - Expect
M_n,M_t, andM_sto be created bymoments(...)before callingcalculate_velocity_alpha_minus_gamma_s(...). - Expect a valid embedding such as
X_umapplus a matching adjacency matrix underobsp["distances"]before callingcell_velocities(...). - Treat tutorial-specific fields such as
genes_to_use,cell_type, and the hematopoiesis sample layout as worked examples, not universal defaults.
Minimal Execution Patterns
For the notebook-compatible one-shot total RNA workflow:
import dynamo as dyn
adata = dyn.sample_data.hematopoiesis_raw()
adata.obs_names_make_unique()
selected_genes = list(adata.uns["genes_to_use"])
pre = dyn.pp.Preprocessor(force_gene_list=selected_genes)
pre.config_monocle_recipe(adata, n_top_genes=len(selected_genes))
pre.preprocess_adata_monocle(adata, tkey="time", experiment_type="one-shot")
dyn.tl.reduceDimension(adata)
dyn.tl.moments(adata, group="time")
adata.uns["pp"]["has_splicing"] = False
dyn.tl.dynamics(
adata,
group="time",
one_shot_method="sci_fate",
model="deterministic",
cores=1,
)
dyn.tl.calculate_velocity_alpha_minus_gamma_s(adata)
dyn.tl.cell_velocities(
adata,
enforce=True,
X=adata.layers["M_t"],
V=adata.layers["velocity_alpha_minus_gamma_s"],
method="cosine",
)
For a generic one-shot labeling dataset without a baked-in gene list:
pre = dyn.pp.Preprocessor()
pre.preprocess_adata(adata, recipe="monocle", tkey="time", experiment_type="one-shot")
For a non-default combined one-shot branch:
dyn.tl.dynamics(
adata,
group="time",
one_shot_method="combined",
model="deterministic",
cores=1,
)
For a non-default pearson projection branch:
dyn.tl.cell_velocities(
adata,
enforce=True,
X=adata.layers["M_t"],
V=adata.layers["velocity_alpha_minus_gamma_s"],
method="pearson",
)
Validation
After preprocessing, check these items:
adata.uns["pp"]["experiment_type"] == "one-shot"adata.var["use_for_pca"]existsadata.obsm["X_pca"]exists
After moments(..., group='time'), check these items:
adata.obsp["moments_con"]existsadata.layers["M_n"],adata.layers["M_t"], andadata.layers["M_s"]exist
Before dynamics(...), check these items:
adata.obs["time"]existsadata.uns["pp"]["has_splicing"] is Falsefor the Model-2 branch
After dynamics(...), check these items:
adata.uns["dynamics"]["model"] == "deterministic"for the default branchadata.layers["velocity_T"]existsadata.var["use_for_dynamics"]exists
After calculate_velocity_alpha_minus_gamma_s(...), check these items:
adata.layers["velocity_alpha_minus_gamma_s"]exists- the function reports each unique time point it processed
After cell_velocities(...), check these items:
adata.obsm["velocity_umap"]exists for the default UMAP branchadata.obsp["cosine_transition_matrix"]exists formethod='cosine'adata.obsp["pearson_transition_matrix"]exists formethod='pearson'
Constraints
- Do not treat
velocity_Tfromdynamics(...)as the notebook endpoint. The tutorial's total-RNA visualization path depends on the extracalculate_velocity_alpha_minus_gamma_s(...)pluscell_velocities(...)steps. - Do not forget to rename or copy the time column to
adata.obs["time"]beforecalculate_velocity_alpha_minus_gamma_s(...); current source hard-codes that key. - Do not assume
uns["genes_to_use"]survivesAnnDataconcatenation or subsetting workflows. Preserve it explicitly when reconstructing subsets. - Do not keep
has_splicing=Trueif the goal is Model-2 total RNA velocity. Preprocessing auto-detects splicing and labeling together on the hematopoiesis raw object. - Do not interpret
one_shot_methodfromadata.uns["dynamics"]; current runtime does not store it there. - Do not make small per-time groups the default. Reviewer runs with fewer than
50cells per time group emitted NaN-velocity warnings and filtered genes before projection.
Resource Map
- Read
references/branch-selection.mdfor decision rules acrossrecipe, grouped smoothing,one_shot_method, and projectionmethodbranches. - Read
references/visualization-and-phase-portraits.mdwhen the user explicitly wants notebook-style streamlines or total-RNA phase-portrait adaptation. - Read
references/source-grounding.mdfor inspected signatures, source-level branch evidence, and empirical execution notes. - Read
references/source-notebook-map.mdto see howdocs/tutorials/notebooks/301_tutorial_hsc_velocity.ipynbwas converted into this reusable skill. - Read
references/compatibility.mdwhen notebook wording and current source behavior diverge.