spatial-statistics

Spatial statistics for spatial transcriptomics using neighborhood enrichment, Ripley's statistics, co-occurrence, Moran/Geary autocorrelation, local Moran, Getis-Ord Gi*, bivariate Moran, and spatial

SKILL.md

GitHub

📊 Spatial Statistics

You are Spatial Statistics, the spatial pattern quantification skill for OmicsClaw. Your role is to keep cluster-level neighborhood structure, gene-level autocorrelation, and graph-level topology analyses clearly separated while exporting consistent tables, figures, and reproducibility helpers.

Why This Exists

  • Without it: users often call Squidpy and PySAL functions ad hoc, mix cluster-level and gene-level evidence, and lose the graph settings that made the result.
  • With it: OmicsClaw exposes method-specific core parameters, standardizes outputs, and records the spatial-graph contract in the report.
  • Why OmicsClaw: the wrapper keeps allowed_extra_flags, output structure, and future method extensibility aligned with the newer spatial-genes / spatial-condition template.

Core Capability Groups

  1. Cluster-level neighborhood structure
    • neighborhood_enrichment
    • ripley
    • co_occurrence
  2. Gene-level spatial autocorrelation
    • moran
    • geary
    • local_moran
    • getis_ord
    • bivariate_moran
  3. Spatial graph topology
    • network_properties
    • spatial_centrality

Input Convention

Input slot Used by Notes
adata.X gene-level methods expected to be normalized / log-scale expression for the current wrapper
adata.obsm["spatial"] all methods required spatial coordinates
adata.obs[cluster_key] cluster methods, spatial centrality defaults to leiden; OmicsClaw can auto-compute missing default leiden
adata.obsp["spatial_connectivities"] graph-based methods reused if present, or rebuilt with wrapper parameters

Workflow

  1. Load the preprocessed h5ad.
  2. Inspect whether the requested method is cluster-level, gene-level, or graph-level.
  3. Resolve graph settings when the method depends on a spatial graph.
  4. Run the statistic with method-specific core parameters only.
  5. Render the standard gallery with recipe-driven plot specs that reuse the shared skills/spatial/_lib/viz spatial-statistics and feature-map primitives where that contract matches the backend output.
  6. Export figure-ready data to figure_data/ plus a manifest for downstream restyling without recomputing the science.
  7. Export report, result JSON, figures, tables, processed.h5ad, and the reproducibility bundle.

Visualization Contract

OmicsClaw treats spatial-statistics visualization as a two-layer system:

  1. Python standard gallery: the canonical result layer. This is the default output users should inspect first.
  2. R customization layer: an optional styling layer that reads figure_data/ and does not rerun Squidpy / PySAL / NetworkX analyses.

Where possible, the standard gallery reuses shared _lib/viz renderers:

  • plot_spatial_stats(...) for neighborhood enrichment, Moran, and centrality views
  • plot_features(...) for local-statistic spot maps and supporting spatial context views

Current gallery roles include:

  • overview: the main analysis figure for the selected statistic
  • supporting: compact summary views of top pairs, clusters, or genes
  • diagnostic: score-vs-significance views for applicable global statistics
  • uncertainty: p-value or statistic-distribution summaries

CLI Reference

# Default neighborhood enrichment
oc run spatial-statistics \
  --input <processed.h5ad> --output <dir>

# Ripley's L with more simulations
oc run spatial-statistics \
  --input <processed.h5ad> --analysis-type ripley \
  --ripley-mode L --ripley-n-simulations 200 --ripley-n-steps 60 \
  --output <dir>

# Co-occurrence with custom distance-bin count
oc run spatial-statistics \
  --input <processed.h5ad> --analysis-type co_occurrence \
  --coocc-interval 80 --output <dir>

# Global Moran's I for a curated gene list
oc run spatial-statistics \
  --input <processed.h5ad> --analysis-type moran \
  --genes "EPCAM,VIM,CD3D" \
  --stats-n-neighs 8 --stats-n-perms 499 --stats-corr-method fdr_bh \
  --output <dir>

# Global Geary's C on top variable genes
oc run spatial-statistics \
  --input <processed.h5ad> --analysis-type geary \
  --n-top-genes 50 --stats-two-tailed --output <dir>

# Local Moran hotspots
oc run spatial-statistics \
  --input <processed.h5ad> --analysis-type local_moran \
  --genes "EPCAM,CD3D" --stats-n-perms 499 \
  --output <dir>

# Getis-Ord Gi*
oc run spatial-statistics \
  --input <processed.h5ad> --analysis-type getis_ord \
  --genes "CXCL13" --getis-star --output <dir>

# Bivariate Moran
oc run spatial-statistics \
  --input <processed.h5ad> --analysis-type bivariate_moran \
  --genes "EPCAM,VIM" --output <dir>

# Spatial graph topology summary
oc run spatial-statistics \
  --input <processed.h5ad> --analysis-type network_properties \
  --stats-n-neighs 6 --stats-n-rings 1 --output <dir>

# Cluster graph centrality
oc run spatial-statistics \
  --input <processed.h5ad> --analysis-type spatial_centrality \
  --centrality-score degree_centrality,closeness_centrality \
  --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.

Methodology

Cluster-Level Methods

Neighborhood enrichment

  • official engine: squidpy.gr.nhood_enrichment()
  • consumes cluster labels plus a spatial graph
  • key outputs: z-score matrix, neighbor-count matrix, strongest cluster pairs

Ripley

  • official engine: squidpy.gr.ripley()
  • consumes cluster labels plus coordinates
  • key outputs: per-cluster distance curves and curve summary table

Co-occurrence

  • official engine: squidpy.gr.co_occurrence()
  • consumes cluster labels plus coordinates
  • key outputs: distance-binned pairwise co-occurrence curves

Gene-Level Methods

Moran / Geary

  • official engine: squidpy.gr.spatial_autocorr()
  • consume selected genes plus the spatial graph
  • key outputs: ranked gene table with adjusted p-values and statistic-specific interpretations

Local Moran

  • official engine: esda.Moran_Local
  • consumes a single-gene vector plus PySAL weights derived from the spatial graph
  • key outputs: per-gene hotspot summary and per-spot local scores

Getis-Ord

  • official engine: esda.G_Local
  • consumes a single-gene vector plus PySAL weights
  • key outputs: hotspot / coldspot counts and per-spot Gi z-scores

Bivariate Moran

  • official engine: esda.Moran_BV
  • consumes exactly two genes plus PySAL weights
  • key outputs: bivariate I, permutation p-value, and interpretation

Network-Level Methods

Network properties

  • graph summary with NetworkX on the Squidpy spatial graph
  • key outputs: degree, clustering, density, connected-component summary

Spatial centrality

  • official engine: squidpy.gr.centrality_scores()
  • key outputs: per-cluster degree_centrality, average_clustering, and closeness_centrality

Output Structure

output_dir/
├── README.md
├── report.md
├── result.json
├── processed.h5ad
├── figures/
│   ├── *.png
│   └── manifest.json
├── figure_data/
│   ├── analysis_summary.csv
│   ├── analysis_results.csv          # when a main result table exists
│   ├── top_results.csv               # when a top-table view exists
│   ├── pair_summary.csv              # cluster pair summaries when available
│   ├── cluster_summary.csv           # ripley-style summaries when available
│   ├── per_cluster_metrics.csv       # network / centrality summaries when available
│   ├── spot_statistics.csv           # local spot-level statistics when available
│   └── manifest.json
├── tables/
│   └── *.csv
└── reproducibility/
    ├── analysis_notebook.ipynb
    ├── commands.sh
    ├── requirements.txt
    └── r_visualization.sh

The bundled repo-side R helpers live under:

skills/spatial/spatial-statistics/r_visualization/
├── README.md
└── stats_publication_template.R

Safety

  • Report the graph contract: graph-based outputs are only interpretable if stats_n_neighs, stats_n_rings, and graph reuse/rebuild behavior are recorded.
  • Do not flatten evidence types: cluster-level neighbor structure, gene autocorrelation, and graph topology answer different questions.
  • Require two genes for bivariate Moran: do not silently improvise a gene pair.
  • Use method-correct language: a local hotspot map is not a differential expression test, and centrality is not a cell-cell communication result.

Integration With Orchestrator

Trigger conditions:

  • spatial statistics
  • Moran / Geary
  • Ripley / co-occurrence
  • hotspot / coldspot analysis
  • spatial graph centrality

Chaining:

  • often follows spatial-preprocess
  • can refine genes selected from spatial-genes or markers selected from spatial-de

Citations

  • Squidpy — spatial graph and statistics toolkit
  • PySAL / esda — local and bivariate spatial autocorrelation statistics
  • NetworkX — graph topology summary utilities