drisso / SingleCellExperiment

Clone of the Bioconductor repository for the SingleCellExperiment package, see https://bioconductor.org/packages/devel/bioc/html/SingleCellExperiment.html for the official development version.
63 stars 17 forks source link

updateObject for classes that inherit from SingleCellExperiment has problem with reducedDims slot change #37

Closed epurdom closed 4 years ago

epurdom commented 4 years ago

Hello,

My package, clusterExperiment (epurdom/clusterExperiment) creates a class ClusterExperiment that inherits from SingleCellExperiment. I am running into a problem with updateObject. In particular, I can no longer run updateObject for out-of-date objects of my class.

Calling updateObject appears to do call updateObject on as(x,"SingleCellExperiment"). But calling as(x,"SingleCellExperiment") creates an SingleCellExperiment object that doesn't allow the @reducedDims option, so I think it's choking on reducedDims(object) <- object@reducedDims in the updateObject function. (the internal storage of the package version is preserved with as(x,"SingleCellExperiment") so it is triggering the update).

> class(rsecFluidigm)
[1] "ClusterExperiment"
attr(,"package")
[1] "clusterExperiment"
> updateObject(rsecFluidigm)
Error in updateObject(as(object, "SingleCellExperiment")) : 
  no slot of name "reducedDims" for this object of class "SingleCellExperiment"
> updateObject(as(rsecFluidigm,"SingleCellExperiment"))
Error in updateObject(as(rsecFluidigm, "SingleCellExperiment")) : 
  no slot of name "reducedDims" for this object of class "SingleCellExperiment"
> objectVersion(as(rsecFluidigm,"SingleCellExperiment"))
[1] ‘1.3.11’
> as(rsecFluidigm,"SingleCellExperiment")@reducedDims
Error: no slot of name "reducedDims" for this object of class "SingleCellExperiment"

I thought I could just put this code (reducedDims(object) <- object@reducedDims) in my updateObject for the clusterExperiment class, though that seems a very inelegant solution to the problem, and seems to defeat the purpose of the inheritance (i.e. not having to recode everything). But it also doesn't work

> reducedDims(rsecFluidigm)<-rsecFluidigm@reducedDims
Error: C stack usage  7969520 is too close to the limit

Based on the traceback, it appears to get into an infinite loop of updateObject, because reducedDims<- first calls updateObject. The first few steps of that infinite loop (from traceback) are:

17: updateObject(x)
16: updateObject(x)
15: `reducedDims<-`(`*tmp*`, value = object@reducedDims)
14: `reducedDims<-`(`*tmp*`, value = object@reducedDims) at updateObject.R#73
13: .local(object, ..., verbose = verbose)
12: updateObject(x)
11: updateObject(x)
10: `reducedDims<-`(`*tmp*`, value = object@reducedDims)
9: `reducedDims<-`(`*tmp*`, value = object@reducedDims) at updateObject.R#73
8: .local(object, ..., verbose = verbose)
7: updateObject(x)
6: updateObject(x)
5: `reducedDims<-`(`*tmp*`, value = new("SimpleList", listData = list(
       PCA = c(-22.3904596425552, -12.9632784401868, 4.58280388095169, 
       -13.7827397709928, 14.9547040765735, 2.24222246196905, 4.56720748224653, 
4: `reducedDims<-`(`*tmp*`, value = new("SimpleList", listData = list(
       PCA = c(-22.3904596425552, -12.9632784401868, 4.58280388095169, 
       -13.7827397709928, 14.9547040765735, 2.24222246196905, 4.56720748224653, 
    ... at updateObject.R#73
3: .local(object, ..., verbose = verbose)
2: updateObject(rsecFluidigm)
1: updateObject(rsecFluidigm)

Thanks for any help with this problem.

All of the best, Elizabeth Purdom

LTLA commented 4 years ago

Woah, why so formal, Liz?

Anyway, the problem is likely because of as(object, "SingleCellExperiment"), which coerces the object into the latest SCE format but leaves the object version as something that's pre-1.7.1. This then means that it goes into the the wrong path within updateObject,SingleCellExperiment-method, leading to the observed problem.

We can add a check to the SCE's updateObject method, but the real solution for you is to call callNextMethod() within the ClusterExperiment method to do the updating of the SCE components. (Might have to use S4Vectors::disableValidity() here.) Currently, if you have any reduced dimensions, these get discarded outright by as() when it converts to the SCE parent of your CE class.

Yours truly,

Aaron Lun, PhD.

epurdom commented 4 years ago

Well, I'm always rather formal on my issues requests....

But you're absolutely right, my code was a mess there. Thanks, using callNextMethod instead appears to have solved the problem.