Third Party Tools
This page walks through reading the per-sample outputs from the results-folder into the two most common single-cell / spatial transcriptomics ecosystems:
Scanpy (Python,
AnnData)Seurat (R,
Seuratobject)
Both walkthroughs follow the same structure:
Read the Matrix Market expression matrix (
matrix.mtx.gz+features.tsv.gz+barcodes.tsv.gz).Parse spatial coordinates
(X, Y)out of the barcode strings.Attach the registered OME-TIFF image and align coordinates to the image's local space.
(Optional) Load cell / nuclei contour CSVs.
Resource requirements: DRAGEN StrataMap outputs are large. A single sample's raw (per-barcode) MTX can contain tens of millions of barcodes and hundreds of millions of non-zero counts, resulting in files that are several gigabytes on disk and expand to 20–60 GB in memory when loaded. Cell-binned and grid-binned matrices are substantially smaller, but still routinely require 8–32 GB RAM depending on tissue area and cell density. Plan for at least 32 GB RAM if you intend to load raw data, run dimensionality reduction, or hold multiple samples in memory simultaneously.
Coordinate note: Transcripts in
barcodes.tsv.gzare in global substrate coordinates (µm). Registered OME-TIFF images and TIFF masks are in local sample coordinates (µm). To overlay points on the image you must subtractGlobal_left/Global_top(read from the OME-TIFF metadata) from the spatial coordinates. See Global and Local Coordinates.
The barcode format is <type>:Y:X, where <type> is one of:
SBC— raw / un-binned (per spatial barcode), e.g.SBC:3084.702:29810.565bin<N>— grid-binned atNµm, e.g.bin10:10005:27955cell<ID>— cell- or nuclei-binned, e.g.cell10119:5238:29404
Throughout the examples below, replace SAMPLEID with your actual sample name. The sample name is the same as the folder name inside results/.
Per-sample inputs used in the examples:
mtx_path (cell-bin)
results/SAMPLEID/SAMPLEID_cell_binned/
mtx_path (grid)
results/SAMPLEID/SAMPLEID_grid_binned_10um/
mtx_path (raw)
results/SAMPLEID/SAMPLEID_raw/
ome_tiff_path
results/SAMPLEID/SAMPLEID.ome.tiff
cell_contour_path
results/SAMPLEID/SAMPLEID_Expanded_5um_cell_contour_coords.csv
nuclei_contour_path
results/SAMPLEID/SAMPLEID_nuclei_contour_coords.csv
The OME-TIFF contains three image planes:
Index (Python tif.pages[i])
Index (R readTIFF(..., all=i))
Contents
0
1
Original-resolution H&E (RGB, variable µm/pixel)
1
2
Tissue mask (1 channel, 1 µm/pixel)
2
3
1 µm/pixel H&E (RGB) — used in the examples below
Scanpy (Python)
Tested with Scanpy 1.10.4.
Requirements
1. Read the Matrix Market files
matrix.mtx.gz is stored as genes × barcodes, so transpose to cells × genes before assigning metadata.
2. Parse spatial coordinates from the barcodes
Each barcode encodes its spatial position as <type>:Y:X (µm, global coordinates).
At this point adata.obsm["spatial"] is in global substrate space and is enough for any analysis that does not need the H&E image.
3. Attach the registered image and convert to local coordinates
To overlay points on the registered OME-TIFF, read Global_top / Global_left from the OME metadata and subtract them from the spatial coordinates so they live in the image's local pixel/µm space.
The 1 µm/pixel H&E is at page index 2 (the third page), which means a scalefactor of 1 (1 pixel = 1 µm).
If you want full-resolution H&E instead, load tif.pages[0] and set tissue_hires_scalef = 1 / pixel_size_um, where pixel_size_um comes from ome_obj["images"][0]["pixels"]["physical_size_x"] / 1000.
4. (Optional) Load cell / nuclei contours
Contour CSVs are also in global coordinates and need the same offset.
5. Quick sanity-check plot
Seurat (R)
Tested with Seurat 5.3.0. The API examples use the Seurat v5
Assay5class; they will not work on Seurat v4 without modification.
Requirements
The easiest way to get a working environment is via conda / mamba:
1. Read the Matrix Market files
Use gzfile() + Matrix::readMM so you don't need any extra .gz reader package.
Seurat may warn
Feature names cannot have underscores ('_'), replacing with dashes ('-'). That is expected and only renames features in the assay; thegene_idscolumn above still holds the original Ensembl IDs.
2. Parse spatial coordinates from the barcodes
At this point the spatial reduction is in global substrate space.
3. Attach the registered image and convert to local coordinates
tiff::readTIFF(path, payload = FALSE) returns just the metadata (no pixels) for the first IFD, including the OME-XML in description. We pull Global_top / Global_left straight out of that, then read only the page we actually want with all = N.
⚠️ Do not use
tiff::readTIFF(path, all = TRUE)on these OME-TIFFs — the original-resolution H&E plane is multiple gigabytes uncompressed and will OOM or segfault.
4. (Optional) Load cell / nuclei contours
5. Quick sanity-check plot
The image needs to be loaded as a numeric [0, 1] array for annotation_raster (i.e. drop as.is = TRUE if you used it above when computing offsets — or read it once more without it for plotting).
Additional Resources
Matrix Market format specification: https://math.nist.gov/MatrixMarket/formats.html
Scanpy documentation: https://scanpy.readthedocs.io/
AnnData documentation: https://anndata.readthedocs.io/
Seurat documentation: https://satijalab.org/seurat/
Last updated
Was this helpful?

