From 47729f6b387c914814d946a486fc8e7652e7ad83 Mon Sep 17 00:00:00 2001 From: Artur-man Date: Mon, 11 May 2026 10:05:31 +0200 Subject: [PATCH 1/2] small fix for image dataset validation --- R/AllGenerics.R | 1 + R/read.R | 15 +++++++++++---- R/sdArray.R | 16 +++++----------- R/sdAttrs.R | 8 ++++++++ 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/R/AllGenerics.R b/R/AllGenerics.R index 7936cba1..d987509a 100644 --- a/R/AllGenerics.R +++ b/R/AllGenerics.R @@ -107,6 +107,7 @@ setGeneric("centroids", \(x, ...) standardGeneric("centroids")) setGeneric("data_type", \(x, ...) standardGeneric("data_type")) setGeneric("geom_type", \(x, ...) standardGeneric("geom_type")) setGeneric("multiscales", \(x, ...) standardGeneric("multiscales")) +setGeneric("datasets", \(x, ...) standardGeneric("datasets")) # tbl ---- diff --git a/R/read.R b/R/read.R index 355ae1fd..3a303fc8 100644 --- a/R/read.R +++ b/R/read.R @@ -46,24 +46,31 @@ NULL #' @importFrom ZarrArray ZarrArray .readArray <- function(x, ...) { md <- read_zarr_attributes(x) - ps <- .get_multiscales_paths(x) + mdattr <- SpatialDataAttrs(md) + # TODO: paths to datasets have to be validated properly in the future + # https://ngff.openmicroscopy.org/specifications/0.5/index.html#images + # The name of the array is arbitrary with the ordering defined by + # by the "multiscales" metadata, but is often a sequence starting at 0. + ps <- .validate_multiscales_paths(x, datasets(mdattr)) ps <- file.path(x, as.character(ps)) as <- lapply(ps, ZarrArray) - list(array=as, md=md) + list(array=as, mdattr=mdattr) } #' @rdname readSpatialData #' @export readImage <- function(x, ...) { l <- .readArray(x, ...) - SpatialDataImage(data=l$array, meta=SpatialDataAttrs(l$md), ...) + # SpatialDataImage(data=l$array, meta=SpatialDataAttrs(l$md), ...) + SpatialDataImage(data=l$array, meta=l$mdattr, ...) } #' @rdname readSpatialData #' @export readLabel <- function(x, ...) { l <- .readArray(x, ...) - SpatialDataLabel(data=l$array, meta=SpatialDataAttrs(l$md), ...) + # SpatialDataLabel(data=l$array, meta=SpatialDataAttrs(l$md), ...) + SpatialDataLabel(data=l$array, meta=l$mdattr, ...) } #' @rdname readSpatialData diff --git a/R/sdArray.R b/R/sdArray.R index 63b72a4f..e94e1a9d 100644 --- a/R/sdArray.R +++ b/R/sdArray.R @@ -146,19 +146,13 @@ setMethod("channels", "SpatialDataImage", \(x, ...) channels(meta(x))) #' @rdname SpatialDataArray setMethod("channels", "SpatialDataElement", \(x, ...) stop("only 'images' have channels")) +# compares metadata dataset paths to arrays on disk #' @importFrom S4Vectors isSequence -.get_multiscales_paths <- function(x) { +.validate_multiscales_paths <- function(x, ds) { ps <- list.files(x) - ps <- suppressWarnings(as.numeric(sort(ps, decreasing=FALSE))) - ps <- ps[!is.na(ps)] - if (length(ps)) { - qs <- seq(min(ps), max(ps)) - if (!isTRUE(all.equal(ps, qs))) - stop("SpatialDataImage paths are ill-defined, should", - " be an integer sequence, e.g., 0,1,...,n") - } else { - stop("SpatialDataImage path is empty") - } + ps <- ps[ps %in% ds] + if (!length(ps)) + stop("Invalid SpatialData image or label: metadata does not match the names of Zarr arrays") return(ps) } diff --git a/R/sdAttrs.R b/R/sdAttrs.R index 8944f798..0518d006 100644 --- a/R/sdAttrs.R +++ b/R/sdAttrs.R @@ -142,6 +142,14 @@ setMethod("$", "SpatialDataAttrs", \(x, name) x[[name]]) #' @noRd setMethod("multiscales", "list", .ms) +# internal use only! +#' @noRd +setMethod("datasets", "list", \(x, ...) { + vapply(multiscales(x)[[1]]$datasets, \(.){ + .$path + }, character(1)) +}) + # features ---- #' @export From fc13b2bfef84c8ecb24d53fc0e543491c6ac6c5a Mon Sep 17 00:00:00 2001 From: Artur-man Date: Mon, 11 May 2026 10:30:44 +0200 Subject: [PATCH 2/2] more updates on validation --- R/read.R | 8 +++----- R/sdArray.R | 6 +++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/R/read.R b/R/read.R index 3a303fc8..30e7cd67 100644 --- a/R/read.R +++ b/R/read.R @@ -51,9 +51,9 @@ NULL # https://ngff.openmicroscopy.org/specifications/0.5/index.html#images # The name of the array is arbitrary with the ordering defined by # by the "multiscales" metadata, but is often a sequence starting at 0. - ps <- .validate_multiscales_paths(x, datasets(mdattr)) - ps <- file.path(x, as.character(ps)) - as <- lapply(ps, ZarrArray) + ds <- .validate_multiscales_paths(x, datasets(mdattr)) + ds <- file.path(x, as.character(ds)) + as <- lapply(ds, ZarrArray) list(array=as, mdattr=mdattr) } @@ -61,7 +61,6 @@ NULL #' @export readImage <- function(x, ...) { l <- .readArray(x, ...) - # SpatialDataImage(data=l$array, meta=SpatialDataAttrs(l$md), ...) SpatialDataImage(data=l$array, meta=l$mdattr, ...) } @@ -69,7 +68,6 @@ readImage <- function(x, ...) { #' @export readLabel <- function(x, ...) { l <- .readArray(x, ...) - # SpatialDataLabel(data=l$array, meta=SpatialDataAttrs(l$md), ...) SpatialDataLabel(data=l$array, meta=l$mdattr, ...) } diff --git a/R/sdArray.R b/R/sdArray.R index e94e1a9d..e61346fd 100644 --- a/R/sdArray.R +++ b/R/sdArray.R @@ -150,10 +150,10 @@ setMethod("channels", "SpatialDataElement", \(x, ...) stop("only 'images' have c #' @importFrom S4Vectors isSequence .validate_multiscales_paths <- function(x, ds) { ps <- list.files(x) - ps <- ps[ps %in% ds] - if (!length(ps)) + ds <- ds[ds %in% ps] + if (!length(ds)) stop("Invalid SpatialData image or label: metadata does not match the names of Zarr arrays") - return(ps) + return(ds) } # sub ----