Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# openpipeline_spatial x.x.x

## NEW FUNCTIONALITY

* `convert/from_h5mu_to_seurat`: Added converter component for H5MU data to Seurat objects with spatial FOV (PR #23).

# openpipeline_spatial 0.1.1

## MINOR CHANGES
Expand Down
5 changes: 3 additions & 2 deletions src/convert/from_cosmx_to_spatialexperiment/test.R
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ spe <- paste0(meta[["resources_dir"]], "/Lung5_Rep2_tiny")
out_rds <- "output.rds"

create_folder_archive <- function(
folder_path,
archive = "Lung5_Rep2_tiny.zip") {
folder_path,
archive = "Lung5_Rep2_tiny.zip"
) {
old_wd <- getwd()
on.exit(setwd(old_wd))
setwd(meta$resources_dir)
Expand Down
88 changes: 88 additions & 0 deletions src/convert/from_h5mu_to_seurat/config.vsh.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: "from_h5mu_to_seurat"
namespace: "convert"
scope: "public"
description: |
Converts an h5ad file or a single modality of an h5mu file into a Seurat file with a Field of View (FOV) field,
storing coordinates of spatially-resolved single cells based on centroid coordinates.
authors:
- __merge__: /src/authors/dorien_roosen.yaml
roles: [ author, maintainer ]
argument_groups:
- name: Inputs
arguments:
- name: "--input"
alternatives: ["-i"]
type: file
description: Input h5ad or h5mu file
direction: input
required: true
example: input.h5ad
- name: "--modality"
type: string
default: "rna"
required: true
description: Modality to be converted if the input file is an h5mu file.
- name: "--obsm_centroid_coordinates"
type: string
description: |
Key name of the .obsm slot in the input file that contains the spatial (centroid) coordinates.
If not provided, no Field of View (FOV) will be created in the Seurat object.
- name: Centroid arguments
arguments:
- name: "--centroid_nsides"
type: integer
required: false
description: |
Number of sides of the polygon to be created around each centroid coordinate to represent the cell shape.
If not provided, circles will be created.
- name: "--centroid_radius"
type: double
required: false
description: |
Radius of the shape around each centroid coordinate to represent the cell shape.
If not provided, a default radius will be calculated based on the provided centroid coordinates.
- name: "--centroid_theta"
type: double
required: false
description: |
Angle to adjust the shapes around each centroid when plotting.
If not provided, no adjustment will be made (theta = 0)
- name: Outputs
arguments:
- name: "--output"
alternatives: ["-o"]
type: file
description: Output Seurat file
direction: output
required: true
example: output.rds
- name: "--assay"
type: string
default: "RNA"
description: Name of the assay to be created.
resources:
- type: r_script
path: script.R
test_resources:
- type: r_script
path: test.R
- path: /resources_test/aviti/aviti_teton_tiny.h5mu
- path: /resources_test/cosmx/Lung5_Rep2_tiny.h5mu
- path: /resources_test/xenium/xenium_tiny.h5mu
engines:
- type: docker
image: rocker/r2u:22.04
setup:
- type: apt
packages: [ libhdf5-dev, libgeos-dev, hdf5-tools ]
- type: r
cran: [ anndata, hdf5r, Seurat, SeuratObject ]
github: scverse/anndataR@36f3caad9a7f360165c1510bbe0c62657580415a
test_setup:
- type: r
cran: [ testthat ]
runners:
- type: executable
- type: nextflow
directives:
label: [lowmem, singlecpu]
93 changes: 93 additions & 0 deletions src/convert/from_h5mu_to_seurat/script.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
library(anndataR)
library(hdf5r)
library(Seurat)

### VIASH START
par <- list(
input = "resources_test/xenium/xenium_tiny_processed.h5mu",
output = "test.rds",
obsm_centroid_coordinates = "spatial",
assay = "RNA",
centroid_nsides = 8,
centroid_radius = 3,
centroid_theta = 0.1,
modality = "rna"
)
### 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
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 in H5AD
h5ad_path <- h5mu_to_h5ad(par$input, par$modality)

# Convert to Seurat
seurat_obj <- read_h5ad(
h5ad_path,
mode = "r",
as = "Seurat",
assay_name = par$assay
)

# Create Centroids object
if (!is.null(par$obsm_centroid_coordinates)) {
reductions <- seurat_obj@reductions[[par$obsm_centroid_coordinates]]
spatial_coords <- as.data.frame(reductions@cell.embeddings)
colnames(spatial_coords) <- c("x_coord", "y_coord")

if (is.null(par$centroid_nsides)) {
par$centroid_nsides <- Inf
}

if (is.null(par$centroid_theta)) {
par$centroid_theta <- 0L
}

centroids <- CreateCentroids(
coords = spatial_coords,
nsides = par$centroid_nsides,
radius = par$centroid_radius,
theta = par$centroid_theta
)

# Create FOV object
fov <- CreateFOV(coords = centroids, assay = par$assay)
seurat_obj[["fov"]] <- fov
seurat_obj@reductions[[par$obsm_centroid_coordinates]] <- NULL
}


saveRDS(seurat_obj, file = par$output)
Loading