Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rotate images for spatial analysis (previous workaround no longer runs) #9344

Open
jgaunt264 opened this issue Sep 27, 2024 · 1 comment
Open
Labels
bug Something isn't working

Comments

@jgaunt264
Copy link

Hi,
I want to rotate some spatial images and the corresponding data by 90 degrees. I was previously using the workaround in issue 2702 by @longmanz (based on code by @AmhedVargas and @JPingLin), reproduced below. However, this code no longer works in Seurat v5.1.0 with error message:
Error in rotateSeuratImage(seu.obj, rotation = "L90", slide = "Sample_1") :
no slot of name "coordinates" for this object of class "VisiumV2"

I've checked each of the attributes in the new object and can't find where the coordinates are now stored. I also note that in a Seurat object generated with a previous version (when the rotate script worked), GetTissueCoordinates() produces an entirely different output than seu.obj@images)[["Sample_1"]]@coordinates.

Can anyone help to update the rotation script?

Many thanks

library(Seurat)
library(ggplot2)
library(patchwork)
library(dplyr)

rotimat=function(foo,rotation){
    if(!is.matrix(foo)){
        cat("Input is not a matrix")
        return(foo)
    }
    if(!(rotation %in% c("180","Hf","Vf", "R90", "L90"))){
        cat("Rotation should be either L90, R90, 180, Hf or Vf\n")
        return(foo)
    }
    if(rotation == "180"){
        foo <- foo %>% 
            .[, dim(.)[2]:1] %>%
            .[dim(.)[1]:1, ]
    }
    if(rotation == "Hf"){
        foo <- foo %>%
            .[, dim(.)[2]:1]
    }
    
    if(rotation == "Vf"){
        foo <- foo %>%
            .[dim(.)[1]:1, ]
    }
    if(rotation == "L90"){
        foo = t(foo)
        foo <- foo %>%
            .[dim(.)[1]:1, ]
    }
    if(rotation == "R90"){
        foo = t(foo)
        foo <- foo %>%
            .[, dim(.)[2]:1]
    }
    return(foo)
}

rotateSeuratImage = function(seuratVisumObject, slide = "slice1", rotation="Vf"){
    if(!(rotation %in% c("180","Hf","Vf", "L90", "R90"))){
        cat("Rotation should be either 180, L90, R90, Hf or Vf\n")
        return(NULL)
    }else{
        seurat.visium = seuratVisumObject
        ori.array = (seurat.visium@images)[[slide]]@image
        img.dim = dim(ori.array)[1:2]/(seurat.visium@images)[[slide]]@scale.factors$lowres
        new.mx <- c()  
        # transform the image array
        for (rgb_idx in 1:3){
            each.mx <- ori.array[,,rgb_idx]
            each.mx.trans <- rotimat(each.mx, rotation)
            new.mx <- c(new.mx, list(each.mx.trans))
        }
        
        # construct new rgb image array
        new.X.dim <- dim(each.mx.trans)[1]
        new.Y.dim <- dim(each.mx.trans)[2]
        new.array <- array(c(new.mx[[1]],
                             new.mx[[2]],
                             new.mx[[3]]), 
                           dim = c(new.X.dim, new.Y.dim, 3))
        
        #swap old image with new image
        seurat.visium@images[[slide]]@image <- new.array
        
        ## step4: change the tissue pixel-spot index
        img.index <- (seurat.visium@images)[[slide]]@coordinates
        
        #swap index
        if(rotation == "Hf"){
            seurat.visium@images[[slide]]@coordinates$imagecol <- img.dim[2]-img.index$imagecol
        }
        
        if(rotation == "Vf"){
            seurat.visium@images[[slide]]@coordinates$imagerow <- img.dim[1]-img.index$imagerow
        }
        
        if(rotation == "180"){
            seurat.visium@images[[slide]]@coordinates$imagerow <- img.dim[1]-img.index$imagerow
            seurat.visium@images[[slide]]@coordinates$imagecol <- img.dim[2]-img.index$imagecol
        }
        
        if(rotation == "L90"){
            seurat.visium@images[[slide]]@coordinates$imagerow <- img.dim[2]-img.index$imagecol
            seurat.visium@images[[slide]]@coordinates$imagecol <- img.index$imagerow
        }
        
        if(rotation == "R90"){
            seurat.visium@images[[slide]]@coordinates$imagerow <- img.index$imagecol
            seurat.visium@images[[slide]]@coordinates$imagecol <- img.dim[1]-img.index$imagerow
        }
        
        return(seurat.visium)
    }  
}


seu.obj <- rotateSeuratImage(seu.obj, rotation = "L90", slide = "Sample_1")

sessionInfo()
R version 4.4.1 (2024-06-14)
Platform: aarch64-apple-darwin20
Running under: macOS Monterey 12.5.1

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: America/New_York
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] dplyr_1.1.4        patchwork_1.2.0    ggplot2_3.5.1      Seurat_5.1.0       SeuratObject_5.0.2
[6] sp_2.1-4          

loaded via a namespace (and not attached):
  [1] deldir_2.0-4           pbapply_1.7-2          gridExtra_2.3          rlang_1.1.4           
  [5] magrittr_2.0.3         RcppAnnoy_0.0.22       matrixStats_1.3.0      ggridges_0.5.6        
  [9] compiler_4.4.1         spatstat.geom_3.3-2    png_0.1-8              vctrs_0.6.5           
 [13] reshape2_1.4.4         stringr_1.5.1          pkgconfig_2.0.3        fastmap_1.2.0         
 [17] utf8_1.2.4             promises_1.3.0         purrr_1.0.2            jsonlite_1.8.8        
 [21] goftest_1.2-3          later_1.3.2            spatstat.utils_3.0-5   irlba_2.3.5.1         
 [25] parallel_4.4.1         cluster_2.1.6          R6_2.5.1               ica_1.0-3             
 [29] stringi_1.8.4          RColorBrewer_1.1-3     spatstat.data_3.1-2    reticulate_1.38.0     
 [33] parallelly_1.37.1      spatstat.univar_3.0-0  lmtest_0.9-40          scattermore_1.2       
 [37] Rcpp_1.0.13            tensor_1.5             future.apply_1.11.2    zoo_1.8-12            
 [41] sctransform_0.4.1      httpuv_1.6.15          Matrix_1.7-0           splines_4.4.1         
 [45] igraph_2.0.3           tidyselect_1.2.1       rstudioapi_0.16.0      abind_1.4-5           
 [49] spatstat.random_3.3-1  codetools_0.2-20       miniUI_0.1.1.1         spatstat.explore_3.3-1
 [53] listenv_0.9.1          lattice_0.22-6         tibble_3.2.1           plyr_1.8.9            
 [57] withr_3.0.0            shiny_1.8.1.1          ROCR_1.0-11            Rtsne_0.17            
 [61] future_1.33.2          fastDummies_1.7.3      survival_3.6-4         polyclip_1.10-7       
 [65] fitdistrplus_1.2-1     pillar_1.9.0           KernSmooth_2.23-24     plotly_4.10.4         
 [69] generics_0.1.3         RcppHNSW_0.6.0         munsell_0.5.1          scales_1.3.0          
 [73] globals_0.16.3         xtable_1.8-4           glue_1.7.0             lazyeval_0.2.2        
 [77] tools_4.4.1            data.table_1.15.4      RSpectra_0.16-2        RANN_2.6.1            
 [81] leiden_0.4.3.1         dotCall64_1.1-1        cowplot_1.1.3          grid_4.4.1            
 [85] tidyr_1.3.1            colorspace_2.1-0       nlme_3.1-164           cli_3.6.3             
 [89] spatstat.sparse_3.1-0  spam_2.10-0            fansi_1.0.6            viridisLite_0.4.2     
 [93] uwot_0.2.2             gtable_0.3.5           digest_0.6.36          progressr_0.14.0      
 [97] ggrepel_0.9.5          htmlwidgets_1.6.4      htmltools_0.5.8.1      lifecycle_1.0.4       
[101] httr_1.4.7             mime_0.12              MASS_7.3-60.2         
@jgaunt264 jgaunt264 added the bug Something isn't working label Sep 27, 2024
@nina-hahn
Copy link

Unfortunately I am facing the same problem.

Best

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants