diff --git a/R/geometry_operation.R b/R/geometry_operation.R index c68421e..af65c1e 100644 --- a/R/geometry_operation.R +++ b/R/geometry_operation.R @@ -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) @@ -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) @@ -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) diff --git a/R/image.R b/R/image.R index 7c0c8a9..7f77769 100644 --- a/R/image.R +++ b/R/image.R @@ -133,7 +133,7 @@ setMethod("addImg", "SpatialFeatureExperiment", #' @export setMethod("transposeImg", "SpatRasterImage", function(x) { - x@image <- terra::trans(x@image) + x@image <- terra::trans(imgRaster(x)) x }) @@ -141,7 +141,7 @@ setMethod("transposeImg", "SpatRasterImage", #' @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 }) @@ -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) { @@ -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) diff --git a/R/saveRDS.R b/R/saveRDS.R index 2d6971a..4a73c1b 100644 --- a/R/saveRDS.R +++ b/R/saveRDS.R @@ -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, diff --git a/tests/testthat/test-coerce.R b/tests/testthat/test-coerce.R index 7a9b48a..c5f563b 100644 --- a/tests/testthat/test-coerce.R +++ b/tests/testthat/test-coerce.R @@ -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))))) @@ -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))))) diff --git a/tests/testthat/test-geometry_operation.R b/tests/testthat/test-geometry_operation.R index 8b09486..01bd32a 100644 --- a/tests/testthat/test-geometry_operation.R +++ b/tests/testthat/test-geometry_operation.R @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) diff --git a/tests/testthat/test-image.R b/tests/testthat/test-image.R index 63627cd..21ef203 100644 --- a/tests/testthat/test-image.R +++ b/tests/testthat/test-image.R @@ -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", { @@ -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) }) @@ -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") }) diff --git a/tests/testthat/test-read.R b/tests/testthat/test-read.R index e50aa67..398a93a 100644 --- a/tests/testthat/test-read.R +++ b/tests/testthat/test-read.R @@ -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) @@ -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) @@ -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)) @@ -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)) @@ -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)) @@ -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) @@ -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")) }) diff --git a/tests/testthat/test-saveRDS.R b/tests/testthat/test-saveRDS.R index 0a8315f..7d39cb8 100644 --- a/tests/testthat/test-saveRDS.R +++ b/tests/testthat/test-saveRDS.R @@ -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") diff --git a/tests/testthat/test-subset.R b/tests/testthat/test-subset.R index 504ec35..5252124 100644 --- a/tests/testthat/test-subset.R +++ b/tests/testthat/test-subset.R @@ -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))