CosMx workflow
CosMx SMI exports a flat-file directory with per-FOV transcripts, cell segmentation polygons, and optional tissue images (Morphology2D TIF tiles).
Loading
using SpatialOmics
# Basic load — transcripts and cell boundaries only
ds = read(CosMx(), "/path/to/cosmx_export/")
# Include tissue images (stitched from Morphology2D TIF tiles)
ds = read(CosMx(morphology_dir="/path/to/Morphology2D"), "/path/to/cosmx_export/")
# Cache to disk for faster subsequent loads
write!(ds, "/path/to/cache.zarr", SpatialDataZarr())
ds2 = read(SpatialDataZarr(), "/path/to/cache.zarr")Exploring elements
keys(elements(ds)) # list all loaded elements
tx = points(ds, "transcripts")
bnd = shapes(ds, "cell_boundaries")
# Top expressed genes
top_features(tx, 20)
# Transcripts per cell (excludes unassigned; instance_id == 0)
counts = count_per_instance(tx)Coordinate systems
Each FOV is registered as a separate CoordinateSystem. All FOVs are registered in a shared global coordinate system, with per-FOV affine transforms in the dataset's transform graph.
# List all registered coordinate systems
coord_systems(ds) # ["fov_1", "fov_2", ..., "global"]
# Resolve a transform from a FOV to global space
t = transform(ds, "fov_1", "global")
# Apply to transform an element between spaces
tx_global = apply(t, points(ds, "transcripts_fov_1"))Spatial filtering
Use SpatialExtent or SpatialROI to define a region of interest. Views are lazy — no data is copied:
ext = SpatialExtent(5000.0, 7000.0, 3000.0, 5000.0; coord_system="global")
roi = view(ds, ext)
# Filter transcripts and shapes to the ROI
tx_roi = points(roi, "transcripts")
bnd_roi = shapes(roi, "cell_boundaries")
# Subsampled scatter for quick overview
scatter!(ax, subsample(collect(tx_roi), 50_000); markersize=1)Visualisation
using CairoMakie
ext = SpatialExtent(5000.0, 6000.0, 3000.0, 4000.0; coord_system="global")
roi = view(ds, ext)
fig = Figure(size=(600, 600))
ax = Axis(fig[1, 1]; aspect=DataAspect(), yreversed=true)
# Tissue image — rescaled for display
image!(ax, scaleminmax(channel(images(roi, "morphology"), 1)))
# Cell boundaries
poly!(ax, shapes(roi, "cell_boundaries"); color=:transparent, strokecolor=:cyan, strokewidth=0.3)
# Top gene transcripts
for gene in top_features(points(roi, "transcripts"), 3)
scatter!(ax, coords(points(roi, "transcripts"), gene); label=gene, markersize=2)
end
axislegend(ax; position=:lt)
tightlimits!(ax)
figExport to SpatialData
The resulting Zarr directory is compatible with Python's SpatialData library, enabling handoff to Python-based downstream analysis:
write!(ds, "/path/to/output.zarr", SpatialDataZarr())