Deepspot m

Generate transcriptome-wide virtual spatial transcriptomics from H&E histology with DeepSpot-M.

How to use it

  1. Hit Copy the whole skill.
  2. Claude: ⋯ → Download .md, then Customize → Skills → Add → Upload skill.
    ChatGPT: make a Project and paste it into Instructions.
    Neither? Paste it at the top of a new chat — it works for that chat.
  3. Describe your job in plain words. The AI follows the skill from there.
Claude Code — installs the whole folder, not just SKILL.md
npx degit K-Dense-AI/scientific-agent-skills/skills/deepspot-m#main ~/.claude/skills/deepspot-m

For one project only, change the path to .claude/skills/deepspot-m.

Not working?
  • Check which app you pasted it into — the steps above name the right one.
  • Some skills need the paid tier of Claude or ChatGPT.
Step-by-step guide with screenshots · Ask in the forum

Paste into Claude, ChatGPT or Cursor.

Show the full text176 lines
deepspot-m/SKILL.md176 lines7.2 KBpushed 45d agoRawView on GitHub

DeepSpot-M

Overview

DeepSpot-M is a multimodal foundation model that maps a 224x224 H&E histology tile to spatial gene expression in log1p-CPM. The output is virtual spatial transcriptomics: one value per queried gene per tile, laid out on the grid the tiles came from.

A LoRA-adapted pathology foundation backbone (Midnight) tokenises the tile. A cross-attention gene decoder lets each gene query attend to the patch tokens, and a gene router hypernetwork builds gene-specific projections from frozen biological embeddings (Evo 2, Orthrus, ProtT5, scGPT, Apertus). Genes enter the model as queryable embeddings rather than fixed output slots, so the released model covers a ~19k protein-coding gene panel including genes unseen in training. The panel ships with the weights as tokens.csv and is exposed as model.gene_names; genes outside it cannot be queried in this release.

Applied to TCGA, the model produced a virtual spatial transcriptomics atlas of 28,664 slides across 32 cancer types.

Licensing

The code is PolyForm Noncommercial 1.0.0 and the weights are CC-BY-NC-SA-4.0. Use it for noncommercial research and check both licences before redistributing outputs.

Installation

uv pip install deepspotm==1.0.0

Version 1.0.0 targets Python 3.10 to 3.13 and pulls in PyTorch. Install the PyTorch build that matches your CUDA version first if you want GPU inference.

Model access

The weights are gated:

  1. Open https://huggingface.co/ratschlab/DeepSpotM and request access.
  2. Once access is granted, authenticate the machine that will download them:
huggingface-cli login

from_pretrained reads that cached token, so a login is needed once per machine.

Quick start

from deepspotm import DeepSpotM

model, image_processor = DeepSpotM.from_pretrained("ratschlab/DeepSpotM", source="scgpt")

vals = model.predict_genes(image_processor(pil_tile).unsqueeze(0), ["EPCAM", "CD3D"])

pil_tile is a PIL image of exactly 224x224 pixels. image_processor turns it into a tensor, unsqueeze(0) adds the batch dimension, and predict_genes takes the batch plus a list of HGNC gene symbols. Values come back in log1p-CPM, aligned with the gene list you passed, so keep that list beside the output to keep the columns labelled. Symbols must be in the released ~19k-gene panel (model.gene_names); an unknown symbol raises KeyError naming the offending genes.

Tile requirements

Tiles must be 224x224 RGB at roughly 20x magnification (about 0.5 microns per pixel). Check the size at the boundary of your pipeline rather than passing an unchecked crop through:

TILE_PX = 224

def require_tile(tile):
    """Return an RGB 224x224 tile, or raise if the crop is the wrong size."""
    if tile.size != (TILE_PX, TILE_PX):
        raise ValueError(
            f"DeepSpot-M expects a {TILE_PX}x{TILE_PX} tile at about 20x "
            f"(~0.5 microns per pixel); got {tile.size[0]}x{tile.size[1]}. "
            "Re-tile at the matching level or resample the crop."
        )
    return tile.convert("RGB")

Extract tiles at the slide level whose resolution is nearest 0.5 microns per pixel, then crop to 224x224 there. Resampling from a coarser level changes the texture the backbone reads.

Keep the dependency optional

deepspotm and its weights are a heavy, gated dependency. Import it inside the function that needs it so the surrounding project installs, imports and tests without it, and turn an ImportError into a message that names every step:

DEEPSPOTM_HELP = (
    "DeepSpot-M is unavailable. Install it with `uv pip install deepspotm==1.0.0`, request "
    "access to the gated weights at https://huggingface.co/ratschlab/DeepSpotM, then "
    "authenticate with `huggingface-cli login`."
)

def load_deepspotm(source="scgpt"):
    try:
        from deepspotm import DeepSpotM
    except ImportError as exc:
        raise RuntimeError(DEEPSPOTM_HELP) from exc
    return DeepSpotM.from_pretrained("ratschlab/DeepSpotM", source=source)

Embedding sources

source selects which frozen gene embedding the router builds projections from. It is one of five values:

source Gene embedding
evo2 genomic sequence
orthrus RNA
prott5 protein sequence
scgpt single-cell expression
apertus language model

Each gives a different view of gene identity. Pick one per run, and run the same tiles through more than one source when the choice matters to your analysis. See references/api.md for the full call surface, batching and device placement, gene symbol handling and output units.

Whole slide workflow

Prediction is per tile, so a slide-scale run is a tiling step followed by batched inference:

  1. Extract 224x224 tiles on a grid with the histolab skill, keeping each tile's coordinates.
  2. Process and stack tiles into batches with torch.stack.
  3. Call predict_genes once per batch with the same gene list.
  4. Concatenate the batches into a tiles-by-genes matrix and attach the coordinates.

That matrix is the virtual spatial transcriptomics map for the slide, and it drops straight into AnnData for downstream spatial analysis. references/whole_slide.md has a worked loop, batch sizing and an AnnData assembly step.

Common use cases

  • Spatial expression maps for marker genes across a tumour section.
  • Transcriptome-wide prediction over a slide cohort with no matching assay run.
  • Querying any of the ~19k panel genes by symbol, including genes unseen in training — far beyond the few hundred genes of a typical spatial assay panel.
  • Adding an expression channel to a morphology-only histology pipeline.
  • Building a slide-level cohort atlas, as done for TCGA.

Detailed references

  • references/api.md: from_pretrained and predict_genes in full, the five embedding sources and how to choose, batching, device placement, gene symbol handling, and converting log1p-CPM output.
  • references/whole_slide.md: tiling with histolab, a slide-scale prediction loop, assembling and storing a tiles-by-genes matrix, and cohort-scale runs.

Primary sources

1---
2name: deepspot-m
3description: Generate transcriptome-wide virtual spatial transcriptomics from H&E histology with DeepSpot-M. Use when you need spatial gene expression in log1p-CPM for 224x224 tiles at about 20x, want to query protein-coding genes by symbol instead of a fixed panel, or want to run prediction across a whole slide after tiling with histolab.
4license: PolyForm-Noncommercial-1.0.0
5compatibility: Needs deepspotm 1.0.0 from PyPI (Python 3.10 to 3.13) plus PyTorch. Weights at ratschlab/DeepSpotM on Hugging Face are gated and licensed CC-BY-NC-SA-4.0, so request access on the model page and then run huggingface-cli login. A CUDA GPU speeds up batched inference.
6allowed-tools: Read Write Edit Bash
7metadata:
8 version: "1.0"
9 skill-author: Ratschlab, ETH Zurich
10---
11 
12# DeepSpot-M
13 
14## Overview
15 
16DeepSpot-M is a multimodal foundation model that maps a 224x224 H&E histology tile to
17spatial gene expression in log1p-CPM. The output is virtual spatial transcriptomics: one
18value per queried gene per tile, laid out on the grid the tiles came from.
19 
20A LoRA-adapted pathology foundation backbone (Midnight) tokenises the tile. A
21cross-attention gene decoder lets each gene query attend to the patch tokens, and a gene
22router hypernetwork builds gene-specific projections from frozen biological embeddings
23(Evo 2, Orthrus, ProtT5, scGPT, Apertus). Genes enter the model as queryable embeddings
24rather than fixed output slots, so the released model covers a ~19k protein-coding gene
25panel including genes unseen in training. The panel ships with the weights as
26`tokens.csv` and is exposed as `model.gene_names`; genes outside it cannot be queried in
27this release.
28 
29Applied to TCGA, the model produced a virtual spatial transcriptomics atlas of 28,664
30slides across 32 cancer types.
31 
32## Licensing
33 
34The code is PolyForm Noncommercial 1.0.0 and the weights are CC-BY-NC-SA-4.0. Use it for
35noncommercial research and check both licences before redistributing outputs.
36 
37## Installation
38 
39```bash
40uv pip install deepspotm==1.0.0
41```
42 
43Version 1.0.0 targets Python 3.10 to 3.13 and pulls in PyTorch. Install the PyTorch build
44that matches your CUDA version first if you want GPU inference.
45 
46## Model access
47 
48The weights are gated:
49 
501. Open <https://huggingface.co/ratschlab/DeepSpotM> and request access.
512. Once access is granted, authenticate the machine that will download them:
52 
53```bash
54huggingface-cli login
55```
56 
57`from_pretrained` reads that cached token, so a login is needed once per machine.
58 
59## Quick start
60 
61```python
62from deepspotm import DeepSpotM
63 
64model, image_processor = DeepSpotM.from_pretrained("ratschlab/DeepSpotM", source="scgpt")
65 
66vals = model.predict_genes(image_processor(pil_tile).unsqueeze(0), ["EPCAM", "CD3D"])
67```
68 
69`pil_tile` is a PIL image of exactly 224x224 pixels. `image_processor` turns it into a
70tensor, `unsqueeze(0)` adds the batch dimension, and `predict_genes` takes the batch plus a
71list of HGNC gene symbols. Values come back in log1p-CPM, aligned with the gene list you
72passed, so keep that list beside the output to keep the columns labelled. Symbols must be
73in the released ~19k-gene panel (`model.gene_names`); an unknown symbol raises `KeyError`
74naming the offending genes.
75 
76## Tile requirements
77 
78Tiles must be 224x224 RGB at roughly 20x magnification (about 0.5 microns per pixel). Check
79the size at the boundary of your pipeline rather than passing an unchecked crop through:
80 
81```python
82TILE_PX = 224
83 
84def require_tile(tile):
85 """Return an RGB 224x224 tile, or raise if the crop is the wrong size."""
86 if tile.size != (TILE_PX, TILE_PX):
87 raise ValueError(
88 f"DeepSpot-M expects a {TILE_PX}x{TILE_PX} tile at about 20x "
89 f"(~0.5 microns per pixel); got {tile.size[0]}x{tile.size[1]}. "
90 "Re-tile at the matching level or resample the crop."
91 )
92 return tile.convert("RGB")
93```
94 
95Extract tiles at the slide level whose resolution is nearest 0.5 microns per pixel, then
96crop to 224x224 there. Resampling from a coarser level changes the texture the backbone
97reads.
98 
99## Keep the dependency optional
100 
101`deepspotm` and its weights are a heavy, gated dependency. Import it inside the function
102that needs it so the surrounding project installs, imports and tests without it, and turn
103an `ImportError` into a message that names every step:
104 
105```python
106DEEPSPOTM_HELP = (
107 "DeepSpot-M is unavailable. Install it with `uv pip install deepspotm==1.0.0`, request "
108 "access to the gated weights at https://huggingface.co/ratschlab/DeepSpotM, then "
109 "authenticate with `huggingface-cli login`."
110)
111 
112def load_deepspotm(source="scgpt"):
113 try:
114 from deepspotm import DeepSpotM
115 except ImportError as exc:
116 raise RuntimeError(DEEPSPOTM_HELP) from exc
117 return DeepSpotM.from_pretrained("ratschlab/DeepSpotM", source=source)
118```
119 
120## Embedding sources
121 
122`source` selects which frozen gene embedding the router builds projections from. It is one
123of five values:
124 
125| `source` | Gene embedding |
126| --------- | --------------------------------- |
127| `evo2` | genomic sequence |
128| `orthrus` | RNA |
129| `prott5` | protein sequence |
130| `scgpt` | single-cell expression |
131| `apertus` | language model |
132 
133Each gives a different view of gene identity. Pick one per run, and run the same tiles
134through more than one source when the choice matters to your analysis. See
135`references/api.md` for the full call surface, batching and device placement, gene symbol
136handling and output units.
137 
138## Whole slide workflow
139 
140Prediction is per tile, so a slide-scale run is a tiling step followed by batched
141inference:
142 
1431. Extract 224x224 tiles on a grid with the `histolab` skill, keeping each tile's
144 coordinates.
1452. Process and stack tiles into batches with `torch.stack`.
1463. Call `predict_genes` once per batch with the same gene list.
1474. Concatenate the batches into a tiles-by-genes matrix and attach the coordinates.
148 
149That matrix is the virtual spatial transcriptomics map for the slide, and it drops
150straight into `AnnData` for downstream spatial analysis. `references/whole_slide.md` has a
151worked loop, batch sizing and an `AnnData` assembly step.
152 
153## Common use cases
154 
155- Spatial expression maps for marker genes across a tumour section.
156- Transcriptome-wide prediction over a slide cohort with no matching assay run.
157- Querying any of the ~19k panel genes by symbol, including genes unseen in training —
158 far beyond the few hundred genes of a typical spatial assay panel.
159- Adding an expression channel to a morphology-only histology pipeline.
160- Building a slide-level cohort atlas, as done for TCGA.
161 
162## Detailed references
163 
164- `references/api.md`: `from_pretrained` and `predict_genes` in full, the five embedding
165 sources and how to choose, batching, device placement, gene symbol handling, and
166 converting log1p-CPM output.
167- `references/whole_slide.md`: tiling with histolab, a slide-scale prediction loop,
168 assembling and storing a tiles-by-genes matrix, and cohort-scale runs.
169 
170## Primary sources
171 
172- Paper: <https://doi.org/10.64898/2026.06.19.26356060> (medRxiv, posted 22 June 2026)
173- Code: <https://github.com/ratschlab/DeepSpotM>
174- Weights: <https://huggingface.co/ratschlab/DeepSpotM>
175- PyPI: <https://pypi.org/project/deepspotm/>
176 

Discussion

Alternatives

Also in Genomics & omics
AnndataData structure for annotated matrices in single-cell analysis. Use when working with .h5ad files or integrating with the scverse ecosystem. This is the data format skill—for analysis workflows use scanpy; for probabilistic models use scvi-tools; for population-scale queries use cellxgene-census.Science · MITArboretoInfer gene regulatory networks (GRNs) from gene expression data using scalable algorithms (GRNBoost2, GENIE3). Use when analyzing transcriptomics data (bulk RNA-seq, single-cell RNA-seq) to identify transcription factor-target gene relationships and regulatory interactions. Supports distributed computation for large-scale datasets.Science · MITBiopython: Computational Molecular Biology in PythonComprehensive molecular biology toolkit. Use for sequence manipulation, file parsing (FASTA/GenBank/PDB), phylogenetics, and programmatic NCBI/PubMed access (Bio.Entrez). Best for batch processing, custom bioinformatics pipelines, BLAST automation. For quick lookups use gget; for multi-service integration use bioservices.Science · MITBulk rnaseqEnd-to-end bulk RNA-seq orchestrator — takes raw FASTQ reads through QC and trimming (FastQC, fastp/Trim Galore), alignment and quantification (STAR, Salmon, featureCounts), assembles a gene-level counts matrix, then hands off to differential expression (pydeseq2), pathway/GSEA enrichment (pathway-enrichment), and publication figures (scientific-visualization). Use whenever the user has bulk RNA-seq reads or quant output and wants a complete, reproducible differential-expression workflow — e.g. "analyze my RNA-seq", "FASTQ to DESeq2", "run nf-core/rnaseq", "STAR/Salmon quantification", "build a counts matrix for DESeq2", or "go from reads to differentially expressed genes and enriched pathways". Routes between an nf-core/rnaseq (Nextflow) path and a standalone STAR/Salmon path, and covers experimental design, strandedness, and QC gates. For single-cell RNA-seq use the scanpy skill instead.Science · MIT