#' @include CAGEr.R
#' @name quantilePositions
#'
#' @title Determine CTSS quantile positions within clusters
#'
#' @description Calculates the positions of \dQuote{upper} and \dQuote{lower}
#' quantiles of CAGE signal along _tag clusters_ or _consensus clusters_ in each
#' sample of a [`CAGEexp`] object.
#'
#' @param object A CAGEexp object.
#'
#' @param clusters Either `tagClusters` or `consensusClusters`.
#'
#' @param qLow,qUp Which \dQuote{lower} or \dQuote{upper} quantiles should be
#' calculated. Numeric vector of values in range `[0,1]`.
#'
#' @param useMulticore Logical, should multicore be used. `useMulticore = TRUE`
#' has only effect on Unix-like platforms.
#'
#' @param nrCores Number of cores to use when `useMulticore = TRUE`. Default
#' value `NULL` uses all detected cores.
#'
#' @details From the 5' end the position, the position of a quantile _q_ is
#' determined as the first base in which of the cumulative expression is higher
#' or equal to _q%_ of the total CAGE signal of that cluster. Promoter
#' _interquantile width_ is defined as the distance (in base pairs) between a
#' \dQuote{lower} and an \dQuote{upper} quantile position.
#'
#' @return Returns the objects, in which the positions of the quantiles are
#' defined relatively to the start point of their cluster, for more efficient
#' `Rle` compression. The quantile data for _tag clusters_ are stored in the
#' `TagClusters` objects directly. The quantile data for `consensus clusters`
#' are stored in [`integer`] matrices named \dQuote{q_\emph{x}}, where \emph{x}
#' represents the quantile (for instance, `q_0.1`), and these matrices are
#' _assays_ of the `consensusClusters` [`RangedSummarizedExperiment`].
#'
#' @author Vanja Haberle
#' @author Charles Plessy
#'
#' @family CAGEr object modifiers
#' @family CAGEr clusters functions
#'
#' @examples
#'
#' quantilePositions(exampleCAGEexp, "tagClusters", qLow = c(0.1, 0.2), qUp = c(0.8, 0.9))
#' tagClustersGR(exampleCAGEexp)
#' quantilePositions(exampleCAGEexp, "consensusClusters", qLow = c(0.1, 0.2), qUp = c(0.8, 0.9))
#'
#' @export
setGeneric( "quantilePositions"
, function( object
, clusters = c("tagClusters", "consensusClusters")
, qLow = 0.1, qUp = 0.9
, useMulticore = FALSE, nrCores = NULL)
standardGeneric("quantilePositions"))
#' @rdname quantilePositions
setMethod( "quantilePositions", "CAGEexp"
, function (object, clusters, qLow, qUp, useMulticore, nrCores) {
clusters <- match.arg(clusters)
message("\nGetting positions of quantiles within clusters...")
if (clusters == "tagClusters") {
ctss.clusters <- bplapply(sampleList(object), function(s) {
message("\t-> ", s)
.get.quant.pos( cum.sums = CTSScumulativesTagClusters(object, s)
, clusters = tagClustersGR(object, s)
, q = c(qLow, qUp))
},
BPPARAM = CAGEr_Multicore(useMulticore, nrCores))
ctss.clusters <- GRangesList(ctss.clusters)
# Keep metadata, it contains information on clustering method!
metadata(ctss.clusters) <- metadata(object)
tagClustersGR(object) <- ctss.clusters
} else if (clusters == "consensusClusters"){
cons.clusters.l <- bplapply(sampleList(object), function(s) {
message("\t-> ", s)
.get.quant.pos( cum.sums = CTSScumulativesCC(object, s)
, clusters = consensusClustersGR(object)
, q = c(qLow, qUp))
},
BPPARAM = CAGEr_Multicore(useMulticore, nrCores))
message("\t-> ", "all samples grouped")
qpos <- .get.quant.pos( cum.sums = object@metadata$CTSScumulativesConsensusClustersAll
, clusters = rowRanges(consensusClustersSE(object))
, q = c(qLow, qUp))
for (quantile in c(qLow, qUp)) {
# Each sample separately
qName <- paste("q", quantile, sep = "_")
assays(consensusClustersSE(object), withDimnames=FALSE)[[qName]] <-
DataFrame(lapply(cons.clusters.l, function(gr) mcols(gr)[,qName]))
# All samples pooled
mcols(rowRanges(consensusClustersSE(object)))[[qName]] <- mcols(qpos)[[qName]]
}
}
object
})
#' Get quantile positions
#'
#' Private function that calculates position of quantiles for CTSS clusters
#' based on distribution of tags within the clusters.
#'
#' @param cum.sums Named list of vectors containing cumulative sum for each
#' cluster (returned by the `CTSScumulativesTagClusters` or
#' `CTSScumulativesCC` function).
#' @param clusters [`TagClusters`] or [`ConsensusClusters`] object representing
#' tag clusters or consensus clusters.
#' @param q desired quantiles - single value or a vector of values.
#'
#' @return Returns the `clusters` object with one more metadata column per value
#' in `q`, containing `Rle` integers giving the relative distance of the
#' quantile boundaries to the start position.
#'
#' @examples
#' cum.sums <- RleList(`1` = Rle(1), `2` = cumsum(Rle(c(1, 1, 1, 2, 4, 0, 1, 1))))
#' clusters <- GRanges(c("chr1:100-101", "chr1:120-127"))
#' CAGEr:::.get.quant.pos(cum.sums, clusters, c(.2, .8))
#' @rdname QuantileWidthFunctions
.get.quant.pos <- function(cum.sums, clusters, q) {
# See benchmarks/quantile_position.Rmd in the source repository
getQuantilepos <- function(q, cum.sums) {
nl <- as(cum.sums, "NumericList")
min(which(nl >= max(nl) * q))
}
# Calculate quantile positions for each quantile.
cluster.q <- lapply(q, getQuantilepos, cum.sums)
names(cluster.q) = paste('q_', q, sep = '')
# Add one metadata column per quantile to the cluster object and return it.
mcols(clusters)[, names(cluster.q)] <- DataFrame(lapply(cluster.q, Rle))
clusters
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.