library(rhdf5)
############################################################
context("h5createFile")
############################################################
## output file name
h5File <- tempfile(pattern = "ex_save", fileext = ".h5")
if(file.exists(h5File))
file.remove(h5File)
test_that("Default arguments", {
expect_true( h5createFile(file = h5File) )
expect_true( file.exists(h5File) )
})
test_that("Don't overwrite existing file", {
expect_message(h5createFile(file = h5File),
regexp = "already exists.\n$")
})
############################################################
context("h5createGroup")
############################################################
if(!file.exists(h5File))
h5createFile(file = h5File)
test_that("Create simple group", {
expect_true( h5createGroup(file = h5File, group = "foo") )
})
test_that("Create group heirachy", {
expect_true( h5createGroup(file = h5File, group = "foo/baa") )
})
test_that("Fail if toplevel group missing", {
## this is really an error, but doesn't get thrown as one
h5errorHandling(type = "suppress")
expect_false( h5createGroup(file = h5File, group = "baa/foo") )
h5closeAll()
})
############################################################
context("h5createDataset")
############################################################
h5File <- tempfile(pattern = "ex_createDS", fileext = ".h5")
if(file.exists(h5File))
file.remove(h5File)
## create empty file
h5createFile(file = h5File)
test_that("Create single dataset", {
expect_true( h5createDataset(file = h5File, dataset = "A", dims = c(2,1)) )
expect_true( "A" %in% names(h5dump(file = h5File)) )
A <- h5read(file = h5File, name = "A")
expect_is(A, "matrix")
expect_true(nrow(A) == 2)
expect_true(ncol(A) == 1)
expect_is(A[1,1], "numeric")
})
test_that("Create more datasets with different data types", {
expect_true( h5createDataset(file = h5File, dataset = "int", dims = c(4,5), storage.mode = "integer") )
expect_true( h5createDataset(file = h5File, dataset = "bool", dims = c(4,5), storage.mode = "logical") )
expect_true( h5createDataset(file = h5File, dataset = "char", dims = c(4,5), storage.mode = "character", size = 255) )
contents <- h5dump(file = h5File)
expect_true( all(c("int", "bool", "char") %in% names(contents)) )
expect_is(contents$int, "matrix")
expect_true(nrow(contents$int) == 4)
expect_true(ncol(contents$int) == 5)
expect_is(contents$int[1,1], "integer")
expect_is(contents$bool[1,1], "logical")
expect_is(contents$char[1,1], "character")
})
test_that("datasets of fixed and variable length characters can be created", {
expect_true(
h5createDataset(file = h5File, dataset = "variable_length",
dims = 1, storage.mode = "character", size = NULL)
)
expect_true(
h5createDataset(file = h5File, dataset = "fixed_length", dims = 1,
storage.mode = "character", size = 10)
)
fid <- H5Fopen(h5File)
did_var <- H5Dopen(fid, name = "variable_length")
tid_var <- H5Dget_type(did_var)
did_fix <- H5Dopen(fid, name = "fixed_length")
tid_fix <- H5Dget_type(did_fix)
## Variable length strings return NULL when queried for size
expect_true(H5Tis_variable_str(tid_var))
expect_false(H5Tis_variable_str(tid_fix))
expect_identical(H5Tget_size(tid_fix), 10L)
sapply(c(did_var, did_fix), FUN = H5Dclose)
H5Fclose(fid)
})
test_that("Encoding of string datasets can be set", {
expect_true(
h5createDataset(file = h5File, dataset = "ascii",
dims = 1, storage.mode = "character",
encoding = "ASCII")
)
expect_true(
h5createDataset(file = h5File, dataset = "utf-8",
dims = 1, storage.mode = "character",
encoding = "UTF-8")
)
## UTF8 should be UTF-8 but is accepted for legacy reasons
expect_silent(
h5createDataset(file = h5File, dataset = "utf8",
dims = 1, storage.mode = "character",
encoding = "UTF8")
) |> expect_true()
fid <- H5Fopen(h5File)
did_ascii <- H5Dopen(fid, name = "ascii")
tid_ascii <- H5Dget_type(did_ascii)
did_utf8 <- H5Dopen(fid, name = "utf-8")
tid_utf8 <- H5Dget_type(did_utf8)
expect_equal(H5Tget_cset(tid_ascii), 0L)
expect_equal(H5Tget_cset(tid_utf8), 1L)
sapply(c(did_ascii, did_utf8), FUN = H5Dclose)
H5Fclose(fid)
})
test_that("Invalid storage mode arguments", {
expect_error( h5createDataset(file = h5File, dataset = "foo", dims = c(1,1), storage.mode = "foo") )
expect_error( h5createDataset(file = h5File, dataset = "foo", dims = c(1,1), storage.mode = 10) )
expect_error( h5createDataset(file = h5File, dataset = "foo", dims = c(1,1), storage.mode = 1L) )
expect_error( h5createDataset(file = h5File, dataset = "foo", dims = c(1,1), storage.mode = FALSE) )
})
test_that("Datasets with different compression levels", {
dataMatrix <- matrix(runif(n = 1e5), nrow = 10000, ncol = 10)
h5File_0 <- tempfile(pattern = "level0_", fileext = ".h5")
if(file.exists(h5File_0))
file.remove(h5File_0)
h5createFile(h5File_0)
expect_true( h5createDataset(file = h5File_0, dataset = "A", dims = dim(dataMatrix), level = 0) )
h5write( dataMatrix, file = h5File_0, name = "A")
h5File_9 <- tempfile(pattern = "level9_", fileext = ".h5")
if(file.exists(h5File_9))
file.remove(h5File_9)
h5createFile(h5File_9)
expect_true( h5createDataset(file = h5File_9, dataset = "A", dims = dim(dataMatrix), level = 9) )
h5write( dataMatrix, file = h5File_9, name = "A")
## expect compressed file to be at least a small as uncompressed
expect_lte( file.size(h5File_9), file.size(h5File_0) )
})
test_that("Extendible datasets", {
mtx4x3 <- matrix(runif(n=12), nrow = 4)
mtx3x3 <- matrix(runif(n=9), nrow = 3)
mtx7x2 <- matrix(runif(n=14), nrow = 7)
extendible <- H5Sunlimited()
h5createDataset(file = h5File, dataset = "extend", dims = c(4,3), maxdims = c(extendible, extendible))
h5write( mtx4x3, file = h5File, name = "extend")
expect_equal(h5read(h5File, "extend"), mtx4x3)
## now extend in first dimension:
## [ mtx4x3 ]
## [ mtx3x3 ]
h5set_extent(h5File, "extend", c(7,3))
h5write(mtx3x3, file = h5File, name = "extend",
index = list(5:7, 1:3))
expect_equal(h5read(h5File, "extend"),
rbind(mtx4x3, mtx3x3))
## now extend in the other dimension:
## [ mtx4x3 mtx7x2 ]
## [ mtx3x3 mtx7x2 ]
h5set_extent(h5File, "extend", c(7,5))
h5write(mtx7x2, file = h5File, name = "extend",
index = list(1:7, 4:5))
expect_equal(h5read(h5File, "extend"),
cbind(rbind(mtx4x3, mtx3x3),
mtx7x2))
## This case, level = 0, used to lead to an error because the chunking, which is required for
## H5Sunlimited, was within a if(level > 0) branch. Mostly we are just checking here that
## no error is thrown, but we'll also do the first extension
h5createDataset(file = h5File, dataset = "nonCompressed", dim = c(4,3), maxdims = c(extendible, extendible),
level = 0)
h5write( mtx4x3, file = h5File, name = "nonCompressed")
h5set_extent(h5File, "nonCompressed", c(7,3))
h5write(mtx3x3, file = h5File, name = "nonCompressed",
index = list(5:7, 1:3))
expect_equal(h5read(h5File, "nonCompressed"),
rbind(mtx4x3, mtx3x3))
})
test_that("Invalid inputs", {
expect_error(
suppressWarnings( h5createDataset(file = h5File, dataset = "fail", dims = "twenty") ),
regexp = "Can not create dataset. 'dims' and 'maxdims' must be numeric"
)
expect_message(h5createDataset(file = h5File, dataset = "A", dims = c(20, 10))) %>%
expect_false()
expect_error(h5createDataset(file = h5File, dataset = "fail", dims = c(-10, 20)))
expect_error(h5createDataset(file = h5File, dataset = "fail", dims = c(10, 20), maxdims = c(20)))
expect_error(h5createDataset(file = h5File, dataset = "fail",
dims = c(10, 20), maxdims = c(20, 20), chunk = NULL))
expect_error(h5createDataset(file = h5File, dataset = "fail", dims = c(10, 20), maxdims = c(20, 10)))
expect_warning(h5createDataset(file = h5File, dataset = "fail", dims = c(10, 20), level = 1, chunk = NULL))
expect_warning(h5createDataset(file = h5File, dataset = "chunkTooLarge",
dims = c(10,20), chunk = c(10,50)),
regexp = "One or more chunk dimensions exceeded the maximum for the dataset")
})
test_that("Using chunks greater than 4GB", {
expect_message(h5createDataset(file = h5File, dataset = "large_double",
dims = c(25000, 25000), storage.mode = "double")) %>%
expect_true()
expect_message(h5createDataset(file = h5File, dataset = "large_int",
dims = c(50000, 50000), storage.mode = "integer")) %>%
expect_true()
expect_silent(h5createDataset(file = h5File, dataset = "small_int",
dims = c(500, 500), storage.mode = "integer")) %>%
expect_true()
})
############################################################
context("h5createAttribute")
############################################################
h5File <- tempfile(pattern = "ex_createAttr", fileext = ".h5")
if(file.exists(h5File))
file.remove(h5File)
## create a new file with a single dataset
h5createFile(h5File)
h5write(1:1, h5File, "foo")
test_that("attributes can be added using file name", {
expect_true( h5createAttribute(obj = "foo", file = h5File, attr = "foo_attr", dims = c(1,1)) )
expect_true( "foo_attr" %in% names(h5readAttributes(file = h5File, name = "foo")) )
})
test_that("Fail is attribute already exists", {
expect_false( h5createAttribute(obj = "foo", file = h5File, attr = "foo_attr", dims = c(1,1)) )
expect_message( h5createAttribute(obj = "foo", file = h5File, attr = "foo_attr", dims = c(1,1)),
"Can not create attribute")
})
test_that("Fail if dims or maxdims not numeric", {
expect_error( h5createAttribute(obj = "foo", file = h5File, attr = "foo_attr2", dims = "A" ) )
expect_error( h5createAttribute(obj = "foo", file = h5File, attr = "foo_attr2", dims = c(1,1), maxdims = "A" ) )
})
test_that("Invalid storage mode arguments", {
expect_error( h5createAttribute(file = h5File, obj = "foo", dims = c(1,1), attr = "bad_attr", storage.mode = "foo") )
expect_error( h5createAttribute(file = h5File, obj = "foo", dims = c(1,1), attr = "bad_attr", storage.mode = 10) )
expect_error( h5createAttribute(file = h5File, obj = "foo", dims = c(1,1), attr = "bad_attr", storage.mode = 1L) )
expect_error( h5createAttribute(file = h5File, obj = "foo", dims = c(1,1), attr = "bad_attr", storage.mode = FALSE) )
})
test_that("variable string attributes are created correctly", {
h5createAttribute(file = h5File, obj = "foo", dims = c(1,1), attr = "var_str_attr",
storage.mode = "character", size = NULL)
fhandle <- H5Fopen(h5File)
dhandle <- H5Dopen(fhandle, "foo")
ahandle <- H5Aopen(dhandle, "var_str_attr")
dtype <- H5Aget_type(ahandle)
expect_null(H5Tget_size(dtype)) # NULL = variable length.
h5closeAll()
# For comparison.
h5createAttribute(file = h5File, obj = "foo", dims = c(1,1), attr = "var_str_attr2",
storage.mode = "character", size = 10)
fhandle <- H5Fopen(h5File)
dhandle <- H5Dopen(fhandle, "foo")
ahandle <- H5Aopen(dhandle, "var_str_attr2")
dtype <- H5Aget_type(ahandle)
expect_identical(H5Tget_size(dtype), 10L)
h5closeAll()
})
test_that("string encoding is handled properly", {
h5createAttribute(file = h5File, obj = "foo", dims = c(1,1), attr = "ascii_str_attr",
storage.mode = "character", size = NULL)
fhandle <- H5Fopen(h5File)
dhandle <- H5Dopen(fhandle, "foo")
ahandle <- H5Aopen(dhandle, "ascii_str_attr")
dtype <- H5Aget_type(ahandle)
expect_identical(H5Tget_cset(dtype), 0L) # aka ASCII
h5closeAll()
# Now Unicode.
expect_silent(h5createAttribute(file = h5File, obj = "foo", dims = c(1,1),
attr = "utf_str_attr", storage.mode = "character",
encoding = "UTF-8", size = NULL)) |>
expect_true()
fhandle <- H5Fopen(h5File)
dhandle <- H5Dopen(fhandle, "foo")
ahandle <- H5Aopen(dhandle, "utf_str_attr")
dtype <- H5Aget_type(ahandle)
expect_identical(H5Tget_cset(dtype), 1L) # aka UTF8
h5closeAll()
})
test_that("scalar dataspaces are created properly", {
# For reference.
h5createAttribute(file = h5File, obj = "foo", dims = 1, attr = "simple_int_attr",
storage.mode = "integer")
fhandle <- H5Fopen(h5File)
dhandle <- H5Dopen(fhandle, "foo")
ahandle <- H5Aopen(dhandle, "simple_int_attr")
space <- H5Aget_space(ahandle)
expect_identical(H5Sget_simple_extent_dims(space)$rank, 1L)
h5closeAll()
# Now, creating the scalar space.
h5createAttribute(file = h5File, obj = "foo", dims = NULL, attr = "scalar_int_attr",
storage.mode = "integer")
fhandle <- H5Fopen(h5File)
dhandle <- H5Dopen(fhandle, "foo")
ahandle <- H5Aopen(dhandle, "scalar_int_attr")
space <- H5Aget_space(ahandle)
expect_identical(H5Sget_simple_extent_dims(space)$rank, 0L)
h5closeAll()
})
test_that("No open HDF5 objects are left", {
expect_equal( length(h5validObjects()), 0 )
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.