Dynamo Least Action Path Cell Fate Transition
Goal
Given a dynamo AnnData with a completed vector field and ddhodge potential in UMAP space, compute pairwise least action paths (LAPs) between all requested cell types, extract per-path action and time metrics, rank transcription factors by their mean square displacement (MSD) along each path, and evaluate TF prioritization quality via ROC analysis.
Quick Workflow
- Confirm the input AnnData has
VecFld_umap, umap_ddhodge_potential, and a cell type column.
- Build a UMAP-basis neighbor graph with
dyn.tl.neighbors(..., basis='umap', result_prefix='umap').
- Run
dyn.pd.compute_cell_type_transitions(...) to compute LAPs for all requested cell type pairs.
- Persist
transition_graph and cells_indices to disk with dyn.utils.save_pickle(...) — this step is long-running.
- Load a human TF list with
dyn.sample_data.human_tfs().
- Extract action and time matrices with
dyn.pd.extract_transition_metrics(...).
- Plot kinetic heatmaps of gene expression dynamics along selected paths with
dyn.pd.plot_kinetic_heatmap(...).
- Rank TFs across all transitions with
dyn.pd.analyze_transition_tfs(...).
- Evaluate TF ranking quality with
dyn.pd.analyze_tf_roc_performance(...).
Interface Summary
dyn.tl.neighbors(adata, X_data=None, genes=None, basis='pca', layer=None, n_pca_components=30, n_neighbors=30, method=None, metric='euclidean', metric_kwads=None, cores=1, seed=19491001, result_prefix='', **kwargs) — build neighbor graph; use basis='umap', result_prefix='umap' to create the X_umap_distances adjacency needed by LAP.
dyn.pd.compute_cell_type_transitions(adata, cell_types, potential_column='umap_ddhodge_potential', cell_type_column='cell_type', reference_cell_types=None, basis_list=['umap', 'pca'], umap_adj_key='X_umap_distances', pca_adj_key='cosine_transition_matrix', EM_steps=2, top_genes=5, enable_plotting=True, enable_gene_analysis=True, marginal_method='combined', verify_selection=False, manual_cell_indices=None, manual_source_indices=None, manual_target_indices=None) — core LAP computation; returns (transition_graph, cells_indices).
dyn.pd.extract_transition_metrics(transition_graph, cells_indices_dict, cell_types, transcription_factors, top_tf_genes=10, lap_method='action') — extract action and time DataFrames per transition pair; returns (action_df, t_df, tf_genes).
dyn.pd.plot_kinetic_heatmap(adata, cells_indices_dict, source_cell_type, target_cell_type, transcription_factors, basis='pca', adj_key='cosine_transition_matrix', figsize=(16, 8), color_map='bwr', font_scale=0.8, scaler=0.6, save_path=None, show_plot=True, return_data=False) — plot gene expression dynamics along a LAP.
dyn.pd.analyze_kinetic_genes(adata, cells_indices_dict, source_cell_type, target_cell_type, transcription_factors, top_genes=20, basis='pca', adj_key='cosine_transition_matrix') — rank TFs by MSD along one selected LAP; returns (ranking_df, top_tfs).
dyn.pd.analyze_transition_tfs(transition_graph, human_tfs_names, transitions_config, plot_type='transdifferentiation', known_tfs_dict=None, transition_pmids=None, transition_types=None, total_tf_count=133, transition_color_dict=None, figsize=(8, 5)) — all-in-one: process rankings, build matrix, and plot for one transition type.
dyn.pd.process_all_transition_rankings(transition_graph, human_tfs_names, known_tfs_dict=None) — step-wise version: add TF and known_TF columns to all transitions; returns processed_rankings.
dyn.pd.create_reprogramming_matrix(transition_graph, transitions_config, transition_pmids=None, transition_types=None, total_tf_count=133) — build normalized priority-score DataFrame; returns (reprogramming_dict, reprogramming_df). Important: pass {} not None for transition_pmids and transition_types — the current source does not guard against None (see references/compatibility.md).
dyn.pd.plot_transition_tf_analysis(reprogramming_df, transition_type='transdifferentiation', figsize=(8, 5), score_threshold=0.8, transition_color_dict=None) — bar/scatter plot of known TF priority scores per transition type.
dyn.pd.analyze_tf_roc_performance(processed_rankings, transitions_to_include=None, plot_roc=True, roc_plot_params=None) — compute and optionally plot ROC curve for TF ranking; returns dict with fpr, tpr, roc_auc, consolidated_df.
dyn.pd.get_tf_statistics(processed_rankings, reprogramming_df) — return counts and overlap of TFs; dict with n_all_tfs, n_valid_tfs, n_overlap, overlap_percentage.
dyn.utils.save_pickle(file, path) / dyn.utils.load_pickle(path) — persist and restore any Python object; falls back to cloudpickle if standard pickle fails.
Read references/source-grounding.md for inspected signatures and storage key evidence.
Stage Selection
- Stage 1 — LAP computation:
compute_cell_type_transitions with enable_plotting=True, enable_gene_analysis=True. This is the slow step. Save outputs with save_pickle before proceeding.
- Stage 2 — Metrics and visualization:
extract_transition_metrics, LAP path plotting, action/time heatmaps. Load from pickle if Stage 1 was already run.
- Stage 3 — Kinetic heatmaps:
plot_kinetic_heatmap and analyze_kinetic_genes for specific source–target pairs. Requires cells_indices and the adata with fitted vector field.
- Stage 4 — TF ranking and ROC:
analyze_transition_tfs or the three-step pattern (process_all_transition_rankings → create_reprogramming_matrix → plot_transition_tf_analysis), then analyze_tf_roc_performance.
Use analyze_transition_tfs (all-in-one) for the quickest path. Use the three-step pattern when you need fine-grained control over known TF dictionaries, PMID tables, or plot parameters.
Read references/stage-selection.md for details on marginal_method, lap_method, and plot_type branch options.
Input Contract
AnnData with VecFld_umap in .uns (vector field must already be fitted).
adata.obs[potential_column] exists (default umap_ddhodge_potential); populated by dyn.ext.ddhodge.
adata.obsm['X_umap'] and adata.obsm['X_pca'] exist.
adata.obsp['cosine_transition_matrix'] exists before calling PCA-basis LAP or kinetic heatmap.
- A cell type label column in
adata.obs (default cell_type).
- A transcription factor name list (e.g., from
dyn.sample_data.human_tfs() for human datasets).
- The hematopoiesis worked example loads from
dyn.sample_data.hematopoiesis() — it already includes all required fields.
Minimal Execution Patterns
Stage 1 — LAP computation
import dynamo as dyn
adata = dyn.sample_data.hematopoiesis()
# Build UMAP neighbor graph needed for LAP
dyn.tl.neighbors(adata, basis="umap", result_prefix="umap")
cell_types = ["HSC", "Meg", "Ery", "Bas", "Mon", "Neu"]
transition_graph, cells_indices = dyn.pd.compute_cell_type_transitions(
adata=adata,
cell_types=cell_types,
reference_cell_types=["HSC"],
marginal_method="combined",
potential_column="umap_ddhodge_potential",
cell_type_column="cell_type",
EM_steps=2,
top_genes=5,
enable_plotting=True,
enable_gene_analysis=True,
)
# Persist — this step is expensive
dyn.utils.save_pickle(transition_graph, "result/transition_graph.pkl")
dyn.utils.save_pickle(cells_indices, "result/cells_indices.pkl")
adata.write("result/adata_labeling_analysis.h5ad")
Stage 2 — Metrics extraction
transition_graph = dyn.utils.load_pickle("result/transition_graph.pkl")
cells_indices = dyn.utils.load_pickle("result/cells_indices.pkl")
human_tfs = dyn.sample_data.human_tfs()
human_tfs_names = list(human_tfs["Symbol"])
action_df, t_df, tf_genes = dyn.pd.extract_transition_metrics(
transition_graph=transition_graph,
cells_indices_dict=cells_indices,
cell_types=cell_types,
transcription_factors=human_tfs_names,
top_tf_genes=10,
lap_method="action_t", # 'action' or 'action_t'
)
Stage 3 — Kinetic heatmap for one pair
ranking, top_tfs = dyn.pd.analyze_kinetic_genes(
adata=adata,
cells_indices_dict=cells_indices,
source_cell_type="HSC",
target_cell_type="Bas",
transcription_factors=human_tfs_names,
top_genes=15,
)
dyn.pd.plot_kinetic_heatmap(
adata=adata,
cells_indices_dict=cells_indices,
source_cell_type="HSC",
target_cell_type="Bas",
transcription_factors=human_tfs_names,
save_path="figures/HSC_to_Bas.png",
figsize=(16, 4),
)
Stage 4 — TF ranking and ROC
KNOWN_TFS_DICT = {
"HSC->Meg": ["GATA1", "GATA2", "ZFPM1", "GFI1B", "FLI1", "NFE2"],
# ... add other transitions
}
TRANSITIONS_CONFIG = {
"standard": [
"HSC->Meg", "HSC->Ery", "HSC->Bas", "HSC->Mon", "HSC->Neu",
"Meg->HSC", "Meg->Neu", "Ery->Mon", "Mon->Meg", "Mon->Ery",
"Mon->Bas", "Neu->Bas"
],
"special": {"Ery->Neu": {"sets": [("TFs1", "TFs_rank1", "Ery->Neu1"), ("TFs2", "TFs_rank2", "Ery->Neu2")]}},
}
# All-in-one path
processed_rankings, reprogramming_dict, reprogramming_df = dyn.pd.analyze_transition_tfs(
transition_graph=transition_graph,
human_tfs_names=human_tfs_names,
transitions_config=TRANSITIONS_CONFIG,
plot_type="transdifferentiation",
known_tfs_dict=KNOWN_TFS_DICT,
total_tf_count=133,
)
# ROC analysis
roc_results = dyn.pd.analyze_tf_roc_performance(
processed_rankings=processed_rankings,
plot_roc=True,
roc_plot_params={"figsize": (3, 3), "fontsize": 12, "legend_size": 12},
)
print("AUC:", roc_results["roc_auc"])
Validation
After LAP computation, confirm:
transition_graph contains keys for each A->B pair
- Each entry has
LAP_umap with prediction and action sub-keys
cells_indices contains one entry per cell type in cell_types
- Pickle files written successfully to disk
After metrics extraction, confirm:
action_df.shape == (len(cell_types), len(cell_types))
t_df.shape == (len(cell_types), len(cell_types))
tf_genes is a dict keyed by transition names
After kinetic heatmap, confirm:
- Output figure file exists at
save_path if provided
ranking DataFrame contains MSD scores
top_tfs list is non-empty
After TF ranking and ROC, confirm:
processed_rankings contains one entry per transition
- Each entry has
TFs and TFs_rank (or TFs1/TFs2 for special cases)
reprogramming_df columns include genes, rank, transition, type
roc_results['roc_auc'] is a float between 0 and 1
Constraints
compute_cell_type_transitions requires VecFld_umap and umap_ddhodge_potential to be precomputed.
- Run
dyn.tl.neighbors(adata, basis='umap', result_prefix='umap') before compute_cell_type_transitions; it creates adata.obsp['X_umap_distances'] required for UMAP-basis LAP.
- The
EM_steps parameter controls the number of iterative optimization rounds; lower values (1–2) are faster for smoke paths; default 2 is used in the tutorial.
- Do not treat the hematopoiesis cell type labels, KNOWN_TFS_DICT, or TRANSITION_PMIDS dicts as required skill inputs — they are hematopoiesis-specific worked example parameters.
- The
transitions_config['special'] key handles transitions with two alternative known TF sets (e.g., Ery->Neu). Define it explicitly if your dataset has such ambiguity.
dyn.pd.plot_kinetic_heatmap is a prediction module function distinct from dyn.pl.kinetic_heatmap; they have different signatures and purposes.
- Set
enable_gene_analysis=True (default) whenever TF prioritization or kinetic heatmaps are needed; with enable_gene_analysis=False, gtraj and ranking are absent from transition_graph, causing process_all_transition_rankings to fail and extract_transition_metrics to skip TF extraction with a logged error.
Resource Map
- Read
references/stage-selection.md when choosing marginal_method, lap_method, or plot_type.
- Read
references/source-grounding.md for full inspected signatures and storage key evidence.
- Read
references/source-notebook-map.md to trace 501_lap_tutorial.ipynb sections to skill resources.
- Read
references/compatibility.md when encountering API name mismatches or missing attributes.
- Use
assets/acceptance.json for the bounded smoke paths used by local acceptance.
1---2name: dynamo-lap-cell-fate-transition3description: Compute least action paths (LAP) between hematopoietic or general cell types in a dynamo vector-field AnnData, then rank transcription factors by MSD along each path and evaluate predictions via ROC analysis. Use when running dyn.pd.compute_cell_type_transitions, predicting optimal cell fate conversion trajectories, prioritizing transcription factor cocktails for cell reprogramming, or reproducing the 501_lap_tutorial.ipynb workflow on scNT-seq or metabolic-labeling data.4---56# Dynamo Least Action Path Cell Fate Transition78## Goal910Given a `dynamo` AnnData with a completed vector field and ddhodge potential in UMAP space, compute pairwise least action paths (LAPs) between all requested cell types, extract per-path action and time metrics, rank transcription factors by their mean square displacement (MSD) along each path, and evaluate TF prioritization quality via ROC analysis.1112## Quick Workflow13141. Confirm the input AnnData has `VecFld_umap`, `umap_ddhodge_potential`, and a cell type column.152. Build a UMAP-basis neighbor graph with `dyn.tl.neighbors(..., basis='umap', result_prefix='umap')`.163. Run `dyn.pd.compute_cell_type_transitions(...)` to compute LAPs for all requested cell type pairs.174. Persist `transition_graph` and `cells_indices` to disk with `dyn.utils.save_pickle(...)` — this step is long-running.185. Load a human TF list with `dyn.sample_data.human_tfs()`.196. Extract action and time matrices with `dyn.pd.extract_transition_metrics(...)`.207. Plot kinetic heatmaps of gene expression dynamics along selected paths with `dyn.pd.plot_kinetic_heatmap(...)`.218. Rank TFs across all transitions with `dyn.pd.analyze_transition_tfs(...)`.229. Evaluate TF ranking quality with `dyn.pd.analyze_tf_roc_performance(...)`.2324## Interface Summary2526- `dyn.tl.neighbors(adata, X_data=None, genes=None, basis='pca', layer=None, n_pca_components=30, n_neighbors=30, method=None, metric='euclidean', metric_kwads=None, cores=1, seed=19491001, result_prefix='', **kwargs)` — build neighbor graph; use `basis='umap', result_prefix='umap'` to create the `X_umap_distances` adjacency needed by LAP.27- `dyn.pd.compute_cell_type_transitions(adata, cell_types, potential_column='umap_ddhodge_potential', cell_type_column='cell_type', reference_cell_types=None, basis_list=['umap', 'pca'], umap_adj_key='X_umap_distances', pca_adj_key='cosine_transition_matrix', EM_steps=2, top_genes=5, enable_plotting=True, enable_gene_analysis=True, marginal_method='combined', verify_selection=False, manual_cell_indices=None, manual_source_indices=None, manual_target_indices=None)` — core LAP computation; returns `(transition_graph, cells_indices)`.28- `dyn.pd.extract_transition_metrics(transition_graph, cells_indices_dict, cell_types, transcription_factors, top_tf_genes=10, lap_method='action')` — extract action and time DataFrames per transition pair; returns `(action_df, t_df, tf_genes)`.29- `dyn.pd.plot_kinetic_heatmap(adata, cells_indices_dict, source_cell_type, target_cell_type, transcription_factors, basis='pca', adj_key='cosine_transition_matrix', figsize=(16, 8), color_map='bwr', font_scale=0.8, scaler=0.6, save_path=None, show_plot=True, return_data=False)` — plot gene expression dynamics along a LAP.30- `dyn.pd.analyze_kinetic_genes(adata, cells_indices_dict, source_cell_type, target_cell_type, transcription_factors, top_genes=20, basis='pca', adj_key='cosine_transition_matrix')` — rank TFs by MSD along one selected LAP; returns `(ranking_df, top_tfs)`.31- `dyn.pd.analyze_transition_tfs(transition_graph, human_tfs_names, transitions_config, plot_type='transdifferentiation', known_tfs_dict=None, transition_pmids=None, transition_types=None, total_tf_count=133, transition_color_dict=None, figsize=(8, 5))` — all-in-one: process rankings, build matrix, and plot for one transition type.32- `dyn.pd.process_all_transition_rankings(transition_graph, human_tfs_names, known_tfs_dict=None)` — step-wise version: add TF and known_TF columns to all transitions; returns `processed_rankings`.33- `dyn.pd.create_reprogramming_matrix(transition_graph, transitions_config, transition_pmids=None, transition_types=None, total_tf_count=133)` — build normalized priority-score DataFrame; returns `(reprogramming_dict, reprogramming_df)`. **Important**: pass `{}` not `None` for `transition_pmids` and `transition_types` — the current source does not guard against None (see `references/compatibility.md`).34- `dyn.pd.plot_transition_tf_analysis(reprogramming_df, transition_type='transdifferentiation', figsize=(8, 5), score_threshold=0.8, transition_color_dict=None)` — bar/scatter plot of known TF priority scores per transition type.35- `dyn.pd.analyze_tf_roc_performance(processed_rankings, transitions_to_include=None, plot_roc=True, roc_plot_params=None)` — compute and optionally plot ROC curve for TF ranking; returns dict with `fpr`, `tpr`, `roc_auc`, `consolidated_df`.36- `dyn.pd.get_tf_statistics(processed_rankings, reprogramming_df)` — return counts and overlap of TFs; dict with `n_all_tfs`, `n_valid_tfs`, `n_overlap`, `overlap_percentage`.37- `dyn.utils.save_pickle(file, path)` / `dyn.utils.load_pickle(path)` — persist and restore any Python object; falls back to `cloudpickle` if standard pickle fails.3839Read `references/source-grounding.md` for inspected signatures and storage key evidence.4041## Stage Selection4243- **Stage 1 — LAP computation**: `compute_cell_type_transitions` with `enable_plotting=True, enable_gene_analysis=True`. This is the slow step. Save outputs with `save_pickle` before proceeding.44- **Stage 2 — Metrics and visualization**: `extract_transition_metrics`, LAP path plotting, action/time heatmaps. Load from pickle if Stage 1 was already run.45- **Stage 3 — Kinetic heatmaps**: `plot_kinetic_heatmap` and `analyze_kinetic_genes` for specific source–target pairs. Requires `cells_indices` and the adata with fitted vector field.46- **Stage 4 — TF ranking and ROC**: `analyze_transition_tfs` or the three-step pattern (`process_all_transition_rankings → create_reprogramming_matrix → plot_transition_tf_analysis`), then `analyze_tf_roc_performance`.4748Use `analyze_transition_tfs` (all-in-one) for the quickest path. Use the three-step pattern when you need fine-grained control over known TF dictionaries, PMID tables, or plot parameters.4950Read `references/stage-selection.md` for details on `marginal_method`, `lap_method`, and `plot_type` branch options.5152## Input Contract5354- `AnnData` with `VecFld_umap` in `.uns` (vector field must already be fitted).55- `adata.obs[potential_column]` exists (default `umap_ddhodge_potential`); populated by `dyn.ext.ddhodge`.56- `adata.obsm['X_umap']` and `adata.obsm['X_pca']` exist.57- `adata.obsp['cosine_transition_matrix']` exists before calling PCA-basis LAP or kinetic heatmap.58- A cell type label column in `adata.obs` (default `cell_type`).59- A transcription factor name list (e.g., from `dyn.sample_data.human_tfs()` for human datasets).60- The hematopoiesis worked example loads from `dyn.sample_data.hematopoiesis()` — it already includes all required fields.6162## Minimal Execution Patterns6364### Stage 1 — LAP computation6566```python67import dynamo as dyn6869adata = dyn.sample_data.hematopoiesis()7071# Build UMAP neighbor graph needed for LAP72dyn.tl.neighbors(adata, basis="umap", result_prefix="umap")7374cell_types = ["HSC", "Meg", "Ery", "Bas", "Mon", "Neu"]7576transition_graph, cells_indices = dyn.pd.compute_cell_type_transitions(77 adata=adata,78 cell_types=cell_types,79 reference_cell_types=["HSC"],80 marginal_method="combined",81 potential_column="umap_ddhodge_potential",82 cell_type_column="cell_type",83 EM_steps=2,84 top_genes=5,85 enable_plotting=True,86 enable_gene_analysis=True,87)8889# Persist — this step is expensive90dyn.utils.save_pickle(transition_graph, "result/transition_graph.pkl")91dyn.utils.save_pickle(cells_indices, "result/cells_indices.pkl")92adata.write("result/adata_labeling_analysis.h5ad")93```9495### Stage 2 — Metrics extraction9697```python98transition_graph = dyn.utils.load_pickle("result/transition_graph.pkl")99cells_indices = dyn.utils.load_pickle("result/cells_indices.pkl")100101human_tfs = dyn.sample_data.human_tfs()102human_tfs_names = list(human_tfs["Symbol"])103104action_df, t_df, tf_genes = dyn.pd.extract_transition_metrics(105 transition_graph=transition_graph,106 cells_indices_dict=cells_indices,107 cell_types=cell_types,108 transcription_factors=human_tfs_names,109 top_tf_genes=10,110 lap_method="action_t", # 'action' or 'action_t'111)112```113114### Stage 3 — Kinetic heatmap for one pair115116```python117ranking, top_tfs = dyn.pd.analyze_kinetic_genes(118 adata=adata,119 cells_indices_dict=cells_indices,120 source_cell_type="HSC",121 target_cell_type="Bas",122 transcription_factors=human_tfs_names,123 top_genes=15,124)125126dyn.pd.plot_kinetic_heatmap(127 adata=adata,128 cells_indices_dict=cells_indices,129 source_cell_type="HSC",130 target_cell_type="Bas",131 transcription_factors=human_tfs_names,132 save_path="figures/HSC_to_Bas.png",133 figsize=(16, 4),134)135```136137### Stage 4 — TF ranking and ROC138139```python140KNOWN_TFS_DICT = {141 "HSC->Meg": ["GATA1", "GATA2", "ZFPM1", "GFI1B", "FLI1", "NFE2"],142 # ... add other transitions143}144TRANSITIONS_CONFIG = {145 "standard": [146 "HSC->Meg", "HSC->Ery", "HSC->Bas", "HSC->Mon", "HSC->Neu",147 "Meg->HSC", "Meg->Neu", "Ery->Mon", "Mon->Meg", "Mon->Ery",148 "Mon->Bas", "Neu->Bas"149 ],150 "special": {"Ery->Neu": {"sets": [("TFs1", "TFs_rank1", "Ery->Neu1"), ("TFs2", "TFs_rank2", "Ery->Neu2")]}},151}152153# All-in-one path154processed_rankings, reprogramming_dict, reprogramming_df = dyn.pd.analyze_transition_tfs(155 transition_graph=transition_graph,156 human_tfs_names=human_tfs_names,157 transitions_config=TRANSITIONS_CONFIG,158 plot_type="transdifferentiation",159 known_tfs_dict=KNOWN_TFS_DICT,160 total_tf_count=133,161)162163# ROC analysis164roc_results = dyn.pd.analyze_tf_roc_performance(165 processed_rankings=processed_rankings,166 plot_roc=True,167 roc_plot_params={"figsize": (3, 3), "fontsize": 12, "legend_size": 12},168)169print("AUC:", roc_results["roc_auc"])170```171172## Validation173174After LAP computation, confirm:175176- `transition_graph` contains keys for each `A->B` pair177- Each entry has `LAP_umap` with `prediction` and `action` sub-keys178- `cells_indices` contains one entry per cell type in `cell_types`179- Pickle files written successfully to disk180181After metrics extraction, confirm:182183- `action_df.shape == (len(cell_types), len(cell_types))`184- `t_df.shape == (len(cell_types), len(cell_types))`185- `tf_genes` is a dict keyed by transition names186187After kinetic heatmap, confirm:188189- Output figure file exists at `save_path` if provided190- `ranking` DataFrame contains MSD scores191- `top_tfs` list is non-empty192193After TF ranking and ROC, confirm:194195- `processed_rankings` contains one entry per transition196- Each entry has `TFs` and `TFs_rank` (or `TFs1`/`TFs2` for special cases)197- `reprogramming_df` columns include `genes`, `rank`, `transition`, `type`198- `roc_results['roc_auc']` is a float between 0 and 1199200## Constraints201202- `compute_cell_type_transitions` requires `VecFld_umap` and `umap_ddhodge_potential` to be precomputed.203- Run `dyn.tl.neighbors(adata, basis='umap', result_prefix='umap')` before `compute_cell_type_transitions`; it creates `adata.obsp['X_umap_distances']` required for UMAP-basis LAP.204- The `EM_steps` parameter controls the number of iterative optimization rounds; lower values (1–2) are faster for smoke paths; default `2` is used in the tutorial.205- Do not treat the hematopoiesis cell type labels, KNOWN_TFS_DICT, or TRANSITION_PMIDS dicts as required skill inputs — they are hematopoiesis-specific worked example parameters.206- The `transitions_config['special']` key handles transitions with two alternative known TF sets (e.g., `Ery->Neu`). Define it explicitly if your dataset has such ambiguity.207- `dyn.pd.plot_kinetic_heatmap` is a prediction module function distinct from `dyn.pl.kinetic_heatmap`; they have different signatures and purposes.208- Set `enable_gene_analysis=True` (default) whenever TF prioritization or kinetic heatmaps are needed; with `enable_gene_analysis=False`, `gtraj` and `ranking` are absent from `transition_graph`, causing `process_all_transition_rankings` to fail and `extract_transition_metrics` to skip TF extraction with a logged error.209210## Resource Map211212- Read `references/stage-selection.md` when choosing `marginal_method`, `lap_method`, or `plot_type`.213- Read `references/source-grounding.md` for full inspected signatures and storage key evidence.214- Read `references/source-notebook-map.md` to trace `501_lap_tutorial.ipynb` sections to skill resources.215- Read `references/compatibility.md` when encountering API name mismatches or missing attributes.216- Use `assets/acceptance.json` for the bounded smoke paths used by local acceptance.