diff --git a/R/CTutils.R b/R/CTutils.R index 15736006..368d17ce 100644 --- a/R/CTutils.R +++ b/R/CTutils.R @@ -3,6 +3,9 @@ #' @aliases axes CTlist CTname CTtype CTdata addCT rmvCT #' #' @param x \code{SpatialData}, an element, or \code{SpatialDataAttrs}. +#' @param y NULL (default) returns a list where each element is +#' an axis: a list with name/type/unit (e.g., x/space/micrometer); +#' \code{y="name/type/unit"} extracts specific data over all axiis. #' @param i for \code{CTpath}, source node label; else, string or #' scalar integer giving the name or index of a coordinate space. #' @param name character(1); name of coordinate space @@ -51,11 +54,13 @@ NULL #' @rdname CTutils #' @export -setMethod("axes", "SpatialDataAttrs", \(x, ...) { +setMethod("axes", "SpatialDataAttrs", \(x, y=NULL, ...) { ms <- multiscales(x) if (!is.null(ms)) x <- ms[[1]] if (is.null(x <- x$axes)) stop("couldn't find 'axes'") - return(x) + if (is.null(y)) return(x) + y <- match.arg(y, c("name", "type", "unit")) + vapply(x, `[[`, character(1), y) }) # CTlist/data/type/name() ---- @@ -105,7 +110,7 @@ setMethod("CTname", "SpatialDataAttrs", \(x, ...) { #' @rdname CTutils #' @export -setMethod("axes", "SpatialDataElement", \(x, ...) axes(meta(x), ...)) +setMethod("axes", "SpatialDataElement", \(x, y=NULL, ...) axes(meta(x), y, ...)) #' @rdname CTutils #' @export diff --git a/R/centroids.R b/R/centroids.R index cd7ac93f..b9fb3d28 100644 --- a/R/centroids.R +++ b/R/centroids.R @@ -36,18 +36,34 @@ setMethod("centroids", "SpatialDataLabel", \(x, as=c("data.frame", "matrix")) { as <- match.arg(as) y <- data(x) + if (length(dim(y)) > 2) { + # max-projection + ax <- match(c("y", "x"), axes(x, "name")) + y <- apply(y, ax, max) + } y <- as(y, "dgCMatrix") i <- summary(y) # flip dimensions so that columns=x, rows=y - # TODO: should these be offset by 0.5? i[, c(1, 2)] <- i[, c(2, 1)]-0.5 xy <- tapply(i[, -3], i[[3]], colMeans) xy <- do.call(rbind, xy) xy <- cbind(xy, as.integer(rownames(xy))) dimnames(xy) <- list(NULL, c("x", "y", "i")) + # multi-scale adjustment + sf <- .get_multiscale_scale(x) + xy[,1] <- xy[,1]*tail(sf, 1) + xy[,2] <- xy[,2]*tail(sf, 2)[1] + # offset + wh <- metadata(x)$wh + if (!is.null(wh)) { + xy[,1] <- xy[,1]+wh[[1]][1] + xy[,2] <- xy[,2]+wh[[2]][1] + } + # output if (as == "matrix") return(xy) xy <- as.data.frame(xy) - xy$i <- factor(xy$i); xy + xy$i <- factor(xy$i) + return(xy) }) #' @export diff --git a/man/CTutils.Rd b/man/CTutils.Rd index 3e28c3d2..e8a33d6d 100644 --- a/man/CTutils.Rd +++ b/man/CTutils.Rd @@ -26,7 +26,7 @@ \alias{addCT,SpatialDataAttrs-method} \title{Coord. trans. utilities} \usage{ -\S4method{axes}{SpatialDataAttrs}(x, ...) +\S4method{axes}{SpatialDataAttrs}(x, y = NULL, ...) \S4method{CTlist}{SpatialDataAttrs}(x, ...) @@ -36,7 +36,7 @@ \S4method{CTname}{SpatialDataAttrs}(x, ...) -\S4method{axes}{SpatialDataElement}(x, ...) +\S4method{axes}{SpatialDataElement}(x, y = NULL, ...) \S4method{CTlist}{SpatialDataElement}(x, ...) @@ -59,6 +59,10 @@ \arguments{ \item{x}{\code{SpatialData}, an element, or \code{SpatialDataAttrs}.} +\item{y}{NULL (default) returns a list where each element is +an axis: a list with name/type/unit (e.g., x/space/micrometer); +\code{y="name/type/unit"} extracts specific data over all axiis.} + \item{...}{option arguments passed to and from other methods.} \item{i}{for \code{CTpath}, source node label; else, string or