Skip to content

Commit

Permalink
Fix zero-element bugs. Add tests. Use file.path in more places.
Browse files Browse the repository at this point in the history
  • Loading branch information
keller-mark committed Jun 18, 2024
1 parent 5327c81 commit a39df6a
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 71 deletions.
39 changes: 21 additions & 18 deletions R/array-nested.R
Original file line number Diff line number Diff line change
Expand Up @@ -239,24 +239,27 @@ NestedArray <- R6::R6Class("NestedArray",
message(value)
stop("Got unexpected type for value in NestedArray$set()")
}

# Cannot figure out how to dynamically set values in an array
# of arbitrary dimensions.
# Tried: abind::afill <- but it doesn't seem to work with arbitrary dims or do.call
if(length(selection_list) == 1) {
self$data[selection_list[[1]]] <- value_data
} else if(length(selection_list) == 2) {
self$data[selection_list[[1]], selection_list[[2]]] <- value_data
} else if(length(selection_list) == 3) {
self$data[selection_list[[1]], selection_list[[2]], selection_list[[3]]] <- value_data
} else if(length(selection_list) == 4) {
self$data[selection_list[[1]], selection_list[[2]], selection_list[[3]], selection_list[[4]]] <- value_data
} else if(length(selection_list) == 5) {
self$data[selection_list[[1]], selection_list[[2]], selection_list[[3]], selection_list[[4]], selection_list[[5]]] <- value_data
} else if(length(selection_list) == 6) {
self$data[selection_list[[1]], selection_list[[2]], selection_list[[3]], selection_list[[4]], selection_list[[5]], selection_list[[6]]] <- value_data
} else {
stop("NestedArray$set() can only handle up to 6D arrays at the moment. Please make a feature request if you need to handle more dims.")

# Only set values if the array is not meant to be empty.
if(sum(length(value_data)) > 0 || sum(dim(value_data)) > 0) {
# Cannot figure out how to dynamically set values in an array
# of arbitrary dimensions.
# Tried: abind::afill <- but it doesn't seem to work with arbitrary dims or do.call
if(length(selection_list) == 1) {
self$data[selection_list[[1]]] <- value_data
} else if(length(selection_list) == 2) {
self$data[selection_list[[1]], selection_list[[2]]] <- value_data
} else if(length(selection_list) == 3) {
self$data[selection_list[[1]], selection_list[[2]], selection_list[[3]]] <- value_data
} else if(length(selection_list) == 4) {
self$data[selection_list[[1]], selection_list[[2]], selection_list[[3]], selection_list[[4]]] <- value_data
} else if(length(selection_list) == 5) {
self$data[selection_list[[1]], selection_list[[2]], selection_list[[3]], selection_list[[4]], selection_list[[5]]] <- value_data
} else if(length(selection_list) == 6) {
self$data[selection_list[[1]], selection_list[[2]], selection_list[[3]], selection_list[[4]], selection_list[[5]], selection_list[[6]]] <- value_data
} else {
stop("NestedArray$set() can only handle up to 6D arrays at the moment. Please make a feature request if you need to handle more dims.")
}
}
},
#' @description
Expand Down
2 changes: 1 addition & 1 deletion R/slicing.R
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ slice <- function(start, stop = NA, step = NA, zero_based = FALSE) {
))
}

#' Convenience function for the internal Sliceclass constructor
#' Convenience function for the internal Slice class constructor
#' with zero-based indexing and exclusive stop index.
#' @param start The start index.
#' @param stop The stop index.
Expand Down
46 changes: 24 additions & 22 deletions R/zarr-array.R
Original file line number Diff line number Diff line change
Expand Up @@ -420,30 +420,32 @@ ZarrArray <- R6::R6Class("ZarrArray",

selection_shape <- indexer$shape
selection_shape_vec <- ensure_integer_vec(indexer$shape)

# Check value shape
if (length(selection_shape) == 0) {
# Setting a single value
} else if (is_scalar(value)) {
# Setting a scalar value
} else if("array" %in% class(value)) {
if (!all(ensure_integer_vec(dim(value)) == selection_shape_vec)) {
stop("Shape mismatch in source array and set selection: ${dim(value)} and ${selectionShape}")
}
value <- NestedArray$new(value, shape = selection_shape_vec, dtype=private$dtype, order = private$order)
} else if ("NestedArray" %in% class(value)) {
if (!all(ensure_integer_vec(value$shape) == selection_shape_vec)) {
stop("Shape mismatch in source NestedArray and set selection: ${value.shape} and ${selectionShape}")

if(sum(as.numeric(selection_shape)) > 0) {
# Check value shape
if (length(selection_shape) == 0) {
# Setting a single value
} else if (is_scalar(value)) {
# Setting a scalar value
} else if("array" %in% class(value)) {
if (!all(ensure_integer_vec(dim(value)) == selection_shape_vec)) {
stop("Shape mismatch in source array and set selection: ${dim(value)} and ${selectionShape}")
}
value <- NestedArray$new(value, shape = selection_shape_vec, dtype=private$dtype, order = private$order)
} else if ("NestedArray" %in% class(value)) {
if (!all(ensure_integer_vec(value$shape) == selection_shape_vec)) {
stop("Shape mismatch in source NestedArray and set selection: ${value.shape} and ${selectionShape}")
}
} else {
# // TODO(zarr.js) support TypedArrays, buffers, etc
stop("Unknown data type for setting :(")
}
} else {
# // TODO(zarr.js) support TypedArrays, buffers, etc
stop("Unknown data type for setting :(")
}

# TODO: use queue to handle async iterator
for (proj in indexer$iter()) {
chunk_value <- private$get_chunk_value(proj, indexer, value, selection_shape)
private$chunk_setitem(proj$chunk_coords, proj$chunk_sel, chunk_value)
# TODO: use queue to handle async iterator
for (proj in indexer$iter()) {
chunk_value <- private$get_chunk_value(proj, indexer, value, selection_shape)
private$chunk_setitem(proj$chunk_coords, proj$chunk_sel, chunk_value)
}
}
},
#' @description
Expand Down
94 changes: 67 additions & 27 deletions tests/testthat/test-compat.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ test_that("Can open Zarr group using convenience function", {

test_that("Can open Zarr group or array using convenience function", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))
g <- zarr_open(root)
a <- zarr_open(root, path="1d.contiguous.lz4.i2")

Expand All @@ -22,7 +22,7 @@ test_that("Can open Zarr group or array using convenience function", {

test_that("Can open Zarr group and read a 1D 2-byte integer array with LZ4 compression", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -41,7 +41,7 @@ test_that("Can open Zarr group and read a 1D 2-byte integer array with LZ4 compr

test_that("Can open Zarr group and read a 1D 2-byte integer array with Zstd compression", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -60,7 +60,7 @@ test_that("Can open Zarr group and read a 1D 2-byte integer array with Zstd comp

test_that("Can open Zarr group and read a 1D 2-byte integer array with Blosc compression", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand Down Expand Up @@ -88,7 +88,7 @@ test_that("Can open Zarr group and read a 1D 2-byte integer array with Blosc com

test_that("Can open Zarr group and read a 1D 2-byte integer array with Zlib compression", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -107,7 +107,7 @@ test_that("Can open Zarr group and read a 1D 2-byte integer array with Zlib comp

test_that("Can open Zarr group and read a 1D 2-byte integer array with no compression", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -126,7 +126,7 @@ test_that("Can open Zarr group and read a 1D 2-byte integer array with no compre

test_that("Can open Zarr group and read a 1D 4-byte integer array", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -143,7 +143,7 @@ test_that("Can open Zarr group and read a 1D 4-byte integer array", {

test_that("Can open Zarr group and read a 1D 1-byte unsigned integer array", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -160,7 +160,7 @@ test_that("Can open Zarr group and read a 1D 1-byte unsigned integer array", {

test_that("Can open Zarr group and read a 1D 4-byte float array, little endian", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -177,7 +177,7 @@ test_that("Can open Zarr group and read a 1D 4-byte float array, little endian",

test_that("Can open Zarr group and read a 1D 4-byte float array, big endian", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -194,7 +194,7 @@ test_that("Can open Zarr group and read a 1D 4-byte float array, big endian", {

test_that("Can open Zarr group and read a 1D 8-byte float array", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -211,7 +211,7 @@ test_that("Can open Zarr group and read a 1D 8-byte float array", {

test_that("Can open Zarr group and read a 1D 2-byte float array, 2 chunks", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -228,7 +228,7 @@ test_that("Can open Zarr group and read a 1D 2-byte float array, 2 chunks", {

test_that("Can open Zarr group and read a 1D 2-byte float array, 2 chunks, ragged", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -245,7 +245,7 @@ test_that("Can open Zarr group and read a 1D 2-byte float array, 2 chunks, ragge

test_that("Can open Zarr group and read a 2D 2-byte integer array", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -263,7 +263,7 @@ test_that("Can open Zarr group and read a 2D 2-byte integer array", {

test_that("Can open Zarr group and read a 2D 2-byte integer array, 2 chunks", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -281,7 +281,7 @@ test_that("Can open Zarr group and read a 2D 2-byte integer array, 2 chunks", {

test_that("Can open Zarr group and read a 2D 2-byte integer array, 2 chunks, ragged", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -301,7 +301,7 @@ test_that("Can open Zarr group and read a 2D 2-byte integer array, 2 chunks, rag

test_that("Can open Zarr group and read a 1D 1-byte boolean array", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -318,7 +318,7 @@ test_that("Can open Zarr group and read a 1D 1-byte boolean array", {

test_that("Can open Zarr group and read a 1D S7 string array", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -335,7 +335,7 @@ test_that("Can open Zarr group and read a 1D S7 string array", {

test_that("Can open Zarr group and read a 1D U7 string array", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -352,7 +352,7 @@ test_that("Can open Zarr group and read a 1D U7 string array", {

test_that("Can open Zarr group and read a 1D U13 little endian string array", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -369,7 +369,7 @@ test_that("Can open Zarr group and read a 1D U13 little endian string array", {

test_that("Can open Zarr group and read a 1D U13 big endian string array", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -386,7 +386,7 @@ test_that("Can open Zarr group and read a 1D U13 big endian string array", {

test_that("Can open Zarr group and read a 2D U7 string array", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -403,7 +403,7 @@ test_that("Can open Zarr group and read a 2D U7 string array", {

test_that("Can open Zarr group and read a 1D VLen-UTF8 string array with no compression", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -420,7 +420,7 @@ test_that("Can open Zarr group and read a 1D VLen-UTF8 string array with no comp

test_that("Can open Zarr group and read a 1D VLen-UTF8 string array with Blosc compression", {

root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -436,7 +436,7 @@ test_that("Can open Zarr group and read a 1D VLen-UTF8 string array with Blosc c
})

test_that("Can open Zarr group and read a 2D VLen-UTF8 string array with no compression", {
root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -452,7 +452,7 @@ test_that("Can open Zarr group and read a 2D VLen-UTF8 string array with no comp
})

test_that("Can open Zarr group and read a 2D VLen-UTF8 string array with Blosc compression", {
root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)
g <- ZarrGroup$new(store)
Expand All @@ -468,9 +468,49 @@ test_that("Can open Zarr group and read a 2D VLen-UTF8 string array with Blosc c
})

test_that("DirectoryStore can listdir", {
root <- pizzarr_sample("fixtures/v2/data.zarr")
root <- pizzarr_sample(file.path("fixtures", "v2", "data.zarr"))

store <- DirectoryStore$new(root)

expect_equal(store$listdir("1d.chunked.i2"), c(".zarray", "0", "1"))
})

test_that("Can create 0-element 1D array", {

store <- MemoryStore$new()
value <- character(0)
dims <- c(0)
name <- "my-0-element-array-1d"

object_codec <- VLenUtf8Codec$new()
data <- array(data = value, dim = dims)
a <- zarr_create_array(data, store = store, path = name, dtype = "|O", object_codec = object_codec, shape = dims)

expect_equal(a$get_shape(), c(0))

sel <- a$get_item("...")

expect_equal(is.character(sel$data), TRUE)
expect_equal(length(sel$data), 0)
expect_equal(dim(sel$data), c(0))
})

test_that("Can create 0-element 2D array", {

store <- MemoryStore$new()
value <- character(0)
dims <- c(0, 0)
name <- "my-0-element-array-2d"

object_codec <- VLenUtf8Codec$new()
data <- array(data = value, dim = dims)
a <- zarr_create_array(data, store = store, path = name, dtype = "|O", object_codec = object_codec, shape = dims)

expect_equal(a$get_shape(), c(0, 0))

sel <- a$get_item("...")

expect_equal(is.character(sel$data), TRUE)
expect_equal(length(sel$data), 0)
expect_equal(dim(sel$data), c(0, 0))
})
Loading

0 comments on commit a39df6a

Please sign in to comment.