Skip to content
mims-harvardPublic

About

Generative modeling of spatially resolved perturbation responses with CONCERT

Topics

Resources

Stars

27 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

30 Commits

Folders and files

Repository files navigation

CONCERT predicts niche-aware perturbation responses in spatial transcriptomics

ProjectPage PaperPage CodePage Data Tutorials License

Xiang Lin, Zhenglun Kong, Boyang Fu, Soumya Ghosh, Manolis Kellis, Marinka Zitnik

Spatial perturbation transcriptomics measures how genetic or chemical edits alter gene expression while preserving tissue context. Perturbation outcomes depend on a cell's intrinsic state and also on how effects propagate across cellular microenvironments. CONCERT is a niche-aware generative model that embeds perturbation context and learns spatial kernels with a Gaussian-process variational autoencoder to predict perturbation effects across tissue. Each perturbation is given a spatial effect field over the section and a gain that controls how strongly the local microenvironment may reshape its response, so the same perturbation can produce different responses in different neighbourhoods. A temporal variant extends the same construction over time, so one model covers a whole time course and can be asked for a timepoint it was never trained on.

We formalise two prediction tasks: within-niche prediction, where a cell's response to a perturbation carried by cells of its own local niche is predicted, and cross-slide prediction, where the response must be transferred to a slide on which that perturbation was never observed. CONCERT is evaluated on a SPAC-seq screen of hundreds of knockouts and on Perturb-map lung tumour sections, and outperforms dissociated counterfactual models, spatial perturbation models and neighbour-averaging strategies on both the magnitude and the gene ranking of the predicted response. Two case studies go beyond benchmarking: in DSS-induced colitis CONCERT reconstructs expression at unmeasured timepoints and recovers the non-monotone course of the injury, rising to a day-9 peak and resolving by day 21, which interpolation between observed timepoints cannot produce; in ischemic stroke it predicts responses under lesion sizes and 3D geometries that photothrombosis cannot produce experimentally.

⚑ Challenges from existing perturbation models

Ignoring cells' tissue context when predicting perturbations

issue

πŸ”₯ Challenges from existing spatial perturbation sequencing technologies

issue2

πŸ› οΈ Tasks

CONCERT predicts perturbation responses in four settings:

  1. 2D tissue sections. Predict how each cell responds to a perturbation in the context of its spatial niche on a tissue section.
  2. 3D tissue. Predict perturbation responses across serial sections arranged as a 3D tissue volume.
  3. Missing-region imputation with counterfactual perturbation prediction. Impute expression in an unmeasured tissue region and predict how its cells respond to a perturbation.
  4. Perturbation prediction with deconvolution. Deconvolve multi-cell spot measurements into cell-level expression and predict perturbation responses at that resolution.

tasks

🧬 CONCERT model

CONCERT disentangles spatial and perturbation effects, learns the spatial effect of each perturbation, corrects technical and batch noise, and generates post-perturbation gene expression across tissue space.

model

πŸ—‚οΈ Repository layout

Path Contents
models/concert_benchmark/ Model used for the SPAC-seq and Perturb-map benchmarks
models/concert_temporal/ Model used for the colitis time-course case study
models/concert_spac_niche/ Model used for the stroke case study
benchmark_evaluation/ Scoring code shared by the two benchmark experiments
experiments/ One directory per experiment: data preparation, training, evaluation, figures
reproduction/ Reproducing the paper: one script per result, with its own README
notebooks/ The same four results as step-by-step tutorials, with figures
datasets/ Where every dataset comes from, and how to point the code at it
config/paths.sh Data, output and environment paths - the one file the SLURM scripts read

The three model directories are deliberate copies rather than one shared package. They diverged in the model source itself, not only in configuration, and keeping them separate means a change made for the time course cannot silently alter a benchmark number.

βš™οΈ Dependencies

Python 3.11.13 and one CUDA GPU for training and for the prediction steps; the figure and table steps run on CPU. The reported results were produced in this environment:

torch==2.3.0          # CUDA 11.8 build
numpy==1.26.4
scipy==1.12.0
pandas==2.3.3
scikit-learn==1.8.0
scanpy==1.10.1
anndata==0.12.2
h5py==3.13.0
matplotlib==3.10.1
scvi-tools==1.3.3
wandb==0.22.1
conda create -n concert_env python=3.11 && conda activate concert_env
pip install torch==2.3.0 --index-url https://download.pytorch.org/whl/cu118
pip install -r env_requirements.txt

CUDA 11.8 supports up to sm_90, so this environment cannot run on Blackwell GPUs - a run that dies with an nvrtc -arch error a few minutes in was scheduled on one. Ask for an H100 or an A100.

πŸ’» Run CONCERT

Getting started

  1. Create the environment from env_requirements.txt.

  2. Obtain the two input folders, data/ and checkpoints/ (available from the authors upon request; see Questions), and place both in the repository root:

    CONCERT/
      data/           sections, benchmark assets, shipped results
      checkpoints/    one directory per trained model
      runs/           created on first use: where reruns write
    

    Every notebook, script and SLURM runner finds them there. To keep them elsewhere, set CONCERT_DATA_DIR, CONCERT_CHECKPOINT_ROOT and CONCERT_WORKDIR. datasets/README.md describes both folders; data/README.md lists every file and the notebook or script that reads it.

  3. Check the wiring. Every script prints an existence table for each input it needs and stops on the first missing one:

    python reproduction/01_spac_seq_benchmark.py --steps aggregate

Example 1 - train on a spatial perturbation dataset

Each dataset has one configuration file with every model setting of the reported runs. A run names the configuration, the data and the output directory:

Dataset Configuration file Training script Trained checkpoint
SPAC-seq models/concert_benchmark/configs/spacseq.yaml experiments/01_spac_seq_benchmark/train/train.sh checkpoints/spacseq_within_niche, checkpoints/spacseq_cross_slide
DSS colitis models/concert_temporal/configs/dss.yaml experiments/03_dss_gut_case_study/train/train.sh checkpoints/dss_colitis
Perturb-map models/concert_benchmark/configs/perturbmap.yaml experiments/02_perturb_map_benchmark/train/train.sh checkpoints/perturbmap_within_niche, checkpoints/perturbmap_cross_slide

SPAC-seq (five sections, within-niche setting):

cd models/concert_benchmark
python run_concert_spac.py --config configs/spacseq.yaml --stage train \
  --multi_sample_files $(ls $CONCERT_DATA_DIR/spacseq/raw/raw_output_1-*.h5ad | paste -sd,) \
  --holdout_file $CONCERT_DATA_DIR/benchmark_assets/holdout_coords/holdout_spac_seen.json \
  --outdir $CONCERT_WORKDIR/spacseq_within_niche

DSS colitis (all sections of the time course, in the order of manifest.csv):

cd models/concert_temporal
python run_concert_spac.py --config configs/dss.yaml --stage train \
  --multi_sample_files $(awk -F, -v d=$CONCERT_DATA_DIR/dss_colitis/sections 'NR>1{print d"/"$1}' \
      $CONCERT_DATA_DIR/dss_colitis/sections/manifest.csv | paste -sd,) \
  --arch_desc_dir $CONCERT_DATA_DIR/dss_colitis/architecture \
  --outdir $CONCERT_WORKDIR/dss_colitis

Perturb-map uses the same command with configs/perturbmap.yaml.

Training writes model.pt and pert_map.json into --outdir; the perturbation vocabulary is read from pert_map.json at evaluation, so the integer code of every perturbation matches the one the weights were trained with. Any flag on the command line overrides the file.

The training scripts in the table are the commands of the reported runs:

sbatch experiments/01_spac_seq_benchmark/train/train.sh seen
sbatch experiments/03_dss_gut_case_study/train/train.sh
sbatch experiments/02_perturb_map_benchmark/train/train.sh seen

Example 2 - counterfactual prediction on chosen spots

Give a file of spot indices and the perturbation to apply. Spots can be selected interactively with the Shiny app in select_cells/. The example knocks out Stat1 in the chosen spots of the trained SPAC-seq model; __KEEP__ leaves each spot in its own tissue.

cp -r $CONCERT_CHECKPOINT_ROOT/spacseq_within_niche $CONCERT_WORKDIR/   # prediction writes next to model.pt
cd models/concert_benchmark
python run_concert_spac.py --config configs/spacseq.yaml --stage eval \
  --multi_sample_files $(ls $CONCERT_DATA_DIR/spacseq/raw/raw_output_1-*.h5ad | paste -sd,) \
  --outdir $CONCERT_WORKDIR/spacseq_within_niche \
  --pert_cells spots.txt --target_cell_tissue __KEEP__ --target_cell_perturbation Stat1

Use the configuration file the model was trained with: it carries the lengthscale band of the spatial field, which is a plain attribute rather than a saved weight.

The decoder is

log mu = f_basal(x, expression) + 1[has_guide] * mu_action + 1[is_real_KO] * f_pert(g, x)

so a decode to perturbation g and a decode to the basal slot differ by exactly the perturbation terms - the basal reconstruction cancels. Every reported score is computed on that difference of two decodes, not on one decode alone.

Example 3 - imputation and counterfactual prediction in a missing patch

CONCERT fills in a patch of tissue that is missing from a slide, and predicts what the missing cells would look like under a perturbation. Train on the slide without the patch, then run --stage impute_patch with a mask file naming the missing cells. Each missing cell is predicted at its own coordinates from the surrounding tissue: cells of the unperturbed group are imputed as they are, and cells of a knockout group are imputed together with the counterfactual effect of that knockout at their location.

cd models/concert_benchmark
python run_concert_spac.py --config configs/spacseq.yaml --stage train \
  --data_file slide_missing_patch.h5ad --outdir $CONCERT_WORKDIR/impute_demo
python run_concert_spac.py --config configs/spacseq.yaml --stage impute_patch \
  --data_file slide_missing_patch.h5ad --outdir $CONCERT_WORKDIR/impute_demo \
  --mask_index_file patch_mask.npz --raw_slide_file slide_full.h5ad

patch_mask.npz holds three arrays over the cells of the full slide: obs_name (cell id), group (perturbation label) and role (1 for a missing cell). The run writes impute_results.npz with the predicted and the measured expression of every missing cell. experiments/08_deconvolution_imputation builds the mask and the masked slide for the SPAC-seq patch experiment of the paper and compares CONCERT with Tangram, SpatialScope and SpaIM.

Naming

The code paths, output directories and CSV columns use seen and unseen. In the manuscript those two settings are within-niche prediction and cross-slide prediction.

πŸ” Reproducing the paper

Everything needed to reproduce the reported results is in reproduction/, with its own README: one script per result, the step-by-step notebooks with their figures, and the end-to-end experiment pipelines.

πŸ—ƒοΈ Datasets

No data is included in this repository. Every dataset is linked, with the processed copies the code reads, in datasets/README.md.

Dataset Raw data Processed data
SPAC-seq CRISPR screen SPAC-seq portal preprocessing scripts
Perturb-map GEO GSE193460 preprocessing scripts
Colitis MERFISH time course Dryad preprocessing script
Brain stroke From the authors of the original paper on request preprocessing script
Perturb-FISH Original data preprocessing script

The trained checkpoints are one folder, checkpoints/, with one subdirectory per model, available from the authors upon request; datasets/README.md lists them. Every result can also be regenerated from the scripts.

βš–οΈ License

The code in this package is licensed under the MIT License. See LICENSE.

πŸ“ Reference

@article{Lin2025.11.08.686890,
  author  = {Lin, Xiang and Kong, Zhenglun and Fu, Boyang and Ghosh, Soumya and Kellis, Manolis and Zitnik, Marinka},
  title   = {CONCERT predicts niche-aware perturbation responses in spatial transcriptomics},
  elocation-id = {2025.11.08.686890},
  year    = {2025},
  doi     = {10.1101/2025.11.08.686890},
  publisher = {Cold Spring Harbor Laboratory},
  URL     = {https://www.biorxiv.org/content/early/2025/11/10/2025.11.08.686890},
  journal = {bioRxiv}
}

πŸ’¬ Questions

Please leave a GitHub issue or contact Xiang Lin or Marinka Zitnik.

About

Generative modeling of spatially resolved perturbation responses with CONCERT

Topics

Resources

Stars

27 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages