satijalab / seurat

R toolkit for single cell genomics
http://www.satijalab.org/seurat
Other
2.31k stars 919 forks source link

How to subset Xenium/ spatial object by cells and keep only molecules within these cells? #9085

Open kaizen89 opened 5 months ago

kaizen89 commented 5 months ago

When I subset a Xenium object, the molecules of the parent object are not touched. I'm not sure if this is the expected behavior but I was wandering if the was a way to keep only the molecules within the cells of the smaller object.

> subset_xenium =subset(xenium.obj, cells=cells2keep)
> dim(xenium.obj@assays$Xenium$counts)
[1]    389 549534
> dim(subset_xenium@assays$Xenium$counts)
[1]   389 80364
> dim(xenium.obj@images$fov$molecules$ACE2@coords)
[1] 7697    2
> dim(subset_xenium@images$fov$molecules$ACE2@coords)
[1] 7697    2

Thanks!

alikhuseynov commented 4 months ago

This is actually for SeuratObject, there have been some updates but I'm not sure if subset now removes molecules that are not within the selected cells (ie, your cells2keep) Sometime ago I implemented subset_opt to also subset molecules. See this threads:

rajuvee commented 2 months ago

Did you every find an answer to this? The subset_opt function (including rev2) does not seem to solve my problems (see below):

image
alikhuseynov commented 2 months ago

Did you every find an answer to this? The subset_opt function (including rev2) does not seem to solve my problems (see below):

first of all, please provide your run code. subset_opt will only remove provided cells or cluster category similar to subset itself. If you want to crop out those red cells then use Crop function or check this discussion:

hope this helps

kaizen89 commented 2 months ago

I tried both subset_obj_seurat and subset_obj_seurat_v2 but did not get what I was expecting.

xenium_sub = subset_opt(xenium.obj, idents = "B_Plasma_0")
xenium_sub_v2 = subset(xenium.obj, idents = "B_Plasma_0")

ImageDimPlot(xenium.obj, fov = "fov", molecules = c("CD3E"), nmols = 10000,size = 0.1, group.by = NA)
ImageDimPlot(xenium_sub, fov = "fov", molecules = c("CD3E"), nmols = 10000,size = 0.1, group.by = NA)
ImageDimPlot(xenium_sub_v2, fov = "fov", molecules = c("CD3E"), nmols = 10000,size = 0.1, group.by = NA)

All the plots look the same, it seems the molecules slot was unchanged.

alikhuseynov commented 2 months ago

ok, my function is only a temporary solution and I haven't experimented much with idents arg. I think Seurat devs will soon add such support. Now, in Seurat the molecules slot is only used for visualization, no analysis is done on mols unless you want to use other R spatial packages or similar. You can try to use cells arg to pass the cell ids that belong to "B_Plasma_0", and features arg to pass a character vector of genes you want to keep (eg, genes for "B_Plasma_0" cluster).

kaizen89 commented 2 months ago

I was only trying to visualize the molecules on the subsetted object.

xenium_sub = subset_opt(xenium.obj, cells = Cells(xenium_sub_v2), features = rownames(xenium_sub_v2)[1:5])

I do manage to subset the molecules this way but they still fall outside of cells used for subsetting, making the visualization not really intuitive.

rajuvee commented 2 months ago

In my image, the cells are subsetting appropriately and when I look inside the assay I believe they are subsetting appropriately as well. I think the only problem is in the FOV molecules slot where that does not work well at all. The problem being that crop is based on coordinates rather than cells which does not help. I have looked through your code base and it is very helpful but I am not seeing how it would apply to this problem?

alikhuseynov commented 2 months ago

the code can be optimized if one knows which molecules belong to which cells and uses that info to subset mols as well.