[Bioc-devel] Problems with converting GPos to GRanges.
Pages, Herve
hp@ge@ @end|ng |rom |redhutch@org
Fri Sep 13 10:12:48 CEST 2019
Hi Charles,
Cryptic (but short) answer: the methods package **automatically**
creates a coercion method from CTSS to GRanges for you. Unfortunately
this method is broken.
Decryption:
Warning, this will take us to the very dark side of the S4 coercion system!
First this automatic method cannot be seen in a fresh session i.e.
selectMethod() does NOT show it:
> library(CAGEr)
> selectMethod("coerce", c("CTSS", "GRanges"))
Method Definition:
function (from, to = "GRanges", strict = TRUE)
{
if (!isTRUEorFALSE(strict))
stop("'strict' must be TRUE or FALSE")
if (!strict)
return(from)
class(from) <- "GRanges"
from using ranges <- as(from using ranges, "IRanges")
from
}
<bytecode: 0x8fa9280>
<environment: namespace:GenomicRanges>
Signatures:
from to
target "CTSS" "GRanges"
defined "UnstitchedGPos" "GRanges"
As we will realize later, the method found by selectMethod() is not the
one that is effectively used when coercing a CTSS object to GRanges. The
method is defined in the GenomicRanges package and does the right thing.
Note that its signature is UnstitchedGPos,GRanges not CTSS,GRanges but
since CTSS extends UnstitchedGPos, it makes sense that it got picked up
by selectMethod(). Note that, predictably, getMethod() doesn't find it
because, unlike selectMethod(), it does not use inheritance:
> getMethod("coerce", c("CTSS", "GRanges"))
Error in getMethod("coerce", c("CTSS", "GRanges")) :
no method found for function 'coerce' and signature CTSS, GRanges
Where it becomes really nasty is that this method is NOT the method that
will get called when we do as(ctss, "GRanges"):
gr0 <- as(new("CTSS"), "GRanges")
How do I know that? Let's use getMethod() again:
> getMethod("coerce", c("CTSS", "GRanges"))
Method Definition:
function (from, to = "GRanges", strict = TRUE)
if (strict) {
from <- {
class(from) <- "UnstitchedGPos"
from
}
{
from <- from
{
value <- new("GRanges")
for (what in c("seqnames", "ranges", "strand", "seqinfo",
"elementMetadata", "elementType", "metadata")) slot(value,
what) <- slot(from, what)
value
}
}
} else from
<environment: namespace:GenomicRanges>
Signatures:
from to
target "CTSS" "GRanges"
defined "CTSS" "GRanges"
Surprise! And don't trust the appearances: this method is NOT defined by
the GenomicRanges package (despite the <environment:
namespace:GenomicRanges> line). It's an automatic coercion method that
is defined on-the-fly by the methods package the first time the coercion
is "needed". The methods package automatically defines these coercion
methods between 2 classes when (1) one class is a parent of the other
and (2) the developer didn't define its own method.
In addition to not be detectable by selectMethod() or getMethod(),
another problem with these automatic coercion methods is that they tend
to be wrong. And that's what happens with the coercion method from CTSS
to GRanges: it returns a broken GRanges instance (which is why calling
promoters() on it fails later).
So all you need to do is define your own coercion method from CTSS to
GRanges. You can do this with:
setMethod("coerce", c("CTSS", "GRanges"), from_GPos_to_GRanges)
The from_GPos_to_GRanges() function is defined in GenomicRanges. It used
to be .from_GPos_to_GRanges() but I just renamed and exported it in
GenomicRanges 1.37.16:
https://github.com/Bioconductor/GenomicRanges/commit/d7a0353830ae01d7776924045bebeabd035659d7
Note that it's important that you use setMethod("coerce", ...) instead
of setAs(...) here. This is another long story but if you are curious I
have some grumpy comments about this in GenomicRanges/R/GPos-class.R and
in other places e.g. here:
https://github.com/Bioconductor/S4Vectors/blob/f4b4ee769d2e57ecc4a672bc117bff5c28edfad4/R/HitsList-class.R#L91-L116
Cheers,
H.
On 9/12/19 21:29, Charles Plessy wrote:
> Hello,
>
> I am trying to make the CAGEr package (1.27.2) pass its regression
> tests, and I am still struggling with the refactoring of GPos to
> UnstitchedGPos and StitchedGPos in the devel branch of Bioconductor...
>
> Currently, my problem is with the following command:
>
> promoters(GRanges(CTSScoordinatesGR(exampleCAGEexp)))
>
> CTSScoordinatesGR(exampleCAGEexp) returns a GPos object of transcription
> start sites, that I want to transform in promoter ranges.
>
> While it worked in the past, I now have the following error:
>
> Error in (function (classes, fdef, mtable) :
> unable to find an inherited method for function ‘update_ranges’ for
> signature ‘"UnstitchedIPos"’
>
> I tried the same command with the gpos1a and gpos1b example objects from
> the GPos manual page, and they do not trigger the error.
>
> Further inspection showed me that
> GRanges(CTSScoordinatesGR(exampleCAGEexp)) returns a GRanges object
> where the ranges are still in UnstitchedIPos class, while in the case of
> gpos1a and gpos1b they has been converted.
>
> I do not know how to deal with that problem and I would appreciate some
> help.
>
> Have a nice day,
>
> Charles
>
--
Hervé Pagès
Program in Computational Biology
Division of Public Health Sciences
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N, M1-B514
P.O. Box 19024
Seattle, WA 98109-1024
E-mail: hpages using fredhutch.org
Phone: (206) 667-5791
Fax: (206) 667-1319
More information about the Bioc-devel
mailing list