## get coverage for fine and coarse view
.get_fine_coverage <- function(x)
{
rng <- vrange(x)
wd <- width(rng)
cvg <- function(aln) {
if (identical(0L, length(aln)))
numeric(wd)
else
as.numeric(unlist(coverage(aln, shift=-start(rng)+1,
width=wd),
use.names=FALSE))
}
lst <- lapply(as.list(files(x)), function(fl, param) {
aln <- readGAlignments(fl, param=param)
seqlevels(aln) <- seqlevels(rng)
list(`+`=cvg(aln[strand(aln)=="+"]),
`-`=cvg(aln[strand(aln)=="-"]))
}, param=ScanBamParam(which=rng))
}
.get_coarse_coverage <- function(x)
{
nbins <- 5000L
rng <- vrange(x)
wd <- width(rng)
breaks <- seq(start(rng), end(rng), length.out=nbins)
lst <- lapply(as.list(files(x)), function(fl) {
param <- ScanBamParam(which=rng, what=c("pos", "strand"))
starts <- scanBam(fl, param=param)[[1]]
bins <- lapply(split(starts$pos, starts$strand)[1:2], function(elt) {
if (length(elt)) cut(elt, breaks=breaks, labels=FALSE)
else integer()
})
lapply(bins, tabulate, length(breaks)-1) #nbins = breaks-1
})
}
.coverage_as_dataframe <- function(lst, range, ignore.strand=FALSE,
resolution.fine=TRUE)
{
positive <- sapply(lst, "[[", "+")
negative <- sapply(lst, "[[", "-")
if (is.matrix(positive))
positive <- rowMeans(positive)
if (is.matrix(negative))
negative <- rowMeans(negative)
if (resolution.fine)
pos <- seq.int(start(range), end(range), length.out=length(positive))
else { ## center the pos at the bin
delta <- (end(range)-start(range))/(length(positive))
pos <- seq.int(start(range)+delta/2, by=delta,
length.out=length(positive))
}
if (!ignore.strand) {
snames <- c("positive", "negative")
group <- factor(rep(snames, each=length(positive)),
levels=snames)
data.frame(data=c(positive, -negative),
group=group,
pos=pos)
} else {
data.frame(data=positive+negative, pos=pos)
}
}
.multiFile_coverage_as_dataframe <- function(lst, range, fac=NULL,
ignore.strand=FALSE,
resolution.fine=TRUE)
{
wd <- width(range)
positive <- sapply(lst, "[[", "+")
negative <- sapply(lst, "[[", "-")
nPoints <- length(lst[[1]][[1]])
if (is.null(fac)) {
## phenolev as file names (must be unique)
fnames <- names(lst)
if (length(unique(fnames))!=length(fnames)) # conform the uniquenss
fnames <- paste(1:length(fnames), fnames, sep="-")
phenolev <- c(do.call(cbind, lapply(fnames, rep, nPoints)))
} else {
## take means of the coverate on each level factor
cvlst <- lapply(levels(fac), function(lev) {
ps <- rowMeans(positive[, fac == lev, drop=FALSE])
ng <- rowMeans(negative[, fac == lev, drop=FALSE])
list("+"=ps, "-"=ng)
})
names(cvlst) <- levels(fac)
positive <- sapply(cvlst, "[[", "+")
negative <- sapply(cvlst, "[[", "-")
phenolev <- c(do.call(cbind, lapply(names(cvlst), rep, nPoints)))
}
## define position
if (resolution.fine)
pos <- seq.int(start(range), end(range))
else { # position should be in the middle of the bin
nIntervals <- length(lst[[1]][[1]])
delta <- (end(range)-start(range))/(nPoints)
pos <- seq.int(start(range)+delta/2, by=delta, length.out=nPoints)
}
fnames <- names(lst)
if (length(unique(fnames))!=length(fnames))
fnames <- paste(1:length(fnames), fnames, sep="-")
file <- c(do.call(cbind, lapply(fnames, rep, nPoints)))
if (ignore.strand) {
data.frame(data=c(positive+negative), pos=pos, levels=phenolev)
} else {
snames <- c("positive", "negative")
strand <- rep(snames, each=length(positive))
file <- rep(file, 2)
data.frame(data=c(positive, -negative),
pos=pos, group=strand, levels=phenolev)
}
}
################### readers #######################
.fine_coverage_reader <- function(x)
{ ## x: a Snapshot instance
## create a plot of coverage as sum of coverage of all the files
lst <- .get_fine_coverage(x)
rng <- vrange(x)
ignore.strand <- ignore.strand(x)
.coverage_as_dataframe(lst, rng, ignore.strand=ignore.strand,
resolution.fine=TRUE)
}
.coarse_coverage_reader <- function(x)
{ ## x: a Snapshot instance
## create a plot of coverage as sum of coverage of all the files
lst <- .get_coarse_coverage(x)
rng <- vrange(x)
ignore.strand <- ignore.strand(x)
.coverage_as_dataframe(lst, rng, ignore.strand=ignore.strand,
resolution.fine=FALSE)
}
.multifine_coverage_reader <- function(x)
{ ## x: a Sanpshot instance
## create a plot of coverage, separate lines for each file
lst <- .get_fine_coverage(x)
rng <- vrange(x)
ignore.strand <- ignore.strand(x)
if (length(fac(x)) )
gfac <- values(files(x))[[fac(x)]]
else gfac <- NULL
.multiFile_coverage_as_dataframe(lst, rng, ignore.strand=ignore.strand,
fac=gfac, resolution.fine=TRUE)
}
.multicoarse_coverage_reader <- function(x)
{ ## x: a Sanpshot instance
## create a plot of coverage, separate lines for each file
lst <- .get_coarse_coverage(x)
rng <- vrange(x)
ignore.strand <- ignore.strand(x)
if (length(fac(x)) )
gfac <- values(files(x))[[fac(x)]]
else gfac <- NULL
.multiFile_coverage_as_dataframe(lst, rng, ignore.strand=ignore.strand,
fac=gfac, resolution.fine=FALSE)
}
.update_viewer <- function(x, cv)
{
## subset annTrack and validate anntrack
anntrack <- annTrack(x)
rng <- vrange(x)
ignore.strand <- ignore.strand(x)
if (any(seqnames(anntrack)@values %in% seqlevels(rng))) {
gr <- anntrack
seqlevels(gr, pruning.mode="coarse") <- seqlevels(vrange(x))
} else {
message(paste(strwrap("SnapshotFunction-helper: seqname of
'annTrack' does not match the imported range. Annotation
track will not be plotted."), collapse="\n"))
return(NULL)
}
## if anntrack has no elementMetada value, then return NULL
if (ncol(values(anntrack)) < 1) {
message(paste(strwrap("SnapshotFunction-helper: at least one
column of 'annTrack' elementMetadata is required. Annotation
track will not be plotted."), collapse="\n"))
return(NULL)
}
# x: a Snapshot instance
if (.currentFunction(x) %in% c("coarse_coverage", "multicoarse_coverage"))
ann <- .coarse_annviewer(gr, rng, ignore.strand)
if (.currentFunction(x) %in% c("fine_coverage", "multifine_coverage"))
ann <- .fine_annviewer(gr, ignore.strand)
strip.label <- c(dimnames(cv)$levels, "annotation track")
npacket <- length(cv$packet.sizes)
ann$x.limits <- cv$x.limits
update(c(cv, ann), x.same=TRUE, layout=c(1,npacket+1),
xlab=NULL, ylab=NULL,
strip=if (!is.null(dimnames(cv)$levels))
strip.custom(factor.levels=strip.label),
par.setting=list(layout.heights=list(panel=c(rep(2,npacket),1))))
}
## viewers
.coverage_viewer <- function(x)
{
## x: a Snapshot instance
sp <- .getData(x) # x$.data
lty <- rep(seq_len(length(levels(sp$group)) / 2), times=2)
## sp: data.frame with "data", "group", and "pos" column
col <- c("#66C2A5", "#FC8D62")
scales <- list(y=list(tck=c(1,0)),
x=list(rot=45, tck=c(1,0), tick.number=20))
cv <- if (!ignore.strand(x))
xyplot(data ~ pos, data=sp, group=sp$group, col=col,
scales=scales)
else
xyplot(data ~ pos, data=sp, col=col[1], scales=scales)
cv <- update(cv, type="s", ylab="Coverage", xlab="Coordinate",
panel=function(...) {
panel.xyplot(...)
panel.grid(h=-1, v=20)
panel.abline(a=0, b=0, col="grey")
})
if (!is.null(annTrack(x))) {
ud <- .update_viewer(x, cv)
if (!is.null(ud)) cv <- ud
}
SpTrellis(trellis=cv)
}
.multicoverage_viewer <- function(x, ...)
{ ## x: a Snapshot instance
sp <- .getData(x) #x$.data
lv <- length(levels(sp$group))/2
lty <- rep(seq_len(lv), times=2)
col <- c("#FC8D62", "#66C2A5")
#col <- c(rep("#FC8D62", lv) , rep("#66C2A5", lv))
scales <- list(y=list(tck=c(1,0)),
x=list(rot=45, tck=c(1,0), tick.number=20))
cv <- if (ignore.strand(x))
xyplot(data ~ pos | levels, data=sp, col=col[2], scales=scales)
else
xyplot(data ~ pos | levels, data=sp, group=sp$group, col=col,
scales=scales)
cv <- update(cv, type="s", ylab="Coverage", xlab="Coordinate",
layout=c(1, length(levels(factor(sp$levels)))),
#key=list(space="top", column=2, cex=0.8,
# lines=list(lty=lty, col=col),
# text=list(levels(sp$group))),
panel=function(...) {
panel.xyplot(...)
panel.grid(h=-1, v=20)
panel.abline(a=0, b=0, col="grey")
})
if (!is.null(annTrack(x))) {
ud <- .update_viewer(x, cv)
if (!is.null(ud)) cv <- ud
}
SpTrellis(trellis=cv)
}
### default annotation track viewer
.fine_annviewer <- function(gr, ignore.strand)
{ ## how to get the window
x <- start(gr)
x1 <- end(gr)
xm <- (x+x1)/2
y <- rep(c(-1.4, -0.7, 0, 0.7, 1.4), length.out=length(x))
col <- c("#66C2A5", "#FC8D62")
myCol <- if (ignore.strand) col[1]
else col[as.numeric(strand(gr)@values)]
mypanel <- function(x,y, genenames, x1, ...) {
panel.xyplot(x,y, ..., col="transparent")
ltext(x=xm, y=y, genenames, cex=0.45, pos=3)
lsegments(x0=x, y0=y, x1=x1, y1=y, col=myCol, alpha=0.5)
}
ann <- xyplot(y ~ x, genenames=as.character(values(gr)[[1]]),
x1=x1, xm=xm, panel=mypanel,
xlab=NULL, ylab=NULL,
scales=list(y=list(tick.number=0, labels=NULL)),
par.settings=
list(axis.text=list(alpha=0.5), axis.line=list(alpha=0.5))
)
ann$y.limits[2] = 2.1
ann
}
.coarse_annviewer <- function(gr, rng, ignore.strand)
{
## gr: GRanges for tracks
## rng: range of an Snapshot instance
col <- c("#66C2A5", "#FC8D62")
nbins=5000L
interval <- seq.int(start(rng), end(rng), length.out=nbins)
l <- length(interval)
ir <- IRanges(start=interval[1:(l-1)], end=interval[2:l])
scales <- list(y=list(alternating=2, tick.number=3,tck=c(0,1)),
x=list(tck=c(0,0), labels=NULL))
annview <- if (!ignore.strand) {
lst <- list("+" = countOverlaps(ir, ranges(gr[strand(gr)=="+"])),
"-" = countOverlaps(ir, ranges(gr[strand(gr)=="-"])))
snames <- c("positive", "negative")
group <- factor(rep(snames, each=length(lst[[1]])),
levels=snames)
cvg <- data.frame(data=c(lst[["+"]], -lst[["-"]]),
group=group,
pos = (start(ir)+end(ir))/2)
xyplot(data ~ pos, data=cvg, groups=group, col=col, scales=scales)
} else {
lst <- countOverlaps(ir, ranges(gr))
cvg <- data.frame(data=lst, pos=(start(ir)+end(ir))/2)
xyplot(data ~ pos, data=cvg, col=col[1], scales=scales)
}
update(annview, type="h", xlab=NULL, ylab=NULL,
par.settings=list(axis.text=list(alpha=0.5),
axis.line=list(alpha=0.5)))
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.