test_that("resample3D", {
arrayDim <- rev(c(256, 128, 16))
fromArray <- array(rnorm(prod(arrayDim)), rev(arrayDim) + 1)
oldVoxToWorld <- matrix(nrow = 4, byrow = TRUE, c(
1.5, 0, 0.8, -200,
0.01, 0, -1, 10,
0, -0.8, 0.1, 60,
0, 0, 0, 1
))
newVoxToWorld <- matrix(nrow = 4, byrow = TRUE, c(
15, 0, 0.08, -140,
0.1, -0.5, 0, 30,
0, 0.1, 0.1, -13.6,
0, 0, 0, 1
))
# Make sure the resulting data has valid data so this test can be valid
expect_true(all(solve(oldVoxToWorld) %*% newVoxToWorld %*% c(arrayDim / 2,1) > 0))
expect_true(all((solve(oldVoxToWorld) %*% newVoxToWorld %*% c(arrayDim / 2,1))[1:3] < dim(fromArray)))
reList <- resample3D(arrayDim, fromArray, t(newVoxToWorld), t(oldVoxToWorld), na = NA_real_)
# reList[[2]] is the point transform of indexing space from new array to old array
dim(reList[[2]]) <- c(4,4)
mat_actual <- reList[[2]]
mat_expected <- solve(oldVoxToWorld) %*% newVoxToWorld
mat <- mat_actual %*% solve(mat_expected)
diag(mat) <- diag(mat) - 1
# should be about 1e-14, but 1e-5 should be fine
expect_lt(max(abs(mat)), 1e-5)
get_expected_array <- function(na_fill = NA_real_) {
# compare with manual
expected_array <- array(na_fill, arrayDim)
# construct index set in ijk1 format
idx <- t(cbind(arrayInd(seq_len(prod(arrayDim)), arrayDim) - 1, 1))
# calculate index in old array
idx <- round(solve(oldVoxToWorld) %*% newVoxToWorld %*% idx)[1:3, , drop = FALSE]
# remove outofbound indexings
idx[idx < 0 | idx >= dim(fromArray)] <- NA
# get 1-index
idx <- colSums(idx * c(1, cumprod(dim(fromArray)))[1:3]) + 1
expected_array[!is.na(idx)] <- fromArray[idx[!is.na(idx)]]
expected_array
}
expected_array <- get_expected_array(NA_real_)
expect_equal(storage.mode(reList[[1]]), storage.mode(fromArray))
expect_equal(reList[[1]], expected_array)
# check if other formats work too
# integer
fromArray <- fromArray * 10
storage.mode(fromArray) <- "integer"
reList <- resample3D(arrayDim, fromArray, t(newVoxToWorld), t(oldVoxToWorld), na = NA_integer_)
dim(reList[[2]]) <- c(4,4)
expect_equal(reList[[2]], expected = mat_actual)
expect_equal(storage.mode(reList[[1]]), "integer")
expect_equal(reList[[1]], get_expected_array(NA_integer_))
# string
storage.mode(fromArray) <- "character"
reList <- resample3D(arrayDim, fromArray, t(newVoxToWorld), t(oldVoxToWorld), na = NA_character_)
dim(reList[[2]]) <- c(4,4)
expect_equal(reList[[2]], expected = mat_actual)
expect_equal(storage.mode(reList[[1]]), "character")
expect_equal(reList[[1]], get_expected_array(NA_character_))
# complex
storage.mode(fromArray) <- "complex"
reList <- resample3D(arrayDim, fromArray, t(newVoxToWorld), t(oldVoxToWorld), na = NA_complex_)
dim(reList[[2]]) <- c(4,4)
expect_equal(reList[[2]], expected = mat_actual)
expect_equal(storage.mode(reList[[1]]), "complex")
expect_equal(reList[[1]], get_expected_array(NA_complex_))
# raw
fromArray <- array(sample(255, size = length(fromArray), replace = TRUE), dim(fromArray))
storage.mode(fromArray) <- "raw"
reList <- resample3D(arrayDim, fromArray, t(newVoxToWorld), t(oldVoxToWorld), na = as.raw(0))
dim(reList[[2]]) <- c(4,4)
expect_equal(reList[[2]], expected = mat_actual)
expect_equal(storage.mode(reList[[1]]), "raw")
expect_equal(reList[[1]], get_expected_array(as.raw(0)))
# logical
fromArray <- array(sample(c(TRUE, FALSE, NA_integer_), size = length(fromArray), replace = TRUE), dim(fromArray))
storage.mode(fromArray) <- "logical"
reList <- resample3D(arrayDim, fromArray, t(newVoxToWorld), t(oldVoxToWorld), na = as.logical(NA))
dim(reList[[2]]) <- c(4,4)
expect_equal(reList[[2]], expected = mat_actual)
expect_equal(storage.mode(reList[[1]]), "logical")
expect_equal(reList[[1]], get_expected_array(as.logical(NA)))
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.