library(SpatialExperiment) library(SingleCellExperiment) library(hdf5r) library(Matrix) library(hdf5r) ## VIASH START par <- list( input = "resources_test/xenium/xenium_tiny.h5mu", output = "xenium_test.rds", modality = "rna", obsm_spatial_coordinates = "spatial" ) ## VIASH END h5mu_to_h5ad <- function(h5mu_path, modality_name) { tmp_path <- tempfile(fileext = ".h5ad") mod_location <- paste("mod", modality_name, sep = "/") h5src <- hdf5r::H5File$new(h5mu_path, "r") h5dest <- hdf5r::H5File$new(tmp_path, "w") # Copy over the child objects and the child attributes from root # Root cannot be copied directly because it always exists and # copying does not allow overwriting. children <- hdf5r::list.objects(h5src, path = mod_location, full.names = FALSE, recursive = FALSE ) for (child in children) { h5dest$obj_copy_from( h5src, paste(mod_location, child, sep = "/"), paste0("/", child) ) } # Also copy the root attributes root_attrs <- hdf5r::h5attr_names(x = h5src) for (attr in root_attrs) { h5a <- h5src$attr_open(attr_name = attr) robj <- h5a$read() h5dest$create_attr_by_name( attr_name = attr, obj_name = ".", robj = robj, space = h5a$get_space(), dtype = h5a$get_type() ) } h5src$close() h5dest$close() tmp_path } read_spatial_coordinates <- function(sce, spatial_coordinates_name) { # Check if the specified spatial coordinates exist in reducedDims reduced_dims <- SingleCellExperiment::reducedDims(sce) if (par$obsm_spatial_coordinates %in% names(reduced_dims)) { spatial_coords <- reduced_dims[[par$obsm_spatial_coordinates]] if (ncol(spatial_coords) != 2) { stop( "Spatial coordinates must have 2 columns, but found ", ncol(spatial_coords), " columns" ) } # Set proper column names for spatial coordinates colnames(spatial_coords) <- c("x", "y") } else { warning( "Spatial coordinates '", par$obsm_spatial_coordinates, "' not found in reducedDims. Available dimensions: ", paste(names(reduced_dims), collapse = ", ") ) spatial_coords <- NULL } spatial_coords } main <- function() { # Convert to AnnData cat("Converting H5MU file to H5AD...\n") h5file <- h5mu_to_h5ad(par$input, par$modality) # Convert to SpatialExperiment cat("Converting to SingleCellExperiment...\n") sce <- anndataR::read_h5ad(h5file, as = "SingleCellExperiment") # Extract spatial coordinates if specified if ( !is.null(par$obsm_spatial_coordinates) && length(par$obsm_spatial_coordinates) > 0 ) { cat("Reading in spatial coordinates...\n") spatial_coords <- read_spatial_coordinates( sce, par$obsm_spatial_coordinates ) SingleCellExperiment::reducedDims(sce)[[ par$obsm_spatial_coordinates ]] <- NULL } else { spatial_coords <- NULL } # Converting SingleCellExperiment to SpatialExperiment cat("Converting to SpatialExperiment...\n") spe <- as(sce, "SpatialExperiment") SpatialExperiment::spatialCoords(spe) <- spatial_coords # Saving SpatialExperiment object cat("Saving SpatialExperiment object to:", par$output, "\n") saveRDS(spe, file = par$output, compress = FALSE) } main()