Skip to content

Commit

Permalink
Unwrap SpatRaster images in imgRaster
Browse files Browse the repository at this point in the history
  • Loading branch information
lambdamoses committed Aug 17, 2023
1 parent 22a0c24 commit a7280c6
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 38 deletions.
6 changes: 3 additions & 3 deletions R/geometry_operation.R
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ setMethod("bbox", "SpatialFeatureExperiment", function(sfe, sample_id = NULL) {
if (nrow(imgData(sfe))) {
inds <- imgData(sfe)$sample_id == sample_id
new_imgs <- lapply(imgData(sfe)$data[inds], function(img) {
img_new <- img_fun(img@image, ...)
img_new <- img_fun(imgRaster(img), ...)
if (shift_img)
img_new <- terra::shift(img_new, dx = add[1], dy = add[2])
new("SpatRasterImage", image = img_new)
Expand Down Expand Up @@ -536,7 +536,7 @@ transpose <- function(sfe, sample_id = "all") {
m <- matrix(c(0,-1,-1,0), ncol = 2)
bboxes <- lapply(sample_id, function(s) {
# Assume that all images of the same sample have the same extent
img <- imgData(sfe)$data[[which(imgData(sfe)$sample_id == s)[1]]]@image
img <- imgRaster(imgData(sfe)$data[[which(imgData(sfe)$sample_id == s)[1]]])
as.vector(ext(img))
})
bboxes <- do.call(cbind, bboxes)
Expand Down Expand Up @@ -571,7 +571,7 @@ mirror <- function(sfe, sample_id = "all",
if (nrow(imgData(sfe))) {
bboxes <- lapply(sample_id, function(s) {
# Assume that all images of the same sample have the same extent
img <- imgData(sfe)$data[[which(imgData(sfe)$sample_id == s)[1]]]@image
img <- imgRaster(imgData(sfe)$data[[which(imgData(sfe)$sample_id == s)[1]]])
as.vector(ext(img))
})
bboxes <- do.call(cbind, bboxes)
Expand Down
14 changes: 9 additions & 5 deletions R/image.R
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,15 @@ setMethod("addImg", "SpatialFeatureExperiment",
#' @export
setMethod("transposeImg", "SpatRasterImage",
function(x) {
x@image <- terra::trans(x@image)
x@image <- terra::trans(imgRaster(x))
x
})

#' @rdname SFE-image
#' @export
setMethod("mirrorImg", "SpatRasterImage",
function(x, direction = "vertical") {
x@image <- terra::flip(x@image, direction = direction)
x@image <- terra::flip(imgRaster(x), direction = direction)
x
})

Expand Down Expand Up @@ -175,14 +175,18 @@ setMethod("mirrorImg", "SpatialFeatureExperiment",

#' @rdname SFE-image
#' @export
setMethod("imgRaster", "SpatRasterImage", function(x) x@image)
setMethod("imgRaster", "SpatRasterImage", function(x) {
if (is(x@image, "PackedSpatRaster")) unwrap(x@image)
else x@image
})

#' @rdname SFE-image
#' @export
#' @importFrom terra sources
setMethod("imgSource",
"SpatRasterImage",
function(x) {
NA_character_
sources(imgRaster(x))
})

.crop_imgs <- function(x, bboxes) {
Expand All @@ -197,7 +201,7 @@ setMethod("imgSource",
img_data <- imgData(x)$data[imgData(x)$sample_id == s]
bbox_use <- ext(bboxes[c("xmin", "xmax", "ymin", "ymax"),s])
lapply(img_data, function(img) {
new("SpatRasterImage", image = terra::crop(img@image, bbox_use, snap = "out"))
new("SpatRasterImage", image = terra::crop(imgRaster(img), bbox_use, snap = "out"))
})
})
new_imgs <- unlist(new_imgs, recursive = FALSE)
Expand Down
3 changes: 1 addition & 2 deletions R/saveRDS.R
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@ setMethod("saveRDS", "SpatialFeatureExperiment",
else {
for (i in seq_len(nrow(imgData(object)))) {
img <- int_metadata(object)$imgData$data[[i]]
if (is(imgRaster(img), "SpatRaster"))
if (is(img@image, "SpatRaster"))
img@image <- wrap(img@image)
int_metadata(object)$imgData$data[[i]] <- img
# Then I need to add unwrap to functions that use the image
}
base::saveRDS(object, file = file, ascii = ascii,
version = version, compress = compress,
Expand Down
4 changes: 2 additions & 2 deletions tests/testthat/test-coerce.R
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ test_that("Convert SPE to SFE, loaded images", {
expect_equal(v1, v2)

bbox <- st_bbox(centroids(sfe))
bbox_img <- as.vector(ext(img2@image)) # That the image is properly scaled
bbox_img <- as.vector(ext(imgRaster(img2))) # That the image is properly scaled
diffs1 <- bbox[3:4] - bbox[1:2]
diffs2 <- bbox_img[c(2,4)] - bbox_img[c(1,3)]
expect_true(all(diffs1 / diffs2 > (1-1/min(dim(img1)))))
Expand All @@ -64,7 +64,7 @@ test_that("Convert SPE to SFE, stored images", {
expect_equal(v1, v2)

bbox <- st_bbox(centroids(sfe))
bbox_img <- as.vector(ext(img2@image))
bbox_img <- as.vector(ext(imgRaster(img2)))
diffs1 <- bbox[3:4] - bbox[1:2]
diffs2 <- bbox_img[c(2,4)] - bbox_img[c(1,3)]
expect_true(all(diffs1 / diffs2 > (1-1/min(dim(img1)))))
Expand Down
12 changes: 6 additions & 6 deletions tests/testthat/test-geometry_operation.R
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ sfe <- read10xVisiumSFE("ob")
test_that("Image is shifted after removing empty space", {
sfe2 <- removeEmptySpace(sfe)
cg <- df2sf(spatialCoords(sfe2), spatialCoordsNames(sfe2))
img <- getImg(sfe2)@image
img <- imgRaster(getImg(sfe2))
v <- terra::extract(terra::mean(img), cg)
nCounts <- Matrix::colSums(counts(sfe2))
expect_true(abs(cor(nCounts, v$mean)) > 0.4)
Expand All @@ -306,7 +306,7 @@ test_that("Image is cropped after cropping SFE object", {
st_bbox() |> st_as_sfc()
sfe2 <- SpatialFeatureExperiment::crop(sfe, bbox_use)
cg <- df2sf(spatialCoords(sfe2), spatialCoordsNames(sfe2))
img <- getImg(sfe2)@image
img <- imgRaster(getImg(sfe2))
v <- terra::extract(terra::mean(img), cg)
nCounts <- Matrix::colSums(counts(sfe2))
expect_true(abs(cor(nCounts, v$mean, use = "complete.obs")) > 0.4)
Expand All @@ -319,7 +319,7 @@ test_that("Image is cropped after cropping SFE object", {
test_that("Transpose SFE object with image", {
sfe2 <- transpose(sfe)
cg <- df2sf(spatialCoords(sfe2), spatialCoordsNames(sfe2))
img <- getImg(sfe2)@image
img <- imgRaster(getImg(sfe2))
v <- terra::extract(terra::mean(img), cg)
nCounts <- Matrix::colSums(counts(sfe2))
expect_true(abs(cor(nCounts, v$mean)) > 0.4)
Expand All @@ -332,7 +332,7 @@ test_that("Transpose SFE object with image, after cropping image", {
sfe <- sfe[,sfe$in_tissue]
sfe2 <- transpose(sfe)
cg <- df2sf(spatialCoords(sfe2), spatialCoordsNames(sfe2))
img <- getImg(sfe2)@image
img <- imgRaster(getImg(sfe2))
v <- terra::extract(terra::mean(img), cg)
nCounts <- Matrix::colSums(counts(sfe2))
expect_true(abs(cor(nCounts, v$mean)) > 0.4)
Expand All @@ -344,7 +344,7 @@ test_that("Transpose SFE object with image, after cropping image", {
test_that("Mirror SFE object with image, vertical", {
sfe2 <- mirror(sfe, direction = "vertical")
cg <- df2sf(spatialCoords(sfe2), spatialCoordsNames(sfe2))
img <- getImg(sfe2)@image
img <- imgRaster(getImg(sfe2))
v <- terra::extract(terra::mean(img), cg)
nCounts <- Matrix::colSums(counts(sfe2))
expect_true(abs(cor(nCounts, v$mean)) > 0.4)
Expand All @@ -356,7 +356,7 @@ test_that("Mirror SFE object with image, vertical", {
test_that("Mirror SFE object with image, horizontal", {
sfe2 <- mirror(sfe, direction = "horizontal")
cg <- df2sf(spatialCoords(sfe2), spatialCoordsNames(sfe2))
img <- getImg(sfe2)@image
img <- imgRaster(getImg(sfe2))
v <- terra::extract(terra::mean(img), cg)
nCounts <- Matrix::colSums(counts(sfe2))
expect_true(abs(cor(nCounts, v$mean)) > 0.4)
Expand Down
20 changes: 14 additions & 6 deletions tests/testthat/test-image.R
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ test_that("transposeImg", {
# SpatRasterImage method
img_t <- transposeImg(img)
expect_s4_class(img_t, "SpatRasterImage")
expect_equal(dim(img@image)[1:2], dim(img_t@image)[2:1])
expect_equal(dim(imgRaster(img))[1:2], dim(imgRaster(img_t))[2:1])
# SFE method
sfe <- transposeImg(sfe, sample_id = "Vis5A", image_id = "lowres")
img_t2 <- getImg(sfe, sample_id = "Vis5A", image_id = "lowres")
expect_equal(dim(img@image)[1:2], dim(img_t2@image)[2:1])
expect_equal(dim(imgRaster(img))[1:2], dim(imgRaster(img_t2))[2:1])
})

test_that("mirrorImg", {
Expand All @@ -44,14 +44,14 @@ test_that("mirrorImg", {
img <- getImg(sfe)
# SpatRasterImage method
img_m <- mirrorImg(img)
mat1 <- terra::as.array(terra::mean(img@image))[,,1]
mat2 <- terra::as.array(terra::mean(img_m@image))[,,1]
mat1 <- terra::as.array(terra::mean(imgRaster(img)))[,,1]
mat2 <- terra::as.array(terra::mean(imgRaster(img_m)))[,,1]
mat2_rev <- apply(mat2, 2, rev)
expect_equal(mat1, mat2_rev)
# SFE method
sfe <- mirrorImg(sfe, sample_id = "Vis5A", image_id = "lowres")
img_m2 <- getImg(sfe)
mat3 <- terra::as.array(terra::mean(img_m2@image))[,,1]
mat3 <- terra::as.array(terra::mean(imgRaster(img_m2)))[,,1]
mat3_rev <- apply(mat3, 2, rev)
expect_equal(mat1, mat3_rev)
})
Expand All @@ -63,6 +63,14 @@ test_that("imgRaster, trivial", {
expect_s4_class(img, "SpatRaster")
})

test_that("imgRaster, loaded from RDS", {
saveRDS(sfe, "baz.rds")
sfe_read <- readRDS("baz.rds")
img <- imgRaster(getImg(sfe))
expect_s4_class(img, "SpatRaster")
unlink("baz.rds")
})

test_that("imgSource, trivial", {
expect_true(is.na(imgSource(getImg(sfe))))
expect_type(imgSource(getImg(sfe)), "character")
})
20 changes: 10 additions & 10 deletions tests/testthat/test-read.R
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@ test_that("Image is properly aligned in pixel space", {
cg <- spotPoly(sfe)
cg$nCounts <- Matrix::colSums(counts(sfe))
cg$geometry <- st_centroid(cg$geometry)
img_lo <- getImg(sfe, image_id = "lowres")@image
img_lo <- getImg(sfe, image_id = "lowres") |> imgRaster()
img_lo <- terra::mean(img_lo)
v_lo <- terra::extract(img_lo, cg)
# This test only works for this tissue for filtered data
expect_true(abs(cor(cg$nCounts, v_lo$mean)) > 0.4)
img_hi <- getImg(sfe, image_id = "hires")@image
img_hi <- getImg(sfe, image_id = "hires") |> imgRaster()
img_hi <- terra::mean(img_hi)
v_hi <- terra::extract(img_hi, cg)
expect_true(abs(cor(cg$nCounts, v_hi$mean)) > 0.4)
Expand All @@ -108,11 +108,11 @@ test_that("Image is properly aligned in micron space", {
cg <- spotPoly(sfe)
cg$nCounts <- Matrix::colSums(counts(sfe))
cg$geometry <- st_centroid(cg$geometry)
img_lo <- getImg(sfe, image_id = "lowres")@image
img_lo <- getImg(sfe, image_id = "lowres") |> imgRaster()
img_lo <- terra::mean(img_lo)
v_lo <- terra::extract(img_lo, cg)
expect_true(abs(cor(cg$nCounts, v_lo$mean)) > 0.4)
img_hi <- getImg(sfe, image_id = "hires")@image
img_hi <- getImg(sfe, image_id = "hires") |> imgRaster()
img_hi <- terra::mean(img_hi)
v_hi <- terra::extract(img_hi, cg)
expect_true(abs(cor(cg$nCounts, v_hi$mean)) > 0.4)
Expand Down Expand Up @@ -142,7 +142,7 @@ test_that("readVizgen flip geometry, use cellpose", {
flip = "geometry", min_area = 15)
expect_equal(unit(sfe), "micron")
expect_equal(imgData(sfe)$image_id, "PolyT")
img <- getImg(sfe)@image
img <- imgRaster(getImg(sfe))
cg <- SpatialFeatureExperiment::centroids(sfe)
v <- terra::extract(img, cg)
nCounts <- Matrix::colSums(counts(sfe))
Expand All @@ -162,7 +162,7 @@ test_that("readVizgen flip geometry, don't use cellpose", {
sfe <- readVizgen(dir_use, z = 0L, use_cellpose = FALSE, image = "PolyT",
flip = "geometry")
expect_equal(unit(sfe), "micron")
img <- getImg(sfe)@image
img <- imgRaster(getImg(sfe))
cg <- SpatialFeatureExperiment::centroids(sfe)
v <- terra::extract(img, cg)
nCounts <- Matrix::colSums(counts(sfe))
Expand All @@ -177,7 +177,7 @@ test_that("readVizgen flip image", {
sfe <- readVizgen(dir_use, z = 0L, use_cellpose = TRUE, image = "PolyT",
flip = "image")
expect_equal(unit(sfe), "micron")
img <- getImg(sfe)@image
img <- imgRaster(getImg(sfe))
cg <- SpatialFeatureExperiment::centroids(sfe)
v <- terra::extract(img, cg)
nCounts <- Matrix::colSums(counts(sfe))
Expand All @@ -191,7 +191,7 @@ test_that("readVizgen don't flip image when image is too large", {
sfe <- readVizgen(dir_use, z = 0L, use_cellpose = TRUE, image = "PolyT",
flip = "image", max_flip = "0.02 MB")
suppressWarnings(img_orig <- rast(file.path(dir_use, "images", "mosaic_PolyT_z0.tif")))
img <- getImg(sfe)@image
img <- imgRaster(getImg(sfe))
# Make sure image was not flipped
expect_equal(terra::values(img), terra::values(img_orig))
cg <- SpatialFeatureExperiment::centroids(sfe)
Expand All @@ -203,12 +203,12 @@ test_that("readVizgen don't flip image when image is too large", {
test_that("Don't flip image if it's GeoTIFF", {
sfe <- readVizgen(dir_use, z = 0L, use_cellpose = TRUE, image = "PolyT",
flip = "image")
terra::writeRaster(getImg(sfe)@image,
terra::writeRaster(imgRaster(getImg(sfe)),
filename = file.path("vizgen", "images", "mosaic_DAPI_z0.tif"),
overwrite = TRUE)
sfe2 <- readVizgen(dir_use, z = 0L, use_cellpose = TRUE, image = "DAPI",
flip = "image")
expect_equal(terra::values(getImg(sfe)@image), terra::values(getImg(sfe2)@image))
expect_equal(terra::values(imgRaster(getImg(sfe))), terra::values(imgRaster(getImg(sfe2))))
file.remove(file.path("vizgen", "images", "mosaic_DAPI_z0.tif"))
})

Expand Down
2 changes: 1 addition & 1 deletion tests/testthat/test-saveRDS.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ test_that("Save SFE with SpatRaster images as RDS", {
saveRDS(sfe, "foo.rds")
sfe2 <- readRDS("foo.rds")
imgs <- imgData(sfe2)$data
classes <- vapply(imgs, function(x) class(imgRaster(x)), FUN.VALUE = character(1))
classes <- vapply(imgs, function(x) class(x@image), FUN.VALUE = character(1))
expect_true(all(classes == "PackedSpatRaster"))
expect_s4_class(sfe2, "SpatialFeatureExperiment")
unlink("foo.rds")
Expand Down
6 changes: 3 additions & 3 deletions tests/testthat/test-subset.R
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,13 @@ test_that("Images are cropped after subsetting, multiple samples", {
cg <- st_centroid(spotPoly(sfe3, sample_id = "all"))
nCounts <- Matrix::colSums(counts(sfe3))
# For sample 1
img1 <- getImg(sfe3, sample_id = "ob")@image
img1 <- getImg(sfe3, sample_id = "ob") |> imgRaster()
bbox_geom <- st_bbox(spotPoly(sfe3, "ob")) |> st_as_sfc()
bbox_img <- as.vector(ext(img1)) |> st_bbox() |> st_as_sfc()
expect_true(st_covered_by(bbox_geom, bbox_img, sparse = FALSE))

# For sample 2
img2 <- getImg(sfe3, sample_id = "kidney")@image
img2 <- getImg(sfe3, sample_id = "kidney") |> imgRaster()
bbox_geom <- st_bbox(spotPoly(sfe3, "kidney")) |> st_as_sfc()
bbox_img <- as.vector(ext(img2)) |> st_bbox() |> st_as_sfc()
expect_true(st_covered_by(bbox_geom, bbox_img, sparse = FALSE))
Expand Down

0 comments on commit a7280c6

Please sign in to comment.