Image Modalities in run_together¶
Morphology / histology images (DAPI, H&E, protein stains, …) are packaged as georeferenced PMTiles layers and added to each sample's catalog.yaml in the images stage. This page is the platform-agnostic reference for how to declare them; the per-platform pages show the image files each platform ships.
Images are declared in one of three ways:
| Way | Flag | Use when |
|---|---|---|
| Image sheet | --images images.tsv |
Multi-sample, or several images; one row per image. |
| Inline CLI | --image key=value,… (repeatable) |
A single sample, a few images. |
| Config JSON | "images": [ … ] in --config (top level, or inside a sample entry) |
Alongside other JSON settings; also how profiles declare auto-detected images. |
The sheet and --image share the same field vocabulary (below). Config JSON entries are used as written, with a few differences — see Config JSON. Built-in profiles also auto-detect standard modalities (e.g. Xenium's morphology_focus_000{0..3}.ome.tif, Stereo-seq's *_regist.tif), so you often need none of these.
| Platform | Images by default |
|---|---|
| Xenium | auto-detected morphology_focus channels, or morphology_focus.ome.tif / morphology.ome.tif |
| Visium HD | H&E from the sample's hne column / key, scaled from scalefactors_json.json |
| MERSCOPE | none; declare them with the merfish_csv transform column |
| Stereo-seq | auto-detected {prefix}_HE/ssDNA/DAPI_regist.tif at 0.5 µm/pixel |
| Seq-Scope | none; an H&E given explicitly is treated as already georeferenced |
| CosMx SMI · Illumina StrataMap · Generic | none; attach explicitly |
Fields¶
Fields of an --images row or an --image value:
| Field (aliases) | Required | Meaning |
|---|---|---|
type |
✅ | Modality — sets the default color and kind from the registry (below). |
source / src / tif |
✅ | Image path. Relative paths are resolved against the sample's in_dir when not found as given. |
sample / sample_id |
(sheet only) | Which sample the image belongs to; * or blank = every sample. |
id / img_id |
Catalog key / output basename. Defaults to type. |
|
color |
Hex color, overrides the type's default (single kind only). |
|
kind |
single | rgb | prebuilt. Defaults to the type's registry kind. |
|
transform (or the platform column, e.g. merfish_csv) |
Geometric transform file → the profile's import flag (MERSCOPE: --micron2pixel-csv). single kind only. |
|
convert |
single kind: ome2png converts the TIFF and supplies the georeferencing bounds. Defaults to ome2png for a .tif, none for a .png. Any value other than ome2png skips that step (see Georeferencing). |
|
um_per_pixel |
Microns per pixel, for a plain (non-OME) TIFF that carries no pixel-size metadata, e.g. 0.5 for a Stereo-seq *_regist.tif. single: sets --px-per-um-x/y. rgb: sets --um-per-pixel, and takes effect only together with georef_plain. |
|
shrink_factor |
single: downscale factor for very large mosaics (else the profile's image_defaults). |
|
high_memory |
single: true for the high-memory import path. Defaults to true whenever use_middle_page is in effect; false opts out. |
|
use_middle_page |
single: true/false, pick the middle page of a multi-page (z-stack) OME-TIFF. Defaults to true for files whose name ends in morphology.ome.tif (Xenium's 3D DAPI stack, also under a prefix such as GSM123_rep1_morphology.ome.tif; import_image otherwise rejects it for lacking a page), false for everything else. |
|
georeferenced |
rgb: true if the TIFF already carries the intended geotransform (e.g. a Seq-Scope H&E registered upstream): its corner coordinates are kept and only the CRS is assigned (--georef-detect gtiff). Else the profile's image_defaults. |
|
georef_detect |
rgb: read the bounds from the file — ome (OME PhysicalSizeX/Y) or gtiff (as georeferenced). Else the profile's image_defaults. An .ome.tif defaults to ome. |
|
georef_plain |
rgb: map the upper-left corner to (0,0) and the lower-right to the image size × um_per_pixel. Any non-empty value turns it on. |
|
swapxy / rotate / flip_vertical / flip_horizontal |
rgb: orientation (see Orientation). Else the profile's image_defaults. |
|
rescale |
rgb: rescale mode for 16-bit imagery (auto | linear | log | none), forwarded to geotiff2pmtiles, which rejects 16-bit input without a range. Use linear with the range below. |
|
rescale_range / rescale_min + rescale_max |
rgb: input value range for rescale (e.g. 0,65535). Give rescale_range in a --images TSV or config; on a --image CLI value use rescale_min/rescale_max instead, since the range's comma would split the value. |
Blank cells (` /-/./NA) mean *unset*. Fields markedsingleorrgb` are accepted for the other kind but have no effect there.
Kinds¶
kind |
Behavior | Typical use |
|---|---|---|
single |
grayscale → colorize with color (import_image) |
DAPI, protein/RNA stains (TIFF / OME-TIFF) |
rgb |
passthrough, no colorizing (image_png2pmtiles) |
H&E histology |
prebuilt |
copy an existing .pmtiles straight into the catalog |
pre-rendered layers |
Type registry (default color + kind)¶
type looks up a default color and kind in assets/run_together_image_types.json — edit that file to add or adjust types (keys starting with _ are ignored):
type |
default color | kind |
|---|---|---|
dapi |
0F73E6 |
single |
boundary |
F300A5 |
single |
rna |
A4A400 |
single |
protein |
008A00 |
single |
cellbound1 / cellbound2 / cellbound3 |
009E73 / E69F00 / CC79A7 |
single |
polyt |
00FFFF |
single |
ssdna |
F0F0F0 |
single |
hne |
— (RGB) | rgb |
An unregistered type with no explicit color is an error (no silent wrong color) — either add a color field or register the type. An unregistered type defaults to kind single.
Georeferencing¶
Every layer needs its bounds in transcript µm. Where they come from depends on the kind:
single — the OME→PNG step (convert: ome2png) supplies them: from the OME-TIFF's pixel-size metadata, from um_per_pixel for a plain TIFF, and through the platform transform (merfish_csv) when given. A source that skips this step (a .png, or convert set to anything else) reaches image_png2pmtiles --georeference with no bounds and the import fails, so single-channel layers need a TIFF source (or, in JSON, extra_flags that supply a --georef-* option).
rgb — the first that applies:
georeferencedis true →--georef-detect gtiff(keep the file's geotransform, assign the CRS).georef_detectis set →--georef-detect <value>.- The source is an
.ome.tif/.ome.tiffand none ofgeoref_plain,um_per_pixel,um_per_pixel_jsonis set →--georef-detect ome. georef_plain→--georef-plain, scaled byum_per_pixel_json(a JSON underin_dir, keyum_per_pixel_key, defaultmicrons_per_pixel; read withjq— the Visium HD H&E setting) or byum_per_pixel(per image;image_defaults.um_per_pixelapplies tosingleimages only).
With none of these, image_png2pmtiles stops with "georeferencing bounds not found or ambiguous".
Orientation (rgb images)¶
rotate (90, 180, 270, clockwise), flip_vertical, and flip_horizontal are forwarded to image_png2pmtiles (rotation precedes flips). swapxy=true transposes the image — for histology stored with its axes swapped relative to the transcript coordinates — and is shorthand for rotate=90 plus flip_vertical, so it cannot be combined with an explicit rotate / flip_* (an error). Each falls back to the profile's image_defaults. They have no effect on single images. See Image orientation for how to choose.
Image sheet (--images images.tsv)¶
One row per image, attached to samples by the sample column. This keeps the sample sheet from blowing up while staying flexible.
1 2 3 4 | |
sample = *(or blank) applies a row to every sample.- A single DAPI or H&E per sample can instead go straight into the sample sheet as a
dapi/hnecolumn (path only); see Specifying Inputs for how those are imported. - The transform column is named by the platform profile (
merfish_csvfor MERSCOPE); a generictransformcolumn also works on such a platform. On a platform without animage_transform, the column is ignored.
Inline CLI (--image)¶
For a single sample, give each image as comma-separated key=value pairs; repeat --image per image (same fields as a sheet row, no sample needed):
1 2 3 4 5 | |
Config JSON ("images")¶
The same records as a list under --config — at the top level (every sample) or inside a sample entry (that sample only). Profiles declare their auto-detected images the same way.
1 2 3 4 | |
Each entry locates its file with exactly one of:
| Key | Meaning |
|---|---|
source |
Explicit path (relative → resolved against in_dir when not found as given). |
match |
A literal path under in_dir (not a glob). |
suffix |
Appended to the sample's in_prefix (Stereo-seq). |
JSON entries are not run through the type registry, so they differ from sheet rows:
idis required (it does not default totype), andtypesets nothing: givekind(defaultsingle) and, forsingle,color(required).convertdefaults toome2pngwhatever the extension.- The
transform/ platform column is not recognized; pass a transform asextra_flags(e.g.["--micron2pixel-csv", "/p/transform.csv"]) or use a sheet row. extra_flags(rawimport_imageflags,singlekind only) andmatch/suffixexist only here.
The other fields (um_per_pixel, shrink_factor, high_memory, use_middle_page, georeferencing, orientation, rescale) work as in the table above.
Merging. A top-level images entry replaces every profile entry with the same id and new ids are appended; { "replace": [ … ] } discards the profile's list. See List assembly.
Which entry wins¶
For each sample the candidates are considered in this order: its own JSON images, then the --images / --image rows that target it, then its sample-sheet dapi / hne columns, then the profile/config images. For each id, the first entry whose file exists is used and the rest are ignored — so an explicit image overrides a profile's auto-detected one with the same id, and a profile can list several same-id fallbacks (Xenium's dapi).
A missing file is skipped silently
An entry whose file does not exist produces no layer and no error. If a layer is missing from the catalog, check the path (relative paths are tried as given, then under in_dir).
What a row runs¶
A colorized single image runs:
1 2 3 4 5 | |
A file ending in morphology.ome.tif (Xenium's multi-page DAPI z-stack, with or without a prefix) gets --use-middle-page and --high-memory, whichever way it was supplied, unless use_middle_page / high_memory say otherwise. shrink_factor, high_memory, and um_per_pixel fall back to the profile's image_defaults (e.g. MERSCOPE sets shrink_factor=5.0, high_memory=true for its large mosaics; Stereo-seq sets um_per_pixel=0.5).
An rgb image runs cartloader image_png2pmtiles --geotif2mbtiles --mbtiles2pmtiles --georeference with the bounds, orientation, and rescale options above. A prebuilt image is copied in as <id>.pmtiles. Each layer is then added to catalog.yaml under its id. See import_image.
With --skip-image-errors, a single image whose OME-TIFF cannot be read during the OME→PNG step is skipped with a warning instead of failing the run, and any image whose PMTiles was not produced is left out of the catalog. Failures of rgb or prebuilt images still stop the run. Re-run with the flag to regenerate the Makefile and resume past a corrupt image.
See also¶
- Specifying Inputs — the three input modes and the sample sheet.
- Per-platform image files: Xenium, Visium HD, MERSCOPE, Stereo-seq, Seq-Scope.
import_image— the underlying module.