spatial-enrichment
Pathway and gene-set enrichment analysis for spatial transcriptomics using ORA-style enrichr, preranked GSEA, or ssGSEA with local-first gene-set resolution and method-aware parameter controls.
SKILL.mdSkills/spatial/spatial-enrichment/SKILL.md
GitHub🛤️ Spatial Enrichment
You are Spatial Enrichment, the pathway and gene-set enrichment skill for OmicsClaw. Your role is to translate spatial group markers or ranked gene signatures into biological programs while keeping ORA, preranked GSEA, and ssGSEA conceptually separate.
Why This Exists
- Without it: users often move between marker discovery and pathway interpretation with ad-hoc exports, ambiguous gene-set sources, and no clear distinction between ORA and rank-based enrichment.
- With it: OmicsClaw builds the marker or ranking input internally, applies method-specific enrichment, and exports standardized tables, figures, and reproducibility helpers.
- Why OmicsClaw: the wrapper keeps enrichment local-first, exposes method-aware parameter hints, and makes later gene-set source extensions easy without breaking the user-facing output contract.
Core Capabilities
- Enrichr-style ORA: per-group enrichment on positive marker genes.
- Preranked GSEA: full ranked marker lists per group with NES-based interpretation.
- ssGSEA: single-sample-style enrichment on group-level mean expression profiles.
- Local-first gene-set resolution: supports built-in OmicsClaw signatures,
local
.json/.gmtfiles, and remote library resolution through GSEApy. - Deterministic fallback behavior: if a remote gene-set library cannot be resolved, OmicsClaw records a warning and falls back to a local library.
- Marker export: writes the ranked marker table used as enrichment input for auditability and extension.
- Score projection for visualization: selected ssGSEA group scores are mapped back to observations for spatial plotting.
- Standard Python gallery: emits a recipe-driven enrichment gallery with
overview, diagnostic, supporting, and uncertainty panels backed by the
shared
skills/spatial/_lib/vizlayer. - Figure-ready exports: writes
figure_data/CSVs plus a gallery manifest so downstream tools can restyle the same enrichment result without recomputing it.
Input Formats
| Format | Extension | Required Fields | Example |
|---|---|---|---|
| AnnData (preprocessed) | .h5ad |
adata.X, obs[groupby]; obsm["spatial"] optional for spatial score maps |
processed.h5ad |
| Demo | n/a | --demo flag |
Runs spatial-preprocess demo first |
Input Matrix Convention
The current wrapper uses log-normalized expression in adata.X for all three
methods, but the statistical role differs:
| Method | Input representation | Why |
|---|---|---|
enrichr |
Scanpy marker table built from adata.X |
ORA depends on thresholded positive markers, not on raw counts |
gsea |
full ranked marker list built from adata.X |
preranked GSEA works on ordered group-specific marker statistics |
ssgsea |
group-level mean expression profiles from adata.X |
current wrapper summarizes expression per group before gene-set scoring |
Core principle:
- Use
enrichrwhen the user wants pathway interpretation of thresholded marker genes. - Use
gseawhen the user wants pathway shifts across the full ranked list. - Use
ssgseawhen the user wants group-level enrichment scores rather than p-value-based per-pathway testing.
Workflow
- Load: read the preprocessed h5ad.
- Validate: confirm
groupbyexists; if defaultleidenis missing, OmicsClaw can compute a minimal clustering pass. - Resolve gene sets: choose local built-in signatures, a local
.json/.gmtlibrary, or an external GSEApy library key. - Build enrichment input:
enrichr: positive markers per groupgsea: full ranked marker list per groupssgsea: group-level mean expression matrix
- Run enrichment and normalize results into a shared output table.
- Render the standard gallery: build the OmicsClaw narrative gallery with grouping context, canonical enrichment overviews, projected diagnostics, and uncertainty panels.
- Export figure-ready data: write
figure_data/*.csvandfigure_data/manifest.jsonfor downstream customization. - Export: write enrichment tables,
report.md,result.json, figures, and reproducibility helpers.
Visualization Contract
OmicsClaw treats spatial-enrichment visualization as a two-layer system:
- Python standard gallery: the canonical result layer. This is the default output users should inspect first.
- R customization layer: an optional styling and publication layer that
reads
figure_data/and does not recompute ORA, GSEA, or ssGSEA.
The standard gallery is declared as a recipe instead of hard-coded if/else
plot branches. Current gallery roles include:
overview: grouping labels on tissue plus canonical enrichment barplot and dotplot viewsdiagnostic: projected top-stat burden maps and, when available, spatial ssGSEA score mapssupporting: top-term summaries, per-group burden barplots, and ssGSEA violin plots when score columns existuncertainty: adjusted p-value distributions and enrichment score distributions
CLI Reference
# Default local-first ORA
oc run spatial-enrichment \
--input <processed.h5ad> --output <dir>
# Enrichr-style ORA using an external library key when available
oc run spatial-enrichment \
--input <processed.h5ad> --method enrichr \
--source GO_Biological_Process --species human \
--de-method wilcoxon --de-corr-method benjamini-hochberg \
--enrichr-padj-cutoff 0.05 --enrichr-log2fc-cutoff 1.0 \
--enrichr-max-genes 200 --output <dir>
# Preranked GSEA
oc run spatial-enrichment \
--input <processed.h5ad> --method gsea \
--source MSigDB_Hallmark \
--gsea-ranking-metric auto --gsea-min-size 15 --gsea-max-size 500 \
--gsea-permutation-num 100 --gsea-weight 1.0 --gsea-threads 1 \
--output <dir>
# ssGSEA with local gene-set file
oc run spatial-enrichment \
--input <processed.h5ad> --method ssgsea \
--gene-set-file ./custom_sets.gmt \
--ssgsea-sample-norm-method rank \
--ssgsea-correl-norm-type rank \
--output <dir>
# Demo mode
oc run spatial-enrichment --demo --output /tmp/enrich_demo
# Direct script entrypoint
python skills/spatial/spatial-enrichment/spatial_enrichment.py \
--input <processed.h5ad> --method enrichr --output <dir>
Every successful standard OmicsClaw wrapper run, including oc run and
conversational skill execution, also writes a top-level README.md and
reproducibility/analysis_notebook.ipynb to make the output directory easier
to inspect and rerun.
Example Queries
- "Run pathway enrichment on my spatial cluster markers"
- "Use preranked GSEA instead of thresholded ORA"
- "Score hallmark-like programs across spatial groups with ssGSEA"
Algorithm / Methodology
Enrichr
- Marker ranking:
scanpy.tl.rank_genes_groups(...)builds per-group marker statistics. - Positive marker selection: OmicsClaw keeps genes that pass the wrapper
marker cutoffs (
enrichr_padj_cutoff,enrichr_log2fc_cutoff,enrichr_max_genes). - ORA engine:
- preferred:
gseapy.enrich(...)on a local gene-set dictionary - fallback: local hypergeometric testing with BH correction
- preferred:
GSEA
- Marker ranking: same Scanpy marker table as above.
- Ranking metric: OmicsClaw chooses or auto-resolves the ranking column.
- Prerank engine:
- preferred:
gseapy.prerank(...) - fallback: local rank-based permutation approximation
- preferred:
ssGSEA
- Expression matrix: OmicsClaw computes group-level mean expression
profiles from
adata.X. - Scoring engine:
- preferred:
gseapy.ssgsea(...) - fallback: simplified local score approximation
- preferred:
- Visualization projection: selected group-level scores are mapped back to observations for plotting.
Output Structure
output_dir/
├── README.md
├── report.md
├── result.json
├── processed.h5ad
├── figures/
│ ├── enrichment_group_spatial_context.png
│ ├── enrichment_barplot.png
│ ├── enrichment_dotplot.png
│ ├── enrichment_group_top_stat_spatial.png
│ ├── enrichment_spatial_scores.png (ssGSEA when projected score columns exist)
│ ├── enrichment_group_top_stat_umap.png (when UMAP is available)
│ ├── top_enriched_terms.png
│ ├── enrichment_group_metrics.png
│ ├── enrichment_score_violin.png (ssGSEA)
│ ├── enrichment_pvalue_distribution.png (enrichr / gsea)
│ ├── enrichment_score_distribution.png
│ └── manifest.json
├── figure_data/
│ ├── enrichment_results.csv
│ ├── enrichment_significant.csv
│ ├── ranked_markers.csv
│ ├── top_enriched_terms.csv
│ ├── enrichment_group_metrics.csv
│ ├── enrichment_term_group_scores.csv
│ ├── enrichment_run_summary.csv
│ ├── enrichment_spatial_points.csv
│ ├── enrichment_umap_points.csv
│ └── manifest.json
├── tables/
│ ├── enrichment_results.csv
│ ├── enrichment_significant.csv
│ ├── ranked_markers.csv
│ ├── top_enriched_terms.csv
│ └── enrichment_group_metrics.csv
└── reproducibility/
├── analysis_notebook.ipynb
├── commands.sh
├── r_visualization.sh
└── requirements.txt
Safety
- Local-first: OmicsClaw prefers local gene-set dictionaries and records any remote-library fallback explicitly.
- Method separation: ORA, GSEA, and ssGSEA answer different questions and should not be presented as interchangeable evidence.
- Two-layer visualization design: Python plots are the canonical standard
gallery; the optional R layer consumes
figure_data/for publication-style refinement without recomputing the science. - No keyword filtering: pathway relevance should be interpreted after significance and score ranking, not by pre-filtering term names.
- Audit trail: ranked markers, resolved library mode, and warnings are exported for inspection.
Integration With Orchestrator
Trigger conditions:
- pathway enrichment
- gene set enrichment
- enrichr
- GSEA
- ssGSEA
- GO / Reactome / MSigDB interpretation
Chaining:
- often follows
spatial-de - can also run directly on clustered output from
spatial-preprocess