--- title: "Loading CosMx and Xenium data with SpaceTrooper" author: "Dario Righelli" date: "`r BiocStyle::doc_date()`" pkg: SpaceTrooper output: BiocStyle::html_document: toc: true toc_float: true vignette: > %\VignetteIndexEntry{Loading CosMx and Xenium data with SpaceTrooper} %\VignetteEncoding{UTF-8} %\VignetteEngine{knitr::rmarkdown} --- ```{r setup, include=FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 6, fig.height = 4 ) suppressPackageStartupMessages({ library(SpaceTrooper) library(SpatialExperiment) }) ``` # Overview This vignette shows how to build a `SpatialExperiment` (SPE) from: - **Nanostring CosMx** (RNA/protein) outputs - **10x Genomics Xenium** outputs For each technology, we demonstrate: - **Route A**: SpaceTrooper’s high-level reader (`readCosmxSPE`, `readCosmxProteinSPE`, `readXeniumSPE`) - **Route B**: read with **SpatialExperimentIO**, then standardize with `updateCosmxSPE` / `updateXeniumSPE` # CosMx (Nanostring) We begin with **CosMx**. The package ships with a small CosMx example for demonstration. ```{r cosmx-path} cospath <- system.file(file.path("extdata", "CosMx_DBKero_Tiny"), package="SpaceTrooper") cospath ``` ## Route A — Direct loading with SpaceTrooper Use `readCosmxSPE()` to construct an SPE from CosMx outputs; it also normalizes names/metadata and records polygons/FOV info if present. ```{r cosmx-route-a} spe_cos <- readCosmxSPE( dirName=cospath, sampleName="DBKero_Tiny", coordNames=c("CenterX_global_px", "CenterY_global_px"), countMatFPattern="exprMat_file.csv", metadataFPattern="metadata_file.csv", polygonsFPattern="polygons.csv", fovPosFPattern="fov_positions_file.csv", fovdims=c(xdim=4256, ydim=4256) ) spe_cos ``` Inspect essentials: ```{r cosmx-route-a-inspect} assayNames(spe_cos) dim(spe_cos) head(colnames(spatialCoords(spe_cos))) metadata(spe_cos)$technology metadata(spe_cos)$polygons ``` ### CosMx protein If working with **CosMx Protein**, use the convenience wrapper: ```{r cosmx-protein, eval=FALSE} protfolder <- system.file("extdata", "S01_prot", package = "SpaceTrooper") spe_cos_prot <- readCosmxProteinSPE( dirName=protfolder, sampleName="cosmx_prots", coordNames=c("CenterX_global_px", "CenterY_global_px"), countMatFPattern="exprMat_file.csv", metadataFPattern="metadata_file.csv", polygonsFPattern="polygons.csv", fovPosFPattern="fov_positions_file.csv", fovdims=c(xdim=4256, ydim=4256) ) metadata(spe_cos_prot)$technology ``` ## Route B — Via SpatialExperimentIO, then standardize If you prefer to read with **SpatialExperimentIO** first, upgrade the object with `updateCosmxSPE()` to harmonize names/metadata and attach polygons. ```{r cosmx-route-b} spe_cos_raw <- SpatialExperimentIO::readCosmxSXE( dirName=cospath, returnType="SPE", countMatPattern="exprMat_file.csv", metaDataPattern="metadata_file.csv", coordNames=c("CenterX_global_px", "CenterY_global_px"), addFovPos=TRUE, fovPosPattern="fov_positions_file.csv", altExps=NULL, addParquetPaths=FALSE ) spe_cos_std<-updateCosmxSPE( spe=spe_cos_raw, dirName=cospath, sampleName="DBKero_Tiny", polygonsFPattern="polygons.csv", fovdims=c(xdim=4256, ydim=4256) ) identical(spe_cos_std, spe_cos) ``` # Xenium (10x Genomics) A small Xenium example is also included for demonstration. ```{r xenium-path} xepath <- system.file("extdata", "Xenium_small", package = "SpaceTrooper") xepath ``` ## Route A — Direct loading with SpaceTrooper `readXeniumSPE()` builds the SPE from a Xenium Output Bundle (root or `outs/`) and standardizes metadata. Key options: - `type`: `"HDF5"` or `"sparse"` (feature matrix) - `boundariesType`: `"parquet"` or `"csv"` (cell boundaries) - `computeMissingMetrics`: compute QC metrics (area/aspect ratio) if needed - `keepPolygons`: append polygons to `colData` - `addFOVs`: derive FOV IDs from transcript parquet ```{r xenium-route-a} spe_xen_a <- readXeniumSPE( dirName=xepath, type="HDF5", coordNames=c("x_centroid", "y_centroid"), boundariesType="parquet", computeMissingMetrics=TRUE, keepPolygons=TRUE, countsFilePattern="cell_feature_matrix", metadataFPattern="cells.csv.gz", polygonsFPattern="cell_boundaries", polygonsCol="polygons", txPattern="transcripts", addFOVs=FALSE ) spe_xen_a ``` Quick checks: ```{r xenium-route-a-inspect} assayNames(spe_xen_a) dim(spe_xen_a) colnames(spatialCoords(spe_xen_a)) metadata(spe_xen_a)$polygons metadata(spe_xen_a)$technology ``` ## Route B — Via SpatialExperimentIO, then standardize Read with **SpatialExperimentIO** and then pass through `updateXeniumSPE()` for SpaceTrooper-standardized metadata and optional metrics/FOV extraction. ```{r xenium-route-b} spe_xen_b <- SpatialExperimentIO::readXeniumSXE( dirName=xepath, countMatPattern="cell_feature_matrix.h5", metaDataPattern="cells.csv.gz", coordNames=c("x_centroid", "y_centroid"), returnType="SPE", addExperimentXenium=FALSE, altExps=NULL, addParquetPaths=FALSE ) spe_xen_b <- updateXeniumSPE( spe=spe_xen_b, dirName=xepath, boundariesType="parquet", computeMissingMetrics=TRUE, keepPolygons=TRUE, polygonsFPattern="cell_boundaries", polygonsCol="polygons", txPattern="transcripts", addFOVs=FALSE ) spe_xen_b ``` Validate: ```{r xenium-route-b-validate} identical(metadata(spe_xen_b)$technology, "10X_Xenium") identical(spe_xen_a, spe_xen_b) ``` ------------------------------------------------------------------------ # File layout notes - **CosMx**: per-cell metadata (e.g. `metadata_file.csv`), expression matrix (`exprMat_file.csv`), optional polygon CSV (`polygons.csv`), and FOV positions. `updateCosmxSPE()` also fixes common field names and records FOV dims in `metadata`. - **Xenium**: unzipped bundle contains an `outs/` folder. Feature matrix may be `cell_feature_matrix.h5` (HDF5) or sparse folder; cells metadata `cells.csv.gz`; boundaries as `.parquet` or `.csv.gz`; transcript parquet for FOV attribution. `readXeniumSPE()` auto-detects `outs/` if you pass the bundle root. # Session info ```{r session-info} sessionInfo() ```