VoltRon is an end-to-end spatial omic analysis package which also supports investigating spatial points in sub-cellular resolution, including those that are based on Fluorescence in situ hybrizrization where one can spatially locate each individual molecule that are hybridrized.
In this use case, we analyse readouts of the experiments conducted on example tissue sections analysed by the Xenium In Situ platform. Two tissue sections of 5 \(\mu\)m tickness are derived from a single formalin-fixed, paraffin-embedded (FFPE) breast cancer tissue block. More information on the spatial datasets and the study can be also be found on the BioArxiv preprint.
You can import these readouts from the 10x Genomics website (specifically, import In Situ Replicate 1/2). Alternatively, you can download a zipped collection of Xenium readouts from here.
VoltRon includes built-in functions for converting readouts of Xenium experiments into VoltRon objects. The importXenium function locates all readout documents under the output folder of the Xenium experiment, and forms a VoltRon object. In this case, the Xenium data includes two assays (in the same layer) where one is the cell segmentation based cell profile data and the other is the pure molecule assay where the identity (gene of origin) of RNA molecules are given.
library(VoltRon)
Xen_R1 <- importXenium("Xenium_R1/outs", sample_name = "XeniumR1", import_molecules = TRUE)
Xen_R1
VoltRon Object
XeniumR1:
Layers: Section1
Assays: Xenium(Main) Xenium_mol
You can also save the imported VoltRon object to disk and still accomplish analysis on molecule datasets.
Xen_R1 <- saveVoltRon(Xen_R1, format = "HDF5VoltRon",
output = "Xen_R1/", replace = TRUE)
The disk-backed data can be loaded once saved on disk again
Xen_R1_disk <- loadVoltRon("Xen_R1/")
With vrSpatialPlot, we can visualize Xenium experiments in subcellular context. We first visualize mRNAs of ACTA2, a marker for smooth muscle cell actin, and other markers found in the breast cancer tissue sample. We can interactively select a subset of interest within the tissue section and visualize the localization of these transcripts. Here we subset a ductal carcinoma niche, and visualize mRNAs of four genes.
Xen_R1_subset <- subset(Xen_R1, interactive = TRUE)
Xen_R1_subset <- Xen_R1_subset$subsets[[1]]
vrSpatialPlot(Xen_R1_subset, assay = "Xenium_mol", group.by = "gene",
group.id = c("ACTA2", "KRT15", "TACSTD2", "CEACAM6"), pt.size = 0.2, legend.pt.size = 5)
We can use the n.tile argument to divide the count of selected group.ids (e.g. genes here) into hexagonal bins. We will use this argument to divide the x and y-axis into 100 tiles and aggregate transcript counts from select group.id
vrSpatialPlot(Xen_R1_subset, assay = "Xenium_mol", group.by = "gene", group.id = "ACTA2",
legend.pt.size = 5, n.tile = 100, background.color = "black")
VoltRon is capable of analyzing localization of sub-cellular entities such as molecules beyond mRNAs, thus the analysis may also extend to extracellular molecules such as viral RNA. Using Xenium in situ, we locate the two open reading frames (ORFs) of genomic and subgenomics RNA of SARS-COV-2, namely S2_N and S2_orf1ab and analyze their abundances over the COVID-19 infected lung tissue.
Specifically, we analyse readouts of eight tissue micro array (TMA) tissue sections that were fitted into the scan area of a slide loaded on a Xenium in situ instrument. These sections were cut from control and COVID-19 lung tissues of donors categorized based on disease durations (acute and prolonged). You can download the standard Xenium output folder here.
For more information on the TMA blocks, see GSE190732 for more information.
Across these eight TMA section, we investigate a section of acute case which is originated from a lung with extreme number of detected open reading frames of virus molecules. For convenience, we load a VoltRon object where cells are already annotated. You can also find the RDS file here.
vr2_merged_acute1 <- readRDS(file = "acutecase1_annotated.rds")
You would see that we have two assays associated with the tissue section, one for the cells and the other for the molecules.
SampleMetadata(vr2_merged_acute1)
Assay Layer Sample
Assay7 Xenium Section1 acute case 1
Assay8 Xenium_mol Section1 acute case 1
We can visualize individual S2_N and S2_orf1ab by simply switching to Xenium_mol assay given
vrSpatialPlot(vr2_merged_acute1, assay = "Xenium_mol", group.by = "gene",
group.ids = c("S2_N", "S2_orf1ab"), n.tile = 500)
You can also visualize both the cellular and subcellular spatial points on the same plot using addSpatialLayer function, which would show points of the section where virus is abundant with no cell segment on top.
vrSpatialPlot(vr2_merged_acute1, assay = "Xenium_mol", group.by = "gene",
group.ids = c("S2_N", "S2_orf1ab"), n.tile = 500) |>
addSpatialLayer(vr2_merged_acute1, assay = "Xenium", group.by = "CellType", n.tile = 500, plot.segments = TRUE)
We switch to the molecule assay of the VoltRon object, and select virus ORFs. We also look for other virus ORFs that are 50 pixel distance from each virus molecule to pin point neighborhoods that are rich in virus.
vr2_merged_acute1 <- getSpatialNeighbors(vr2_merged_acute1, assay = "Xenium_mol",
group.by = "gene", group.ids = c("S2_N", "S2_orf1ab"),
method = "radius", radius = 50)
We can now observe the new spatial neighborhood graph saved in the VoltRon object with name radius.
vrGraphNames(vr2_merged_acute1)
[1] "radius"
We now select the feature type and graph name to run an hot spot analysis which will label each molecule if their neighborhood are dense in other virus molecules.
vr2_merged_acute1 <- getHotSpotAnalysis(vr2_merged_acute1, assay = "Xenium_mol",
features = "gene", graph.type = "radius")
The getHotSpotAnalysis function will produce test statistics and adjusted p-values for all the selected molecules in the region.
meta <- Metadata(vr2_merged_acute1, assay = "Xenium_mol")
head(meta[meta$gene %in% c("S2_N", "S2_orf1ab"),])
id assay_id overlaps_nucleus gene z_location qv fov_name nucleus_distance
1: 281694020045508_25831b Assay8 0 S2_N 20.37133 40 Q7 402.4913
2: 281694020045511_25831b Assay8 0 S2_N 20.39390 40 Q7 362.9937
3: 281694020042882_25831b Assay8 0 S2_N 20.14611 40 Q7 233.1110
4: 281694020045509_25831b Assay8 0 S2_N 20.14540 40 Q7 241.3636
5: 281694020042883_25831b Assay8 0 S2_N 19.92565 40 Q7 170.5991
6: 281694020042884_25831b Assay8 0 S2_N 19.96041 40 Q7 167.2583
postfix Assay Layer Sample gene_hotspot_stat gene_hotspot_pvalue gene_hotspot_flag
1: _25831b Xenium_mol Section1 acute case 1 0.000000e+00 NA
2: _25831b Xenium_mol Section1 acute case 1 0.000000e+00 NA
3: _25831b Xenium_mol Section1 acute case 1 1.469335e-08 1 cold
4: _25831b Xenium_mol Section1 acute case 1 1.469335e-08 1 cold
5: _25831b Xenium_mol Section1 acute case 1 4.408006e-08 1 cold
6: _25831b Xenium_mol Section1 acute case 1 4.408006e-08 1 cold
Now we can visualize the localization of S2_N and S2_orf1ab molecules that are located in “hot regions”, or niches that are significantly abundant with these molecules.
vrSpatialPlot(vr2_merged_acute1, assay = "Xenium_mol",
group.by = "gene_hotspot_flag", group.ids = c("cold", "hot"),
alpha = 1, background.color = "white")