Overview

This vignette demonstrates how to use OME-TIFF files generated by the NanoString GeoMx instrument to enhance the data visualization for a NanoString GeoMx experiment. SpatialOmicsOverlay was specifically made to visualize and analyze the free-handed nature of Region of Interest (ROI) selection in a GeoMx experiment, and the immunofluorescent-guided segmentation process. The overlay from the instrument is recreated in the R environment allowing for plotting overlays with data like ROI type or gene expression.

In this vignette, we will be walking through a mouse brain dataset from the Spatial Organ Atlas

Package installation

Download package tarball from NanoString’s GeoScriptHub (link pending)

if (!requireNamespace("BiocManager", quietly=TRUE))
    install.packages("BiocManager")

BiocManager::install("GeomxTools")
BiocManager::install("SpatialOmicsOverlay")

Load Libraries

library(SpatialOmicsOverlay)
library(GeomxTools)

Data Ingestion

Files needed:

  1. OME-TIFF from GeoMx instrument (other OME-TIFFs should work with custom parsing functions)
  2. Lab Worksheet from instrument readout
  3. Annotation file(s)

Reading in the SpatialOverlay object can be done with or without the image. We will start without the image as that can be added later.

If outline = TRUE, only ROI outline points are saved. This decreases memory needed and figure rendering time downstream. If ANY ROIs are segmented in the study, outline will be FALSE. In this particular example, there are segmented ROIs, so we set outline = FALSE.

In this example, we are downloading a TIFF image from AWS S3 but this variable is simply the file path to a OME-TIFF.

This function will be downloading a 13 GB file and will keep a 4 GB file in BiocFileCache. This download will take ~15 minutes but you will only have to download once

tifFile <- downloadMouseBrainImage()
tifFile
## [1] "/home/biocbuild/.cache/R/SpatialOmicsOverlay/22729e44db382_mu_brain_004.ome.tiff"
muBrainLW <- system.file("extdata", "muBrain_LabWorksheet.txt",
                         package = "SpatialOmicsOverlay")

muBrain <- readSpatialOverlay(ometiff = tifFile, annots = muBrainLW, 
                              slideName = "D5761 (3)", image = FALSE,  
                              saveFile = FALSE, outline = FALSE)

The readSpatialOverlay function is a wrapper to walk through all of the necessary steps to store the OME-TIFF file components. This function automates XML extraction & parsing, image extraction, and coordinate generation. These functions can also be run separately if desired (xmlExtraction, parseScanMetadata, parseOverlayAttrs, addImageOmeTiff, createCoordFile).

If you are getting a java.lang.OutOfMemoryError: Java heap space when running readSpatialOverlay(), restart your R session and try increasing the maximum heap size by supplying the -Xmx parameter before the Java Virtual Machine is initialized used by a dependency package RBioFormats. Run the code below before loading any other libraries. RBioFormats source

options(java.parameters = "-Xmx4g")
library(RBioFormats)

SpatialOverlay Accessors

SpatialOverlay objects hold data specific to the image and the ROIs. Here are a couple of functions to access the most important parts.

#full object
muBrain
## SpatialOverlay 
## Slide Name: D5761 (3) 
## Overlay Data: 93 samples 
##    Overlay Names: DSP-1012999073013-A-A02 ... DSP-1012999073013-A-H09 ( 93 total ) 
## Scan Metadata 
##    Panels: TAP Mouse Whole Transcriptome Atlas 
##    Segmentation: Segmented 
## Outline: FALSE
#sample names
head(sampNames(muBrain))
## [1] "DSP-1012999073013-A-A02" "DSP-1012999073013-A-A03"
## [3] "DSP-1012999073013-A-A04" "DSP-1012999073013-A-A05"
## [5] "DSP-1012999073013-A-A06" "DSP-1012999073013-A-A07"
#slide name
slideName(muBrain)
## [1] "D5761 (3)"
#metadata of ROI overlays
#Height, Width, X, Y values are in pixels
head(meta(overlay(muBrain)))
ROILabel Sample_ID Height Width X Y Segmentation
001 DSP-1012999073013-A-A02 751 751 10363 15008 Geometric
002 DSP-1012999073013-A-A03 1239 782 14346 16630 Geometric
003 DSP-1012999073013-A-A04 1272 902 15664 16603 Geometric
004 DSP-1012999073013-A-A05 1119 1276 13707 16135 Geometric
005 DSP-1012999073013-A-A06 1054 1124 15932 16228 Geometric
006 DSP-1012999073013-A-A07 751 751 10756 14259 Geometric
#coordinates of each ROI
head(coords(muBrain))
sampleID ycoor xcoor
DSP-1012999073013-A-A02 15383 10363
DSP-1012999073013-A-A02 15356 10364
DSP-1012999073013-A-A02 15357 10364
DSP-1012999073013-A-A02 15358 10364
DSP-1012999073013-A-A02 15359 10364
DSP-1012999073013-A-A02 15360 10364

Plotting Without Image

After parsing, ROIs can be plotted without the image in the object. These plots are the highest resolution versions since there is no scaling down to the image size, and might take a little time to render. If the image is attached to the object, coordinates are automatically scaled down to the image size and plotted as if they are on top of the image.

While manipulating the figure, there is a low-resolution option for faster rendering times.

A scale bar is automatically calculated when plotting. This functionality can be turned off using scaleBar = FALSE. Scale bars can be fully customized using corner, textDistance, and variables that start with scaleBar: scaleBarWidth, scaleBarColor, etc.

plotSpatialOverlay(overlay = muBrain, hiRes = FALSE, legend = FALSE)

colorBy, by default, is Sample_ID but almost any annotation or data can be added instead, including gene expression, tissue morphology annotations, pathway score, etc. These annotations can come from a data.frame, matrix, GeomxSet object, or vector. Below we attach the gene expression for CALM1 from a GeomxSet object and color the segments by that value.

muBrainAnnots <- readLabWorksheet(lw = muBrainLW, slideName = "D5761 (3)")
muBrainGeomxSet <- readRDS(unzip(system.file("extdata", "muBrain_GxT.zip",
                                  package = "SpatialOmicsOverlay")))
muBrain <- addPlottingFactor(overlay = muBrain, annots = muBrainAnnots, 
                             plottingFactor = "segment")
muBrain <- addPlottingFactor(overlay = muBrain, annots = muBrainGeomxSet, 
                             plottingFactor = "Calm1")
muBrain <- addPlottingFactor(overlay = muBrain, annots = 1:length(sampNames(muBrain)), 
                             plottingFactor = "ROILabel")
muBrain
## SpatialOverlay 
## Slide Name: D5761 (3) 
## Overlay Data: 93 samples 
##    Overlay Names: DSP-1012999073013-A-A02 ... DSP-1012999073013-A-H09 ( 93 total ) 
## Scan Metadata 
##    Panels: TAP Mouse Whole Transcriptome Atlas 
##    Segmentation: Segmented 
## Plotting Factors: 
##    varLabels: segment Calm1 ROILabel 
## Outline: FALSE
head(plotFactors(muBrain))
segment Calm1 ROILabel
DSP-1012999073013-A-A02 Full ROI 1177 1
DSP-1012999073013-A-A03 Full ROI 765 2
DSP-1012999073013-A-A04 Full ROI 1045 3
DSP-1012999073013-A-A05 Full ROI 1730 4
DSP-1012999073013-A-A06 Full ROI 1119 5
DSP-1012999073013-A-A07 Full ROI 600 6

Customizing the graph

All generated figures are ggplot based so they can be easily customized using functions from that or similar grammar of graphs packages. For example, we can change the color scale to the viridis color palette.

Note: hiRes and outline figures use fill, lowRes uses color

plotSpatialOverlay(overlay = muBrain, hiRes = FALSE, colorBy = "Calm1", 
                   scaleBarWidth = 0.3, scaleBarColor = "green") +
    viridis::scale_color_viridis()+
    ggplot2::labs(title = "Calm1 Expression in Mouse Brain")

Adding the Image

Images can be added automatically using readSpatialOverlay(image = TRUE) or added after reading in the object.

An OME-TIFF file is a pyramidal file, meaning that many sizes of an image are saved. The largest having the highest resolution and decreasing as the image gets smaller. Images are 1/2 the size as the previous resolution.

Pyramidal TIFF

Pyramidal TIFF

The res variable says which resolution of the image to extract. 1 = largest image and the higher values get smaller. Each OME-TIFF has a different number of layers, with most having around 8. It is suggested to use the smallest res value, and highest resolution, your environment can handle. This is a trial and error process.

Using too big of an image will cause a java memory error. If this error occurs, increase your res value. Below is an example of the error you will receive if the resolution is too high for your system.

Error in .jcall("RBioFormats", "Ljava/lang/Object;", "readPixels", i,  : 
  java.lang.NegativeArraySizeException: -2147483648

The resolution size will affect speed and image resolution through the rest of the analysis. To check the smallest resolution size available, for the fastest speeds, use checkValidRes(). For the rest of this tutorial we will be using res = 8 for vignette size restrictions, but res 4-6 is recommended.

#lowest resolution = fastest speeds
checkValidRes(ometiff = tifFile)
## [1] 8
res <- 8
muBrain <- addImageOmeTiff(overlay = muBrain, ometiff = tifFile, res = res)
muBrain
## SpatialOverlay 
## Slide Name: D5761 (3) 
## Overlay Data: 93 samples 
##    Overlay Names: DSP-1012999073013-A-A02 ... DSP-1012999073013-A-H09 ( 93 total ) 
## Scan Metadata 
##    Panels: TAP Mouse Whole Transcriptome Atlas 
##    Segmentation: Segmented 
## Plotting Factors: 
##    varLabels: segment Calm1 ROILabel 
## Outline: FALSE 
## Image: /home/biocbuild/.cache/R/SpatialOmicsOverlay/22729e44db382_mu_brain_004.ome.tiff
showImage(muBrain)