Skip to content
Back to skills

Spatial Microenvironment Subset

ASecurity

Load when extracting a niche / microenvironment subset around a center cell-type by spatial

  • 8 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 6, 2026
datapythongobashbackend

Works with

  • cli

Security analysis

A100/100

Pro scans all 7 files and shows the line behind each finding

Scanned September 6, 2026

npx -y skills add lilinji/GeneTind-Life-Skills --skill spatial-microenvironment-subset --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Spatial Microenvironment Subset?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Spatial Microenvironment Subset
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lilinji-spatial-microenvironment-subset/badge)](https://www.skillsdirectory.com/skills/lilinji-spatial-microenvironment-subset)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
# AUTO-GENERATED header from skill.yaml — do not edit by hand.
# Edit skill.yaml, then run: python scripts/generate_skill_md.py <skill_dir>
name: spatial-microenvironment-subset
description: Load when extracting a niche / microenvironment subset around a center cell-type by spatial
  radius from a labelled spatial AnnData, producing a smaller AnnData of centers + their within-radius
  neighbours. Skip when running global tissue-domain detection (use spatial-domains); cross-condition
  comparison (use spatial-condition).
version: 0.3.0
author: OmicsClaw
license: MIT
tags:
- spatial
- microenvironment
- niche
- subsetting
- neighbourhood
- visium
- xenium
requires:
- anndata
- matplotlib
- numpy
- pandas
- scanpy
- scipy
---

# spatial-microenvironment-subset

## When to use

The user has a labelled spatial AnnData (cell-type or domain labels in
`obs[--center-key]`) and wants to extract a niche around a chosen cell
population — i.e., the center cells PLUS every spot / cell within a
spatial radius of any center. Output is a downstream-ready AnnData
restricted to that microenvironment.

Single backend (radius-based KD-tree neighbourhood). Two radius modes:
`--radius-microns` (with `--microns-per-coordinate-unit` if your
coords aren't in microns) OR `--radius-native` (in the AnnData's
native coordinate units). Exactly one is required.

For *global* tissue-domain detection use `spatial-domains`. For
cross-condition niche comparison use `spatial-condition`.

## Inputs & Outputs

<!-- AUTO-GENERATED from skill.yaml (interface) — do not edit by hand. Regenerate: python scripts/generate_skill_md.py <skill_dir> -->

**Inputs**

- Input kinds: `file`, `directory`
- Modalities: visium, xenium
- File types: `.h5ad`, `.h5`, `.hdf5`, `.zarr`
- Expects `obsm`: `spatial`

**Outputs**

- `tables/center_observations.csv`
- `tables/label_composition.csv`
- `tables/selected_observations.csv`
- `tables/selection_summary.csv`
- `figures/microenvironment_selection.png`
- `spatial_microenvironment_subset.h5ad`
- `report.md`
- `result.json`
- Processed AnnData (`saves_h5ad`) — adds `obs`: `microenv_is_center`, `microenv_role`, `microenv_within_radius`, `microenv_nearest_center`, `microenv_distance_native`, `microenv_distance_microns`

## Flow

1. Load AnnData (`--input`) or build a demo.
2. Validate radius flags (`parser.error` on `≤ 0`); resolve `--microns-per-coordinate-unit` if needed.
3. Resolve center mask: rows where `obs[--center-key] ∈ --center-values` (comma-split).
4. Build a KD-tree on `obsm["spatial"]`; query each center for neighbours within radius.
5. Optionally restrict neighbour pool to `obs[--target-key] ∈ --target-values`.
6. Build the subset (centers + qualified neighbours; optionally drop centers via `--exclude-centers`).
7. Save subset AnnData with role + distance columns; emit composition / summary tables; render selection figure.

## Gotchas

- **All input + radius validation goes through `parser.error` (exit code 2).** `spatial_microenvironment_subset.py:403` for missing `--input`; `:405` for missing path; `:407` for non-positive `--microns-per-coordinate-unit`; `:409` for non-positive `--radius-microns`; `:411` for non-positive `--radius-native`. Wrappers expecting `ValueError` need to catch exit-2.
- **`--radius-microns` and `--radius-native` are mutually exclusive AND required.** `argparse.add_mutually_exclusive_group(required=True)` enforces it before the manual checks at `:409` / `:411`. Using neither hits a different `parser.error` (argparse-generated). Mixing the two raises argparse's standard "not allowed with" error.
- **`--microns-per-coordinate-unit` is needed when coords aren't in microns.** Visium typically already stores spatial coords in pixels; pass the platform-specific scale (e.g., `0.65` µm / pixel for high-res Visium) to make `--radius-microns` meaningful. Without it, the radius is treated as if coords were already in microns.
- **`--center-values` is required and `--center-key` is auto-resolvable.** `--center-values` always required (no default); `--center-key` defaults to None and the script auto-picks a sensible labelled obs column. For ambiguous AnnDatas, pass both explicitly.
- **`--exclude-centers` drops the center cells from the output.** Useful when you want to characterise *the niche around* a population without the population itself biasing downstream stats. By default centers ARE retained — `spatial_microenvironment_subset.py:461` invokes the helper with `include_centers=not args.exclude_centers`; `result.json["params"]["exclude_centers"]` records the raw flag at `:488`.
- **No raise for empty selection.** If the radius is too small or `--center-values` matches no rows, the script proceeds with an empty / center-only AnnData; `tables/selection_summary.csv` and `result.json["n_selected_observations"]` (line 195) record `0`. Always check before chaining downstream.

## Key CLI

```bash
# Demo (synthetic spatial with cell-type labels)
python omicsclaw.py run spatial-microenvironment-subset --demo --output /tmp/spatial_microenv_demo

# T-cell niche, 50 µm radius (Visium with 0.65 µm/pixel scale)
python omicsclaw.py run spatial-microenvironment-subset \
  --input annotated.h5ad --output results/ \
  --center-key cell_type --center-values "T cell,CD8+ T cell" \
  --radius-microns 50 --microns-per-coordinate-unit 0.65

# Tumor-infiltrating lymphocyte niche restricted to immune neighbours only
python omicsclaw.py run spatial-microenvironment-subset \
  --input annotated.h5ad --output results/ \
  --center-key cell_type --center-values "Tumor" \
  --target-key cell_type --target-values "T cell,B cell,Macrophage,NK cell" \
  --radius-microns 100 --microns-per-coordinate-unit 0.65

# Niche around domain "1" using native coords, exclude the centers
python omicsclaw.py run spatial-microenvironment-subset \
  --input annotated.h5ad --output results/ \
  --center-key spatial_domain --center-values "1" \
  --radius-native 50 --exclude-centers
```

## See also

- `references/parameters.md` — every CLI flag, radius / scale conventions
- `references/methodology.md` — radius selection guide; coordinate-unit semantics
- `references/output_contract.md` — `obs["microenv_is_center"]` / `obs["microenv_role"]` / `obs["microenv_distance_native"]` / `obs["microenv_distance_microns"]` schema
- Adjacent skills: `spatial-annotate` / `spatial-domains` (upstream — produce `obs[--center-key]` labels), `spatial-de` (downstream — DE on the niche subset between center vs neighbours), `spatial-communication` (downstream — L-R analysis restricted to a niche), `spatial-condition` (parallel — cross-condition niche comparison)

Files in this skill

  • SKILL.md6.5 KB
  • references/methodology.md1.4 KB
  • references/output_contract.md1.7 KB
  • references/parameters.md437 B
  • skill.yaml1.9 KB
  • spatial_microenvironment_subset.py16.7 KB
  • tests/test_spatial_microenvironment_subset.py3.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…