diff --git a/.Rbuildignore b/.Rbuildignore index 2c31b3e..f3a87a4 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -7,3 +7,4 @@ ^vignettes$ ^docs$ ^index\.md$ +^LICENSE\.md$ diff --git a/DESCRIPTION b/DESCRIPTION index 27de6b4..38ac3ed 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -9,10 +9,17 @@ Authors@R: c( email = "mark_keller@g.harvard.edu", role = c("cre", "aut"), comment = c(ORCID = "0000-0003-3003-874X") - ) + ), + person(given = "David", + family = "Blodgett", + role = c("ctb"), + email = "dblodgett@usgs.gov", + comment = c(ORCID = "0000-0001-9489-1710")) ) -Description: An implementation of chunked, compressed, - N-dimensional arrays for R. +Description: An implementation of chunked, compressed, + N-dimensional arrays for R. Zarr spec V2 (2024) + . +Language: en-US License: MIT + file LICENSE BugReports: https://github.com/keller-mark/pizzarr/issues URL: https://github.com/keller-mark/pizzarr @@ -42,4 +49,7 @@ Suggests: pbapply, parallel, future, + future.apply, bench +Config/testthat/parallel: true +Config/testthat/edition: 3 diff --git a/LICENSE b/LICENSE index 73cefaf..fa7dbc0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,2 @@ -MIT License - -Copyright (c) 2021 Mark Keller - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +YEAR: 2024 +COPYRIGHT HOLDER: Mark Keller diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..5154ac2 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2024 Mark Keller + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/NAMESPACE b/NAMESPACE index 16d9a0f..9f74420 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -42,3 +42,10 @@ export(zarr_open_group) export(zarr_save_array) export(zb_int) export(zb_slice) +importFrom(R6,R6Class) +importFrom(memoise,memoise) +importFrom(memoise,timeout) +importFrom(qs,lz4_compress_raw) +importFrom(qs,lz4_decompress_raw) +importFrom(qs,zstd_compress_raw) +importFrom(qs,zstd_decompress_raw) diff --git a/R/array-nested.R b/R/array-nested.R index 79ee933..387c7fb 100644 --- a/R/array-nested.R +++ b/R/array-nested.R @@ -61,6 +61,7 @@ zero_based_to_one_based <- function(selection, shape) { #' Represents a multi-dimensional array that can be #' accessed and subsetted via list of Slice instances. #' @rdname NestedArray +#' @importFrom R6 R6Class #' @export NestedArray <- R6::R6Class("NestedArray", private = list( diff --git a/R/creation.R b/R/creation.R index 30f3ec6..fd2d1e2 100644 --- a/R/creation.R +++ b/R/creation.R @@ -17,17 +17,21 @@ contains_array <- function(store, path=NA) { path <- normalize_storage_path(path) prefix <- path_to_prefix(path) key <- paste0(prefix, ARRAY_META_KEY) - return(store$contains_item(key)) + ret <- store$contains_item(key) + return(!is.null(ret) && ret) } #' @keywords internal contains_group <- function(store, path=NA) { # Reference: https://github.com/zarr-developers/zarr-python/blob/5dd4a0e6cdc04c6413e14f57f61d389972ea937c/zarr/storage.py#L99 # Return True if the store contains a group at the given logical path. + path <- normalize_storage_path(path) prefix <- path_to_prefix(path) key <- paste0(prefix, GROUP_META_KEY) - return(store$contains_item(key)) + ret <- store$contains_item(key) + + return(!is.null(ret) && ret) } #' @keywords internal @@ -243,7 +247,7 @@ require_parent_group <- function( #' Primary compressor. #' @param fill_value : object #' Default value to use for uninitialized portions of the array. -#' @param order : {'C', 'F'}, optional +#' @param order : \code{'C', 'F'}, optional #' Memory layout to be used within each chunk. #' @param overwrite : bool, optional #' If True, erase all data in `store` prior to initialisation. @@ -256,7 +260,7 @@ require_parent_group <- function( #' Sequence of filters to use to encode chunk data prior to compression. #' @param object_codec : Codec, optional #' A codec to encode object arrays, only needed if dtype=object. -#' @param dimension_separator : {'.', '/'}, optional +#' @param dimension_separator : \code{'.', '/'}, optional #' Separator placed between the dimensions of a chunk. #' @keywords internal init_array <- function( @@ -307,15 +311,7 @@ init_array <- function( #' Initialize a group store. Note that this is a low-level function and there should be no #' need to call this directly from user code. -#' @param store : Store -#' A mapping that supports string keys and byte sequence values. -#' @param overwrite : bool, optional -#' If True, erase all data in `store` prior to initialisation. -#' @param path : string, optional -#' Path under which array is stored. -#' @param chunk_store : Store, optional -#' Separate storage for chunks. If not provided, `store` will be used -#' for storage of both chunks and metadata. +#' @inheritParams init_array #' @keywords internal init_group <- function( store, @@ -339,35 +335,14 @@ init_group <- function( #' Create an empty array -#' @param shape : int or tuple of ints -#' Array shape. +#' @inheritParams init_array #' @param chunks : int or tuple of ints, optional #' Chunk shape. If True, will be guessed from `shape` and `dtype`. If #' False, will be set to `shape`, i.e., single chunk for the whole array. #' If an int, the chunk size in each dimension will be given by the value #' of `chunks`. Default is True. -#' @param dtype : string or dtype, optional -#' NumPy dtype. -#' @param compressor : Codec, optional -#' Primary compressor. -#' @param fill_value : object -#' Default value to use for uninitialized portions of the array. -#' @param order : {'C', 'F'}, optional -#' Memory layout to be used within each chunk. -#' @param store : MutableMapping or string -#' Store or path to directory in file system or name of zip file. #' @param synchronizer : object, optional #' Array synchronizer. -#' @param overwrite : bool, optional -#' If True, delete all pre-existing data in `store` at `path` before -#' creating the array. -#' @param path : string, optional -#' Path under which array is stored. -#' @param chunk_store : MutableMapping, optional -#' Separate storage for chunks. If not provided, `store` will be used -#' for storage of both chunks and metadata. -#' @param filters : sequence of Codecs, optional -# Sequence of filters to use to encode chunk data prior to compression. #' @param cache_metadata : bool, optional #' If True, array configuration metadata will be cached for the #' lifetime of the object. If False, array metadata will be reloaded @@ -379,10 +354,6 @@ init_group <- function( #' to all attribute read operations. #' @param read_only : bool, optional #' True if array should be protected against modification. -#' @param object_codec : Codec, optional -#' A codec to encode object arrays, only needed if dtype=object. -#' @param dimension_separator : {'.', '/'}, optional -#' Separator placed between the dimensions of a chunk. #' @param write_empty_chunks : bool, optional #' If True (default), all chunks will be stored regardless of their #' contents. If False, each chunk is compared to the array's fill value @@ -449,7 +420,7 @@ zarr_create <- function( } #' Create an array filled with NAs. -#' @param shape : int or tuple of ints +#' @inheritParams zarr_create #' @param ... The params of zarr_create() #' @returns ZarrArray #' @export @@ -470,7 +441,7 @@ zarr_create_array <- function(data, ...) { } #' Create an array filled with zeros. -#' @param shape : int or tuple of ints +#' @inheritParams zarr_create #' @param ... The params of zarr_create() #' @returns ZarrArray #' @export @@ -479,22 +450,8 @@ zarr_create_zeros <- function(shape, ...) { } #' Create a group. -#' @param store : MutableMapping or string, optional -#' Store or path to directory in file system. -#' @param overwrite : bool, optional -#' If True, delete any pre-existing data in `store` at `path` before -#' creating the group. -#' @param chunk_store : MutableMapping, optional -#' Separate storage for chunks. If not provided, `store` will be used -#' for storage of both chunks and metadata. -#' @param cache_attrs : bool, optional -#' If True (default), user attributes will be cached for attribute read -#' operations. If False, user attributes are reloaded from the store prior -#' to all attribute read operations. -#' @param synchronizer : object, optional -#' Array synchronizer. -#' @param path : string, optional -#' Group path within store. +#' @inheritParams init_array +#' @inheritParams zarr_create #' @returns ZarrGroup #' @export zarr_create_group <- function( @@ -529,23 +486,8 @@ zarr_create_group <- function( } #' Open a group using file-mode-like semantics. -#' @param store : MutableMapping or string, optional -#' Store or path to directory in file system or name of zip file. -#' @param mode : {'r', 'r+', 'a', 'w', 'w-'}, optional -#' Persistence mode: 'r' means read only (must exist); 'r+' means -#' read/write (must exist); 'a' means read/write (create if doesn't -#' exist); 'w' means create (overwrite if exists); 'w-' means create -#' (fail if exists). -#' @param cache_attrs : bool, optional -#' If True (default), user attributes will be cached for attribute read -#' operations. If False, user attributes are reloaded from the store prior -#' to all attribute read operations. -#' @param synchronizer : object, optional -#' Array synchronizer. -#' @param path : string, optional -#' Group path within store. -#' @param chunk_store : MutableMapping or string, optional -#' Store or path to directory in file system or name of zip file. +#' @inheritParams zarr_open +#' @inheritParams zarr_create #' @param storage_options : dict #' If using an fsspec URL to create the store, these will be passed to #' the backend implementation. Ignored otherwise. @@ -617,66 +559,10 @@ zarr_open_group <- function( } #' Open an array using file-mode-like semantics. -#' @param store : MutableMapping or string, optional -#' Store or path to directory in file system or name of zip file. -#' @param storage_options : dict -#' If using an fsspec URL to create the store, these will be passed to -#' the backend implementation. Ignored otherwise. -#' @param mode : {'r', 'r+', 'a', 'w', 'w-'}, optional -#' Persistence mode: 'r' means read only (must exist); 'r+' means -#' read/write (must exist); 'a' means read/write (create if doesn't -#' exist); 'w' means create (overwrite if exists); 'w-' means create -#' (fail if exists). -#' @param shape : int or tuple of ints -#' Array shape. -#' @param chunks : int or tuple of ints, optional -#' Chunk shape. If True, will be guessed from `shape` and `dtype`. If -#' False, will be set to `shape`, i.e., single chunk for the whole array. -#' If an int, the chunk size in each dimension will be given by the value -#' of `chunks`. Default is True. -#' @param dtype : string or dtype, optional -#' NumPy dtype. -#' @param compressor : Codec, optional -#' Primary compressor. -#' @param fill_value : object -#' Default value to use for uninitialized portions of the array. -#' @param order : {'C', 'F'}, optional -#' Memory layout to be used within each chunk. -#' @param store : MutableMapping or string -#' Store or path to directory in file system or name of zip file. -#' @param synchronizer : object, optional -#' Array synchronizer. -#' @param overwrite : bool, optional -#' If True, delete all pre-existing data in `store` at `path` before -#' creating the array. -#' @param path : string, optional -#' Path under which array is stored. -#' @param chunk_store : MutableMapping, optional -#' Separate storage for chunks. If not provided, `store` will be used -#' for storage of both chunks and metadata. -#' @param filters : sequence of Codecs, optional -# Sequence of filters to use to encode chunk data prior to compression. -#' @param cache_metadata : bool, optional -#' If True, array configuration metadata will be cached for the -#' lifetime of the object. If False, array metadata will be reloaded -#' prior to all data access and modification operations (may incur -#' overhead depending on storage and data access pattern). -#' @param cache_attrs : bool, optional -#' If True (default), user attributes will be cached for attribute read -#' operations. If False, user attributes are reloaded from the store prior -#' to all attribute read operations. -#' @param object_codec : Codec, optional -#' A codec to encode object arrays, only needed if dtype=object. -#' @param dimension_separator : {'.', '/'}, optional -#' Separator placed between the dimensions of a chunk. -#' @param write_empty_chunks : bool, optional -#' If True (default), all chunks will be stored regardless of their -#' contents. If False, each chunk is compared to the array's fill value -#' prior to storing. If a chunk is uniformly equal to the fill value, then -#' that chunk is not be stored, and the store entry for that chunk's key -#' is deleted. This setting enables sparser storage, as only chunks with -#' non-fill-value data are stored, at the expense of overhead associated -#' with checking the data of each chunk. +#' @inheritParams init_array +#' @inheritParams zarr_create +#' @inheritParams zarr_open +#' @inheritParams zarr_open_group #' @returns ZarrArray #' @export zarr_open_array <- function( @@ -784,8 +670,7 @@ zarr_open_array <- function( } #' Convenience function to save a ZarrArray to the local file system. -#' @param store : MutableMapping or string -#' Store or path to directory in file system or name of zip file. +#' @inheritParams init_array #' @param arr : ZarrArray #' The array with data to save. #' @param ... Additional arguments to pass to zarr_create_array(). @@ -797,15 +682,12 @@ zarr_save_array <- function(store, arr, ...) { } #' Convenience function to open a group or array using file-mode-like semantics. -#' @param store : MutableMapping or string, optional -#' Store or path to directory in file system or name of zip file. -#' @param mode : {'r', 'r+', 'a', 'w', 'w-'}, optional +#' @inheritParams init_array +#' @param mode : \code{'r', 'r+', 'a', 'w', 'w-'}, optional #' Persistence mode: 'r' means read only (must exist); 'r+' means #' read/write (must exist); 'a' means read/write (create if doesn't #' exist); 'w' means create (overwrite if exists); 'w-' means create #' (fail if exists). -#' @param path : str or NA, optional -#' The path within the store to open. #' @param ... Additional arguments to pass to zarr_open_array or zarr_open_group. #' @returns ZarrArray or ZarrGroup #' @export diff --git a/R/dtypes.R b/R/dtypes.R index ffb0de2..e635acf 100644 --- a/R/dtypes.R +++ b/R/dtypes.R @@ -131,14 +131,14 @@ get_dtype_asrtype <- function(dtype) { return(DTYPE_RTYPE_MAPPING[[dtype_parts$basic_type]]) } - -# Reference: https://numpy.org/doc/stable/reference/arrays.dtypes.html - #' The Zarr Dtype class. #' @title Dtype Class #' @docType class #' @description -#' TODO +#' A data type object (an instance of Dtype class) describes how +#' the bytes in the fixed-size block of memory corresponding to an array +#' item should be interpreted. +#' @references https://numpy.org/doc/stable/reference/arrays.dtypes.html #' @rdname Dtype #' @export Dtype <- R6::R6Class("Dtype", diff --git a/R/indexing.R b/R/indexing.R index fb687b5..8723c07 100644 --- a/R/indexing.R +++ b/R/indexing.R @@ -34,7 +34,7 @@ is_pure_fancy_indexing <- function(selection, ndim = length(selection)) { #' @title OIndex Class #' @docType class #' @description -#' TODO +#' Orthogonal index class #' @rdname OIndex #' @keywords internal OIndex <- R6::R6Class("OIndex", @@ -66,7 +66,7 @@ OIndex <- R6::R6Class("OIndex", #' @title VIndex Class #' @docType class #' @description -#' TODO +#' Vectorized index class #' @rdname VIndex #' @keywords internal VIndex <- R6::R6Class("VIndex", @@ -107,7 +107,7 @@ IntDimIndexer <- R6::R6Class("IntDimIndexer", dim_chunk_len = NULL, #' @description #' Create a new IntDimIndexer instance. - #' @param dim_sel integer dimention selection + #' @param dim_sel integer dimension selection #' @param dim_len integer dimension length #' @param dim_chunk_len integer dimension chunk length #' @return A `IntDimIndexer` instance. @@ -172,7 +172,7 @@ SliceDimIndexer <- R6::R6Class("SliceDimIndexer", step = NULL, #' @description #' Create a new SliceDimIndexer instance. - #' @param dim_sel integer dimention selection + #' @param dim_sel integer dimension selection #' @param dim_len integer dimension length #' @param dim_chunk_len integer dimension chunk length #' @return A `SliceDimIndexer` instance. diff --git a/R/meta.R b/R/meta.R index 8c88913..7790f85 100644 --- a/R/meta.R +++ b/R/meta.R @@ -8,7 +8,7 @@ Metadata2 <- R6::R6Class("Metadata2", ), public = list( decode_metadata = function(s, auto_unbox=FALSE) { - if(is.list(s)) { + if(is.list(s) || is.null(s)) { return(s) } else { return(try_fromJSON(rawToChar(s), simplifyVector = FALSE)) @@ -19,12 +19,12 @@ Metadata2 <- R6::R6Class("Metadata2", }, decode_array_metadata = function(s) { meta <- self$decode_metadata(s) - validate_v2_meta(meta) + if(!is.null(meta)) validate_v2_meta(meta) return(meta) }, decode_group_metadata = function(s) { meta <- self$decode_metadata(s) - validate_v2_meta(meta) + if(!is.null(meta)) validate_v2_meta(meta) return(meta) }, encode_array_metadata = function(meta) { diff --git a/R/numcodecs.R b/R/numcodecs.R index 99e1845..cb1735d 100644 --- a/R/numcodecs.R +++ b/R/numcodecs.R @@ -40,6 +40,7 @@ Codec <- R6::R6Class("Codec", #' Class representing a ZSTD compressor #' @rdname ZstdCodec +#' @importFrom qs zstd_compress_raw zstd_decompress_raw #' @export ZstdCodec <- R6::R6Class("ZstdCodec", inherit = Codec, @@ -61,7 +62,7 @@ ZstdCodec <- R6::R6Class("ZstdCodec", #' @return Compressed data. encode = function(buf, zarr_arr) { # Reference: https://github.com/traversc/qs/blob/84e30f4/R/RcppExports.R#L16 - result <- qs::zstd_compress_raw(buf, self$level) + result <- zstd_compress_raw(buf, self$level) return(result) }, #' @description @@ -70,7 +71,7 @@ ZstdCodec <- R6::R6Class("ZstdCodec", #' @param zarr_arr The ZarrArray instance. #' @return Un-compressed data. decode = function(buf, zarr_arr) { - result <- qs::zstd_decompress_raw(buf) + result <- zstd_decompress_raw(buf) return(result) }, #' @description @@ -92,6 +93,7 @@ ZstdCodec <- R6::R6Class("ZstdCodec", #' Class representing a LZ4 compressor #' #' @rdname Lz4Codec +#' @importFrom qs lz4_compress_raw lz4_decompress_raw #' @export Lz4Codec <- R6::R6Class("Lz4Codec", inherit = Codec, @@ -113,7 +115,7 @@ Lz4Codec <- R6::R6Class("Lz4Codec", #' @return Compressed data. encode = function(buf, zarr_arr) { # Reference: https://github.com/traversc/qs/blob/84e30f4/R/RcppExports.R#L24 - body <- qs::lz4_compress_raw(buf, self$acceleration) + body <- lz4_compress_raw(buf, self$acceleration) # The compressed output includes a 4-byte header storing the original size # of the decompressed data as a little-endian 32-bit integer. @@ -133,7 +135,7 @@ Lz4Codec <- R6::R6Class("Lz4Codec", decode = function(buf, zarr_arr) { body <- buf[5:length(buf)] - result <- qs::lz4_decompress_raw(body) + result <- lz4_decompress_raw(body) return(result) }, #' @description diff --git a/R/options.R b/R/options.R index a3043af..c886bc7 100644 --- a/R/options.R +++ b/R/options.R @@ -10,9 +10,15 @@ pizzarr_option_defaults <- list( #' @keywords internal parse_parallel_option <- function(val) { + + if(inherits(val, "cluster")) { + return(val) + } + if(val == "future") { return("future") } + logical_val <- suppressWarnings(as.logical(val)) integer_val <- suppressWarnings(as.integer(val)) diff --git a/R/slicing.R b/R/slicing.R index 6706aa8..fe31c1b 100644 --- a/R/slicing.R +++ b/R/slicing.R @@ -94,7 +94,7 @@ Slice <- R6::R6Class("Slice", ) ) -#' Convenience function for the internal Slice class constructor. +#' Convenience function for the internal Slice R6 class constructor. #' @param start The start index. #' @param stop The stop index. #' @param step The step size. @@ -119,11 +119,10 @@ slice <- function(start, stop = NA, step = NA, zero_based = FALSE) { )) } -#' Convenience function for the internal Slice class constructor +#' Convenience function for the internal Slice R6 class constructor #' with zero-based indexing and exclusive stop index. -#' @param start The start index. -#' @param stop The stop index. -#' @param step The step size. +#' @inheritParams slice +#' @inherit slice return #' @export zb_slice <- function(start, stop = NA, step = NA) { return(slice(start, stop, step, zero_based = TRUE)) diff --git a/R/stores.R b/R/stores.R index 96af264..24a821d 100644 --- a/R/stores.R +++ b/R/stores.R @@ -343,14 +343,20 @@ MemoryStore <- R6::R6Class("MemoryStore", # Reference: https://github.com/manzt/zarrita.js/blob/main/packages/storage/src/fetch.ts -#' HttpStore for Zarr #' @title HttpStore Class #' @docType class #' @description #' Store class that uses HTTP requests. #' Read-only. Depends on the `crul` package. -#' +#' @details For parallel operation, set the "pizzarr.parallel_read_enabled" option +#' to one of: +#' * `"future"` if a future plan has been set up +#' * `integer` if you would like a one-time use cluster created per call +#' * `cluster` object created with `parallel::make_cluster()` if you want to reuse a cluster +#' +#' For more, see `vignette("parallel").` #' @rdname HttpStore +#' @importFrom memoise memoise timeout #' @export HttpStore <- R6::R6Class("HttpStore", inherit = Store, @@ -388,14 +394,17 @@ HttpStore <- R6::R6Class("HttpStore", res$request() return(unclass(res$responses())[[1]]) } else { - return(private$client$get(path = path)) + ret <- NULL + try(ret <- private$client$get(path = path)) + if(is.null(ret)) warning("Can't procede, web request failed.") + return(ret) } }, memoize_make_request = function() { if(private$cache_enabled) { - private$make_request_memoized <- memoise::memoise( + private$make_request_memoized <- memoise( function(key) private$make_request(key), - ~memoise::timeout(private$cache_time_seconds) + ~timeout(private$cache_time_seconds) ) } else { private$make_request_memoized <- private$make_request @@ -404,7 +413,7 @@ HttpStore <- R6::R6Class("HttpStore", get_zmetadata = function() { res <- private$make_request(".zmetadata") - if(res$status_code == 200) { + if(!is.null(res$status_code) && res$status_code == 200) { out <- try_fromJSON(res$parse("UTF-8")) } else out <- NULL @@ -462,7 +471,6 @@ HttpStore <- R6::R6Class("HttpStore", #' @param item The item key. #' @return A boolean value. contains_item = function(item) { - # use consolidated metadata if it exists if(!is.null(try_from_zmeta(item_to_key(item), self))) { return(TRUE) @@ -471,7 +479,7 @@ HttpStore <- R6::R6Class("HttpStore", } else { res <- private$make_request_memoized(item) - return(res$status_code == 200) + return(!is.null(res$status_code) && res$status_code == 200) } }, diff --git a/R/utils.R b/R/utils.R index 75c55a8..23fd932 100644 --- a/R/utils.R +++ b/R/utils.R @@ -351,6 +351,9 @@ item_to_key <- function(item) { #' @keywords internal is_truthy_parallel_option <- function(val) { + if(inherits(val, "cluster")) { + return(TRUE) + } if(val == "future") { return(TRUE) } diff --git a/R/zarr-array.R b/R/zarr-array.R index 965500d..ce0d80a 100644 --- a/R/zarr-array.R +++ b/R/zarr-array.R @@ -79,8 +79,8 @@ ZarrArray <- R6::R6Class("ZarrArray", #' oindex TODO #' @keywords internal oindex = NULL, - #' @description - #' (Re)load metadata from store. + #' method_description + #' (Re)load metadata from store without synchronization (file locking). load_metadata_nosync = function() { mkey <- paste0(private$key_prefix, ARRAY_META_KEY) @@ -89,7 +89,8 @@ ZarrArray <- R6::R6Class("ZarrArray", if(is.null(meta)) { meta_bytes <- private$store$get_item(mkey) - meta <- private$store$metadata_class$decode_array_metadata(meta_bytes) + if(!is.null(meta_bytes)) + meta <- private$store$metadata_class$decode_array_metadata(meta_bytes) } private$meta <- meta @@ -134,28 +135,28 @@ ZarrArray <- R6::R6Class("ZarrArray", } private$dtype <- normalize_dtype(meta$dtype, object_codec = object_codec) }, - #' @description - #' TODO + #' method_description + #' Load or reload metadata from store. load_metadata = function() { private$load_metadata_nosync() # TODO: support for synchronization }, - #' @description - #' TODO + #' method_description + #' Referesh metadata if not cached without synchronization (file locking). refresh_metadata_nosync = function() { if(!private$cache_metadata && !private$is_view) { private$load_metadata_nosync() } }, - #' @description - #' TODO + #' method_description + #' Refresh metadata from store if not cached. refresh_metadata = function() { if(!private$cache_metadata) { private$load_metadata() } }, - #' @description - #' TODO + #' method_description + #' Write metadata to store without synchronization (file locking). flush_metadata_nosync = function() { if(private$is_view) { stop("Operation not permitted for views") @@ -187,13 +188,13 @@ ZarrArray <- R6::R6Class("ZarrArray", encoded_meta <- private$store$metadata_class$encode_array_metadata(zarray_meta) private$store$set_item(mkey, encoded_meta) }, - #' @description + #' method_description #' TODO chunk_key = function(chunk_coords) { # Reference: https://github.com/zarr-developers/zarr-python/blob/5dd4a0/zarr/core.py#L2063 return(paste0(private$key_prefix, do.call(paste, c(as.list(chunk_coords), sep = private$dimension_separator)))) }, - #' @description + #' method_description #' TODO compute_cdata_shape = function() { # Reference: https://github.com/zarr-developers/zarr-python/blob/5dd4a0/zarr/core.py#L428 @@ -211,8 +212,8 @@ ZarrArray <- R6::R6Class("ZarrArray", cdata_shape <- as.numeric(cdata_shape) return(cdata_shape) }, - #' @description - #' TODO + #' method_description + #' Resize an array without synchronization (file locking) resize_nosync = function(...) { # Note: When resizing an array, the data are not rearranged in any way. # If one or more dimensions are shrunk, any chunks falling outside the @@ -251,7 +252,7 @@ ZarrArray <- R6::R6Class("ZarrArray", } } }, - #' @description + #' method_description #' TODO get_basic_selection_zd = function(selection = NA, out = NA, fields = NA) { # Special case basic selection for zero-dimensional array @@ -295,20 +296,19 @@ ZarrArray <- R6::R6Class("ZarrArray", } return(out) }, - #' @description + #' method_description #' TODO get_basic_selection_nd = function(selection = NA, out = NA, fields = NA) { indexer <- BasicIndexer$new(selection, self) return(private$get_selection(indexer, out = out, fields = fields)) }, - #' @description + #' method_description #' TODO get_selection = function(indexer, out = NA, fields = NA) { # Reference: https://github.com/gzuidhof/zarr.js/blob/292804/src/core/index.ts#L304 # We iterate over all chunks which overlap the selection and thus contain data # that needs to be extracted. Each chunk is processed in turn, extracting the # necessary data and storing into the correct location in the output array. - out_dtype <- private$dtype out_shape <- indexer$shape out_size <- compute_size(indexer$shape) @@ -326,13 +326,29 @@ ZarrArray <- R6::R6Class("ZarrArray", parallel_option <- getOption("pizzarr.parallel_read_enabled") cl <- parse_parallel_option(parallel_option) is_parallel <- is_truthy_parallel_option(cl) - apply_func <- lapply if(is_parallel) { if(!requireNamespace("pbapply", quietly = TRUE)) { stop("Parallel reading requires the 'pbapply' package.") } - apply_func <- pbapply::pblapply + + if(is.integer(cl) & .Platform$OS.type == "windows") { + # See #105 + cl <- parallel::makeCluster(cl) + on.exit(parallel::stopCluster(cl)) + } + + apply_func <- function(X, FUN, ..., cl = NULL) { + + if(isTRUE(cl == "future")) { + pbapply::pblapply(X, FUN, ..., + future.packages = "Rarr", + future.seed=TRUE, cl = cl) + } else { + pbapply::pblapply(X, FUN, ..., cl = cl) + } + } + } parts <- indexer$iter() @@ -353,7 +369,7 @@ ZarrArray <- R6::R6Class("ZarrArray", return(out) }, - #' @description + #' method_description #' TODO set_basic_selection_zd = function(selection, value, fields = NA) { # Reference: https://github.com/zarr-developers/zarr-python/blob/5dd4a0e6cdc04c6413e14f57f61d389972ea937c/zarr/core.py#L1625 @@ -416,13 +432,13 @@ ZarrArray <- R6::R6Class("ZarrArray", c_data <- private$encode_chunk(chunk_raw) self$get_chunk_store()$set_item(c_key, c_data) }, - #' @description + #' method_description #' TODO set_basic_selection_nd = function(selection, value, fields = NA) { indexer <- BasicIndexer$new(selection, self) return(private$set_selection(indexer, value = value, fields = fields)) }, - #' @description + #' method_description #' TODO set_selection = function(indexer, value, fields = NA) { # Reference: https://github.com/zarr-developers/zarr-python/blob/5dd4a0/zarr/core.py#L1682 @@ -467,9 +483,28 @@ ZarrArray <- R6::R6Class("ZarrArray", if(!requireNamespace("pbapply", quietly=TRUE)) { stop("Parallel writing requires the 'pbapply' package.") } - apply_func <- pbapply::pblapply + + if(is.integer(cl) & .Platform$OS.type == "windows") { + # See #105 + cl <- parallel::makeCluster(cl) + on.exit(parallel::stopCluster(cl)) + + } + + apply_func <- function(X, FUN, ..., cl = NULL) { + + if(isTRUE(cl == "future")) { + pbapply::pblapply(X, FUN, ..., + future.packages = "Rarr", + future.seed=TRUE, cl = cl) + } else { + pbapply::pblapply(X, FUN, ..., cl = cl) + } + } + } - + + parts <- indexer$iter() apply_func(parts, function(proj, cl = NA) { chunk_value <- private$get_chunk_value(proj, indexer, value, selection_shape) @@ -480,13 +515,13 @@ ZarrArray <- R6::R6Class("ZarrArray", return() } }, - #' @description + #' method_description #' TODO process_chunk = function(out, cdata, chunk_selection, drop_axes, out_is_ndarray, fields, out_selection, partial_read_decode = FALSE) { # Reference: https://github.com/zarr-developers/zarr-python/blob/5dd4a0/zarr/core.py#L1755 # TODO }, - #' @description + #' method_description #' TODO get_chunk_value = function(proj, indexer, value, selection_shape) { # Reference: https://github.com/gzuidhof/zarr.js/blob/15e3a3f00eb19f0133018fb65f002311ea53bb7c/src/core/index.ts#L550 @@ -506,12 +541,12 @@ ZarrArray <- R6::R6Class("ZarrArray", } return(chunk_value) }, - #' @description + #' method_description #' TODO chunk_buffer_to_raw_array = function(decoded_chunk) { # TODO }, - #' @description + #' method_description #' For parallel usage chunk_getitem_part1 = function(chunk_coords, chunk_selection, out, out_selection, drop_axes = NA, fields = NA) { if(length(chunk_coords) != length(private$chunks)) { @@ -532,7 +567,7 @@ ZarrArray <- R6::R6Class("ZarrArray", }) return(result) }, - #' @description + #' method_description #' For parallel usage chunk_getitem_part2 = function(part1_result, chunk_coords, chunk_selection, out, out_selection, drop_axes = NA, fields = NA) { c_key <- private$chunk_key(chunk_coords) @@ -575,7 +610,7 @@ ZarrArray <- R6::R6Class("ZarrArray", } } }, - #' @description + #' method_description #' For non-parallel usage chunk_getitem = function(chunk_coords, chunk_selection, out, out_selection, drop_axes = NA, fields = NA) { # TODO @@ -623,12 +658,12 @@ ZarrArray <- R6::R6Class("ZarrArray", } }) }, - #' @description + #' method_description #' TODO chunk_getitems = function(lchunk_coords, lchunk_selection, out, lout_selection, drop_axes = NA, fields = NA) { # TODO }, - #' @description + #' method_description #' TODO chunk_setitem = function(chunk_coords, chunk_selection, value, fields = NA) { # Reference: https://github.com/gzuidhof/zarr.js/blob/15e3a3f00eb19f0133018fb65f002311ea53bb7c/src/core/index.ts#L625 @@ -706,17 +741,17 @@ ZarrArray <- R6::R6Class("ZarrArray", chunk_data <- private$encode_chunk(chunk_raw) self$get_chunk_store()$set_item(chunk_key, chunk_data) }, - #' @description + #' method_description #' TODO chunk_setitem_nosync = function(chunk_coords, chunk_selection, value, fields = NA) { # TODO }, - #' @description + #' method_description #' TODO chunk_setitems = function(lchunk_coords, lchunk_selection, values, fields = NA) { # TODO }, - #' @description + #' method_description #' TODO process_for_setitem = function(ckey, chunk_selection, value, fields = NA) { # TODO @@ -724,12 +759,12 @@ ZarrArray <- R6::R6Class("ZarrArray", chunk_delitem = function(ckey) { # TODO }, - #' @description + #' method_description #' TODO chunk_delitems = function(ckeys) { # TODO }, - #' @description + #' method_description #' TODO decode_chunk = function(cdata, start = NA, nitems = NA, expected_shape = NA) { # Reference: https://github.com/zarr-developers/zarr-python/blob/5dd4a0e6cdc04c6413e14f57f61d389972ea937c/zarr/core.py#L2066 @@ -771,7 +806,7 @@ ZarrArray <- R6::R6Class("ZarrArray", # ensure correct chunk shape return(chunk) }, - #' @description + #' method_description #' TODO encode_chunk = function(chunk_as_raw) { # Reference: https://github.com/zarr-developers/zarr-python/blob/5dd4a0e6cdc04c6413e14f57f61d389972ea937c/zarr/core.py#L2105 @@ -802,7 +837,7 @@ ZarrArray <- R6::R6Class("ZarrArray", return(cdata) }, - #' @description + #' method_description #' TODO append_nosync = function(data, axis = 0) { # Reference: https://github.com/zarr-developers/zarr-python/blob/5dd4a0/zarr/core.py#L2141 @@ -811,7 +846,7 @@ ZarrArray <- R6::R6Class("ZarrArray", ), public = list( #' @description - #' Create a new Array instance. + #' Create a new ZarrArray instance. #' @param store Array store already initialized. #' @param path character path #' @param read_only logical read only? @@ -850,17 +885,17 @@ ZarrArray <- R6::R6Class("ZarrArray", private$oindex <- VIndex$new(self) }, #' @description - #' TODO + #' get store from array. get_store = function() { return(private$store) }, #' @description - #' TODO + #' get array path get_path = function() { return(private$path) }, #' @description - #' TODO + #' get full array name get_name = function() { if(!is.na(private$path)) { name <- private$path @@ -873,7 +908,7 @@ ZarrArray <- R6::R6Class("ZarrArray", return(NA) }, #' @description - #' TODO + #' get the basename of an array get_basename = function() { name <- self$get_name() if(!is.na(name)) { @@ -883,18 +918,18 @@ ZarrArray <- R6::R6Class("ZarrArray", return(NA) }, #' @description - #' TODO + #' get the read only property of an array (TRUE/FALSE) get_read_only = function() { return(private$read_only) }, #' @description - #' TODO + #' set the read only property of an array #' @param val value to set set_read_only = function(val) { private$read_only <- val }, #' @description - #' TODO + #' get the chunk store for an array get_chunk_store = function() { if(is_na(private$chunk_store)) { return(private$store) @@ -903,13 +938,13 @@ ZarrArray <- R6::R6Class("ZarrArray", } }, #' @description - #' TODO + #' get the shape of an array get_shape = function() { private$refresh_metadata() return(private$shape) }, #' @description - #' TODO + #' set or reset the size of an array #' @param value numeric size to set set_shape = function(value) { self$resize(value) @@ -922,70 +957,70 @@ ZarrArray <- R6::R6Class("ZarrArray", do.call(private$resize_nosync, args) }, #' @description - #' TODO + #' get the chunk metadata of an array get_chunks = function() { return(private$chunks) }, #' @description - #' TODO + #' get the Dtype of an array get_dtype = function() { return(private$dtype) }, #' @description - #' TODO + #' get the compressor of an array get_compressor = function() { return(private$compressor) }, #' @description - #' TODO + #' get the fill value of an array get_fill_value = function() { return(private$fill_value) }, #' @description - #' TODO + #' set the fill value of an array #' @param val fill value to use set_fill_value = function(val) { private$fill_value <- val private$flush_metadata_nosync() }, #' @description - #' TODO + #' get the storage order metadata of an array. get_order = function() { return(private$order) }, #' @description - #' TODO + #' get the filters metadata of an array get_filters = function() { return(private$filters) }, #' @description - #' TODO + #' get the synchronizer of an array TODO: not implemented get_synchronizer = function() { return(private$synchronizer) }, #' @description - #' TODO + #' get attributes of array get_attrs = function() { return(private$attrs) }, #' @description - #' TODO + #' get number of dimensions of array get_ndim = function() { return(length(private$shape)) }, #' @description - #' TODO + #' get size of an array TODO: not implemented get_size = function() { # Reference: https://github.com/zarr-developers/zarr-python/blob/5dd4a0/zarr/core.py#L383 # TODO }, #' @description - #' TODO + #' TODO: not implemented get_itemsize = function() { # TODO }, #' @description - #' TODO + #' get number of bytes of an array get_nbytes = function() { private$refresh_metadata() return(self$get_size() * self$get_itemsize()) @@ -1013,27 +1048,27 @@ ZarrArray <- R6::R6Class("ZarrArray", # TODO }, #' @description - #' TODO + #' get is_view metadata of array get_is_view = function() { return(private$is_view) }, #' @description - #' TODO + #' get orthogonal index of array get_oindex = function() { return(private$oindex) }, #' @description - #' TODO + #' get vectorized index of array get_vindex = function() { return(private$vindex) }, #' @description - #' TODO + #' get write empty chunks setting of array get_write_empty_chunks = function() { return(private$write_empty_chunks) }, #' @description - #' TODO + #' check if another object refers to the same array. does not check array data #' @param other other object to check equals = function(other) { return(all(c( @@ -1077,7 +1112,7 @@ ZarrArray <- R6::R6Class("ZarrArray", } }, #' @description - #' TODO + #' get a selection of an array based on a "basic"list of slices #' @param out TODO #' @param fields TODO @@ -1275,7 +1310,7 @@ ZarrArray <- R6::R6Class("ZarrArray", #' S3 method for as.array #' -#' @param obj object +#' @param x object #' @param ... not used #' @keywords internal #' @export diff --git a/R/zarr-group.R b/R/zarr-group.R index 54cbf22..1c58657 100644 --- a/R/zarr-group.R +++ b/R/zarr-group.R @@ -160,7 +160,8 @@ ZarrGroup <- R6::R6Class("ZarrGroup", } }) - private$meta <- private$store$metadata_class$decode_group_metadata(meta_bytes) + if(!is.null(meta_bytes)) + private$meta <- private$store$metadata_class$decode_group_metadata(meta_bytes) } @@ -229,6 +230,10 @@ ZarrGroup <- R6::R6Class("ZarrGroup", #' Obtain a group member. #' @param item character item to test for get_item = function(item) { + if(is.null(item)) { + #for case with no internet + stop("item can not be null") + } path <- private$item_path(item) if(contains_array(private$store, path)) { return(ZarrArray$new( @@ -253,7 +258,7 @@ ZarrGroup <- R6::R6Class("ZarrGroup", } }, #' @description - #' greate a group + #' create a group #' @param name character group name #' @param overwrite logical overwrite? create_group = function(name, overwrite = FALSE) { diff --git a/README.md b/README.md index da45637..9e9fda6 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,8 @@ devtools::load_all() ## Testing +Set `TESTTHAT_CPUS=#` in .Renviron to run tests in parallel + ```r devtools::check() devtools::test() diff --git a/inst/WORDLIST b/inst/WORDLIST new file mode 100644 index 0000000..977f5dd --- /dev/null +++ b/inst/WORDLIST @@ -0,0 +1,85 @@ +AnnData +BasicIndexer +Blosc +BloscCodec +Bz +ChunkProjection +Codec +DirectoryStore +Dtype +Gzip +GzipCodec +HttpStore +IntDimIndexer +JSON +KeyError +LZ +Lz +Lzma +LzmaCodec +MemoryStore +Multisession +NGFF +NestArray +NestedArray +NumPy +OIndex +OME +README +Rarr +RawArray +Referesh +Renviron +SliceDimIndexer +Un +VIndex +VLenUTF +VLenUtf +Vectorized +ZSTD +Zarr +ZarrArray +ZarrArrays +ZarrGroup +ZarrGroups +Zlib +ZlibCodec +Zstd +ZstdCodec +attrs +bool +bz +cloneable +codec +config +crul +de +doi +dtype +dtypes +eraseable +fsspec +gzip +http +https +initialisation +ints +js +json +listable +lzma +nr +numpy +params +pkgdown +roxygen +synchronizer +un +vectorized +writeable +zarr +zarray +zarrita +zenodo +zlib +zmetadata diff --git a/man/Dtype.Rd b/man/Dtype.Rd index a88f218..ed7bdf9 100644 --- a/man/Dtype.Rd +++ b/man/Dtype.Rd @@ -5,11 +5,16 @@ \alias{Dtype} \title{Dtype Class} \description{ -TODO +A data type object (an instance of Dtype class) describes how +the bytes in the fixed-size block of memory corresponding to an array +item should be interpreted. } \details{ The Zarr Dtype class. } +\references{ +https://numpy.org/doc/stable/reference/arrays.dtypes.html +} \section{Public fields}{ \if{html}{\out{
}} \describe{ diff --git a/man/HttpStore.Rd b/man/HttpStore.Rd index e227462..22962a3 100644 --- a/man/HttpStore.Rd +++ b/man/HttpStore.Rd @@ -9,7 +9,15 @@ Store class that uses HTTP requests. Read-only. Depends on the \code{crul} package. } \details{ -HttpStore for Zarr +For parallel operation, set the "pizzarr.parallel_read_enabled" option +to one of: +\itemize{ +\item \code{"future"} if a future plan has been set up +\item \code{integer} if you would like a one-time use cluster created per call +\item \code{cluster} object created with \code{parallel::make_cluster()} if you want to reuse a cluster +} + +For more, see \verb{vignette("parallel").} } \section{Super class}{ \code{\link[pizzarr:Store]{pizzarr::Store}} -> \code{HttpStore} diff --git a/man/IntDimIndexer.Rd b/man/IntDimIndexer.Rd index d6af809..67434c2 100644 --- a/man/IntDimIndexer.Rd +++ b/man/IntDimIndexer.Rd @@ -45,7 +45,7 @@ Create a new IntDimIndexer instance. \subsection{Arguments}{ \if{html}{\out{
}} \describe{ -\item{\code{dim_sel}}{integer dimention selection} +\item{\code{dim_sel}}{integer dimension selection} \item{\code{dim_len}}{integer dimension length} diff --git a/man/OIndex.Rd b/man/OIndex.Rd index b582235..ce2592c 100644 --- a/man/OIndex.Rd +++ b/man/OIndex.Rd @@ -5,7 +5,7 @@ \alias{OIndex} \title{OIndex Class} \description{ -TODO +Orthogonal index class } \details{ The Zarr OIndex class. diff --git a/man/SliceDimIndexer.Rd b/man/SliceDimIndexer.Rd index a4fa8d8..79ae544 100644 --- a/man/SliceDimIndexer.Rd +++ b/man/SliceDimIndexer.Rd @@ -51,7 +51,7 @@ Create a new SliceDimIndexer instance. \subsection{Arguments}{ \if{html}{\out{
}} \describe{ -\item{\code{dim_sel}}{integer dimention selection} +\item{\code{dim_sel}}{integer dimension selection} \item{\code{dim_len}}{integer dimension length} diff --git a/man/VIndex.Rd b/man/VIndex.Rd index f9d832c..fafe4d0 100644 --- a/man/VIndex.Rd +++ b/man/VIndex.Rd @@ -5,7 +5,7 @@ \alias{VIndex} \title{VIndex Class} \description{ -TODO +Vectorized index class } \details{ The Zarr VIndex class. diff --git a/man/ZarrArray.Rd b/man/ZarrArray.Rd index 9b69386..8c4d8ed 100644 --- a/man/ZarrArray.Rd +++ b/man/ZarrArray.Rd @@ -13,23 +13,32 @@ Instantiate an array from an initialized store. \details{ The Zarr Array class. } +\keyword{(Re)load} \keyword{(default),} +\keyword{(file} \keyword{Array} \keyword{False} \keyword{False,} +\keyword{For} \keyword{If} +\keyword{Load} \keyword{Object,} +\keyword{Referesh} +\keyword{Refresh} +\keyword{Resize} \keyword{Separate} \keyword{Storage} \keyword{String,} \keyword{TODO} \keyword{True} \keyword{True,} +\keyword{Write} \keyword{`store`} \keyword{a} \keyword{access} \keyword{against} \keyword{all} +\keyword{an} \keyword{and} \keyword{array} \keyword{array's} @@ -39,6 +48,7 @@ The Zarr Array class. \keyword{both} \keyword{cache_attrs} \keyword{cache_metadata} +\keyword{cached} \keyword{cached.} \keyword{chunk} \keyword{chunk's} @@ -60,21 +70,28 @@ The Zarr Array class. \keyword{fill_value} \keyword{filters} \keyword{for} +\keyword{from} \keyword{if} \keyword{internal} \keyword{is} \keyword{is_view} \keyword{key} \keyword{key_prefix} +\keyword{locking)} +\keyword{locking).} \keyword{meta} \keyword{metadata} \keyword{metadata.} +\keyword{method_description} \keyword{modification.} +\keyword{non-parallel} \keyword{not} \keyword{of} \keyword{oindex} \keyword{optional.} +\keyword{or} \keyword{order} +\keyword{parallel} \keyword{path} \keyword{path.} \keyword{prior} @@ -82,14 +99,17 @@ The Zarr Array class. \keyword{provided,} \keyword{read_only} \keyword{regardless} +\keyword{reload} \keyword{reloaded} \keyword{shape} \keyword{should} \keyword{storage} \keyword{store} +\keyword{store.} \keyword{stored} \keyword{stored,} \keyword{storing.} +\keyword{synchronization} \keyword{synchronizer} \keyword{synchronizer.} \keyword{that} @@ -98,12 +118,14 @@ The Zarr Array class. \keyword{then} \keyword{to} \keyword{uniformly} +\keyword{usage} \keyword{used} \keyword{user} \keyword{value} \keyword{value,} \keyword{vindex} \keyword{will} +\keyword{without} \keyword{write_empty_chunks} \section{Methods}{ \subsection{Public methods}{ @@ -170,94 +192,7 @@ The Zarr Array class. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-new}{}}} \subsection{Method \code{new()}}{ -(Re)load metadata from store. - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -For parallel usage - - -For parallel usage - - -For non-parallel usage - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -TODO - - -Create a new Array instance. +Create a new ZarrArray instance. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$new( store, @@ -300,7 +235,7 @@ An \code{Array} instance. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_store}{}}} \subsection{Method \code{get_store()}}{ -TODO +get store from array. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_store()}\if{html}{\out{
}} } @@ -310,7 +245,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_path}{}}} \subsection{Method \code{get_path()}}{ -TODO +get array path \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_path()}\if{html}{\out{
}} } @@ -320,7 +255,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_name}{}}} \subsection{Method \code{get_name()}}{ -TODO +get full array name \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_name()}\if{html}{\out{
}} } @@ -330,7 +265,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_basename}{}}} \subsection{Method \code{get_basename()}}{ -TODO +get the basename of an array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_basename()}\if{html}{\out{
}} } @@ -340,7 +275,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_read_only}{}}} \subsection{Method \code{get_read_only()}}{ -TODO +get the read only property of an array (TRUE/FALSE) \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_read_only()}\if{html}{\out{
}} } @@ -350,7 +285,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-set_read_only}{}}} \subsection{Method \code{set_read_only()}}{ -TODO +set the read only property of an array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$set_read_only(val)}\if{html}{\out{
}} } @@ -367,7 +302,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_chunk_store}{}}} \subsection{Method \code{get_chunk_store()}}{ -TODO +get the chunk store for an array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_chunk_store()}\if{html}{\out{
}} } @@ -377,7 +312,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_shape}{}}} \subsection{Method \code{get_shape()}}{ -TODO +get the shape of an array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_shape()}\if{html}{\out{
}} } @@ -387,7 +322,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-set_shape}{}}} \subsection{Method \code{set_shape()}}{ -TODO +set or reset the size of an array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$set_shape(value)}\if{html}{\out{
}} } @@ -421,7 +356,7 @@ Change the shape of the array by growing or shrinking one or more dimensions. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_chunks}{}}} \subsection{Method \code{get_chunks()}}{ -TODO +get the chunk metadata of an array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_chunks()}\if{html}{\out{
}} } @@ -431,7 +366,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_dtype}{}}} \subsection{Method \code{get_dtype()}}{ -TODO +get the Dtype of an array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_dtype()}\if{html}{\out{
}} } @@ -441,7 +376,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_compressor}{}}} \subsection{Method \code{get_compressor()}}{ -TODO +get the compressor of an array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_compressor()}\if{html}{\out{
}} } @@ -451,7 +386,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_fill_value}{}}} \subsection{Method \code{get_fill_value()}}{ -TODO +get the fill value of an array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_fill_value()}\if{html}{\out{
}} } @@ -461,7 +396,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-set_fill_value}{}}} \subsection{Method \code{set_fill_value()}}{ -TODO +set the fill value of an array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$set_fill_value(val)}\if{html}{\out{
}} } @@ -478,7 +413,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_order}{}}} \subsection{Method \code{get_order()}}{ -TODO +get the storage order metadata of an array. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_order()}\if{html}{\out{
}} } @@ -488,7 +423,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_filters}{}}} \subsection{Method \code{get_filters()}}{ -TODO +get the filters metadata of an array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_filters()}\if{html}{\out{
}} } @@ -498,7 +433,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_synchronizer}{}}} \subsection{Method \code{get_synchronizer()}}{ -TODO +get the synchronizer of an array TODO: not implemented \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_synchronizer()}\if{html}{\out{
}} } @@ -508,7 +443,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_attrs}{}}} \subsection{Method \code{get_attrs()}}{ -TODO +get attributes of array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_attrs()}\if{html}{\out{
}} } @@ -518,7 +453,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_ndim}{}}} \subsection{Method \code{get_ndim()}}{ -TODO +get number of dimensions of array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_ndim()}\if{html}{\out{
}} } @@ -528,7 +463,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_size}{}}} \subsection{Method \code{get_size()}}{ -TODO +get size of an array TODO: not implemented \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_size()}\if{html}{\out{
}} } @@ -538,7 +473,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_itemsize}{}}} \subsection{Method \code{get_itemsize()}}{ -TODO +TODO: not implemented \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_itemsize()}\if{html}{\out{
}} } @@ -548,7 +483,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_nbytes}{}}} \subsection{Method \code{get_nbytes()}}{ -TODO +get number of bytes of an array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_nbytes()}\if{html}{\out{
}} } @@ -598,7 +533,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_is_view}{}}} \subsection{Method \code{get_is_view()}}{ -TODO +get is_view metadata of array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_is_view()}\if{html}{\out{
}} } @@ -608,7 +543,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_oindex}{}}} \subsection{Method \code{get_oindex()}}{ -TODO +get orthogonal index of array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_oindex()}\if{html}{\out{
}} } @@ -618,7 +553,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_vindex}{}}} \subsection{Method \code{get_vindex()}}{ -TODO +get vectorized index of array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_vindex()}\if{html}{\out{
}} } @@ -628,7 +563,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_write_empty_chunks}{}}} \subsection{Method \code{get_write_empty_chunks()}}{ -TODO +get write empty chunks setting of array \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_write_empty_chunks()}\if{html}{\out{
}} } @@ -638,7 +573,7 @@ TODO \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-equals}{}}} \subsection{Method \code{equals()}}{ -TODO +check if another object refers to the same array. does not check array data \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$equals(other)}\if{html}{\out{
}} } @@ -703,7 +638,7 @@ array dimension.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrArray-get_basic_selection}{}}} \subsection{Method \code{get_basic_selection()}}{ -TODO +get a selection of an array based on a "basic"list of slices \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrArray$get_basic_selection(selection = NA, out = NA, fields = NA)}\if{html}{\out{
}} } diff --git a/man/ZarrGroup.Rd b/man/ZarrGroup.Rd index 2431425..421b547 100644 --- a/man/ZarrGroup.Rd +++ b/man/ZarrGroup.Rd @@ -196,7 +196,7 @@ Obtain a group member. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZarrGroup-create_group}{}}} \subsection{Method \code{create_group()}}{ -greate a group +create a group \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ZarrGroup$create_group(name, overwrite = FALSE)}\if{html}{\out{
}} } diff --git a/man/as.array.ZarrArray.Rd b/man/as.array.ZarrArray.Rd index 2a8c3e6..082fb8a 100644 --- a/man/as.array.ZarrArray.Rd +++ b/man/as.array.ZarrArray.Rd @@ -7,9 +7,9 @@ \method{as.array}{ZarrArray}(x, ...) } \arguments{ -\item{...}{not used} +\item{x}{object} -\item{obj}{object} +\item{...}{not used} } \description{ S3 method for as.array diff --git a/man/create_zarray_meta.Rd b/man/create_zarray_meta.Rd index 9bf4db8..e20f2d5 100644 --- a/man/create_zarray_meta.Rd +++ b/man/create_zarray_meta.Rd @@ -34,12 +34,13 @@ Primary compressor.} \item{fill_value}{: object Default value to use for uninitialized portions of the array.} -\item{order}{: {'C', 'F'}, optional +\item{order}{: \code{'C', 'F'}, optional Memory layout to be used within each chunk.} -\item{filters}{: sequence of Codecs, optional} +\item{filters}{: sequence, optional +Sequence of filters to use to encode chunk data prior to compression.} -\item{dimension_separator}{: {'.', '/'}, optional +\item{dimension_separator}{: \code{'.', '/'}, optional Separator placed between the dimensions of a chunk.} } \value{ diff --git a/man/init_array.Rd b/man/init_array.Rd index 63ad760..6e5e5fc 100644 --- a/man/init_array.Rd +++ b/man/init_array.Rd @@ -41,7 +41,7 @@ Primary compressor.} \item{fill_value}{: object Default value to use for uninitialized portions of the array.} -\item{order}{: {'C', 'F'}, optional +\item{order}{: \code{'C', 'F'}, optional Memory layout to be used within each chunk.} \item{overwrite}{: bool, optional @@ -60,7 +60,7 @@ Sequence of filters to use to encode chunk data prior to compression.} \item{object_codec}{: Codec, optional A codec to encode object arrays, only needed if dtype=object.} -\item{dimension_separator}{: {'.', '/'}, optional +\item{dimension_separator}{: \code{'.', '/'}, optional Separator placed between the dimensions of a chunk.} } \description{ diff --git a/man/init_group.Rd b/man/init_group.Rd index 5b65169..7149725 100644 --- a/man/init_group.Rd +++ b/man/init_group.Rd @@ -9,12 +9,12 @@ init_group(store, overwrite = FALSE, path = NA, chunk_store = NA) } \arguments{ \item{store}{: Store -A mapping that supports string keys and byte sequence values.} +A mapping that supports string keys and bytes-like values.} \item{overwrite}{: bool, optional If True, erase all data in \code{store} prior to initialisation.} -\item{path}{: string, optional +\item{path}{: string, bytes, optional Path under which array is stored.} \item{chunk_store}{: Store, optional diff --git a/man/slice.Rd b/man/slice.Rd index fc2e974..c29cbec 100644 --- a/man/slice.Rd +++ b/man/slice.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/slicing.R \name{slice} \alias{slice} -\title{Convenience function for the internal Slice class constructor.} +\title{Convenience function for the internal Slice R6 class constructor.} \usage{ slice(start, stop = NA, step = NA, zero_based = FALSE) } @@ -19,5 +19,5 @@ slice(start, stop = NA, step = NA, zero_based = FALSE) A Slice instance with the specified parameters. } \description{ -Convenience function for the internal Slice class constructor. +Convenience function for the internal Slice R6 class constructor. } diff --git a/man/zarr_create.Rd b/man/zarr_create.Rd index 1508544..0a70802 100644 --- a/man/zarr_create.Rd +++ b/man/zarr_create.Rd @@ -44,27 +44,27 @@ Primary compressor.} \item{fill_value}{: object Default value to use for uninitialized portions of the array.} -\item{order}{: {'C', 'F'}, optional +\item{order}{: \code{'C', 'F'}, optional Memory layout to be used within each chunk.} -\item{store}{: MutableMapping or string -Store or path to directory in file system or name of zip file.} +\item{store}{: Store +A mapping that supports string keys and bytes-like values.} \item{synchronizer}{: object, optional Array synchronizer.} \item{overwrite}{: bool, optional -If True, delete all pre-existing data in \code{store} at \code{path} before -creating the array.} +If True, erase all data in \code{store} prior to initialisation.} -\item{path}{: string, optional +\item{path}{: string, bytes, optional Path under which array is stored.} -\item{chunk_store}{: MutableMapping, optional +\item{chunk_store}{: Store, optional Separate storage for chunks. If not provided, \code{store} will be used for storage of both chunks and metadata.} -\item{filters}{: sequence of Codecs, optional} +\item{filters}{: sequence, optional +Sequence of filters to use to encode chunk data prior to compression.} \item{cache_metadata}{: bool, optional If True, array configuration metadata will be cached for the @@ -83,7 +83,7 @@ True if array should be protected against modification.} \item{object_codec}{: Codec, optional A codec to encode object arrays, only needed if dtype=object.} -\item{dimension_separator}{: {'.', '/'}, optional +\item{dimension_separator}{: \code{'.', '/'}, optional Separator placed between the dimensions of a chunk.} \item{write_empty_chunks}{: bool, optional diff --git a/man/zarr_create_empty.Rd b/man/zarr_create_empty.Rd index 69795fe..f8163c8 100644 --- a/man/zarr_create_empty.Rd +++ b/man/zarr_create_empty.Rd @@ -7,7 +7,8 @@ zarr_create_empty(shape, ...) } \arguments{ -\item{shape}{: int or tuple of ints} +\item{shape}{: int or tuple of ints +Array shape.} \item{...}{The params of zarr_create()} } diff --git a/man/zarr_create_group.Rd b/man/zarr_create_group.Rd index ecd2a66..01c713b 100644 --- a/man/zarr_create_group.Rd +++ b/man/zarr_create_group.Rd @@ -14,14 +14,13 @@ zarr_create_group( ) } \arguments{ -\item{store}{: MutableMapping or string, optional -Store or path to directory in file system.} +\item{store}{: Store +A mapping that supports string keys and bytes-like values.} \item{overwrite}{: bool, optional -If True, delete any pre-existing data in \code{store} at \code{path} before -creating the group.} +If True, erase all data in \code{store} prior to initialisation.} -\item{chunk_store}{: MutableMapping, optional +\item{chunk_store}{: Store, optional Separate storage for chunks. If not provided, \code{store} will be used for storage of both chunks and metadata.} @@ -33,8 +32,8 @@ to all attribute read operations.} \item{synchronizer}{: object, optional Array synchronizer.} -\item{path}{: string, optional -Group path within store.} +\item{path}{: string, bytes, optional +Path under which array is stored.} } \value{ ZarrGroup diff --git a/man/zarr_create_zeros.Rd b/man/zarr_create_zeros.Rd index 2e072d8..581939a 100644 --- a/man/zarr_create_zeros.Rd +++ b/man/zarr_create_zeros.Rd @@ -7,7 +7,8 @@ zarr_create_zeros(shape, ...) } \arguments{ -\item{shape}{: int or tuple of ints} +\item{shape}{: int or tuple of ints +Array shape.} \item{...}{The params of zarr_create()} } diff --git a/man/zarr_open.Rd b/man/zarr_open.Rd index 8133590..b5b4c3b 100644 --- a/man/zarr_open.Rd +++ b/man/zarr_open.Rd @@ -7,17 +7,17 @@ zarr_open(store = NA, mode = NA, path = NA, ...) } \arguments{ -\item{store}{: MutableMapping or string, optional -Store or path to directory in file system or name of zip file.} +\item{store}{: Store +A mapping that supports string keys and bytes-like values.} -\item{mode}{: {'r', 'r+', 'a', 'w', 'w-'}, optional +\item{mode}{: \code{'r', 'r+', 'a', 'w', 'w-'}, optional Persistence mode: 'r' means read only (must exist); 'r+' means read/write (must exist); 'a' means read/write (create if doesn't exist); 'w' means create (overwrite if exists); 'w-' means create (fail if exists).} -\item{path}{: str or NA, optional -The path within the store to open.} +\item{path}{: string, bytes, optional +Path under which array is stored.} \item{...}{Additional arguments to pass to zarr_open_array or zarr_open_group.} } diff --git a/man/zarr_open_array.Rd b/man/zarr_open_array.Rd index 01c1e70..dfdc006 100644 --- a/man/zarr_open_array.Rd +++ b/man/zarr_open_array.Rd @@ -27,14 +27,14 @@ zarr_open_array( ) } \arguments{ -\item{store}{: MutableMapping or string -Store or path to directory in file system or name of zip file.} +\item{store}{: Store +A mapping that supports string keys and bytes-like values.} \item{storage_options}{: dict If using an fsspec URL to create the store, these will be passed to the backend implementation. Ignored otherwise.} -\item{mode}{: {'r', 'r+', 'a', 'w', 'w-'}, optional +\item{mode}{: \code{'r', 'r+', 'a', 'w', 'w-'}, optional Persistence mode: 'r' means read only (must exist); 'r+' means read/write (must exist); 'a' means read/write (create if doesn't exist); 'w' means create (overwrite if exists); 'w-' means create @@ -43,11 +43,9 @@ exist); 'w' means create (overwrite if exists); 'w-' means create \item{shape}{: int or tuple of ints Array shape.} -\item{chunks}{: int or tuple of ints, optional +\item{chunks}{: bool, int or tuple of ints, optional Chunk shape. If True, will be guessed from \code{shape} and \code{dtype}. If -False, will be set to \code{shape}, i.e., single chunk for the whole array. -If an int, the chunk size in each dimension will be given by the value -of \code{chunks}. Default is True.} +False, will be set to \code{shape}, i.e., single chunk for the whole array.} \item{dtype}{: string or dtype, optional NumPy dtype.} @@ -58,24 +56,24 @@ Primary compressor.} \item{fill_value}{: object Default value to use for uninitialized portions of the array.} -\item{order}{: {'C', 'F'}, optional +\item{order}{: \code{'C', 'F'}, optional Memory layout to be used within each chunk.} \item{synchronizer}{: object, optional Array synchronizer.} \item{overwrite}{: bool, optional -If True, delete all pre-existing data in \code{store} at \code{path} before -creating the array.} +If True, erase all data in \code{store} prior to initialisation.} -\item{path}{: string, optional +\item{path}{: string, bytes, optional Path under which array is stored.} -\item{chunk_store}{: MutableMapping, optional +\item{chunk_store}{: Store, optional Separate storage for chunks. If not provided, \code{store} will be used for storage of both chunks and metadata.} -\item{filters}{: sequence of Codecs, optional} +\item{filters}{: sequence, optional +Sequence of filters to use to encode chunk data prior to compression.} \item{cache_metadata}{: bool, optional If True, array configuration metadata will be cached for the @@ -91,7 +89,7 @@ to all attribute read operations.} \item{object_codec}{: Codec, optional A codec to encode object arrays, only needed if dtype=object.} -\item{dimension_separator}{: {'.', '/'}, optional +\item{dimension_separator}{: \code{'.', '/'}, optional Separator placed between the dimensions of a chunk.} \item{write_empty_chunks}{: bool, optional diff --git a/man/zarr_open_group.Rd b/man/zarr_open_group.Rd index d62cf57..e2ba3aa 100644 --- a/man/zarr_open_group.Rd +++ b/man/zarr_open_group.Rd @@ -15,10 +15,10 @@ zarr_open_group( ) } \arguments{ -\item{store}{: MutableMapping or string, optional -Store or path to directory in file system or name of zip file.} +\item{store}{: Store +A mapping that supports string keys and bytes-like values.} -\item{mode}{: {'r', 'r+', 'a', 'w', 'w-'}, optional +\item{mode}{: \code{'r', 'r+', 'a', 'w', 'w-'}, optional Persistence mode: 'r' means read only (must exist); 'r+' means read/write (must exist); 'a' means read/write (create if doesn't exist); 'w' means create (overwrite if exists); 'w-' means create @@ -32,11 +32,12 @@ to all attribute read operations.} \item{synchronizer}{: object, optional Array synchronizer.} -\item{path}{: string, optional -Group path within store.} +\item{path}{: string, bytes, optional +Path under which array is stored.} -\item{chunk_store}{: MutableMapping or string, optional -Store or path to directory in file system or name of zip file.} +\item{chunk_store}{: Store, optional +Separate storage for chunks. If not provided, \code{store} will be used +for storage of both chunks and metadata.} \item{storage_options}{: dict If using an fsspec URL to create the store, these will be passed to diff --git a/man/zarr_save_array.Rd b/man/zarr_save_array.Rd index 0e2318c..418789d 100644 --- a/man/zarr_save_array.Rd +++ b/man/zarr_save_array.Rd @@ -7,8 +7,8 @@ zarr_save_array(store, arr, ...) } \arguments{ -\item{store}{: MutableMapping or string -Store or path to directory in file system or name of zip file.} +\item{store}{: Store +A mapping that supports string keys and bytes-like values.} \item{arr}{: ZarrArray The array with data to save.} diff --git a/man/zb_slice.Rd b/man/zb_slice.Rd index f4c0203..1eb139d 100644 --- a/man/zb_slice.Rd +++ b/man/zb_slice.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/slicing.R \name{zb_slice} \alias{zb_slice} -\title{Convenience function for the internal Slice class constructor +\title{Convenience function for the internal Slice R6 class constructor with zero-based indexing and exclusive stop index.} \usage{ zb_slice(start, stop = NA, step = NA) @@ -14,7 +14,10 @@ zb_slice(start, stop = NA, step = NA) \item{step}{The step size.} } +\value{ +A Slice instance with the specified parameters. +} \description{ -Convenience function for the internal Slice class constructor +Convenience function for the internal Slice R6 class constructor with zero-based indexing and exclusive stop index. } diff --git a/tests/fixtures/http_listdir.yml b/tests/fixtures/http_listdir.yml index 8dd8221..a91a8b8 100644 --- a/tests/fixtures/http_listdir.yml +++ b/tests/fixtures/http_listdir.yml @@ -26,21 +26,21 @@ http_interactions: x-content-type-options: nosniff x-frame-options: deny x-xss-protection: 1; mode=block - x-github-request-id: C9A0:2E1F0A:E4FCF1:10550D3:664F3D72 + x-github-request-id: 60A6:40449:5823C6:5F4A54:673E47B2 content-encoding: gzip accept-ranges: bytes - date: Thu, 23 May 2024 13:16:07 GMT + date: Wed, 20 Nov 2024 20:44:27 GMT via: 1.1 varnish - x-served-by: cache-iad-kiad7000164-IAD + x-served-by: cache-msp11861-MSP x-cache: HIT - x-cache-hits: '0' - x-timer: S1716470168.762871,VS0,VE1 + x-cache-hits: '1' + x-timer: S1732135467.214991,VS0,VE1 vary: Authorization,Accept-Encoding,Origin access-control-allow-origin: '*' cross-origin-resource-policy: cross-origin - x-fastly-request-id: ae1f9d2726d515b4f0e8fad7cb142a9c221e509e - expires: Thu, 23 May 2024 13:21:07 GMT - source-age: '153' + x-fastly-request-id: 57c44dababb32bb128e2dd21836a549acd128a0d + expires: Wed, 20 Nov 2024 20:49:27 GMT + source-age: '182' body: encoding: '' file: no @@ -232,5 +232,1418 @@ http_interactions: }, "zarr_consolidated_format": 1 } - recorded_at: 2024-05-23 13:16:08 GMT + recorded_at: 2024-11-20 20:44:27 GMT + recorded_with: vcr/1.2.2, webmockr/0.9.0 +- request: + method: get + uri: https://raw.githubusercontent.com/DOI-USGS/rnz/main/inst/extdata/bcsd.zarr/pr/0.0.0 + body: + encoding: '' + string: '' + headers: + User-Agent: libcurl/8.3.0 r-curl/5.2.1 crul/1.4.2 + Accept-Encoding: gzip, deflate + Accept: application/json, text/xml, application/xml, */* + response: + status: + status_code: '200' + message: OK + explanation: Request fulfilled, document follows + headers: + status: HTTP/1.1 200 OK + connection: keep-alive + content-length: '82010' + cache-control: max-age=300 + content-security-policy: default-src 'none'; style-src 'unsafe-inline'; sandbox + content-type: application/octet-stream + etag: W/"a9b0a9a147932e1f6dfd797b7ebb0687d2127f34cc76943129c68e8eb69c9a29" + strict-transport-security: max-age=31536000 + x-content-type-options: nosniff + x-frame-options: deny + x-xss-protection: 1; mode=block + x-github-request-id: 6CD8:24B317:5C6110:639130:673E48A2 + accept-ranges: bytes + date: Wed, 20 Nov 2024 20:44:27 GMT + via: 1.1 varnish + x-served-by: cache-msp11861-MSP + x-cache: HIT + x-cache-hits: '1' + x-timer: S1732135468.520604,VS0,VE1 + vary: Authorization,Accept-Encoding,Origin + access-control-allow-origin: '*' + cross-origin-resource-policy: cross-origin + x-fastly-request-id: 902f6197e0cc9b7075551681d892f6d2c0fc8a6b + expires: Wed, 20 Nov 2024 20:49:27 GMT + source-age: '45' + body: + encoding: '' + file: no + base64_string: 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 + recorded_at: 2024-11-20 20:44:27 GMT recorded_with: vcr/1.2.2, webmockr/0.9.0 diff --git a/tests/testthat/test-parallel.R b/tests/testthat/test-01-parallel.R similarity index 82% rename from tests/testthat/test-parallel.R rename to tests/testthat/test-01-parallel.R index 20cb74c..b3ce873 100644 --- a/tests/testthat/test-parallel.R +++ b/tests/testthat/test-01-parallel.R @@ -5,7 +5,7 @@ SlowGettingDirectoryStore <- R6::R6Class("SlowGettingDirectoryStore", public = list( get_item = function(key) { # Simulate a slow read such as an HTTP request. - Sys.sleep(1.0/10.0) + Sys.sleep(1.0/25) return(super$get_item(key)) } ) @@ -16,7 +16,7 @@ SlowSettingDirectoryStore <- R6::R6Class("SlowSettingDirectoryStore", public = list( set_item = function(key, value) { # Simulate a slow write such as an HTTP request. - Sys.sleep(1.0/10.0) + Sys.sleep(1.0/25) return(super$set_item(key, value)) } ) @@ -65,37 +65,41 @@ run_parallel_set <- function(num_workers) { return(sum(doubled_arr)) } -test_that("can run get_item() in parallel", { +cl1 <- parallel::makeCluster(1) +cl2 <- parallel::makeCluster(2) + +test_that("can run get_item() and set_item in parallel", { + bench_df <- bench::mark( - run_parallel_get(1), - run_parallel_get(2), - run_parallel_get(4), - iterations = 10, + run_parallel_get(cl1), + run_parallel_get(cl2), + iterations = 1, memory = FALSE, filter_gc = FALSE ) - expect_equal(unlist(bench_df$result), rep(134538481, 3)) + expect_equal(unlist(bench_df$result), rep(134538481, 2)) expect_equal(bench_df$total_time[[1]] > bench_df$total_time[[2]], TRUE) - expect_equal(bench_df$total_time[[2]] > bench_df$total_time[[3]], TRUE) + }) test_that("can run set_item() in parallel", { + bench_df <- bench::mark( - run_parallel_set(1), - run_parallel_set(2), - run_parallel_set(4), - iterations = 10, + run_parallel_set(cl1), + run_parallel_set(cl2), + iterations = 1, memory = FALSE, filter_gc = FALSE ) - expect_equal(unlist(bench_df$result), rep(134538481*2.0, 3)) + expect_equal(unlist(bench_df$result), rep(134538481*2.0, 2)) expect_equal(bench_df$total_time[[1]] > bench_df$total_time[[2]], TRUE) - expect_equal(bench_df$total_time[[2]] > bench_df$total_time[[3]], TRUE) + }) test_that("parse_parallel_option works as expected", { + expect_equal(parse_parallel_option(cl1), cl1) expect_equal(parse_parallel_option("future"), "future") expect_equal(parse_parallel_option("0"), FALSE) expect_equal(parse_parallel_option(0), FALSE) @@ -110,6 +114,7 @@ test_that("parse_parallel_option works as expected", { }) test_that("is_truthy_parallel_option works as expected", { + expect_equal(is_truthy_parallel_option(cl1), TRUE) expect_equal(is_truthy_parallel_option("future"), TRUE) expect_equal(is_truthy_parallel_option(FALSE), FALSE) expect_equal(is_truthy_parallel_option(0), FALSE) @@ -117,3 +122,6 @@ test_that("is_truthy_parallel_option works as expected", { expect_equal(is_truthy_parallel_option(1), TRUE) expect_equal(is_truthy_parallel_option(2), TRUE) }) + +parallel::stopCluster(cl1) +parallel::stopCluster(cl2) diff --git a/tests/testthat/test-http-store.R b/tests/testthat/test-http-store.R index e70c89f..66b46a8 100644 --- a/tests/testthat/test-http-store.R +++ b/tests/testthat/test-http-store.R @@ -70,10 +70,34 @@ vcr::use_cassette("http_listdir", { expect_equal(names(g$get_store()$get_consolidated_metadata()$metadata), names(z$get_consolidated_metadata()$metadata)) + options(pizzarr.parallel_write_enabled = "future") + old_plan <- future::plan(future::multisession, workers = 2) + + expect_equal(dim(g$get_item("pr")$as.array()), c(12, 33, 81)) + + options(pizzarr.parallel_write_enabled = FALSE) + future::plan(old_plan) }) }) +test_that("http broken", { + + url<- "https://nogonnawork.zarr" + + expect_warning(z <- pizzarr::HttpStore$new(url), "Can't procede, web request failed.") + expect_equal(class(z), c("HttpStore", "Store", "R6")) + + expect_message(vars <- z$listdir(), "not found for this http store") + + expect_null(vars) + + w <- capture_warnings(g <- pizzarr::zarr_open_group(z)) + + expect_equal(w, c("Can't procede, web request failed.", + "Can't procede, web request failed.")) +}) + vcr::use_cassette("http_github_pattern", { test_that("http_listdir", { diff --git a/tests/testthat/test-orthogonal-selection.R b/tests/testthat/test-orthogonal-selection.R index 51d8d4b..689b0aa 100644 --- a/tests/testthat/test-orthogonal-selection.R +++ b/tests/testthat/test-orthogonal-selection.R @@ -22,8 +22,7 @@ test_that("orthogonal selection", { # int and zb_int expect_equal( z$get_orthogonal_selection(list(zb_int(c(0,1)), zb_int(c(1,2,3))))$data, - z$get_orthogonal_selection(list(int(c(1, 2)), int(c(2,3,4))))$data, - ) + z$get_orthogonal_selection(list(int(c(1, 2)), int(c(2,3,4))))$data) # TODO: do not expect error once negative indexing has been implemented. expect_error(z$get_orthogonal_selection(list(c(-1,1),c(12,1,6)))$data) diff --git a/vignettes/parallel.Rmd b/vignettes/parallel.Rmd index d82a644..7956d9e 100644 --- a/vignettes/parallel.Rmd +++ b/vignettes/parallel.Rmd @@ -13,12 +13,15 @@ vignette: > comment = "#>", out.width = "100%" ) +library(pizzarr) ``` By default, reads and writes are performed sequentially (i.e., not in parallel). Users can opt-in to parallel read/write functionality via `options`. -```{r} +```{r, eval=FALSE} +# not run by default + library(pizzarr) if(!requireNamespace("pbapply", quietly = TRUE)) { @@ -46,7 +49,7 @@ SlowDirectoryStore <- R6::R6Class("SlowDirectoryStore", ## Read in parallel -Provide an integer >= 2 to the option to use forking-based parallelism. +Provide an integer >= 2 or a cluster object to the option to use forking-based parallelism. This value will be passed to the `cl` parameter of `pbapply::pblapply`. ```{r} @@ -99,6 +102,7 @@ Multisession-based: ```{r} options(pizzarr.parallel_read_enabled = "future") +oldplan <- future::plan() future::plan(future::multisession, workers = 4) root <- pizzarr_sample("dog.ome.zarr") @@ -106,6 +110,8 @@ store <- SlowDirectoryStore$new(root) zarr_arr <- zarr_open(store = store, path = "/0") arr <- zarr_arr$get_item("...")$data sum(arr) + +future::plan(oldplan) ``` ## Sequential operations