ludvigla / semla

Other
59 stars 5 forks source link

How to Convert a Merged Seurat Object with Multiple Samples to a Usable Semla Object? #40

Open yangxinzhi opened 2 weeks ago

yangxinzhi commented 2 weeks ago

image image

Hello, I am encountering an issue when using the Semla package. Specifically, I am trying to convert my merged Seurat object (which contains multiple samples) into a format that is compatible with Semla, but I keep getting errors. Is there a way to make VisiumV2 data compatible with Semla?

yangxinzhi commented 2 weeks ago

image image I even attempted to convert the V5 format to V4 for compatibility, but the same error persists.

yangxinzhi commented 2 weeks ago

image

jemorlanes commented 1 week ago

Hello!

Are you working with VisiumHD data? If that is the case, I would recommend you load the data with semla's functions. We have a tutorial available in the website regarding how to do this, as well as some guides for the analysis!

We will add compatibility for conversion of Seurat's VisiumHD peculiarities in the future, but if you cannot wait to do the analysis, I recommend you try to load the data using semla directly.

Hope this helps and thanks for using the package!

yangxinzhi commented 2 days ago

Hello! I wanted to let you know that when I use Seurat version 5.1.0, I encountered an issue with image formatting. Specifically, when I used the following commands:

Early2 <- CreateSeuratObject(counts = Read10X("Early_R2/"), assay = "Spatial") # Load expression matrix and create Seurat object
Early2_img <- Read10X_Image(image.dir = file.path("F:/博士单细胞分析/空间转录组/GSE212903_spatial/Young_R02_S1_spatial/Young_R02_S1_spatial/"), filter.matrix = TRUE) # Load a 10X Genomics Visium Image
Early2_img <- Early2_img[Cells(x = Early2)]
DefaultAssay(Early2_img) <- "Spatial"

This command creates a v2-format image object. However, when I use a modified function from GitHub, as shown below:

Read10X_Image <- function(image.dir, image.name = "tissue_hires_image.png", filter.matrix = TRUE, ...) {

  library(png)
  library(jsonlite)

  image <- readPNG(source = file.path(image.dir, image.name))
  scale.factors <- fromJSON(txt = file.path(image.dir, 'scalefactors_json.json'))
  tissue.positions.path <- Sys.glob(paths = file.path(image.dir, 'tissue_positions*'))
  tissue.positions <- read.csv(
    file = tissue.positions.path[1],
    col.names = c('barcodes', 'tissue', 'row', 'col', 'imagerow', 'imagecol'),
    header = ifelse(
      test = basename(tissue.positions.path[1]) == "tissue_positions.csv",
      yes = TRUE,
      no = FALSE
    ),
    as.is = TRUE,
    row.names = 1
  )
  if (filter.matrix) {
    tissue.positions <- tissue.positions[which(x = tissue.positions$tissue == 1), , drop = FALSE]
  }
  unnormalized.radius <- scale.factors$fiducial_diameter_fullres * scale.factors$tissue_hires_scalef
  spot.radius <- unnormalized.radius / max(dim(x = image))
  return(new(
    Class = 'VisiumV1',
    image = image,
    scale.factors = scalefactors(
      spot = scale.factors$tissue_hires_scalef,
      fiducial = scale.factors$fiducial_diameter_fullres,
      hires = scale.factors$tissue_hires_scalef,
      scale.factors$tissue_hires_scalef
    ),
    coordinates = tissue.positions,
    spot.radius = spot.radius
  ))
}

This indeed outputs v1-format data. However, when I use this v1-format data with Seurat’s SpatialDimPlot function, as in:

SpatialDimPlot(Spatial_integrated, images = 'Early2', image.alpha = 0, pt.size.factor = 3)

I find that parameters like pt.size.factor = 3 don’t work. So I am currently only able to read the data using Seurat’s default Read10X_Image function to maintain functionality.

Hope this clarifies my issue!

yangxinzhi commented 2 days ago

Additionally, I found that when I attempted to convert the v2 format to v1 format using the following code:

scale_factors <- scalefactors(
    spot = Early1_img@scale.factors$spot,
    fiducial = Early1_img@scale.factors$fiducial,
    hires = Early1_img@scale.factors$hires,
    lowres = Early1_img@scale.factors$lowres
)
coordinates_df <- as.data.frame(Early1_img@centroids@coords)

img_v1 <- new(
    Class = "VisiumV1",
    image = Early1_img@image,
    coordinates = coordinates_df,
    spot.radius = Early1_img@boundaries$centroids@radius,
    scale.factors = scale_factors
)

I was able to successfully convert it. However, when using semla.data <- UpdateSeuratForSemla(Spatial_integrated), I encountered the following output:

ℹ Found VisiumV1 object(s).
ℹ Expecting 'tissue_lowres' format.

── Collecting data from @images slot 
ℹ Collecting data for sample 1:
→   Exporting H&E image width dimensions 600x578 to C:\Users\Public\Documents\Wondershare\CreatorTemp\Rtmp8GmGRK/1.png
→   Collected scale factors.
→   Collected image information.
→   Collected coordinates.
ℹ Collecting data for sample 2:
→   Exporting H&E image width dimensions 600x577 to C:\Users\Public\Documents\Wondershare\CreatorTemp\Rtmp8GmGRK/2.png
→   Collected scale factors.
→   Collected image information.
→   Collected coordinates.
...
! Paths to raw images are unavailable. See '?ReplaceImagePaths()' for more information on how to update the paths.

✔ Returning updated Seurat object.

Then, when I ran the following commands to check if the paths were correctly set:

lapply(semla.data@images, function(img) img@image.path)

I got the error:

Error in FUN(X[[i]], ...) : 
  no slot of name "image.path" for this object of class "VisiumV1"

Finally, when trying to analyze using Semla’s function with the following code:

MapFeaturesSummary(semla.data, features = "nFeature_Spatial", subplot_type = "box")

I received the error:

Error in vapply(X = .FilterObjects(object = object, classes.keep = c("SpatialImage",  : 
  values must be length 1, but FUN(X[[6]]) result is length 0

I would like to know if there is currently a simple way to convert a Seurat object with multiple merged spatial transcriptomics samples into an object that can be used with Semla for improved visualization.

yangxinzhi commented 2 days ago

image Is it because this can only analyze a Seurat object that contains only one image at a time, and then use MergeSTData for merging afterward?