diff --git a/02_session3.Rmd b/02_session3.Rmd index b73fb6a..688dedc 100644 --- a/02_session3.Rmd +++ b/02_session3.Rmd @@ -699,9 +699,191 @@ knitr::include_graphics("img/02_session3/spat_leiden.png") ## Niche clustering +Building on top of these leiden annotations, we can define spatial niche signatures based on which leiden types are often found together. + +### Spatial network + +First a spatial network must be generated so that spatial relationships between cells can be understood. + +```{r, eval=FALSE} +g <- createSpatialNetwork(g, + method = "Delaunay" +) + +spatPlot2D(g, + point_shape = "no_border", + show_network = TRUE, + point_size = 0.1, + network_color = "grey" +) +``` + +```{r, out.width="60%", echo=FALSE, fig.cap="Delaunay spatial network`"} +knitr::include_graphics("img/02_session3/spatnet.png") +``` + +### Niche calculation + +Calculate a proportion table for a cell metadata table for all the spatial neighbors of each cell. This means that with each cell established as the center of its local niche, the enrichment of each leiden cluster label is found for that local niche. +The results are stored as a new spatial enrichment entry called 'leiden_niche' + +```{r, eval=FALSE} +g <- calculateSpatCellMetadataProportions(g, + spat_network = "Delaunay_network", + metadata_column = "leiden_clus", + name = "leiden_niche" +) +``` + + +### kmeans clustering based on niche signature + +```{r, eval=FALSE} +# retrieve the niche info +prop_table <- getSpatialEnrichment(g, name = "leiden_niche", output = "data.table") +# convert to matrix +prop_matrix <- GiottoUtils::dt_to_matrix(prop_table) + +# perform kmeans clustering +set.seed(1234) # make kmeans clustering reproducible +prop_kmeans <- kmeans( + x = prop_matrix, + centers = 7, # controls how many clusters will be formed + iter.max = 1000, + nstart = 100 +) +prop_kmeansDT = data.table::data.table( + cell_ID = names(prop_kmeans$cluster), + niche = prop_kmeans$cluster +) + +# return kmeans clustering on niche to gobject +g <- addCellMetadata(g, + new_metadata = prop_kmeansDT, + by_column = TRUE, + column_cell_ID = "cell_ID" +) + +# visualize niches +spatInSituPlotPoints(g, + show_image = TRUE, + image_name = "HE", + polygon_fill = "niche", + polygon_fill_as_factor = TRUE +) +``` + +```{r, echo=FALSE, fig.cap="Leiden annotation-based spatial niches"} +knitr::include_graphics("img/02_session3/spat_niches.png") +``` + ## Pseudovisium +Another thing we can do is create a "pseudovisium" dataset by tessellating across this dataset using the same layout and resolution as a Visium capture array. + +`makePseudoVisium` generates a Visium array of circular polygons across the spatial extent provided. + +Here we use `ext()` with the `prefer` arg pointing to the polygon and points data and `all_data = TRUE`, meaning that the combined spatial extent of those two data types will be returned, giving a good measure of where all the data in the object is at the moment. + +`micron_size = 1` since the Xenium data is already scaled to microns. + +```{r, eval=FALSE} +pvis <- makePseudoVisium( + extent = ext(g, + prefer = c("polygon", "points"), + all_data = TRUE # this is the default + ), + micron_size = 1 +) +g <- setGiotto(g, pvis) +g <- addSpatialCentroidLocations(g, poly_info = "pseudo_visium") + +plot(pvis) +``` + +```{r, out.width="60%", echo=FALSE, fig.cap="Pseudovisium spot geometries generated by `makePseudoVisium()`"} +knitr::include_graphics("img/02_session3/pvis_poly.png") +``` + +### Pseudovisium aggregation and workflow + +Make 'pseudo_visium' the new default spatial unit then proceed with aggregation and usual aggregate workflow +```{r, eval=FALSE} +activeSpatUnit(g) <- "pseudo_visium" + +g <- calculateOverlap(g, + spatial_info = "pseudo_visium", + feat_info = "rna" +) +g <- overlapToMatrix(g) + +g <- filterGiotto(g, + expression_threshold = 1, + feat_det_in_min_cells = 1, + min_det_feats_per_cell = 100 +) + +g <- normalizeGiotto(g) +g <- addStatistics(g) + +spatInSituPlotPoints(g, + show_image = TRUE, + image_name = "HE", + polygon_feat_type = "pseudo_visium", + polygon_fill = "total_expr", + polygon_fill_gradient_style = "sequential" +) +``` + +```{r, echo=FALSE, fig.cap="Pseudo visium total detections per spot"} +knitr::include_graphics("img/02_session3/pvis_total_expr.png") +``` + +```{r, eval=FALSE} +g <- runPCA(g, feats_to_use = NULL) +g <- runUMAP(g, + dimensions_to_use = seq(15), + n_neighbors = 15 +) + +g <- createNearestNetwork(g, + dimensions_to_use = seq(15), + k = 15 +) + +g <- doLeidenCluster(g, resolution = 1.5) + +# plots +plotPCA(g, cell_color = "leiden_clus", point_size = 2) +plotUMAP(g, cell_color = "leiden_clus", point_size = 2) +spatInSituPlotPoints(g, + polygon_feat_type = "pseudo_visium", + polygon_fill = "leiden_clus", + polygon_fill_as_factor = TRUE +) +spatInSituPlotPoints(g, + polygon_feat_type = "pseudo_visium", + polygon_fill = "leiden_clus", + polygon_fill_as_factor = TRUE, + show_image = TRUE, + image_name = "HE" +) +``` + + +```{r, echo=FALSE, fig.cap="Leiden clustering in PCA (top left) and UMAP (top right) spaces, and in spatial plot with no image (bottom left), and with image (bottom right)"} +knitr::include_graphics("img/02_session3/pvis_clustering.png") +``` + + + + + + + + + - Feature/molecule specific analysis diff --git a/img/02_session3/pvis_clustering.png b/img/02_session3/pvis_clustering.png new file mode 100644 index 0000000..79329b1 Binary files /dev/null and b/img/02_session3/pvis_clustering.png differ diff --git a/img/02_session3/pvis_poly.png b/img/02_session3/pvis_poly.png new file mode 100644 index 0000000..2ff87dc Binary files /dev/null and b/img/02_session3/pvis_poly.png differ diff --git a/img/02_session3/pvis_total_expr.png b/img/02_session3/pvis_total_expr.png new file mode 100644 index 0000000..04a3028 Binary files /dev/null and b/img/02_session3/pvis_total_expr.png differ diff --git a/img/02_session3/spat_niches.png b/img/02_session3/spat_niches.png new file mode 100644 index 0000000..f5ea889 Binary files /dev/null and b/img/02_session3/spat_niches.png differ diff --git a/img/02_session3/spatnet.png b/img/02_session3/spatnet.png new file mode 100644 index 0000000..181be2e Binary files /dev/null and b/img/02_session3/spatnet.png differ