Nothing
# tests/testthat/test-clustered-neurovec.R
library(neuroim2)
test_that("ClusteredNeuroVec: construction, dims, and broadcast are correct", {
# 3D space (2x2x2), mask covers all 8 voxels
sp3 <- NeuroSpace(c(2,2,2), spacing = c(1,1,1))
mask <- LogicalNeuroVol(array(TRUE, dim = c(2,2,2)), sp3)
# Two clusters: first 4 voxels -> 1, next 4 voxels -> 2
cids <- rep(c(1L, 2L), each = 4L)
cvol <- ClusteredNeuroVol(mask, cids)
# 4D source data with T = 3 time points
sp4 <- NeuroSpace(c(2,2,2,3), spacing = c(1,1,1))
arr <- array(NA_real_, dim = c(2,2,2,3))
# Explicit voxel values by time (vectorized in R column-major order)
v_t1 <- c(10,12, 8, 6, 1,3, 5,7) # means: cl1=9, cl2=4
v_t2 <- c(20,18, 22,20, 2,4, 6,8) # means: cl1=20, cl2=5
v_t3 <- c( 0, 0, 0,10, 10,10,10,10) # means: cl1=2.5, cl2=10
arr[,,,1] <- array(v_t1, dim = c(2,2,2))
arr[,,,2] <- array(v_t2, dim = c(2,2,2))
arr[,,,3] <- array(v_t3, dim = c(2,2,2))
vec <- NeuroVec(arr, sp4)
cv <- ClusteredNeuroVec(vec, cvol, FUN = mean)
# 4D dims preserved (3D from mask + time)
expect_equal(dim(cv), c(2,2,2,3))
# Broadcast check at each timepoint: constant within clusters
vol1 <- cv[,,,1]; m1 <- mean(v_t1[1:4]); m2 <- mean(v_t1[5:8])
vol2 <- cv[,,,2]; n1 <- mean(v_t2[1:4]); n2 <- mean(v_t2[5:8])
vol3 <- cv[,,,3]; p1 <- mean(v_t3[1:4]); p2 <- mean(v_t3[5:8])
a1 <- as.vector(vol1); a2 <- as.vector(vol2); a3 <- as.vector(vol3)
expect_true(all(a1[which(cids==1L)] == m1) && all(a1[which(cids==2L)] == m2))
expect_true(all(a2[which(cids==1L)] == n1) && all(a2[which(cids==2L)] == n2))
expect_true(all(a3[which(cids==1L)] == p1) && all(a3[which(cids==2L)] == p2))
})
test_that("ClusteredNeuroVec: cluster-level time-series matrix is correct (T x K)", {
sp3 <- NeuroSpace(c(2,2,2), spacing = c(1,1,1))
mask <- LogicalNeuroVol(array(TRUE, dim = c(2,2,2)), sp3)
cids <- rep(c(1L, 2L), each = 4L)
cvol <- ClusteredNeuroVol(mask, cids)
sp4 <- NeuroSpace(c(2,2,2,3), spacing = c(1,1,1))
arr <- array(NA_real_, dim = c(2,2,2,3))
v_t1 <- c(10,12, 8, 6, 1,3, 5,7) # cl1=9, cl2=4
v_t2 <- c(20,18, 22,20, 2,4, 6,8) # cl1=20, cl2=5
v_t3 <- c( 0, 0, 0,10, 10,10,10,10) # cl1=2.5, cl2=10
arr[,,,1] <- array(v_t1, dim = c(2,2,2))
arr[,,,2] <- array(v_t2, dim = c(2,2,2))
arr[,,,3] <- array(v_t3, dim = c(2,2,2))
vec <- NeuroVec(arr, sp4)
cv <- ClusteredNeuroVec(vec, cvol, FUN = mean)
# Expected T x K matrix
expected <- cbind(
c(mean(v_t1[1:4]), mean(v_t2[1:4]), mean(v_t3[1:4])), # cluster 1
c(mean(v_t1[5:8]), mean(v_t2[5:8]), mean(v_t3[5:8])) # cluster 2
)
expect_equal(cv@ts, expected, tolerance = 1e-10)
})
test_that("ClusteredNeuroVec: voxels in the same cluster match across time", {
sp3 <- NeuroSpace(c(2,2,2), spacing = c(1,1,1))
mask <- LogicalNeuroVol(array(TRUE, dim = c(2,2,2)), sp3)
cids <- rep(c(1L, 2L), each = 4L)
cvol <- ClusteredNeuroVol(mask, cids)
sp4 <- NeuroSpace(c(2,2,2,3), spacing = c(1,1,1))
arr <- array(seq_len(2*2*2*3), dim = c(2,2,2,3)) # arbitrary but deterministic
vec <- NeuroVec(arr, sp4)
cv <- ClusteredNeuroVec(vec, cvol, FUN = mean)
# Two coordinates known to fall in the first 4 linear voxels -> cluster 1
for (tt in 1:3) {
vol <- cv[,,,tt]
expect_equal(vol[1,1,1], vol[2,2,1]) # both in cluster 1 => identical
}
})
test_that("cluster_searchlight_series (k-NN): returns ROIs with correct shapes and seed-first", {
# Make a 2x2x1 lattice with 4 single-voxel clusters at the corners.
sp3 <- NeuroSpace(c(2,2,1), spacing = c(1,1,1))
mask <- LogicalNeuroVol(array(TRUE, dim = c(2,2,1)), sp3)
cids <- as.integer(1:4)
cvol <- ClusteredNeuroVol(mask, cids)
# Build a vec whose voxel series are unique per cluster.
sp4 <- NeuroSpace(c(2,2,1,2), spacing = c(1,1,1))
arr <- array(NA_real_, dim = c(2,2,1,2))
arr[,,,1] <- array(c(10,11,12,13), dim = c(2,2,1)) # t1
arr[,,,2] <- array(c(20,21,22,23), dim = c(2,2,1)) # t2
vec <- NeuroVec(arr, sp4)
cv <- ClusteredNeuroVec(vec, cvol, FUN = mean)
wins <- cluster_searchlight_series(cv, k = 2L) # self + nearest neighbor
expect_length(wins, 4)
# Check first seed window
roi1 <- wins[[1]]
expect_true(inherits(roi1, "ROIVec"))
V <- values(roi1) # (time) x (#neighbors)
expect_equal(dim(V), c(2, 2)) # 2 timepoints, 2 neighbors
expect_equal(V[,1], c(10, 20)) # seed (self) first column equals cluster-1 series
})
test_that("cluster_searchlight_series (radius): selects by centroid distance", {
# Same 2x2x1 four-cluster setup as above
sp3 <- NeuroSpace(c(2,2,1), spacing = c(1,1,1))
mask <- LogicalNeuroVol(array(TRUE, dim = c(2,2,1)), sp3)
cids <- as.integer(1:4)
cvol <- ClusteredNeuroVol(mask, cids)
sp4 <- NeuroSpace(c(2,2,1,2), spacing = c(1,1,1))
arr <- array(NA_real_, dim = c(2,2,1,2))
arr[,,,1] <- array(c(10,11,12,13), dim = c(2,2,1))
arr[,,,2] <- array(c(20,21,22,23), dim = c(2,2,1))
vec <- NeuroVec(arr, sp4)
cv <- ClusteredNeuroVec(vec, cvol, FUN = mean)
# Centroids are at (1,1,1),(2,1,1),(1,2,1),(2,2,1)
# With radius=1.1 from seed (1,1,1), we include self + two orthogonal neighbors (distance 1)
winsr <- cluster_searchlight_series(cv, radius = 1.1)
roi1 <- winsr[[1]]
V1 <- values(roi1)
expect_true(inherits(roi1, "ROIVec"))
expect_equal(nrow(V1), 2) # time = 2
expect_equal(ncol(V1), 3) # self + two neighbors (exclude diagonal at ~1.414)
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.