BIMSBbioinfo / VoltRon

Spatial omic analysis toolbox for multi-resolution and multi-omic integration using image registration
http://bioinformatics.mdc-berlin.de/VoltRon/
Other
41 stars 10 forks source link

importImageData() not found #80

Closed pakiessling closed 8 months ago

pakiessling commented 8 months ago

Hi Artür,

I am having a strange problem where I can't use importImageData()

Error in importImageData(): could not find function "importImageData"

?importImageData shows me the docstring and importXenium works, not sure what is going on.

R version 4.3.2 (2023-10-31)
Platform: x86_64-conda-linux-gnu (64-bit)
Running under: Ubuntu 22.04.3 LTS
VoltRon_1.0.0
Artur-man commented 8 months ago

Dear Paul,

Can you try my personal repo for now, I might not have pushed the latest commits. Otherwise I am gonna correct if there are further issues, test and push!

https://github.com/Artur-man/VoltRon

Best, Artür

pakiessling commented 8 months ago

Hm, same thing happening on that version

Artur-man commented 8 months ago

Needed a quick fix :P seems it was not exported at all, pretty new function. I will test it on the registration workflow now!

Artur-man commented 8 months ago

I just did a quick check and test on this using the image registration workflow too.

It seems the function successfully imports the H&E image (image only, no Visium) and registers it to the DAPI of the Xenium section (same exact section as the H&E).

Fill us in on how it goes with your image :D

# import Xenium
Xen_R1 <- importXenium("Xenium_R1/outs", sample_name = "XeniumR1", 
                       resolution_level = 3, overwrite_resolution = TRUE)

# import H&E image
Xen_R1_image <- importImageData("Xenium_FFPE_Human_Breast_Cancer_Rep1_he_image_highres.tif",
                                sample_name = "XeniumR1image", 
                                image_name = "H&E")

# Registration
xen_reg <- registerSpatialData(object_list = list(Xen_R1, Xen_R1_image))

# add registered H&E image to Xenium section 
Xenium_reg <- xen_reg2$registered_spat[[2]]
vrImages(Xen_R1[["Assay1"]], name = "DAPI", channel = "H&E") <- vrImages(Xenium_reg, name = "H&E_reg")
Screenshot 2024-02-22 at 16 26 03
pakiessling commented 8 months ago

Nice!

I can now load the function, but I receive a new error:

Error in seq.default((tile.size/2) + even_odd_corretion, imageinfo$width, : 'to' must be of length 1
Traceback:

1. importImageData("/home/kuppelab/Documents/ST_align_Spacehack/Spacehack_2023/2021-AKK019_remote.vmic.tiff", 
 .     sample_name = "AKK019", image_name = "H&E")
2. seq((tile.size/2) + even_odd_corretion, imageinfo$width, tile.size)
3. seq.default((tile.size/2) + even_odd_corretion, imageinfo$width, 
 .     tile.size)
4. stop("'to' must be of length 1")

It is a normal RGB TIFF

Any idea?

Artur-man commented 8 months ago

Interesting, this should only happen when the to argument of seq.default is of length not 1 or missing.

if (!missing(to) && length(to) != 1L) 
  stop("'to' must be of length 1")

In this case, there should be a problem with the return value of magick::image_info which should have a width component returning an integer, giving the pixel range of the x-axis of the image for dividing image into tiles

You can do

library(magick)
img <- magick::image_read("/home/kuppelab/Documents/ST_align_Spacehack/Spacehack_2023/2021-AKK019_remote.vmic.tiff")
imageinfo <- magick::image_info(img)

and check if imageinfo has a width column with only one entry. Here, imageinfo should be of a tbl class. Lets check first if the width of the image are parsed successfully using magick.

You can also use

debug(importImageData)

and see what is the value of imageinfo$width as the function is running.

Artur-man commented 8 months ago

Perhaps @pakiessling, magick reads this image as a stacked magick object instead of a single layer?

Hence, importImageData may correct for that to collapse the multi-stack magick to one layer before moving forward.

Although I have never seen such as an example. Would be happy if we can get an example and implement special cases.

pakiessling commented 8 months ago

Hi Artür, here is the output:

A tibble: 8 × 7
format  width   height  colorspace  matte   filesize    density
<chr>   <int>   <int>   <chr>   <lgl>   <int>   <chr>
TIFF64  14848   17408   sRGB    FALSE   305309664   +18035x+18035
TIFF64  7424    8704    sRGB    FALSE   305309664   +18035x+18035
TIFF64  3712    4352    sRGB    FALSE   305309664   +18035x+18035
TIFF64  1856    2176    sRGB    FALSE   305309664   +18035x+18035
TIFF64  928 1088    sRGB    FALSE   305309664   +18035x+18035
TIFF64  464 544 sRGB    FALSE   305309664   +18035x+18035
TIFF64  232 272 sRGB    FALSE   305309664   +18035x+18035
TIFF64  116 136 sRGB    FALSE   305309664   +18035x+18035

Seems to be a pyramidical .tif maybe that is the problem?

Artur-man commented 8 months ago

Ah yes! It doesn't understand now which layer should be used for tiling, and importImageData does not support multiple coordinate systems (for now) so we have to choose which spatial resolution should go through the VoltRon object.

I will take a note here to support images with multiple resolutions. This can essentially be done with other types (ROI, cell, spot and molecule etc.) but not for image only datasets at the moment.

I guess the easiest solution now would be to define an additional argument, say stack.id, to select which spatial resolution should go through formVoltRon.

Will let know if I can complete this today.

pakiessling commented 8 months ago

yeah sure thanks. I can just convert to simple tif for now

Artur-man commented 8 months ago

yeah sure thanks. I can just convert to simple tif for now

Yes that would work too :D

One suggestion would be, if registration needed, to select moderately large resolution (e.g. around 5000 x 5000) or perhaps a resolution similar to the target image for the best performance.