whtns / chevreul

Set of tools for interacting with singlecellexperiment objects as projects
Other
8 stars 2 forks source link

> They have changed the structure of the Seurat object with sc@assays$RNA@layers$counts rather than sc@assays$RNA@counts, so the save isn't recognising this difference when saving. #42

Open whtns opened 8 months ago

whtns commented 8 months ago
          > They have changed the structure of the Seurat object with sc@assays$RNA@layers$counts rather than sc@assays$RNA@counts, so the save isn't recognising this difference when saving.

Is it possible to have a version with the 'layers' bit added to the save and load Seurat Object?

It is possible to "patch" each of SaveH5Seurat, LoadH5Seurat functions (tested with Seurat v5.0.1).

Here it is for SaveH5Seurat:

#' Patch of SeuratDisk::SaveH5Seurat function
#'
#' The "Assay5" class attribute "RNA" needs to be converted to a standard "Assay"
#' class for compatibility with SeuratDisk. It requires to make a temporary copy
#' so the size of the object grows bigger.
#'
#' @param object the Seurat object
#' @param filename the file path where to save the Seurat object
#' @param verbose SaveH5Seurat verbosity
#' @param overwrite whether to overwrite an existing file
#' 
#' @return NULL
SaveH5SeuratObject <- function(
    object,
    filename,
    verbose = TRUE,
    overwrite = TRUE
    ) {

  # add copy of "RNA" 
  object[["RNA-tmp"]] <- CreateAssayObject(counts = object[["RNA"]]$counts)
  # remove original
  object[["RNA"]] <- NULL
  # export
  SaveH5Seurat(object, filename = filename, overwrite, verbose)

  return(NULL)
}

And for LoadH5Seurat:

#' Patch of SeuratDisk::LoadH5Seurat function
#'
#' The "Assay" class attribute "RNA" needs to be converted to the new "Assay5"
#' class. It requires to make a temporary copy so the size of the object grows
#' bigger.
#'
#' @param filename the file path where to save the Seurat object
#' @param verbose LoadH5Seurat verbosity
#' 
#' @return NULL
LoadH5SeuratObject <- function(
    filename,
    verbose = TRUE
) {

  # load h5 data
  object <- LoadH5Seurat(filename)
  # create "Assay5" class from old "Assay" class
  keys <- Key(object)
  slotID <- names(keys)[startsWith(keys, "rna")]
  object[["RNA"]] <- CreateAssay5Object(counts = object[[slotID]]$counts)
  # delete "Assay" class
  object[[slotID]] <- NULL
  # reorder assays list
  object@assays <- object@assays[sort(names(object@assays))]

  return(object)
}

The biggest caveat is that it requires to make a copy of the RNA assay at each pass (saving or loading). A direct conversion would be preferable, but I have not found such a function in the SeuratObject package.

EDIT: A better function would iterate over all assays and do what I did for RNA for each "Assay5" class assay.

Originally posted by @Gilquin in https://github.com/mojaveazure/seurat-disk/issues/172#issuecomment-1931709246

as224 commented 1 month ago

I got an error while using your SaveH5SeuratObject function. It says: Cannot delete default assay. Do you know what to do?

Gilquin commented 1 month ago

I got an error while using your SaveH5SeuratObject function. It says: Cannot delete default assay. Do you know what to do?

It's because you cannot assign NULL to a default Assay: https://github.com/satijalab/seurat-object/blob/1a140c74b25f0f9755c21032bc1a97c15140b36d/R/seurat.R#L4899

@whtns A fix is to switch the default assay to "RNA-tmp" before removing the original:

DefaultAssay(object) <- "RNA-tmp"

And do the same in LoadH5SeuratObject for the Assay5 "RNA" before deleting the corresponding "Assay" class.