drieslab / Giotto

Spatial omics analysis toolbox
https://drieslab.github.io/Giotto_website/
Other
240 stars 94 forks source link

Applying ext and spatShift tranformations on gobj #945

Closed rbutleriii closed 1 month ago

rbutleriii commented 2 months ago

Is there a way to apply the spatial transformations to the entire giotto object, including the images?

I am joining multiple gobjs via joinGiottoObjects shift method, each with several fovs. However each has global coordinates from it's own original slide. image

I would like to align them each to xmin = 0, ymin = 0 before joining them. Something like this:

# Load slide objects squares ----------------------------------------
my_slides <- unlist(strsplit(slides, ","))
gobjs <- lapply(my_slides, function(i){
  print(sprintf("Loading %s giotto object...", i))
  loadGiotto(file.path(data_path, paste(i, group, "giotto_obj", sep=".")))
})

# shift each slide to the bottom-left most global coords (0,0) prior to merging
gobjs <- lapply(gobjs, function(i) {
  coords <- ext(i)
  spatShift(i, dx = -coords$xmin, dy = -coords$ymin)
})

# merge the slides 
gobj <- joinGiottoObjects(
  gobjs,
  gobject_names = my_slides,
  join_method = "shift",
  x_shift = NULL,
  y_shift = NULL,
  x_padding = 0,
  y_padding = NULL,
  verbose = TRUE
)

That presents two problems: (1) figuring out the absolute bounds of all parts and (2) applying to all parts.

For the first, ext does not apply to a gobj:

library(Giotto)
library(GiottoData)

viz <- loadGiottoMini(dataset = 'vizgen')
activeSpatUnit(viz) <- 'aggregate'

> ext(viz)
Error in (function (classes, fdef, mtable)  :
  unable to find an inherited method for function ‘ext’ for signature ‘"giotto"’

It would appear that I would have to call it on all images, spat_locs, spatNetwork, feature_info, and all polygon types and find the absolute xmin and ymin?

For the second, spatShift does appear to apply to a gobj, and seems to shift everything but the images. So for that do I basically have to modify the ext for each image after the initial? I was trying unsuccessfully to apply that with set.ext, but the way it works is counterintuitive to say the least

library(Giotto)
library(GiottoData)

go <- loadGiottoMini(dataset = 'cosmx')

go <- spatShift(go, dx = 0, dy = 150000)
lapply(names(go@images), function(i) {
  img <- getGiottoImage(go, image_type = 'image', name = i)
  e <- ext(img)
  e <- e + c(-0, 0, -150000, 150000) # I do not understand why it subtracts from ymin instead of adding
  terra::set.ext(img, e) # this fails unable to find an inherited method for function ‘set.ext’ for signature ‘"giottoImage"’
  setGiottoImage(go, 
    image = img, 
    image_type = 'image', 
    name = i
  )
})
# now the same for largeImages
jiajic commented 1 month ago

Hi @rbutleriii,

These functionalities should have just been added in GiottoClass 0.3.0

For the behavior of the SpatExtent object, we import this functionality from terra. Numeric additions to a SpatExtent will expand one of the bounds, which is why you needed to apply negative values in order perform a shift.

Best, George

rbutleriii commented 1 month ago

Looks good:

library(Giotto)
library(GiottoData)

go <- loadGiottoMini(dataset = 'cosmx')
go <- spatShift(go, dx = 60000, dy = 150000)
go2 <- loadGiottoMini(dataset = 'cosmx')
my_slides <- c("go", "go2")
gobjs <- list(go, go2)

# merge the slides 
gobj <- joinGiottoObjects(
  gobjs,
  gobject_names = my_slides,
  join_method = "shift",
  x_shift = NULL,
  y_shift = NULL,
  x_padding = 0,
  y_padding = NULL,
  verbose = TRUE
)

# plot merged obj
img_list = grep("*-composite", names(gobj@images), value = TRUE)

gobj %>%
  spatPlot2D(
    point_size = 2,
    point_alpha = 0.5,
    show_image = TRUE,
    image_name = img_list,
    return_plot = FALSE,
    show_plot = TRUE
  )

image

# shift each slide to the bottom-left most global coords (0,0) prior to merging
gobjs <- lapply(gobjs, function(i) {
  coords <- ext(i)
  spatShift(i, dx = -coords$xmin, dy = -coords$ymin)
})

# merge the slides 
gobj <- joinGiottoObjects(
  gobjs,
  gobject_names = my_slides,
  join_method = "shift",
  x_shift = NULL,
  y_shift = NULL,
  x_padding = 0,
  y_padding = NULL,
  verbose = TRUE
)

gobj %>%
  spatPlot2D(
    point_size = 2,
    point_alpha = 0.5,
    show_image = TRUE,
    image_name = img_list,
    return_plot = FALSE,
    show_plot = TRUE
  )

image