# \item{chromosomes}{An optional @numeric @vector specifying which
# chromosomes to plot.}
#
# \item{seed}{An (optional) @integer specifying the random seed to be
# set before subsampling. The random seed is
# set to its original state when exiting. If @NULL, it is not set.}
#
# \item{verbose}{See @see "R.utils::Verbose".}
#
setMethodS3("plotTracksManyChromosomes", "PairedPSCBS", function(fit, chromosomes=getChromosomes(fit), tracks=NULL, scatter="*", calls=if (callLoci || length(chromosomes) == 1L) ".*" else NULL, callLoci=FALSE, callThresholds=TRUE, boundaries=TRUE, knownSegments=FALSE, quantiles=c(0.05,0.95), seed=0xBEEF, pch=".", Clim=c(0,3*ploidy(fit)), Blim=c(0,1), xScale=1e-6, xlabTicks=if (length(chromosomes) == 1L) "[pos]" else "[chr]", ..., subset=if (length(chromosomes) > 1L) 0.1 else NULL, add=FALSE, subplots=!add && (length(tracks) > 1L), oma=c(0,0,2,0), mar=c(2,5,1,3)+0.1, onBegin=NULL, onEnd=NULL, verbose=FALSE) {
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Local functions
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
attachGH <- function(gh, envir=parent.frame()) {
if (!is.list(gh)) return()
if (is.null(gh$track)) return()
if (!is.null(value <- gh$track)) assign("track", value, envir=envir)
if (!is.null(value <- gh$subtracks)) assign("trackT", value, envir=envir)
if (!is.null(value <- gh$scatter$col)) assign("colS", value, envir=envir)
if (!is.null(value <- gh$scatter$pch)) assign("pchT", value, envir=envir)
if (!is.null(value <- gh$level$col)) assign("colL", value, envir=envir)
if (!is.null(value <- gh$cis$col)) assign("colC", value, envir=envir)
} # attachGH()
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Graphical styles
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
opts <- list(
scatter = list(pch=".", col=c("#aaaaaa")),
callScatter = list(col=c("#aaaaaa", LOSS="blue", GAIN="red", LOH="purple")),
smoothScatter = list(pch=".", col=c("#666666")),
level = list(lty=1L, col=c("black", tcn="purple", c1="blue", c2="red", dh="orange")),
callLevel = list(lty=1L, col=c("#666666")),
knownSegment = list(lty=1L, col=c("#aaaaaa"))
)
getOptionValue <- function(option, what, track, ...) {
values <- opts[[option]][[what]]
value <- values[track]
if (is.na(value)) value <- values[1L]
unname(value)
} # getOptionValue()
getScatterColor <- function(track, ...) {
getOptionValue("scatter", "col", track, ...)
} # getScatterColor()
getLevelColor <- function(track, ...) {
getOptionValue("level", "col", track, ...)
} # getLevelColor()
getCallScatterColor <- function(track, ...) {
getOptionValue("callScatter", "col", track, ...)
} # getCallScatterColor()
getCallLevelColor <- function(track, ...) {
getOptionValue("callLevel", "col", track, ...)
} # getCallLevelColor()
getCallLevelLty <- function(track, ...) {
getOptionValue("callLevel", "lty", track, ...)
} # getCallLevelColor()
getCIColor <- function(track, ...) {
getLevelColor(track, ...)
} # getLevelColor()
getKnownSegmentColor <- function(track, ...) {
getOptionValue("knownSegment", "col", track, ...)
} # getKnownSegmentColor()
getKnownSegmentLty <- function(track, ...) {
getOptionValue("knownSegment", "lty", track, ...)
} # getKnownSegmentColor()
drawXLabelTicks <- function() {
if (identical(xlabTicks, "[chr]")) {
mtext(text=chrTags, side=rep(c(1,3), length.out=length(chrTags)), at=mids, line=0.1, cex=0.7)
} else if (identical(xlabTicks, "[pos]")) {
axis(side=1L)
}
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Validate arguments
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Argument 'fit':
# Argument 'chromosomes':
if (!is.null(chromosomes)) {
disallow <- c("NaN", "Inf")
chromosomes <- Arguments$getIntegers(chromosomes, range=c(0,Inf), disallow=disallow)
.stop_if_not(all(is.element(chromosomes, getChromosomes(fit))))
}
# Argument 'tracks':
knownTracks <- c("tcn", "dh", "tcn,c1,c2", "c1,c2", "c1", "c2",
"betaN", "betaT", "betaTN")
defaultTracks <- knownTracks[1:3]
if (is.null(tracks)) {
tracks <- defaultTracks
} else {
tracks <- match.arg(tracks, choices=knownTracks, several.ok=TRUE)
tracks <- unique(tracks)
}
# Argument 'scatter':
if (!is.null(scatter)) {
scatter <- Arguments$getCharacter(scatter)
if (scatter == "*") {
scatter <- tracks
} else {
scatterT <- strsplit(scatter, split=",", fixed=TRUE)
tracksT <- strsplit(tracks, split=",", fixed=TRUE)
.stop_if_not(all(is.element(scatterT, tracksT)))
# Not needed anymore
scatterT <- tracksT <- NULL
}
}
# Argument 'calls':
if (!is.null(calls)) {
calls <- sapply(calls, FUN=Arguments$getRegularExpression)
}
# Argument 'callLoci':
callLoci <- Arguments$getLogical(callLoci)
# Argument 'callThresholds':
callThresholds <- Arguments$getLogical(callThresholds)
# Argument 'boundaries':
boundaries <- Arguments$getLogical(boundaries)
# Argument 'knownSegments':
knownSegments <- Arguments$getLogical(knownSegments)
# Argument 'add':
add <- Arguments$getLogical(add)
# Argument 'Clim' & 'Blim':
if (!add) {
Clim <- Arguments$getNumerics(Clim, length=c(2L,2L),
disallow=c("Inf", "NA", "NaN"))
Blim <- Arguments$getNumerics(Blim, length=c(2L,2L),
disallow=c("Inf", "NA", "NaN"))
}
# Argument 'xScale':
xScale <- Arguments$getNumeric(xScale, range=c(0,Inf))
# Argument 'xlabTicks':
if (!is.null(xlabTicks)) {
xlabTicks <- Arguments$getCharacter(xlabTicks)
}
# Argument 'subset':
if (!is.null(subset)) {
subset <- Arguments$getDouble(subset)
}
# Argument 'verbose':
verbose <- Arguments$getVerbose(verbose)
if (verbose) {
pushState(verbose)
on.exit(popState(verbose))
}
verbose && enter(verbose, "Plotting PSCN tracks")
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Subset by chromosomes
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if (!is.null(chromosomes)) {
verbose && enter(verbose, "Plotting a subset of the chromosomes")
fit <- extractChromosomes(fit, chromosomes=chromosomes, verbose=verbose)
verbose && exit(verbose)
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Tile chromosomes
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
fit <- tileChromosomes(fit, verbose=verbose)
verbose && str(verbose, fit)
# Extract the input data
data <- getLocusData(fit)
if (is.null(data)) {
stop("Cannot plot segmentation results. No input data available.")
}
# Extract the segmentation
segs <- as.data.frame(fit)
# Identify available calls
callData <- NULL
if (!is.null(calls) || callThresholds) {
verbose && enter(verbose, "Identifying calls")
pattern <- "Call$"
allCallColumns <- grep(pattern, colnames(segs), value=TRUE)
allCallLabels <- toupper(gsub(pattern, "", allCallColumns))
verbose && cat(verbose, "Call columns:")
verbose && print(verbose, allCallColumns)
if (!is.null(calls)) {
callColumns <- allCallColumns
if (length(callColumns) > 0L) {
keep <- sapply(calls, FUN=function(pattern) {
(regexpr(pattern, callColumns) != -1L)
})
if (is.matrix(keep)) {
keep <- rowAnys(keep, useNames=FALSE)
}
callColumns <- callColumns[keep]
callLabels <- allCallLabels[keep]
# Annotate individual loci by calls?
if (callLoci) {
callData <- extractCallsByLocus(fit, verbose=less(verbose,5))
}
}
verbose && cat(verbose, "Call to be annotated:")
verbose && print(verbose, callColumns)
}
verbose && exit(verbose)
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Subset of the loci?
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if (!is.null(subset)) {
# (a) Set and unset the random seed
if (!is.null(seed)) {
randomSeed("set", seed=seed, kind="L'Ecuyer-CMRG")
on.exit(randomSeed("reset"), add=TRUE)
verbose && printf(verbose, "Random seed temporarily set (seed=%d)\n", seed)
}
# (b) Subset
n <- nrow(data)
keep <- sample(n, size=subset*n)
data <- data[keep,]
if (!is.null(callData)) {
callData <- callData[keep,]
}
}
# To please R CMD check
CT <- rho <- muN <- betaT <- betaN <- betaTN <- rho <- NULL
rm(list=c("CT", "rho", "muN", "betaT", "betaN", "betaTN"))
attachLocally(data)
# Calculate (C1,C2)
C1 <- 1/2*(1-rho)*CT
C2 <- CT - C1
# BACKWARD COMPATIBILITY:
# If 'rho' is not available, recalculate it from tumor BAFs.
# NOTE: This should throw an error in the future. /HB 2013-10-25
if (is.null(data$rho)) {
isSnp <- (!is.na(betaTN) & !is.na(muN))
isHet <- isSnp & (muN == 1/2)
rho <- rep(NA_real_, times=nbrOfLoci)
rho[isHet] <- 2*abs(betaTN[isHet]-1/2)
warning(sprintf("Locus-level DH signals ('rho') were not available in the %s object and therefore recalculated from the TumorBoost-normalized tumor BAFs ('betaTN').", class(fit)[1L]))
}
x <- xScale * x
vs <- xScale * fit$chromosomeStats[,1:2,drop=FALSE]
mids <- (vs[,1]+vs[,2])/2
nbrOfLoci <- length(x)
chrTags <- sprintf("Chr%02d", chromosomes)
if (subplots) {
subplots(length(tracks), ncol=1L)
par(oma=oma, mar=mar)
}
pchT <- if (!is.null(scatter)) { pch } else { NA }
xlim <- range(x, na.rm=TRUE)
xlab <- "Genomic position"
# Graphical handle
gh <- list(fit=fit)
gh$xScale <- xScale
gh$xlim <- xlim
gh$xlab <- xlab
if (!is.null(callData)) {
gh$callsByLocus <- callData
}
for (tt in seq_along(tracks)) {
track <- tracks[tt]
verbose && enter(verbose, sprintf("Track #%d ('%s') of %d",
tt, track, length(tracks)))
# Get graphical style parameters.
tracksT <- unlist(strsplit(track, split=",", fixed=TRUE))
colS <- sapply(tracksT, FUN=getScatterColor)
colL <- sapply(tracksT, FUN=getLevelColor)
colC <- sapply(tracksT, FUN=getCIColor)
# Color scatter plot according to calls?
if (!is.null(calls) && callLoci && length(callColumns) > 0L) {
colsT <- rep(colS[1L], times=nrow(callData))
for (cc in seq_along(callColumns)) {
callColumn <- callColumns[cc]
callLabel <- callLabels[cc]
verbose && enter(verbose, sprintf("Call #%d ('%s') of %d",
cc, callLabel, length(callColumns)))
verbose && cat(verbose, "Column: ", callColumn)
skip <- TRUE
if (regexpr("tcn", track) != -1L) {
skip <- !is.element(callLabel, c("LOSS", "NTCN", "GAIN", "LOH"))
} else if (track == "dh") {
skip <- !is.element(callLabel, c("AB", "LOH"))
}
if (skip) {
verbose && exit(verbose)
next
}
callsCC <- callData[[callColumn]]
idxs <- which(callsCC)
# Nothing to do?
if (length(idxs) == 0L) {
verbose && exit(verbose)
next
}
callCol <- getCallScatterColor(callLabel)
colsT[idxs] <- callCol
} # for (cc in ...)
colS <- colsT
} # if (!is.null(calls))
# Assign graphical-handle parameters
gh$track <- track
gh$subtracks <- tracksT
gh$scatter <- list(col=colS, pch=pchT)
gh$level <- list(col=colL)
gh$cis <- list(col=colC)
if (track == "tcn") {
plot(NA, xlim=xlim, ylim=Clim, xlab=xlab, ylab="TCN", axes=FALSE)
if (!is.null(onBegin)) attachGH(onBegin(gh=gh))
if (!is.na(pchT)) {
points(x, CT, pch=pchT, col=colS)
}
drawConfidenceBands(fit, what="tcn", quantiles=quantiles, col=colC["tcn"], xScale=xScale)
drawLevels(fit, what="tcn", col=colL, xScale=xScale)
}
if (is.element(track, c("tcn,c1,c2", "c1,c2", "c1", "c2"))) {
tracksT <- unlist(strsplit(track, split=",", fixed=TRUE))
plot(NA, xlim=xlim, ylim=Clim, xlab=xlab, ylab="C1, C2, TCN", axes=FALSE)
if (!is.null(onBegin)) attachGH(onBegin(gh=gh))
# Draw scatter for TCN or C1 and C2.
if (!is.na(pchT)) {
if (is.element("tcn", tracksT)) {
points(x, CT, pch=pchT, col=colS)
} else {
if (is.element("c1", tracksT)) {
points(x, C1, pch=pchT, col=colS)
}
if (is.element("c2", tracksT)) {
points(x, C2, pch=pchT, col=colS)
}
}
}
# Draw confidence bands for TCN, C1, C2.
if (is.element("tcn", tracksT)) {
drawConfidenceBands(fit, what="tcn", quantiles=quantiles, col=colC["tcn"], xScale=xScale)
}
if (is.element("c2", tracksT)) {
drawConfidenceBands(fit, what="c2", quantiles=quantiles, col=colC["c2"], xScale=xScale)
}
if (is.element("c1", tracksT)) {
drawConfidenceBands(fit, what="c1", quantiles=quantiles, col=colC["c1"], xScale=xScale)
}
# Draw segment means for TCN, C1, C2.
if (is.element("tcn", tracksT)) {
drawLevels(fit, what="tcn", col=colL["tcn"], xScale=xScale)
}
if (is.element("c2", tracksT)) {
drawLevels(fit, what="c2", col=colL["c2"], xScale=xScale)
}
if (is.element("tcn", tracksT)) {
# In case C2 overlaps with TCN
drawLevels(fit, what="tcn", col=colL["tcn"], lty="22", xScale=xScale)
}
# In case C1 overlaps with C2
if (is.element("c1", tracksT)) {
drawLevels(fit, what="c1", col=colL["c1"], xScale=xScale)
if (is.element("c2", tracksT)) {
drawLevels(fit, what="c2", col=colL["c2"], lty="22", xScale=xScale)
}
if (is.element("tcn", tracksT)) {
drawLevels(fit, what="tcn", col=colL["tcn"], lty="22", xScale=xScale)
}
}
}
if (track == "betaN") {
plot(NA, xlim=xlim, ylim=Blim, xlab=xlab, ylab="BAF_N", axes=FALSE)
if (!is.null(onBegin)) attachGH(onBegin(gh=gh))
if (!is.na(pchT)) {
points(x, betaN, pch=pchT, col=colS)
}
}
if (track == "betaT") {
plot(NA, xlim=xlim, ylim=Blim, xlab=xlab, ylab="BAF_T", axes=FALSE)
if (!is.null(onBegin)) attachGH(onBegin(gh=gh))
if (!is.na(pchT)) {
points(x, betaT, pch=pchT, col=colS)
}
}
if (track == "betaTN") {
plot(NA, xlim=xlim, ylim=Blim, xlab=xlab, ylab="BAF_TN", axes=FALSE)
if (!is.null(onBegin)) attachGH(onBegin(gh=gh))
if (!is.na(pchT)) {
points(x, betaTN, pch=pchT, col=colS)
}
}
if (track == "dh") {
plot(NA, xlim=xlim, ylim=Blim, xlab=xlab, ylab="DH", axes=FALSE)
if (!is.null(onBegin)) attachGH(onBegin(gh=gh))
if (!is.na(pchT)) {
points(x, rho, pch=pchT, col=colS)
}
drawConfidenceBands(fit, what="dh", quantiles=quantiles, col=colC["dh"], xScale=xScale)
drawLevels(fit, what="dh", col=colL["dh"], xScale=xScale)
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# For each panel of tracks, annotate segments with calls?
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if (!is.null(calls) && !callLoci && length(callColumns) > 0L) {
for (cc in seq_along(callColumns)) {
callColumn <- callColumns[cc]
callLabel <- callLabels[cc]
verbose && enter(verbose, sprintf("Call #%d ('%s') of %d",
cc, callLabel, length(callColumns)))
verbose && cat(verbose, "Column: ", callColumn)
segsT <- segs[,c("dhStart", "dhEnd", callColumn)]
isCalled <- which(segsT[[callColumn]])
segsT <- segsT[isCalled,1:2,drop=FALSE]
verbose && printf(verbose, "Number of segments called %s: %d\n",
callLabel, nrow(segsT))
segsT <- xScale * segsT
verbose && str(verbose, segsT)
side <- 2*((cc+1) %% 2) + 1
# For each segment called...
for (ss in seq_len(nrow(segsT))) {
x0 <- segsT[ss,1,drop=TRUE]
x1 <- segsT[ss,2,drop=TRUE]
abline(v=c(x0,x1), lty=3, col="gray")
xMid <- (x0+x1)/2
mtext(side=side, at=xMid, line=-1, cex=0.7, col="#666666", callLabel)
} # for (ss in ...)
verbose && exit(verbose)
} # for (cc in ...)
} # if (!is.null(calls))
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# For each panel of tracks, annotate with call thresholds?
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if (callThresholds) {
# Add call parameter estimates, e.g. deltaAB
colCL <- sapply(tracksT, FUN=getCallLevelColor)
ltyCL <- sapply(tracksT, FUN=getCallLevelLty)
trackT <- track
for (cc in seq_along(allCallColumns)) {
callColumn <- allCallColumns[cc]
callLabel <- allCallLabels[cc]
h <- NULL
if (callLabel == "AB") {
if (track == "dh") {
h <- fit$params$deltaAB
label <- expression(Delta[AB])
}
} else if (callLabel == "LOH") {
if (regexpr("c1", track) != -1L) {
h <- fit$params$deltaLowC1
label <- expression(Delta[LOH])
trackT <- "c1"
}
} else if (callLabel == "NTCN") {
if (track == "tcn") {
h <- fit$params$ntcnRange
label <- c(expression(Delta[-NTCN]), expression(Delta[+NTCN]))
}
}
if (!is.null(h)) {
abline(h=h, lty=ltyCL[trackT], lwd=2, col=colCL[trackT])
for (ss in 1:2) {
side <- c(2,4)[ss]
adj <- c(1.2,-0.2)[ss]
mtext(side=side, at=h, label, adj=adj, las=2, xpd=TRUE)
}
}
} # for (cc in ...)
} # if (callThresholds)
drawXLabelTicks()
if (boundaries) {
abline(v=vs, lty=1, lwd=2)
}
if (knownSegments) {
colT <- getKnownSegmentColor()
ltyT <- getKnownSegmentLty()
drawKnownSegments(fit, col=colT, lty=ltyT)
}
axis(side=2); box()
if (!is.null(onEnd)) onEnd(gh=gh)
verbose && exit(verbose)
} # for (tt ...)
verbose && exit(verbose)
invisible(gh)
}, private=TRUE) # plotTracksManyChromosomes()
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.