Tutorial 5 — Running kaleidoCell on mouse data#

kaleidoCell is species-agnostic: the NMF decomposition and consensus meta-program derivation work identically regardless of the organism. The only step that requires species-specific input is GSEA, because gene-set databases must use the same gene symbols as your data.

The bundled GMT files in kaleidoCell contain human (HGNC) gene symbols. For a mouse dataset you have two options:

Option

When to use

Skip GSEA entirely

You only need the meta-programs and the HTML report

Supply a mouse GMT file

You want pathway enrichment for Mus musculus

This tutorial walks through both options. It also explains the difference between the two GSEA methods available in run_gsea_pipeline:

Method

Description

enrichr (default)

Hypergeometric test on the top-N genes of each MP

prerank

GSEA preranked — uses the full ranked gene list, more sensitive

Dataset — example mouse scRNA-seq cohort (mouse.h5ad), log-normalised counts in adata.X.

0 · Imports and data preparation#

[ ]:
import kaleidocell
import scanpy as sc

adata = sc.read_h5ad('../data/mouse.h5ad')
print(adata)

1 · Run NMF on every sample#

This step is identical to a human dataset — NMF has no species-specific logic.

[ ]:
results_nmf, nmf_convergence = kaleidocell.multi_sample_nmf(
    adata,
    batch_key='batch',
    test_ranks=[4, 5, 6, 7, 8, 9],
    n_initializations=10,
    seed=42,
)

results_mp = kaleidocell.derive_nmf_metaprograms(results_nmf)

print(f"Derived {len(results_mp['mp_dict'])} meta-programs.")

2 · Score cells by MP activity#

[ ]:
mp_scores = kaleidocell.compute_mp_scores(results_mp, adata)
mp_scores.head()

3 · Run GSEA with a mouse gene-set file#

Obtaining mouse GMT files#

Mouse gene-set collections are available from MSigDB:

https://www.gsea-msigdb.org/gsea/msigdb/mouse/genesets.jsp

Download the collection(s) you need (e.g. mh.all.v2024.1.Mm.symbols.gmt for mouse Hallmarks) and place the file(s) in a convenient location — here we assume ../data/mh.all.v2024.1.Mm.symbols.gmt.

enrichr vs prerank#

run_gsea_pipeline supports two complementary methods, selected via the method parameter:

``enrichr`` (default)

  • Takes the top N genes of each meta-program (controlled by n_top_genes)

  • Runs a hypergeometric over-representation test against each gene set

  • Fast; well-suited when you trust the discrete gene signature

``prerank``

  • Uses the full ranked gene list (all genes, sorted by NMF weight)

  • Runs GSEA preranked (Subramanian et al. 2005)

  • More sensitive to subtle pathway signals; slower

  • Recommended when the gene boundary between “in” and “out” is uncertain

Option A — enrichr (hypergeometric, fast)#

[ ]:
gsea_results_enrichr, gsea_plots_enrichr = kaleidocell.run_gsea_pipeline(
    results_mp,
    from_file=['../data/mh.all.v2024.1.Mm.symbols.gmt'],
    method='enrichr',        # hypergeometric over-representation test
    n_top_genes=50,          # top genes per MP used as query
    top_n_plot=6,
    plot=True,
    save_csv=False,
)

gsea_results_enrichr.head(20)

Option B — prerank (full ranked list, more sensitive)#

[ ]:
gsea_results_prerank, gsea_plots_prerank = kaleidocell.run_gsea_pipeline(
    results_mp,
    from_file=['../data/mh.all.v2024.1.Mm.symbols.gmt'],
    method='prerank',        # GSEA preranked on full NMF weight vector
    top_n_plot=6,
    plot=True,
    save_csv=False,
)

gsea_results_prerank.head(20)

4 · Generate HTML report#

Option 1 — skip GSEA (no gene-set file required)#

If you do not need pathway enrichment, pass results_mp directly to get_html. All other tabs (heatmap, UMAP, metrics, gene table, violin plots) are still produced.

[ ]:
path = kaleidocell.get_html(
    results_mp,
    adata,
    mp_scores=mp_scores,
    obs=['batch'],           # adjust to your obs columns of interest
    output_path='../results/05_no_gsea/',
)
print(f"Report written to: {path}")

Option 2 — include GSEA results in the report#

Pass the gsea_results and gsea_plots returned by run_gsea_pipeline to get_html to add a GSEA tab to the report.

[ ]:
path = kaleidocell.get_html(
    results_mp,
    adata,
    mp_scores=mp_scores,
    obs=['batch'],
    gsea_results=gsea_results_enrichr,   # from run_gsea_pipeline above
    gsea_plots=gsea_plots_enrichr,
    output_path='../results/05_with_gsea/',
)
print(f"Report written to: {path}")