Diff of /R/assay.R [000000] .. [413088]

Switch to side-by-side view

--- a
+++ b/R/assay.R
@@ -0,0 +1,1190 @@
+#' @include zzz.R
+#' @importClassesFrom Matrix dgCMatrix dgRMatrix dgeMatrix
+#' @importClassesFrom S4Arrays Array
+NULL
+
+####
+# Objects and Classes ####
+####
+
+## vrAssay and vrAssayV2####
+
+## UpdateAssay ####
+
+updateAssayvrAssay <- function(object){
+  
+  # data matrix and feature data
+  data_list <- list(main = object@rawdata, main_norm = object@normdata)
+  featuredata_list <- list(main = object@featuredata)
+  
+  # create assay v2
+  methods::new("vrAssayV2",
+               data = data_list,
+               featuredata = featuredata_list,
+               embeddings = object@embeddings,
+               image = object@image,
+               params = object@params,
+               type = object@type,
+               name = object@name,
+               main_image = object@main_image,
+               main_featureset = "main")
+}
+
+#' @param object a vrAssay object to be converted to vrAssayV2
+#' @rdname updateAssay
+#' @method updateAssay vrAssay
+#' @importFrom methods new
+setMethod("updateAssay", "vrAssay", updateAssayvrAssay)
+
+updateAssayvrAssayV2 <- function(object){
+  message("The assay is of version 2, nothing to change!")
+  return(object)
+}
+
+#' @param object a vrAssayV2 object to be converted to vrAssayV2
+#' @rdname updateAssay
+#' @method updateAssay vrAssayV2
+setMethod("updateAssay", "vrAssayV2", updateAssayvrAssayV2)
+
+####
+# Methods ####
+####
+
+### Create vrAssay Object ####
+
+#' formAssay
+#'
+#' Create a vrAssay (VoltRon assay) object
+#'
+#' @param data the feature matrix of spatialpoints
+#' @param coords the coordinates of the spatial points
+#' @param segments the list of segments each associated with a spatial point (optional)
+#' @param image a singelton or list of images as magick-image objects
+#' @param params additional parameters of the object
+#' @param type the type of the assay (tile, molecule, cell, spot or ROI)
+#' @param name the name of the assay
+#' @param main_image the name of the main_image
+#' @param main_featureset the name of the main_featureset
+#' @param assay_version the assay version
+#' @param ... additional arguements passed to \link{formImage}
+#'
+#' @importFrom methods new
+#'
+#' @export
+#'
+formAssay <- function(data = NULL, 
+                      coords, 
+                      segments = list(), 
+                      image = NULL, 
+                      params = list(), 
+                      type = "ROI", 
+                      name = "Assay1", 
+                      main_image = "image_1", 
+                      main_featureset = NULL, 
+                      assay_version = "v2", 
+                      ...){
+
+  # get data
+  if(is.null(data)){
+    data <- matrix(nrow = 0, ncol = nrow(coords))
+    colnames(data) <- rownames(coords)
+  }
+
+  # get image object
+  image <- formImage(coords = coords, segments = segments, image = image, ...)
+  image <- list(image)
+  names(image) <- main_image
+
+  # check feature
+  if(is.null(main_featureset))
+    main_featureset <- "main"
+  
+  # make vrAssay object
+  data_list <- list(main = data, main_norm = data)
+  names(data_list) <- c(main_featureset, paste0(main_featureset, "_norm"))
+  if(assay_version == "v2"){
+    object <-   methods::new("vrAssayV2", 
+                             data = data_list,
+                             image = image, params = params, type = type, name = name, 
+                             main_image = main_image, main_featureset = main_featureset)
+  } else {
+    object <-   methods::new("vrAssay", 
+                             rawdata = data, normdata = data,
+                             image = image, params = params, type = type, name = name, 
+                             main_image = main_image)
+  }
+  return(object)
+}
+
+### Subset vrAssay objects ####
+
+subsetvrAssay <- function(x, subset, spatialpoints = NULL, features = NULL, image = NULL) {
+  
+  # start 
+  object <- x
+  
+  if (!missing(x = subset)) {
+    subset <- rlang::enquo(arg = subset)
+  }
+  
+  # subseting on samples, layers and assays
+  if(!is.null(features)){
+    
+    # select features
+    nonmatching_features <- setdiff(features, vrFeatures(object))
+    features <- intersect(vrFeatures(object), features)
+    
+    if(length(features) > 0){
+      # object@rawdata <- object@rawdata[rownames(object@rawdata) %in% features,, drop = FALSE]
+      # object@normdata <- object@normdata[rownames(object@normdata) %in% features,, drop = FALSE]
+      object <- subsetData(object, features = features)
+      object <- subsetData(object, features = features)
+      
+    } else {
+      stop("none of the provided features are found in the assay")
+    }
+    
+    if(length(nonmatching_features))
+      message("the following features are not found in the assay: ", paste(nonmatching_features, collapse = ", "))
+    
+  } else {
+    
+    if(!is.null(spatialpoints)){
+      
+      # check if spatial points are here
+      spatialpoints <- intersect(spatialpoints, vrSpatialPoints(object))
+      if(length(spatialpoints) == 0){
+        return(NULL)
+      }
+      
+      # data
+      # object@rawdata  <- object@rawdata[,spatialpoints, drop = FALSE]
+      # object@normdata  <- object@normdata[,spatialpoints, drop = FALSE]
+      object <- subsetData(object, spatialpoints = spatialpoints)
+      object <- subsetData(object, spatialpoints = spatialpoints)
+      
+      # embeddings
+      for(embed in vrEmbeddingNames(object)){
+        embedding <- vrEmbeddings(object, type = embed)
+        vrEmbeddings(object, type = embed) <- embedding[spatialpoints[spatialpoints %in% rownames(embedding)],, drop = FALSE]
+      }
+      
+      # image
+      # for(img in vrImageNames(object))
+      for(img in vrSpatialNames(object))
+        object@image[[img]] <- subsetvrImage(object@image[[img]], spatialpoints = spatialpoints)
+        # object@image[[img]] <- subset.vrImage(object@image[[img]], spatialpoints = spatialpoints)
+      
+    } else if(!is.null(image)) {
+      
+      # images
+      img <- vrMainSpatial(object)
+      object@image <- object@image[img]
+      object@image[[img]] <- subsetvrImage(object@image[[img]], image = image)
+      # object@image[[img]] <- subset.vrImage(object@image[[img]], image = image)
+      spatialpoints <- rownames(vrCoordinates(object@image[[img]]))
+      
+      # data
+      # object@rawdata  <- object@rawdata[,colnames(object@rawdata) %in% spatialpoints, drop = FALSE]
+      # object@normdata  <- object@normdata[,colnames(object@normdata) %in% spatialpoints, drop = FALSE]
+      object <- subsetData(object, spatialpoints = spatialpoints)
+      object <- subsetData(object, spatialpoints = spatialpoints)
+      
+      # embeddings
+      for(embed in vrEmbeddingNames(object)){
+        embedding <- vrEmbeddings(object, type = embed)
+        vrEmbeddings(object, type = embed) <- embedding[rownames(embedding) %in% spatialpoints,, drop = FALSE]
+      }
+    } else {
+      
+      # else return empty
+      return(NULL)
+    }
+  }
+  
+  # set VoltRon class
+  return(object)
+}
+
+#' Subsetting vrAssay objects
+#'
+#' Given a vrAssay object, subset the object given one of the attributes
+#'
+#' @param x a vrAssay object
+#' @param subset Logical statement for subsetting
+#' @param spatialpoints the set of spatial points to subset the object
+#' @param features the set of features to subset the object
+#' @param image the subseting string passed to \link{image_crop}
+#'
+#' @method subset vrAssay
+#' @order 4
+#'
+#' @importFrom rlang enquo
+#'
+#' @export
+setMethod("subset", "vrAssay", subsetvrAssay)
+
+#' Subsetting vrAssayV2 objects
+#'
+#' Given a vrAssayV2 object, subset the object given one of the attributes
+#'
+#' @param x a vrAssayV2 object
+#' @param subset Logical statement for subsetting
+#' @param spatialpoints the set of spatial points to subset the object
+#' @param features the set of features to subset the object
+#' @param image the subseting string passed to \link{image_crop}
+#'
+#' @method subset vrAssayV2
+#' @order 4
+#'
+#' @export
+setMethod("subset", "vrAssayV2", subsetvrAssay)
+
+#' subsetCoordinates
+#'
+#' subsetting coordinates given cropping parameters of a magick image objects
+#'
+#' @param coords the coordinates of the spatial points
+#' @param image the magick image associated with the coordinates
+#' @param crop_info the subseting string passed to \link{image_crop}
+#'
+subsetCoordinates <- function(coords, image, crop_info){
+
+  # image
+  imageinfo <- image_info(image)
+
+  # get crop information
+  crop_info <- strsplit(crop_info, split = "\\+")[[1]]
+  crop_info <- unlist(lapply(crop_info, function(x) strsplit(x, "x")))
+  crop_info <- as.numeric(crop_info)
+
+  # get uncropped spatial points
+  xlim <- c(crop_info[3], crop_info[3]+crop_info[1])
+  ylim <- c(crop_info[4], crop_info[4]+crop_info[2])
+  ylim <- rev(imageinfo$height - ylim)
+
+  # adjust for maximum res
+  if(ylim[2] < 0){
+    ylim[2] <- 0
+    # ylim[1] <- ylim[2] - imageinfo$height + crop_info[2] # CHANGE THIS LATER ?
+  }
+  if(xlim[2] > imageinfo$width){
+    xlim[2] <- imageinfo$width
+    # xlim[1] <- xlim[2] - crop_info[1] # CHANGE THIS LATER ?
+  }
+
+  # get inside coords
+  if(inherits(coords, "IterableMatrix")){
+    # BPCells only accepts e1 > e2 ## S4 method for signature 'IterableMatrix,numeric'
+    inside <- (!!as.vector(as(coords[,1] > xlim[1], "dgCMatrix")) & 
+                 !!!as.vector(as(coords[,1] > xlim[2], "dgCMatrix"))) & 
+      (!!as.vector(as(coords[,2] > ylim[1], "dgCMatrix")) & 
+         !!!as.vector(as(coords[,2] > ylim[2], "dgCMatrix"))) 
+  } else {
+    inside <- (coords[,1] > xlim[1] & coords[,1] < xlim[2]) & (coords[,2] > ylim[1] & coords[,2] < ylim[2])
+  }
+  coords <- coords[inside,]
+
+  if(nrow(coords) > 0){
+    # adjust coordinates
+    coords[,1] <- coords[,1] - xlim[1]
+    coords[,2] <- coords[,2] - ylim[1]
+
+    # return new coords
+    return(coords)
+  } else {
+    stop("No spatial points remain after cropping!")
+  }
+}
+
+#' subsetSegments
+#'
+#' subsetting segments given cropping parameters of a magick image objects
+#'
+#' @param segments the list of segments each associated with a spatial point
+#' @param image the magick image associated with the coordinates
+#' @param crop_info the subseting string passed to \link{image_crop}
+#'
+#' @importFrom dplyr bind_rows
+subsetSegments <- function(segments, image, crop_info){
+
+  # get segments
+  segment_names <- names(segments)
+  segments <- do.call(dplyr::bind_rows, segments)
+  rownames(segments) <- seq_len(nrow(segments))
+  segments <- data.frame(segments, row_id = rownames(segments))
+  
+  # subset
+  cropped_segments <- subsetCoordinates(segments[,c("x","y")], image, crop_info)
+  if(any(colnames(segments) %in% c("rx", "ry"))){
+    cropped_segments_extra <- segments[rownames(cropped_segments), c("rx", "ry")]
+    cropped_segments <- cbind(cropped_segments, cropped_segments_extra)
+  }
+  cropped_segments <- data.frame(cropped_segments, id = segments[rownames(cropped_segments),1], row_id = rownames(cropped_segments))
+  cropped_segments <- cropped_segments %>% right_join(segments[,c(colnames(segments)[1], "row_id")], by = c("row_id" = "row_id"))
+  if(any(colnames(segments) %in% c("rx", "ry"))){
+    cropped_segments <- cropped_segments[,c(colnames(cropped_segments)[which(grepl(colnames(segments)[1], colnames(cropped_segments)))[1]], "x", "y", "rx", "ry")]
+    colnames(cropped_segments) <- c("id", "x", "y", "rx", "ry")
+    
+  } else {
+    cropped_segments <- cropped_segments[,c(colnames(cropped_segments)[which(grepl(colnames(segments)[1], colnames(cropped_segments)))[1]], "x", "y")]
+    colnames(cropped_segments) <- c("id", "x", "y")
+  }
+  # split back to segments
+  segments <- split(cropped_segments, cropped_segments[,1])
+  segments <- lapply(segments, function(df){
+    df[,colSums(is.na(df))<nrow(df), drop = FALSE]
+  })
+  names(segments) <- segment_names
+  
+  # return
+  return(segments)
+}
+
+#' subsetData
+#'
+#' subsetting data matrices given spatialpoints, features etc.
+#'
+#' @param object a vrAssay object
+#' @param spatialpoints the set of spatial points to subset the object
+#' @param features the set of features to subset the object
+#'
+#' @noRd
+subsetData <- function(object, spatialpoints = NULL, features = NULL){
+  
+  # features
+  if(!is.null(features)){
+    
+    if(inherits(object, "vrAssay")){
+      if(nrow(object@rawdata) > 0){
+        object@rawdata <- object@rawdata[rownames(object@rawdata) %in% features,, drop = FALSE]
+        object@normdata <- object@normdata[rownames(object@normdata) %in% features,, drop = FALSE]
+      }
+    } else {
+      main <- vrMainFeatureType(object)
+      if(nrow(object@data[[main]]) > 0){
+        object@data[[main]] <- object@data[[main]][rownames(object@data[[main]]) %in% features,, drop = FALSE]
+        object@data[[paste0(main, "_norm")]] <- object@data[[paste0(main, "_norm")]][rownames(object@data[[paste0(main, "_norm")]]) %in% features,, drop = FALSE]
+      }
+    }
+  }
+  
+  # spatialpoints
+  if(!is.null(spatialpoints)){
+    
+    if(inherits(object, "vrAssay")){
+      # if(nrow(object@rawdata) > 0){
+      if(ncol(object@rawdata) > 0){
+        object@rawdata  <- object@rawdata[,colnames(object@rawdata) %in% spatialpoints, drop = FALSE]
+        object@normdata  <- object@normdata[,colnames(object@normdata) %in% spatialpoints, drop = FALSE]
+      }
+    } else {
+      for(nm in vrFeatureTypeNames(object)){
+        # if(nrow(object@data[[nm]]) > 0){
+        if(ncol(object@data[[nm]]) > 0){
+          object@data[[nm]] <- object@data[[nm]][,colnames(object@data[[nm]]) %in% spatialpoints, drop = FALSE]
+          object@data[[paste0(nm, "_norm")]] <- object@data[[paste0(nm, "_norm")]][,colnames(object@data[[paste0(nm, "_norm")]]) %in% spatialpoints, drop = FALSE]
+        }
+      }
+    }
+  }
+  
+  # return
+  return(object)
+}
+
+#' getData
+#'
+#' get data matrix
+#'
+#' @param object a vrAssay object
+#'
+#' @noRd
+getData <- function(object){
+  
+  if(inherits(object, "vrAssay")){
+    data <- object@rawdata
+  } else {
+    data <- object@data[[vrMainFeatureType(object)]]
+  }
+  
+  return(data)
+}
+
+#' updateData
+#'
+#' update data matrix
+#'
+#' @param object a vrAssay object
+#' @param value the new column names
+#'
+#' @noRd
+updateData <- function(object, value){
+  
+  if(inherits(object, "vrAssay")){
+    if(ncol(object@rawdata) > 0){
+      colnames(object@rawdata) <- value
+      colnames(object@normdata) <- value 
+    }
+  } else {
+    for(nm in vrFeatureTypeNames(object)){
+      if(ncol(object@data[[nm]] > 0)){
+        colnames(object@data[[nm]]) <- value
+        colnames(object@data[[paste0(nm, "_norm")]]) <- value
+      }
+    }
+  }
+  
+  return(object)
+}
+
+### Feature Methods ####
+
+vrMainFeatureTypevrAssayV2 <- function(object){
+  if(inherits(object, "vrAssayV2")){
+    return(object@main_featureset)
+  } else {
+    return(NULL)
+  }
+}
+
+#' @rdname vrMainFeatureType
+#' @order 3
+#' @export
+setMethod("vrMainFeatureType", "vrAssayV2", vrMainFeatureTypevrAssayV2)
+
+#' @rdname vrMainFeatureType
+#' @order 3
+#' @export
+setMethod("vrMainFeatureType", "vrAssay", vrMainFeatureTypevrAssayV2)
+
+vrMainFeatureTypeReplacevrAssayV2 <- function(object, ignore = FALSE, value){
+  if(value %in% names(object@data)){
+    object@main_featureset <- value
+  } else {
+    if(ignore){
+      warning("The feature type '", value, "' is not found in '", vrAssayNames(object),"'. Main feature type is still set to '", vrMainFeatureType(object), "'")
+    } else {
+      stop("The feature type '", value, "' is not found in '", vrAssayNames(object),"'. Use ignore = TRUE for ignoring this message")
+    }
+  }
+  
+  return(object)
+}
+
+#' @param ignore ignore if some assays dont have the feature set name
+#' 
+#' @rdname vrMainFeatureType
+#' @order 5
+#' @export
+setMethod("vrMainFeatureType<-", "vrAssayV2", vrMainFeatureTypeReplacevrAssayV2)
+
+#' @param ignore ignore if some assays dont have the feature set name
+#' 
+#' @rdname vrMainFeatureType
+#' @order 5
+#' @export
+setMethod("vrMainFeatureType<-", "vrAssay", function(object, ignore = FALSE, value){
+  stop("vrAssay V1 objects do not have multiple feature types!")
+})
+
+vrFeatureTypeNamesvrAssayV2 <- function(object){
+  names_data <- names(object@data)
+  return(names_data[!grepl("_norm$", names_data)])
+}
+
+#' @rdname vrFeatureTypeNames
+#'
+#' @export
+setMethod("vrFeatureTypeNames", "vrAssayV2", vrFeatureTypeNamesvrAssayV2)
+
+#' @rdname vrFeatureTypeNames
+#'
+#' @export
+setMethod("vrFeatureTypeNames", "vrAssay", function(object){
+  stop("vrAssay V1 objects do not have multiple feature types!")
+})
+
+addFeaturevrAssayV2 <- function(object, data, feature_name){
+  
+  # get feature name
+  featuresets <- vrFeatureTypeNames(object)
+  if(feature_name %in% featuresets){
+    stop("Feature type '", feature_name, "' already exists in the assay.")
+  }
+  
+  # check spatial point names in the object
+  colnames_data <- colnames(data)
+  colnames_data <- stringr::str_remove(colnames_data, pattern = "_Assay[0-9]+$")
+  colnames(data) <- paste0(colnames_data, "_", vrAssayNames(object))
+  
+  # check spatial points
+  spatialpoints <- vrSpatialPoints(object)
+  if(length(setdiff(colnames(data), vrSpatialPoints(object))) > 0){
+    stop("The number of spatial points is not matching with number of points in the input data")
+  } 
+
+  # add new features
+  feature_list_name <- names(object@data)
+  feature_list_name <- c(feature_list_name, feature_name, paste0(feature_name, "_norm"))
+  object@data <- c(object@data, list(data,data))
+  names(object@data) <- feature_list_name
+  
+  # return
+  return(object)
+}
+
+#' @rdname addFeature
+#' @method addFeature vrAssayV2
+#' 
+#' @importFrom stringr str_remove
+#' 
+#' @export
+setMethod("addFeature", "vrAssayV2", addFeaturevrAssayV2)
+
+### Other Methods ####
+
+#' @rdname vrSpatialPoints
+#' @order 4
+#' 
+#' @export
+setMethod("vrSpatialPoints", "vrAssay", function(object) {
+  return(rownames(vrCoordinates(object)))
+})
+
+#' @rdname vrSpatialPoints
+#' @order 4
+#' 
+#' @export
+setMethod("vrSpatialPoints", "vrAssayV2", function(object) {
+  return(rownames(vrCoordinates(object)))
+})
+
+vrSpatialPointsReplacevrAssayV2 <- function(object, value) {
+  
+  # spatial points 
+  spatialpoints <- vrSpatialPoints(object)
+  
+  # data
+  if(length(vrSpatialPoints(object)) != length(value)){
+    stop("The number of spatial points is not matching with the input")
+  } else {
+    if(ncol(getData(object)) > 0){
+      object <- updateData(object, value)
+    }
+  }
+  
+  # images
+  for(img in vrSpatialNames(object)){
+    vrSpatialPoints(object@image[[img]]) <- value
+  }
+  
+  # embeddings
+  embeddings <- object@embeddings
+  embed_names <- names(embeddings)
+  if(length(embed_names) > 0){
+    for(type in embed_names){
+      if(nrow(embeddings[[type]]) > 0){
+        rownames(embeddings[[type]]) <- value[match(rownames(embeddings[[type]]), spatialpoints)]
+        object@embeddings[[type]] <- embeddings[[type]]
+      }
+    }
+  }
+  
+  # return
+  return(object)
+}
+
+#' @rdname vrSpatialPoints
+#' @order 8
+#' @export
+setMethod("vrSpatialPoints<-", "vrAssay", vrSpatialPointsReplacevrAssayV2)
+
+#' @rdname vrSpatialPoints
+#' @order 8
+#' @export
+setMethod("vrSpatialPoints<-", "vrAssayV2", vrSpatialPointsReplacevrAssayV2)
+
+vrFeaturesvrAssay <- function(object) {
+  return(rownames(getData(object)))
+}
+
+#' @rdname vrFeatures
+#' @order 3
+#' @export
+setMethod("vrFeatures", signature = "vrAssay", definition = vrFeaturesvrAssay)
+ 
+#' @rdname vrFeatures
+#' @method vrFeatures vrAssayV2
+#' @order 3
+#' @export
+setMethod("vrFeatures", "vrAssayV2", vrFeaturesvrAssay)
+
+vrFeatureDatavrAssay <- function(object) {
+  return(object@featuredata)
+}
+
+#' @rdname vrFeatureData
+#' @order 3
+#' @export
+setMethod("vrFeatureData", "vrAssay", vrFeatureDatavrAssay)
+
+vrFeatureDatavrAssayV2 <- function(object, feat_type = NULL){
+  if(is.null(feat_type))
+    feat_type <- vrMainFeatureType(object)
+  return(object@featuredata[[feat_type]])
+}
+
+#' @param feat_type the feature set type
+#'
+#' @rdname vrFeatureData
+#' @order 3
+#' @export
+setMethod("vrFeatureData", "vrAssayV2", vrFeatureDatavrAssayV2)
+
+vrFeatureDataRreplacevrAssay <- function(object, value) {
+  object@featuredata <- value
+  return(object)
+}
+
+#' @rdname vrFeatureData
+#' @order 5
+#' @export
+setMethod("vrFeatureData<-", "vrAssay", vrFeatureDataRreplacevrAssay)
+
+vrFeatureDataReplacevrAssayV2 <- function(object, feat_type = NULL, value) {
+  if(is.null(feat_type))
+    feat_type <- vrMainFeatureType(object)
+  object@featuredata[[feat_type]] <- value
+  return(object)
+}
+
+#' @rdname vrFeatureData
+#' @order 5
+#' @export
+setMethod("vrFeatureData<-", "vrAssayV2", vrFeatureDataReplacevrAssayV2)
+
+vrAssayNamesvrAssay <- function(object) {
+  
+  if(.hasSlot(object, name = "name")){
+    if(grep("Assay", object@name)){
+      return(object@name)
+    } else {
+      assay_ids <- stringr::str_extract(vrSpatialPoints(object), "Assay[0-9]+$")
+      assay_id <- unique(assay_ids)
+      return(assay_id)
+    }
+  } else {
+    assay_ids <- stringr::str_extract(vrSpatialPoints(object), "Assay[0-9]+$")
+    assay_id <- unique(assay_ids)
+    return(assay_id)
+  }
+}
+
+#' @rdname vrAssayNames
+#' @order 4
+#' @export
+setMethod("vrAssayNames", "vrAssay", vrAssayNamesvrAssay)
+
+#' @rdname vrAssayNames
+#' @order 4
+#' @export
+setMethod("vrAssayNames", "vrAssayV2", vrAssayNamesvrAssay)
+
+vrAssayNamesReplacevrAssay <- function(object, value){
+  
+  # get original assay name
+  assayname <- vrAssayNames(object)
+  
+  # change assay names
+  spatialpoints <- stringr::str_replace(vrSpatialPoints(object), assayname, value)
+  
+  # add assay name if missing
+  if(vrAssayTypes(object) %in% c("ROI", "cell", "spot")){
+    ind <- !grepl("Assay[0-9]+$", spatialpoints)
+    spatialpoints[ind] <- stringr::str_replace(spatialpoints[ind], "$", paste0("_", value))
+  }
+  
+  # replace spatial point names
+  vrSpatialPoints(object) <- spatialpoints
+  object@name <- value
+  
+  # return
+  return(object)
+}
+
+#' @param value assay name
+#' 
+#' @rdname vrAssayNames
+#' @order 5
+#' @importFrom stringr str_replace
+setMethod("vrAssayNames<-", "vrAssay", vrAssayNamesReplacevrAssay)
+
+vrAssayNamesReplacevrAssayV2 <- function(object, value){
+  
+  # get original assay name
+  assayname <- vrAssayNames(object)
+  
+  # change assay names
+  spatialpoints <- stringr::str_replace(vrSpatialPoints(object), assayname, value)
+  
+  # add assay name if missing
+  if(vrAssayTypes(object) %in% c("ROI", "cell", "spot")){
+    ind <- !grepl("Assay[0-9]+$", spatialpoints)
+    spatialpoints[ind] <- stringr::str_replace(spatialpoints[ind], "$", paste0("_", value))
+  }
+  
+  # replace spatial point names
+  vrSpatialPoints(object) <- spatialpoints
+  object@name <- value
+  
+  # return
+  return(object)
+}
+
+#' @param value assay name
+#' 
+#' @rdname vrAssayNames
+#' @order 5
+#' @importFrom stringr str_replace
+setMethod("vrAssayNames<-", "vrAssayV2", vrAssayNamesReplacevrAssayV2)
+
+vrAssayTypesvrAssay <- function(object) {
+  return(object@type)
+}
+
+#' @rdname vrAssayTypes
+#' @order 3
+#' @export
+setMethod("vrAssayTypes", "vrAssay", vrAssayTypesvrAssay)
+
+#' @rdname vrAssayTypes
+#' @order 3
+#' @export
+setMethod("vrAssayTypes", "vrAssayV2", vrAssayTypesvrAssay)
+
+#' Get assay parameters
+#'
+#' Given a vrAssay object, if there are any, get a list of parameters of the assay(s)
+#'
+#' @param object a vrAssay object
+#' @param param the parameter value to return
+#'
+#' @rdname vrAssayParams
+#'
+#' @export
+vrAssayParams <- function(object, param = NULL) {
+  if(!is.null(param)){
+    if(param %in% names(object@params)){
+      return(object@params[[param]])
+    } else {
+      message(param, " not found in the param list")
+      return(NULL)
+    }
+  } else {
+    return(object@params)
+  }
+}
+
+vrDatavrAssay <- function(object, features = NULL, feat_type = NULL, norm = FALSE, ...) {
+  
+  # get assay types
+  assay.type <- vrAssayTypes(object)
+  
+  # for ROIs, cells and spots
+  if(assay.type %in% c("ROI", "cell", "spot")){
+    
+    # check if there are features
+    if(!is.null(features)){
+      if(!all(features %in% vrFeatures(object))){
+        stop("Some features are not available in the assay!")
+      }
+      
+      if(inherits(object, "vrAssay")){
+        if(norm){
+          return(object@normdata[features,,drop = FALSE])
+        } else {
+          return(object@rawdata[features,,drop = FALSE])
+        }
+      } else {
+        if(is.null(feat_type))
+          feat_type <- vrMainFeatureType(object)
+        if(norm){
+          return(object@data[[paste0(feat_type, "_norm")]][features,,drop = FALSE])
+        } else {
+          return(object@data[[feat_type]][features,,drop = FALSE])
+        }
+      }
+      
+      # if there are no features requested, return the data
+    } else {
+      
+      if(inherits(object, "vrAssay")){
+        if(norm){
+          return(object@normdata)
+        } else {
+          return(object@rawdata)
+        }
+      } else {
+        if(is.null(feat_type))
+          feat_type <- vrMainFeatureType(object)
+        if(norm){
+          return(object@data[[paste0(feat_type, "_norm")]])
+        } else {
+          return(object@data[[feat_type]])
+        }
+      }
+    }
+    
+    # for tiles and molecules
+  } else {
+    
+    # check if features are requested
+    if(!is.null(features)){
+      stop("No features are available for tile and molecule assays!")
+    } else{
+      
+      if(inherits(object, "vrAssay")){
+        if(norm){
+          return(object@normdata)
+        } else {
+          return(object@rawdata)
+        }
+      } else {
+        if(is.null(feat_type))
+          feat_type <- vrMainFeatureType(object)
+        if(norm){
+          return(object@data[[paste0(feat_type, "_norm")]])
+        } else {
+          return(object@data[[feat_type]])
+        }
+      }
+    }
+  }
+}
+
+#' @rdname vrData
+#' @order 3
+#'
+#' @importFrom magick image_raster
+#'
+#' @export
+setMethod("vrData", "vrAssay", vrDatavrAssay)
+
+#' @rdname vrData
+#' @order 3
+#'
+#' @export
+setMethod("vrData", "vrAssayV2", vrDatavrAssay)
+
+generateTileDatavrAssay <- function(object, name = NULL, reg = FALSE, channel = NULL) {
+  
+  if(vrAssayTypes(object) != "tile"){
+    stop("generateTileData can only be used for tile-based assays")
+  } else {
+    image_data <- as.numeric(vrImages(object, name = name, reg = reg, channel = channel, as.raster = TRUE))
+    image_data <- (0.299 * image_data[,,1] + 0.587 * image_data[,,2] + 0.114 * image_data[,,3])
+    image_data <- split_into_tiles(image_data, tile_size = vrAssayParams(object, param = "tile.size"))
+    image_data <- sapply(image_data, function(x) return(as.vector(x)))
+    image_data <- image_data*255
+    rownames(image_data) <- paste0("pixel", seq_len(nrow(image_data)))
+    colnames(image_data) <- vrSpatialPoints(object)
+    feat_type <- vrMainFeatureType(object)
+    
+    if(inherits(object, "vrAssay")){
+      object@rawdata <- object@normdata <- image_data
+    } else{
+      object@data[[feat_type]] <- image_data
+      object@data[[paste0(feat_type, "_norm")]] <- image_data
+    }
+  }
+  return(object)
+}
+
+#' @param name the name of the main spatial system
+#' @param reg TRUE if registered coordinates of the main image (\link{vrMainSpatial}) is requested
+#' @param channel the name of the channel associated with the image
+#' 
+#' @rdname generateTileData
+#' @order 3
+#'
+#' @export
+setMethod("generateTileData", "vrAssay", generateTileDatavrAssay)
+
+#' @rdname generateTileData
+#' @order 3
+#'
+#' @export
+setMethod("generateTileData", "vrAssayV2", generateTileDatavrAssay)
+
+vrCoordinatesvrAssay <- function(object, image_name = NULL, spatial_name = NULL, reg = FALSE) {
+  
+  # get spatial name
+  if(!is.null(spatial_name)) 
+    image_name <- spatial_name
+  
+  # check main image
+  if(is.null(image_name)){
+    image_name <- vrMainSpatial(object)
+  }
+  
+  # check registered coordinates
+  if(reg){
+    if(!paste0(image_name, "_reg") %in% vrSpatialNames(object)){
+      warning("There are no registered spatial systems with name ", image_name, "!")
+    } else {
+      image_name <- paste0(image_name, "_reg")
+    }
+  }
+  
+  # check coordinates
+  if(!image_name %in% vrSpatialNames(object)){
+    stop(image_name, " is not among any spatial system in this vrAssay object")
+  }
+  
+  # return coordinates
+  return(vrCoordinates(object@image[[image_name]]))
+}
+
+#' @rdname vrCoordinates
+#' @order 3
+#' @export
+#'
+setMethod("vrCoordinates", "vrAssay", vrCoordinatesvrAssay)
+
+#' @rdname vrCoordinates
+#' @order 3
+#' @export
+#'
+setMethod("vrCoordinates", "vrAssayV2", vrCoordinatesvrAssay)
+
+vrCoordinatesReplacevrAssay <- function(object, image_name = NULL, spatial_name = NULL, reg = FALSE, value) {
+  
+  # get spatial name
+  if(!is.null(spatial_name)) 
+    image_name <- spatial_name
+  
+  # check main image
+  if(is.null(image_name)){
+    image_name <- vrMainSpatial(object)
+  }
+  
+  # check registered coordinates
+  if(reg){
+    image_name <- paste0(image_name, "_reg")
+  }
+  
+  # check coordinates
+  if(!image_name %in% vrSpatialNames(object)){
+    stop(image_name, " is not among any spatial system in this vrAssay object")
+  }
+  
+  vrCoordinates(object@image[[image_name]]) <- value
+  return(object)
+}
+
+#' @rdname vrCoordinates
+#' @order 5
+#' @importFrom methods slot
+#'
+#' @export
+setMethod("vrCoordinates<-", "vrAssay", vrCoordinatesReplacevrAssay)
+
+#' @rdname vrCoordinates
+#' @order 5
+#' @importFrom methods slot
+#'
+#' @export
+setMethod("vrCoordinates<-", "vrAssayV2", vrCoordinatesReplacevrAssay)
+
+flipCoordinatesvrAssay <- function(object, image_name = NULL, spatial_name = NULL, ...) {
+  
+  # get spatial name
+  if(!is.null(spatial_name)) 
+    image_name <- spatial_name
+  
+  # get coordinates
+  coords <- vrCoordinates(object, image_name = image_name, ...)
+  
+  # get image info
+  image <- vrImages(object, name = image_name)
+  if(!is.null(image)){
+    imageinfo <- magick::image_info(vrImages(object, name = image_name))
+    height <- imageinfo$height
+  } else{
+    height <- max(coords[,"y"])
+  }
+  
+  # flip coordinates
+  coords[,"y"] <- height - coords[,"y"]
+  vrCoordinates(object, image_name = image_name, ...) <- coords
+  
+  # flip segments
+  segments <- vrSegments(object, image_name = image_name, ...)
+  if(length(segments) > 0){
+    name_segments <- names(segments)
+    segments <- do.call("rbind", segments)
+    segments[,"y"] <- height - segments[,"y"]
+    segments <- split(segments, segments[,1])
+    names(segments) <- name_segments
+    vrSegments(object, image_name = image_name, ...) <- segments
+  }
+  
+  # return
+  return(object)
+}
+
+#' @rdname flipCoordinates
+#' @order 3
+#'
+#' @importFrom magick image_info
+#'
+#' @export
+setMethod("flipCoordinates", "vrAssay", flipCoordinatesvrAssay)
+
+#' @rdname flipCoordinates
+#' @order 3
+#'
+#' @export
+setMethod("flipCoordinates", "vrAssayV2", flipCoordinatesvrAssay)
+
+vrSegmentsvrAssay <- function(object, image_name = NULL, spatial_name = NULL, reg = FALSE) {
+  
+  # get spatial name
+  if(!is.null(spatial_name)) 
+    image_name <- spatial_name
+  
+  # check main image
+  if(is.null(image_name)){
+    image_name <- vrMainSpatial(object)
+  }
+  
+  # check registered segments
+  if(reg){
+    if(!paste0(image_name, "_reg") %in% vrSpatialNames(object)){
+      warning("There are no registered spatial systems with name ", image_name, "!")
+    } else {
+      image_name <- paste0(image_name, "_reg")
+    }
+  }
+  
+  # check coordinates
+  if(!image_name %in% vrSpatialNames(object)){
+    stop(image_name, " is not among any spatial system in this vrAssay object")
+  }
+  
+  # return coordinates
+  return(vrSegments(object@image[[image_name]]))
+}
+
+#' @rdname vrSegments
+#' @order 3
+#' @export
+setMethod("vrSegments", "vrAssay", vrSegmentsvrAssay)
+
+#' @rdname vrSegments
+#' @order 3
+#' @export
+setMethod("vrSegments", "vrAssayV2", vrSegmentsvrAssay)
+
+vrSegmentsReplacevrAssay <- function(object, image_name = NULL, spatial_name = NULL, reg = FALSE, value) {
+  
+  # get spatial name
+  if(!is.null(spatial_name)) 
+    image_name <- spatial_name
+  
+  # check main image
+  if(is.null(image_name)){
+    image_name <- vrMainSpatial(object)
+  }
+  
+  # check registered segments
+  if(reg){
+    image_name <- paste0(image_name, "_reg")
+  }
+  
+  # check coordinates
+  if(!image_name %in% vrSpatialNames(object)){
+    stop(image_name, " is not among any spatial system in this vrAssay object")
+  }
+  
+  vrSegments(object@image[[image_name]]) <- value
+  return(object)
+}
+
+#' @rdname vrSegments
+#' @order 6
+#' @importFrom methods slot
+#' @export
+setMethod("vrSegments<-", "vrAssay", vrSegmentsReplacevrAssay)
+
+#' @rdname vrSegments
+#' @order 6
+#' @importFrom methods slot
+#' @export
+setMethod("vrSegments<-", "vrAssayV2", vrSegmentsReplacevrAssay)
+
+vrEmbeddingsvrAssay <- function(object, type = "pca", dims = seq_len(30)) {
+  
+  # embeddings
+  embeddings <- object@embeddings
+  embedding_names <- names(embeddings)
+  
+  # check embeddings and return
+  if(!type %in% embedding_names){
+    stop("Embedding type ", type, " is not found!")
+  } else{
+    embedding <- object@embeddings[[type]]
+    if(max(dims) > ncol(embedding)){
+      dims <- seq_len(ncol(embedding))
+    }
+    return(embedding[,dims, drop = FALSE])
+  }
+}
+
+#' @rdname vrEmbeddings
+#' @order 3
+#' @export
+setMethod("vrEmbeddings", "vrAssay", vrEmbeddingsvrAssay)
+
+#' @rdname vrEmbeddings
+#' @order 3
+#' @export
+#'
+setMethod("vrEmbeddings", "vrAssayV2", vrEmbeddingsvrAssay)
+
+vrEmbeddingsReplacevrAssay <- function(object, type = "pca", value) {
+  object@embeddings[[type]] <- value
+  return(object)
+}
+
+#' @rdname vrEmbeddings
+#' @order 4
+#' @export
+setMethod("vrEmbeddings<-", "vrAssay", vrEmbeddingsReplacevrAssay)
+
+vrEmbeddingsReplacevrAssayV2 <- function(object, type = "pca", value) {
+  object@embeddings[[type]] <- value
+  return(object)
+}
+
+#' @rdname vrEmbeddings
+#' @order 4
+#' @export
+setMethod("vrEmbeddings<-", "vrAssayV2", vrEmbeddingsReplacevrAssayV2)
+
+vrEmbeddingNamesvrAssay <- function(object){
+  return(names(object@embeddings))
+}
+
+#' @rdname vrEmbeddingNames
+#' @order 3
+#'
+#' @export
+setMethod("vrEmbeddingNames", "vrAssay", vrEmbeddingNamesvrAssay)
+
+#' @rdname vrEmbeddingNames
+#' @order 3
+#'
+#' @export
+setMethod("vrEmbeddingNames", "vrAssayV2", vrEmbeddingNamesvrAssay)
\ No newline at end of file