SpatialAgent_N2_DEEPAGENT / spatialagent /skill /cell_deconvolution.md
jkkkkyuedtrt's picture
Upload 381 files
bd52a47 verified
|
Raw
History Blame Contribute Delete
5.11 kB

Cell Deconvolution with Tangram

Deconvolve spatial spots into individual cells using Tangram's constrained mapping mode with cell segmentation.

When to Use

  • Spatial technology has multiple cells per spot (Visium, Slide-seq)
  • You have histology images with cell segmentation
  • Goal: Assign cell types to individual segmented cells

Requirements

Before running deconvolution, you need:

  1. scRNA-seq reference with cell type annotations
  2. Spatial data with:
    • Gene expression
    • Cell segmentation from histology (via Squidpy)

Workflow Overview

  1. Segment cells from histology image (Squidpy)
  2. Calculate image features
  3. Preprocess for Tangram
  4. Run constrained mapping
  5. Assign cell types to segments
  6. Visualize deconvolved cells

Step 1: Cell Segmentation (Squidpy)

If not already done, segment cells from histology:

import squidpy as sq
import scanpy as sc

# Load spatial data with image
adata_sp = sc.read_h5ad("spatial.h5ad")
img = sq.datasets.visium_fluo_image_crop()  # or load your image

# Smooth image
sq.im.process(img=img, layer="image", method="smooth")

# Segment nuclei
sq.im.segment(
    img=img,
    layer="image_smooth",
    method="watershed",
    channel=0,  # DAPI channel
)

# Calculate features (cell counts per spot)
sq.im.calculate_image_features(
    adata_sp,
    img,
    layer="image",
    features="segmentation",
    features_kwargs={
        "segmentation": {
            "label_layer": "segmented_watershed",
            "props": ["label", "centroid"],
        }
    },
    mask_circle=True,
)

# Check cell counts
print(adata_sp.obs["cell_count"].describe())
adata_sp.write_h5ad("spatial_with_segmentation.h5ad")

Step 2: Visualize Segmentation

Verify segmentation quality:

import matplotlib.pyplot as plt

sc.pl.spatial(adata_sp, color="cell_count", title="Cells per Spot")
plt.savefig("cell_counts.png")

# Check total cells
total_cells = adata_sp.obsm["image_features"]["segmentation_label"].sum()
print(f"Total segmented cells: {total_cells}")

Step 3: Preprocess for Tangram

Tool: tangram_preprocess

tangram_preprocess(
    adata_sc_path="scrna.h5ad",
    adata_sp_path="spatial_with_segmentation.h5ad",
    marker_genes="auto",
    cell_type_key="cell_type"
)

Step 4: Constrained Mapping

Run Tangram in constrained mode to fit exactly the number of segmented cells:

import scanpy as sc
import tangram as tg
import numpy as np

# Load preprocessed data
adata_sc = sc.read_h5ad("experiments/tangram_sc_prep.h5ad")
adata_sp = sc.read_h5ad("experiments/tangram_sp_prep.h5ad")

# Get cell counts from segmentation
cell_counts = adata_sp.obsm["image_features"]["segmentation_label"]
target_count = int(cell_counts.sum())
density_prior = np.array(cell_counts) / cell_counts.sum()

print(f"Target cell count: {target_count}")

# Constrained mapping
ad_map = tg.map_cells_to_space(
    adata_sc,
    adata_sp,
    mode="constrained",
    target_count=target_count,
    density_prior=density_prior,
    num_epochs=1000,
    device="cuda:0",  # GPU recommended
)

ad_map.write_h5ad("experiments/tangram_constrained_mapping.h5ad")

Step 5: Assign Cell Types to Segments

# Create segment dataframe
tg.create_segment_cell_df(adata_sp)

# Count cell types per spot
tg.count_cell_annotations(
    ad_map,
    adata_sc,
    adata_sp,
    annotation="cell_type",
)

# Deconvolve to individual cells
adata_segment = tg.deconvolve_cell_annotations(adata_sp)
adata_segment.write_h5ad("experiments/deconvolved_cells.h5ad")

print(f"Deconvolved {adata_segment.shape[0]} cells")
print(adata_segment.obs["cluster"].value_counts())

Step 6: Visualize Deconvolved Cells

import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(12, 12))
sc.pl.spatial(
    adata_segment,
    color="cluster",
    size=0.4,
    show=False,
    frameon=False,
    alpha_img=0.2,
    ax=ax,
)
plt.title("Deconvolved Cell Types")
plt.savefig("deconvolved_spatial.png", dpi=200)

Output Files

  • spatial_with_segmentation.h5ad - Spatial data with cell counts
  • tangram_constrained_mapping.h5ad - Constrained mapping result
  • deconvolved_cells.h5ad - Individual cell annotations
  • Visualization plots

Interpreting Results

The deconvolved AnnData contains:

  • obs['cluster']: Assigned cell type for each segmented cell
  • obs['x'], obs['y']: Spatial coordinates of cell centroids
  • obsm['spatial']: Spatial coordinates array

Note: Deconvolution assigns cell types probabilistically based on the mapping. Cells are assigned to the most likely type given the spot's expression profile.


Tips

  1. Segmentation quality matters: Poor segmentation = poor deconvolution
  2. Use GPU: Constrained mode is computationally intensive
  3. More epochs: Use 1000+ epochs for constrained mode
  4. Validate patterns: Check that deconvolved cell types match expected tissue architecture
  5. Compare to spot-level: Deconvolved proportions should roughly match spot-level predictions