@@ -11,7 +11,6 @@ library(shinyhelper)
1111library(shinycssloaders )
1212library(shinyBS )
1313library(Seurat )
14- library(SeuratDisk )
1514library(SeuratObject )
1615library(scCustomize )
1716library(sp )
@@ -36,6 +35,9 @@ library(stringr)
3635library(reshape2 )
3736library(htmltools )
3837library(cicerone )
38+ library(hdf5r )
39+ library(qs )
40+ library(SingleCellExperiment )
3941
4042# Moved to R/, because stuff in `R` gets sourced automatically when in package/project
4143# source("./Data/get_expressed_genes_mod.R")
@@ -1150,6 +1152,169 @@ filtres <- function(data,
11501152 }
11511153}
11521154
1155+ load_to_seurat <- function (filepath ){
1156+ ext <- tools :: file_ext(filepath )
1157+
1158+ if (ext == " qs" ) {
1159+ obj <- qread(filepath )
1160+ }else if (ext == " QS" ) {
1161+ obj <- qread(filepath )
1162+ }else if (ext == " Qs" ) {
1163+ obj <- qread(filepath )
1164+ }
1165+
1166+ else if (ext == " rds" ) {
1167+ obj <- readRDS(filepath )
1168+ } else if (ext == " RDS" ) {
1169+ obj <- readRDS(filepath )
1170+ } else if (ext == " Rds" ) {
1171+ obj <- readRDS(filepath )
1172+ }
1173+
1174+ else if (ext == " h5ad" ) {
1175+ obj <- load_h5ad_to_list(filepath )
1176+
1177+ } else if (ext == " H5AD" ) {
1178+ obj <- load_h5ad_to_list(filepath )
1179+
1180+ }else if (ext == " H5ad" ) {
1181+ obj <- load_h5ad_to_list(filepath )
1182+ } else {
1183+ stop(" Unsupported file type." )
1184+ }
1185+
1186+ # Convert depending on object type
1187+ if (inherits(obj , " Seurat" )) {
1188+ return (obj )
1189+
1190+ } else if (inherits(obj , " SingleCellExperiment" )) {
1191+ return (sce_to_seurat(obj ))
1192+
1193+ } else if (is.list(obj ) && all(c(" X" , " obs" , " var" ) %in% names(obj ))) {
1194+ return (list_to_seurat(obj ))
1195+
1196+ } else {
1197+ stop(" Unknown object structure." )
1198+ }
1199+ }
1200+
1201+ load_h5ad_to_list <- function (filepath ){
1202+ library(Matrix )
1203+ library(hdf5r )
1204+ library(Seurat )
1205+
1206+ h5 <- H5File $ new(filepath , mode = " r" )
1207+ X_entry <- h5 [[" X" ]]
1208+
1209+ if (inherits(X_entry , " H5Group" )) {
1210+ message(" Loading sparse X matrix from h5ad" )
1211+ data <- X_entry [[" data" ]]$ read()
1212+ indices <- X_entry [[" indices" ]]$ read()
1213+ indptr <- X_entry [[" indptr" ]]$ read()
1214+
1215+ n_rows <- length(indptr ) - 1
1216+ n_cols <- max(indices ) + 1
1217+
1218+ i <- integer(length(data ))
1219+ j <- integer(length(data ))
1220+
1221+ for (row in seq_len(n_rows )) {
1222+ start <- indptr [row ] + 1
1223+ end <- indptr [row + 1 ]
1224+ if (start < = end ) {
1225+ idx <- start : end
1226+ i [idx ] <- row
1227+ j [idx ] <- indices [idx ] + 1
1228+ }
1229+ }
1230+
1231+ counts <- sparseMatrix(
1232+ i = i ,
1233+ j = j ,
1234+ x = data ,
1235+ dims = c(n_rows , n_cols )
1236+ )
1237+ } else if (inherits(X_entry , " H5D" )) {
1238+ message(" Loading dense X matrix from h5ad" )
1239+ counts <- X_entry $ read()
1240+ } else {
1241+ stop(" Unknown X format." )
1242+ }
1243+
1244+ # obs and var
1245+ obs <- tryCatch({
1246+ if (" obs" %in% names(h5 )) {
1247+ df <- as.data.frame(h5 [[" obs" ]]$ read())
1248+ rownames(df ) <- rownames(h5 [[" obs" ]]) # <- important: set rownames
1249+ df
1250+ } else {
1251+ NULL
1252+ }
1253+ }, error = function (e ) NULL )
1254+
1255+ var <- tryCatch({
1256+ if (" var" %in% names(h5 )) {
1257+ df <- as.data.frame(h5 [[" var" ]]$ read())
1258+ rownames(df ) <- rownames(h5 [[" var" ]]) # <- important: set rownames
1259+ df
1260+ } else {
1261+ NULL
1262+ }
1263+ }, error = function (e ) NULL )
1264+
1265+ h5 $ close_all()
1266+
1267+ # Add names to matrix
1268+ if (! is.null(obs )) {
1269+ colnames(counts ) <- rownames(obs )
1270+ }
1271+ if (! is.null(var )) {
1272+ rownames(counts ) <- rownames(var )
1273+ }
1274+
1275+ # Now create Seurat object
1276+ seurat_obj <- CreateSeuratObject(counts = counts , meta.data = obs )
1277+
1278+ return (seurat_obj )
1279+ }
1280+
1281+ list_to_seurat <- function (lst ){
1282+ counts <- lst $ X
1283+ metadata <- lst $ obs
1284+ features <- lst $ var
1285+
1286+ seu <- CreateSeuratObject(counts = counts , meta.data = metadata )
1287+
1288+ # Set feature names if available
1289+ if (! is.null(features ) && " gene_ids" %in% colnames(features )) {
1290+ rownames(seu ) <- features $ gene_ids
1291+ } else if (! is.null(features ) && " index" %in% colnames(features )) {
1292+ rownames(seu ) <- features $ index
1293+ }
1294+
1295+ return (seu )
1296+ }
1297+
1298+ sce_to_seurat <- function (sce ){
1299+ counts <- counts(sce )
1300+ metadata <- as.data.frame(colData(sce ))
1301+
1302+ seu <- CreateSeuratObject(counts = counts , meta.data = metadata )
1303+
1304+ # Transfer reducedDims if they exist
1305+ if (length(reducedDims(sce )) > 0 ) {
1306+ for (rd in names(reducedDims(sce ))) {
1307+ seu [[paste0(" pca_" , rd )]] <- CreateDimReducObject(
1308+ embeddings = reducedDims(sce )[[rd ]],
1309+ key = paste0(toupper(rd ), " _" ),
1310+ assay = DefaultAssay(seu )
1311+ )
1312+ }
1313+ }
1314+
1315+ return (seu )
1316+ }
1317+
11531318
11541319# Define UI for application
11551320ui <- fluidPage(
@@ -1230,7 +1395,7 @@ ui <- fluidPage(
12301395 " .QS"
12311396 )) %> % helper(type = " inline" ,
12321397 title = " Accepted file types" ,
1233- content = c(" MatriCom accepts scRNA-seq files of up to 1 GB from Seurat (RDS or QS format) and ScanPy/Loom (H5AD format)." ,
1398+ content = c(" MatriCom accepts scRNA-seq files of up to 1 GB from Seurat or SingleCellExperiment (RDS or QS format), and ScanPy/Loom (H5AD format)." ,
12341399 " " ,
12351400 " IMPORTANT: MatriCom currently only accepts human and mouse datasets. If your file contains Ensembl gene IDs, you must convert them to HGCN (human) or MGI (mouse) Gene Symbols by activating the conversion button." ),
12361401 buttonLabel = " OK" )),
@@ -1535,26 +1700,27 @@ server <- function(input,output,session) {
15351700
15361701 du <- reactive({
15371702 req(input $ file1 )
1538-
1539- dp <- input $ file1 $ datapath
1540-
1541- if (isTruthy(length(dp [grepl(" .RDS" ,dp ,ignore.case = T )])> 0 )){
1542- df <- readRDS(input $ file1 $ datapath )
1543-
1544- if (strsplit(as.character(df @ version ),split = " \\ ." )[[1 ]][1 ] != 3 ){
1545- def <- DefaultAssay(df )
1546- mat <- df @ assays [[def ]]$ counts
1547- rownames(mat ) <- rownames(df @ assays [[def ]]$ counts )
1548- colnames(mat ) <- colnames(df @ assays [[def ]]$ counts )
1549- mat <- CreateAssayObject(counts = mat )
1550- mat2 <- CreateSeuratObject(counts = mat ,meta.data = df @ meta.data )
1551- mat2 <- NormalizeData(mat2 )
1552- # df[["RNA"]] <- as(object = df[["RNA"]], Class = "Assay")
1553- }
1554-
1555- value(1 )
1556- return (mat2 )
1703+ df <- load_to_seurat(input $ file1 $ datapath )
1704+
1705+ if (strsplit(as.character(df @ version ),split = " \\ ." )[[1 ]][1 ] != 3 ){
1706+ def <- DefaultAssay(df )
1707+ mat <- df @ assays [[def ]]$ counts
1708+ rownames(mat ) <- rownames(df @ assays [[def ]]$ counts )
1709+ colnames(mat ) <- colnames(df @ assays [[def ]]$ counts )
1710+ mat <- CreateAssayObject(counts = mat )
1711+ mat2 <- CreateSeuratObject(counts = mat ,meta.data = df @ meta.data )
1712+ mat2 <- NormalizeData(mat2 )
1713+ DefaultAssay(mat2 ) <- " RNA"
1714+ # df[["RNA"]] <- as(object = df[["RNA"]], Class = "Assay")
1715+ }else {
1716+ mat2 <- df
1717+ DefaultAssay(mat2 ) <- " RNA"
15571718 }
1719+
1720+ value(1 )
1721+ return (mat2 )
1722+
1723+ }) # user-specific FILE READ-IN
15581724
15591725 if (isTruthy(length(dp [grepl(" .qs" ,dp ,ignore.case = T )])> 0 )){
15601726 df <- qread(input $ file1 $ datapath )
0 commit comments