Nothing
###
### $Id: rs5-rppaSet.R
### Fit a set of slides with a common layout
###
##=============================================================================
setClassUnion("OptionalRPPASpatialParams", c("RPPASpatialParams", "NULL"))
setClass("RPPASet",
representation(call="call", ## function invocation
design="RPPADesignParams",
rppas="array", ## vector of RPPAs
spatialparams="OptionalRPPASpatialParams",
prefitqcs="array", ## vector of QC values
fitparams="RPPAFitParams",
fits="array", ## set of fits
completed="matrix", ## what worked/failed
normparams="RPPANormalizationParams",
version="character",
residualsrotation="integer",
warningsFileName="character",
errorsFileName="character"
)) ## package version
##-----------------------------------------------------------------------------
is.RPPASet <- function(x) {
is(x, "RPPASet")
}
##-----------------------------------------------------------------------------
## Method to rotate a matrix 90 degrees, by default clockwise.
rotateMatrix <- function(x, clockwise = T)
{
if (clockwise)
{
t( apply(x, 2, rev))
}
else
{
apply( t(x),2, rev)
}
}
##-----------------------------------------------------------------------------
## Method to rotate a matrix numRots increments x 90 degrees clockwise.
rotateMatrixClockwise90Degrees <- function(m, numRots = c(0,1,2,3))
{
#numRots
# 0: 0 degree rotation, return original matrix
# 1: 90 degree rotation, rotate matrix clockwise once
# 2: 180 degree rotation, rotate matrix clockwise twice
# 3: 270 degree rotation, rotate matrix counterclockwise once
return (switch(numRots+1, m, rotateMatrix(m), rotateMatrix(rotateMatrix(m)), rotateMatrix(m,FALSE)))
}
##-----------------------------------------------------------------------------
## Create the fit graphs and save them as PNG files
createResidualsPNG <- function (
topPlotFileName,
outputfilename,
measure,
antibody,
m,
majorxpoints = as.integer(NA),
majorypoints = as.integer(NA),
plotcolors = NA,
missingvaluecolor = "#AAAAAA",
gridcolor = "black",
colorlegend = FALSE,
cellsize = 3,
rotation
)
{
#---------------------------------------------
#Setup for matrix colors
#---------------------------------------------
#Set up where breaks between colors should be.
#10 color breaks with 11 color values over range from .4 to 1.
#Set default Red-Yellow-Green color range if no color range was specified
if (anyNA(plotcolors))
{
#Colors to use for rectangles in plot
#Go from Red (.4) to Yellow (.7) to Green (1.0)
RYG <- c("#A50026", #Red
"#D73027",
"#F46D43",
"#FDAE61",
"#FEE066",
"#FFFF88", #Yellow
"#D9EF88",
"#A6D96A",
"#66BD63",
"#1A9850",
"#006837" #Green
)
plotcolors <- RYG
}
numcolors <- length(plotcolors)
mincolorvalue <- .39999999999
rangeofvalues <- 1 - mincolorvalue
breakpoints <- mincolorvalue + (0:(numcolors-1))/(numcolors/rangeofvalues)
if (colorlegend)
{
nacolorbarheight <- 12
nacolordivider <- 10
colorbarxsize <- 40
colorbarysize <- as.integer(256/numcolors) * numcolors
if (colorbarysize / numcolors > 12)
{
colorbarysize <- 12 * numcolors
}
colorbartotalheight <- colorbarysize + nacolordivider + nacolorbarheight
}
#Apply requested rotations to data values and switch grid labels as needed
if (rotation == as.integer(90))
{
m <- rotateMatrixClockwise90Degrees(m, 1)
temp <- majorxpoints
majorxpoints <- majorypoints
majorypoints <- temp
}
else if (rotation == as.integer(180))
{
m <- rotateMatrixClockwise90Degrees(m, 2)
}
else if (rotation == as.integer(270))
{
m <- rotateMatrixClockwise90Degrees(m, 3)
temp <- majorxpoints
majorxpoints <- majorypoints
majorypoints <- temp
}
values <- as.vector(m)
xpoints <- ncol(m)
ypoints <- nrow(m)
# Make matrices to plot series of rectangles based on number of x and y elements
# times the sizes of the cells. This calculates the left (mxl) and bottom (myb)
# coordinates of each rectangle to plot.
mxl <- matrix(rep(0:(xpoints-1) * cellsize, ypoints), ncol=xpoints, nrow=ypoints, byrow=TRUE)
myb <- matrix(rep(0:(ypoints-1) * cellsize, xpoints), ncol=xpoints, nrow=ypoints, byrow=FALSE)
#Set index values for all colors in data matrix for slide RR2 values
colindex <- as.integer(cut(as.array(m), breaks=c( unlist(breakpoints), 1)))
#Color all blocks according to color scale adjusted from .4 to 1
gcolors <- plotcolors[colindex]
#Color all NA (missing) values gray.
gcolors[is.na(gcolors)] <- missingvaluecolor
#Base x grid labels off x major grid sections
#gridxlabels <- (0:majorxpoints) * as.integer(xpoints/majorxpoints)
gridxlabels <- (0:as.integer(xpoints/majorxpoints)) * majorxpoints
#Base y grid labels off y major grid sections
#If y grid labels are defined, attempt to use those, otherwise base them off y major grid sections
#gridylabels <- ((majorypoints:0) * as.integer(ypoints/majorypoints))
gridylabels <- ((as.integer(ypoints/majorypoints):0) * majorypoints)
#Calculate how much to adjust grid locations to move each one a 2 pixels from axis per grid line > 0
gridxadjust <- (0:(length(gridxlabels)-1)) * 2
#if (min(gridxlabels) > 0) gridxadjust <- gridxadjust + 1
gridyadjust <- ((length(gridylabels)-1):0) * 2
#if (min(gridylabels) > 0) gridyadjust <- gridyadjust + 1
#Set the pixel locations on grid for axis tick marks
gridxlocs <- as.integer(gridxlabels * cellsize + gridxadjust - cellsize/2) + 1
gridylocs <- as.integer(gridylabels * cellsize + gridyadjust - cellsize/2) + 1
#Adjust left and top lines to be at 0 instead 1
gridxlocs[1] <- -1
gridylocs[length(gridylocs)] <- gridylocs[length(gridylocs)]
#If the last x grid location is not included in the generated locations, then add it.
if ((xpoints %% majorxpoints != 0) && (length(gridxlocs) < xpoints + 1))
{
gridxlocs <- append(gridxlocs, as.integer(xpoints* cellsize + max(gridxadjust) + 1))
}
#If the last y grid location is not included in the generated locations, then add it.
if ((ypoints %% majorypoints != 0) && (length(gridylocs) < ypoints + 1))
{
gridylocs <- append(gridylocs, as.integer(ypoints * cellsize + max(gridyadjust)))
}
#Adjust x coordinates of boxes by 2 pixels for each grid mark before it
for(labloc in 1:length(gridxlabels))
{
mxl[,(1:xpoints)[(1:xpoints) > gridxlabels[labloc]]] <- mxl[,(1:xpoints)[(1:xpoints) > gridxlabels[labloc]]] + 2
}
#Adjust x coordinates of boxes by 2 pixels for each grid mark before it
for(labloc in 1:length(gridylabels))
{
myb[(1:ypoints)[(1:ypoints) > gridylabels[labloc]],] <- myb[(1:ypoints)[(1:ypoints) > gridylabels[labloc]],] + 2
}
#Calculate plot dimensions of RSS portion of plot based on size of rectangles and gridlines to be drawn
pdlx <- min(mxl)
pdrx <- max(mxl) + cellsize
pdby <- min(myb)
pdty <- max(myb) + cellsize
#Total plot size in pixels
rssxsize <- pdrx - pdlx
rssysize <- pdty - pdby
#bottom, left, top, right
top_image_height <- 320
text_height_top <- 20
text_height_bottom <- 20
margins_all <- 30
mar_top <- margins_all + text_height_top + top_image_height
mar_left <- margins_all + cellsize
mar_bottom <- margins_all
mar_right <- margins_all - 5
pngxsize <- as.integer(rssxsize + mar_left + mar_right)
pngysize <- as.integer(rssysize + mar_top + mar_bottom + text_height_bottom)
#Adjust width to include color legend if it has been included.
if (colorlegend)
{
pngxsize <- pngxsize + colorbarxsize + mar_right
pngysize <- as.integer(max(rssysize, colorbarysize) + text_height_bottom + mar_top + mar_bottom)
}
#If width is less than 640 pixels, then increase it to 640 to match with width of other plot.
if (pngxsize < 640)
{
expandx <- 640 - pngxsize
pngxsize <- 640
mar_left <- mar_left + as.integer((expandx + 1) / 2)
mar_right <- mar_right + as.integer(expandx / 2)
}
png(filename=outputfilename, bg="white", width = pngxsize, height = pngysize, units="px", type="cairo-png")
plot.new()
viewport(x=unit(mar_left, "native"), y=unit(mar_bottom, "native"))
grid.raster(readPNG(topPlotFileName), x = unit(0, "native"), y = unit(0, "native"), just=c("left","top"))
grid.rect(
x=unit(mxl+mar_left, "native"),
y=unit(myb+mar_top, "native"),
width=unit(cellsize, "native"),
height=unit(cellsize, "native"),
gp=gpar(fill=gcolors, col=gcolors, lwd=0, alpha=1)
)
label_pos <- 1
for(x_loc in (gridxlocs+mar_left))
{
grid.lines(x = unit(x_loc, "native"),
y = unit(c(min(gridylocs) + mar_top, max(gridylocs) + mar_top + 5 ), "native"),
arrow = NULL, name = NULL, gp=gpar(col=gridcolor,lwd=unit(2,"native"),lex=1), draw = TRUE)
if (!is.na(gridxlabels[label_pos]))
{
grid.text(gridxlabels[label_pos], x = unit(x_loc, "native"), y = unit( max(gridylocs) + mar_top + 10, "native"),
just = "top", hjust = NULL, vjust = NULL, rot = 0,
check.overlap = FALSE, default.units = "native",
name = NULL, gp = gpar(color="black", cex=1, fontfamily="Times"), draw = TRUE)
}
label_pos <- label_pos + 1
}
label_pos <- 1
for(y_loc in (gridylocs + mar_top))
{
grid.lines(y = unit(y_loc, "native"),
x = unit(c(min(gridxlocs) + mar_left - 5, max(gridxlocs) + mar_left), "native"),
gp=gpar(col=gridcolor, lwd=unit(2,"native"),lex=1),
draw = TRUE
)
if (!is.na(gridylabels[label_pos]))
{
grid.text(gridylabels[label_pos], x = unit(mar_left - max(c(8,cellsize/2 + 8)), "native"), y = unit(y_loc, "native"),
just = "right", rot = 0,
check.overlap = FALSE, default.units = "native",
gp = gpar(color="black", cex=1, fontfamily="Times"),
draw = TRUE
)
}
label_pos <- label_pos + 1
}
if (colorlegend)
{
cgcellheight <- colorbarysize / numcolors
cgcellwidth <- colorbarxsize %/% 2
cgleft <- pngxsize - mar_right - colorbarxsize
cgtop <- mar_top
cgcelltops <- cgtop + cgcellheight * (0:(numcolors-1))
cggridmarklabels <- c("1.0", "0.9", "0.8", "0.7", "0.6", "0.5", "0.4")
cgtextlocsarea <- max(cgcelltops) - min(cgcelltops) + 0 * cgcellheight
cgtextdist <- cgtextlocsarea / (length(cggridmarklabels)-1)
cgtextylocs <- cgtop + (0:(length(cggridmarklabels)-1)) * cgtextdist + 1
#Draw color scale grid
grid.rect(
x=unit(cgleft, "native"),
y=unit(cgcelltops, "native"),
width=unit(cgcellwidth, "native"),
height=unit(cgcellheight, "native"),
just=c("left","bottom"),
gp=gpar(fill=rev(plotcolors),lwd=0, alpha=1)
)
#Draw color scale area border
grid.rect(
x=unit(cgleft, "native"),
y=unit(cgtop, "native"),
width=unit(cgcellwidth, "native"),
height=unit(cgcellheight * numcolors, "native"),
just=c("left","bottom"),
gp=gpar(fill=NA, col="black", lwd=unit(2,"native"), alpha=1)
)
#Place color scale ticks and labels
for (yloc in cgtextylocs)
{
grid.lines(
x = unit(c(cgleft + colorbarxsize/2,cgleft + colorbarxsize/2 + 5), "native"),
y = unit(c(yloc,yloc), "native"),
gp=gpar(col="black", lwd=unit(2,"native"),lex=1),
draw = TRUE
)
}
grid.text(cggridmarklabels,
x = unit(cgleft + colorbarxsize/2 + 8, "native"),
y = unit(cgtextylocs, "native"),
just = c("left","centre"),
check.overlap = FALSE,
default.units = "native",
gp = gpar(color="black", cex=1, fontfamily="Times"),
draw = TRUE
)
#Add missing color legend elements
grid.rect(
x = unit(cgleft, "native"),
y = unit(max(cgcelltops) + cgcellheight + nacolordivider, "native"),
width = unit(cgcellwidth, "native"),
height = unit(nacolorbarheight, "native"),
just = c("left","bottom"),
gp = gpar(fill=missingvaluecolor, col="black", lwd=unit(2,"native"), alpha=1)
)
grid.lines(
x = unit(c(cgleft + cgcellwidth, cgleft + cgcellwidth + 3), "native"),
y = unit(c(max(cgcelltops) + cgcellheight + nacolordivider + nacolorbarheight/2,
max(cgcelltops) + cgcellheight + nacolordivider + nacolorbarheight/2), "native"),
gp = gpar(col="black", lwd=unit(2,"native"),lex=1),
draw = TRUE
)
grid.text("NA",
x = unit(cgleft + cgcellwidth + 5, "native"),
y = unit(max(cgcelltops) + cgcellheight + nacolordivider + nacolorbarheight/2, "native"),
just = c("left","centre"),
check.overlap = FALSE,
default.units = "native",
gp = gpar(color="black", cex=1, fontfamily="Times"),
draw = TRUE
)
}
#Plot title text
grid.text(
paste(measure, ":", antibody),
x = unit(as.integer(pngxsize / 2), "native"),
y = unit(as.integer(mar_top - text_height_top), "native"),
just = c("center","bottom"),
default.units = "native",
gp = gpar(color="black", cex=1.2, fontface = "bold", fontfamily="Times"),
draw = TRUE)
#Footer text (file name)
grid.text(
paste("File:", outputfilename),
x = unit(as.integer(pngxsize / 2), "native"),
y = unit(as.integer(pngysize - mar_bottom / 2), "native"),
just = c("center","center"),
default.units = "native",
gp = gpar(color="black", cex=1, fontfamily="Times"),
draw = TRUE)
dev.off()
return(c(x = pngxsize, y = pngysize))
}
##-----------------------------------------------------------------------------
## Create the fit graphs and save them as PNG files
.createFitGraphs <- function(rppaset,
path,
prefix,
residualsrotation,
majorXDivisions = rppaset@design@majorXDivisions,
majorYDivisions = rppaset@design@majorYDivisions
) {
## Check arguments
stopifnot(is.RPPASet(rppaset))
stopifnot(is.character(path) && length(path) == 1)
stopifnot(is.character(prefix) && length(prefix) == 1)
## Begin processing
saved.par <- par(no.readonly=TRUE)
on.exit(par(saved.par))
fitdev <- dev.cur()
## Use red/yellow/green palette for residual plots.
## From RColorBrewer palette RdYlGn
RYG <- c("#A50026",
"#D73027",
"#F46D43",
"#FDAE61",
"#FEE08B",
"#FFFFBF",
"#D9EF8B",
"#A6D96A",
"#66BD63",
"#1A9850",
"#006837")
plotcolors <- RYG
fitxform <- rppaset@fitparams@xform
antibodies <- rownames(rppaset@fits)
for (i in seq_along(antibodies)) {
antibody <- antibodies[i]
rppafit <- rppaset@fits[[i]]
print(paste("Creating fit images for slide ", i, " (", antibody, ")"))
#print(paste("Creating fit image 1, top part, for slide ", i, " (", antibody, ")"))
if (!is.RPPAFit(rppafit)) {
msg <- paste("Slide ", i, " (", antibody, ") will not have fit graphs due to missing or invalid RPPAFit object.", sep="")
warning(msg)
write(msg, warningsFileName, append=TRUE)
next
}
measure <- "ResidualsR2"
main <- .mkPlotTitle(rppafit@measure, antibody)
#-----------------------------------------------------------------
##
## First pair of plots
##
par(bg="white", mfrow=c(1, 1))
## Plot sigmoid curve graph
#Write it to a temporary file to be added to the later plot.
tryCatch(plot(rppafit,
main=main,
xform=fitxform,
xlim=c(-15, 15)),
error=function(e) {
msg <- paste("Slide ", i, " (", antibody, ") unable to plot fit curve due to following issue:", conditionMessage(e), sep="")
write(msg, warningsFileName, append=TRUE)
message(sprintf("cannot plot sigmoid curve for %s", antibody))
warning(conditionMessage(e), immediate.=TRUE)
})
topPlotFileName <- sprintf("temp_%s_%s_1.png", prefix, antibody)
outputfilename <- sprintf("%s_%s_1.png", prefix, antibody)
dev.copy(png,
file.path(path, .portableFilename(topPlotFileName)),
width=640,
height=320)
dev.off()
#print(paste("Creating fit image 1, bottom part, for slide ", i, " (", antibody, ")"))
rppa <- rppafit@rppa
residualData <- residuals(rppafit, "r2")
## Begin processing
dim.rppa <- dim(rppa)
mx <- max(rppa@data$Main.Col) * max(rppa@data$Sub.Col)
my <- max(rppa@data$Main.Row) * max(rppa@data$Sub.Row)
m <- matrix(residualData, ncol=mx, nrow=my, byrow=TRUE)
if (is.na(majorXDivisions))
{
majorxpoints <- dim.rppa["Main.Col"]
}
else
{
majorxpoints <- majorXDivisions
}
if (majorxpoints <= 1)
{
warning(paste("Invalid majorXDivisions setting:", majorxpoints, ". Defaulting to value of 10."))
majorxpoints <- 10
}
if (is.na(majorYDivisions))
{
majorypoints <- dim.rppa["Main.Row"]
}
else
{
majorypoints <- majorYDivisions
}
if (majorypoints <= 1)
{
warning(paste("Invalid majorYDivisions setting:", majorypoints, "Defaulting to value of 10."))
majorypoints <- 10
}
residualsPlotDimensions <-
createResidualsPNG(
file.path(path, .portableFilename(topPlotFileName)),
.portableFilename(outputfilename),
measure,
antibody,
m,
majorxpoints,
majorypoints,
plotcolors,
missingvaluecolor = "#AAAAAA",
gridcolor = "black",
colorlegend = TRUE,
cellsize = 3,
rotation = residualsrotation
)
dev.off()
file.remove(.portableFilename(topPlotFileName))
dev.set(fitdev)
#-----------------------------------------------------------------
##
## Second pair of plots
##
#print(paste("Creating fit image 2 for slide ", i, " (", antibody, ")"))
par(bg="white", mfrow=c(2, 1))
## Plot residuals graph
tryCatch(plot(rppafit,
main=main,
type="resid",
xform=fitxform,
xlim=c(-15, 15)),
error=function(e) {
msg <- paste("Slide ", i, " (", antibody, ") unable to plot residuals graph due to following issue:", conditionMessage(e), sep="")
write(msg, warningsFileName, append=TRUE)
message(sprintf("cannot plot residuals graph for %s", antibody))
warning(conditionMessage(e), immediate.=TRUE)
})
## Plot steps graph
tryCatch(plot(rppafit,
main=main,
type="steps",
xform=fitxform,
xlim=c(-15, 15)),
error=function(e) {
msg <- paste("Slide ", i, " (", antibody, ") unable to plot cannot plot steps graph due to following issue:", conditionMessage(e), sep="")
write(msg, warningsFileName, append=TRUE)
message(sprintf("cannot plot steps graph for %s", antibody))
warning(conditionMessage(e), immediate.=TRUE)
})
filename <- sprintf("%s_%s_2.png", prefix, antibody)
dev.copy(png,
file.path(path, .portableFilename(filename)),
width=640,
height=640)
dev.off()
dev.set(fitdev)
}
return(c(plot_1=residualsPlotDimensions, plot_2 = c(x=640,y=640)))
}
##-----------------------------------------------------------------------------
## Examine system() return code to determine if execution of the shell failed.
.execShellFailed <- if (getRversion() <= "2.12") {
function(rc) { rc == 32512 }
} else {
function(rc) { rc == 127 }
}
##-----------------------------------------------------------------------------
## Merge output graph png files with source slide image file, save it as JPG file
.mergeGraphsAndImage <- function(antibody,
prefix,
outputdir,
slideImageName,
slideImageRotation = 0,
missingSlide = FALSE,
#dimensions of two graphs already written to disk
graphDimensions = c(plot_1 = c(x=0, y=0), plot_2 = c(x=0, y=0))
) {
fitdev <- dev.cur()
## Check arguments
stopifnot(is.character(antibody) && length(antibody) == 1)
stopifnot(is.character(prefix) && length(prefix) == 1)
stopifnot(is.character(outputdir) && length(outputdir) == 1)
stopifnot(is.character(slideImageName) && length(slideImageName) == 1)
rc <- FALSE
tryCatch({
if (!(slideImageRotation %in% c(0, 90, 180, 270))) {
msg <- paste("Invalid slideImageRotation value =",
slideImageRotation,
". Acceptable values are 0, 90, 180, and 270. ",
"Rotation request ignored. Default rotation of 0 used.",
sep="")
write(msg, warningsFileName, append=TRUE)
message(msg)
slideImageRotation = 0
}
## Begin processing
filename <- sprintf("%s_%s_1.png", prefix, antibody)
pg1 <- file.path(outputdir, .portableFilename(filename))
filename <- sprintf("%s_%s_2.png", prefix, antibody)
pg2 <- file.path(outputdir, .portableFilename(filename))
filename <- sprintf(".%s.temp.png", antibody)
tempImageName <- file.path(outputdir, .portableFilename(filename))
filename <- sprintf("%s.png", antibody)
outputImageName <- file.path(outputdir, .portableFilename(filename))
#The imager package fails to display the pngs if trying to append a 16 bit monochrome tif converted to color and color pngs
#If we save the slide image as a png or jpg and then reload it, the merge works fine.
#Converting before rotating or scaling takes much less time than saving and loading after add.color
lenSlideImageName = nchar(slideImageName)
if (missingSlide == FALSE && (substr(slideImageName, lenSlideImageName - 3, lenSlideImageName) %in% c(".tif", "tiff"))) {
img <- readTIFF(slideImageName, native=TRUE, convert=TRUE)
#writeJPEG(img, target=tempImageName, quality=1)
writePNG(img, target=tempImageName)
slideImage <- load.image(tempImageName)
file.remove(tempImageName)
} else {
#Load the slide Image file
slideImage <- load.image(slideImageName)
}
#Get image heights and widths
slideWidth <- dim(slideImage)[1]
slideHeight <- dim(slideImage)[2]
minDim <- min(slideWidth, slideHeight)
if (minDim > 640)
{
slideImage <- imresize(slideImage, scale = 640 / minDim, interpolation = 6)
#Get new image heights and widths
slideWidth <- dim(slideImage)[1]
slideHeight <- dim(slideImage)[2]
}
#Rotate slide image if requested
if (slideImageRotation != 0) {
slideImage <- imrotate(slideImage, slideImageRotation)
}
if (dim(slideImage)[4] == 1) { #Monochrome Image
#Color depth will be lost if was initially 16 bit grayscale, being switched to 8 bit rgb.
slideImage <- add.color(slideImage)
}
#Get image heights and widths
slideWidth <- dim(slideImage)[1]
slideHeight <- dim(slideImage)[2]
save.image(slideImage, tempImageName)
rm(slideImage)
png1x <- graphDimensions["plot_1.x"]
png1y <- graphDimensions["plot_1.y"]
png2x <- graphDimensions["plot_2.x"]
png2y <- graphDimensions["plot_2.y"]
#Determine which slide image dimension is greater, width or height.
if (slideHeight > slideWidth)
{
orientation <- 1 # alternate layout: graphs left, slide right
combinedGraphsWidth <- max(png1x, png2x)
combinedGraphsHeight <- png1y + png2y
combinedWidth <- combinedGraphsWidth + slideWidth
combinedHeight <- max(combinedGraphsHeight, slideHeight)
}
else
{
orientation <- 0 # default layout: graphs top, slide bottom
combinedGraphsWidth <- png1x + png2x
combinedGraphsHeight <- max(png1y, png2y)
combinedWidth <- max(combinedGraphsWidth, slideWidth)
combinedHeight <- combinedGraphsHeight + slideHeight
}
print(paste("Creating combined output graphic", filename))
png(filename=outputImageName, bg="white", width = combinedWidth, height = combinedHeight, units="px", type="cairo-png")
plot.new()
if (orientation == 1)
{
grid.raster(readPNG(pg1), x = unit(0, "native"), y = unit(0, "native"), just=c("left","top"), interpolate = FALSE,
width = unit(png1x, "native"), height = unit(-png1y, "native"))
grid.raster(readPNG(pg2), x = unit(0, "native"), y = unit(png1y, "native"), just=c("left","top"), interpolate = FALSE,
width = unit(png2x, "native"), height = unit(-png2y, "native"))
grid.raster(readPNG(tempImageName), x = unit(combinedGraphsWidth, "native"), y = unit(0, "native"), interpolate = FALSE,
just=c("left","top"), width = unit(slideWidth, "native"), height = unit(-slideHeight, "native"))
}
else
{
grid.raster(readPNG(pg1), x = unit(0, "native"), y = unit(0, "native"), just=c("left","top"), interpolate = FALSE,
width = unit(png1x, "native"), height = unit(-png1y, "native"))
grid.raster(readPNG(pg2), x = unit(png1x, "native"), y = unit(0, "native"), just=c("left","top"), interpolate = FALSE,
width = unit(png2x, "native"), height = unit(-png2y, "native"))
grid.raster(readPNG(tempImageName), x = unit(0, "native"), y = unit(combinedGraphsHeight, "native"), just=c("left","top"),
interpolate=FALSE, width = unit(slideWidth, "native"), height = unit(-slideHeight, "native"))
}
dev.off()
file.remove(tempImageName)
rc <- TRUE
},
error=function(cond) {
print("Error merging graphs and slide image")
message("###stacktrace###")
dump.frames()
message("<<<ERROR>>>", cond)
})
dev.set(fitdev)
return(rc)
}
##-----------------------------------------------------------------------------
.plotProbabilityOfGoodSlide <- function(qcprobs,
good.cutoff=0.8) {
stopifnot(is.numeric(qcprobs) && length(qcprobs) >= 1)
stopifnot(is.numeric(good.cutoff) && length(good.cutoff) == 1)
stopifnot(.isProbability(qcprobs))
stopifnot(.isProbability(good.cutoff))
nslides <- length(qcprobs)
rating <- rep("poor", len=nslides)
rating[which(qcprobs >= good.cutoff)] <- "good"
rating.fac <- ordered(rating, levels=c("poor", "good"))
col.qcprobs <- c("red", "green")
stopifnot(nlevels(rating.fac) == length(col.qcprobs))
plot(qcprobs,
las=1,
main="Predicted Slide Quality",
sub=sprintf("#Good = %d, #Poor = %d",
ngood <- sum(rating == "good"),
npoor <- nslides - ngood),
type='n',
xaxt='n',
xlim=c(1, nslides),
yaxt='n',
ylab="Probability of Good Slide",
ylim=0:1)
mtext(side=3, paste("cutoff =", good.cutoff))
axis(1, at=seq_len(nslides))
axis(2, at=seq(0, 1, by=0.1), las=1)
rect(xleft=1,
ybottom=c(0, good.cutoff),
xright=nslides,
ytop=c(good.cutoff, 1),
col=c('lightpink', 'lightgreen'),
border=NA)
text(x=(nslides+1)/2,
y=c(good.cutoff/2, 1-((1-good.cutoff)/2)),
labels=toupper(levels(rating.fac)),
cex=2)
abline(h=good.cutoff)
points(qcprobs,
bg=col.qcprobs[rating.fac],
col='black',
pch=21)
}
##-----------------------------------------------------------------------------
## Return TRUE if PreFit QC was performed.
ran.prefitqc <- function(rppaset) {
## Check arguments
stopifnot(is.RPPASet(rppaset))
## Begin processing
prefitqcs.tf <- rppaset@completed[, "prefitqc"]
return(!all(is.na(prefitqcs.tf)))
}
##-----------------------------------------------------------------------------
setMethod("normalize", signature(object="RPPASet"),
function(object, ...) {
concs <- .fitSlot(object, "concentrations")
normparams <- object@normparams
arglist <- c(list(concs,
method=normparams@method),
normparams@arglist,
...)
## Assemble matrix of concentrations from all fits in object
do.call(callGeneric, arglist)
})
##-----------------------------------------------------------------------------
## See R FAQ (8.1 How should I write summary methods?)
setMethod("summary", signature(object="RPPASet"),
function(object,
onlynormqcgood=ran.prefitqc(object),
...) {
dots <- list(...)
RPPASetSummary(object,
onlynormqcgood)
})
##-----------------------------------------------------------------------------
## Provide a convenience function to save fit results to disk
setMethod("write.summary", signature(object="RPPASet"),
function(object,
path,
prefix="rppaspace",
graphs=TRUE,
createcombinedoutputimage=FALSE,
imagedir=NULL,
onlynormqcgood=ran.prefitqc(object),
imageextension=".tif",
imagerotation=as.integer(0),
residualsrotation=as.integer(0),
majorXDivisions=object@design@majorXDivisions,
majorYDivisions=object@design@majorYDivisions,
...) {
## Check arguments
if (!is.character(path)) {
stop(sprintf("argument %s must be character",
sQuote("path")))
} else if (!(length(path) == 1)) {
stop(sprintf("argument %s must be of length 1",
sQuote("path")))
} else if (!dir.exists(path)) {
stop(sprintf("directory %s does not exist",
dQuote(path)))
} else if (!dir.writable(path)) {
stop(sprintf("directory %s is not writable",
dQuote(path)))
}
if (!is.character(prefix)) {
stop(sprintf("argument %s must be character",
sQuote("prefix")))
} else if (!(length(prefix) == 1)) {
stop(sprintf("argument %s must be of length 1",
sQuote("prefix")))
}
if (is.numeric(graphs)) {
graphs <- as.logical(graphs)
}
if (!is.logical(graphs)) {
stop(sprintf("argument %s must be logical",
sQuote("graphs")))
} else if (!(length(graphs) == 1)) {
stop(sprintf("argument %s must be of length 1",
sQuote("graphs")))
}
if (is.numeric(onlynormqcgood)) {
onlynormqcgood <- as.logical(onlynormqcgood)
}
if (!is.logical(onlynormqcgood)) {
stop(sprintf("argument %s must be logical",
sQuote("onlynormqcgood")))
} else if (!(length(onlynormqcgood) == 1)) {
stop(sprintf("argument %s must be of length 1",
sQuote("onlynormqcgood")))
}
## Begin processing
## Make sure at least one fit exists
rppafits <- object@fits
if (all(sapply(rppafits, is.null))) {
stop("cannot summarize as no fits were stored")
}
graphDimensions <- c(plot_1 = c(x=0, y=0), plot_2 = c(x=0, y=0))
## Graph fits, if requested
if (graphs) {
tryCatch({
#t <- proc.time()
#print("Saving fit graphs")
tm <- proc.time()
## Save fit graphs
dev.new(title="Fit Graphs")
graphDimensions <- .createFitGraphs(object, path, prefix, residualsrotation, majorXDivisions, majorYDivisions)
#t <- proc.time() - tm
#print(paste("Fit graph output time:",t[3]))
},
error=function(cond) {
print("Error creating Fit Graphs")
message("###stacktrace###")
dump.frames()
message("<<<ERROR>>>", cond)
})
}
if (createcombinedoutputimage){
#t <- proc.time()
pkgimgdir <- system.file("images", package="RPPASPACE")
print(paste("imagedir:",imagedir))
if (is.null(imagedir)) {
## Assume the tif images are in a sibling directory named "tif"
print("null imagedir")
imagedir <- normalizePath(file.path(dirname(path), "tif"))
if (!dir.exists(imagedir)) {
## As last resort, use package directory for missing image
message(sprintf("image directory unspecified and sibling directory %s does not exist",
dQuote(imagedir)))
imagedir <- pkgimgdir
}
}
if (!is.character(imagedir)) {
stop(sprintf("argument %s must be character",
sQuote("imagedir")))
} else if (!(length(imagedir) == 1)) {
stop(sprintf("argument %s must be of length 1",
sQuote("imagedir")))
} else if (!dir.exists(imagedir)) {
stop(sprintf("directory %s does not exist",
dQuote(imagedir)))
}
if(!(imageextension %in% c(".tif", ".png", ".bmp", ".gif", ".jpg"))) {
stop(paste("Supported image extensions for slides include .tif, .tiff, .png, .bmp, .jpg.",
"Only one slide image file type can be used in a single run of slides."))
}
## Merge output graphs with source tiff file for each antibody
imgfiles <- {
txtfiles <- sapply(rppafits,
function(fit) {
if (!is.null(fit) && is.RPPAFit(fit)) {
fit@rppa@file
} else {
NA
}
})
txt.re <- "\\.[tT][xX][tT]$"
sub(txt.re, imageextension, txtfiles)
}
## For each antibody...
antibodies <- names(rppafits)
#When using the imager package, do not do graphics merge in parallel or
#it will probably either take much longer or completely lock up the computer.
i<- 0
foreach (i = seq_along(antibodies)) %do% {
antibody <- antibodies[i]
rppafit <- rppafits[[i]]
#cat(c("Testing ", antibody, "\n" ))
if (!is.null(rppafit) && is.RPPAFit(rppafit)) {
#print(paste("Merging graphs and image for", antibody))
flush.console()
## If no corresponding image exists, substitute "missing" image
imgfile <- file.path(imagedir, imgfiles[antibody])
missingSlide <- FALSE
if (is.na(imgfile) || !file.exists(imgfile)) {
#imgfile <- file.path(pkgimgdir, "missing_slide.jpg")
imgfile <- file.path(pkgimgdir, paste("missing_slide", ".jpg", sep=""))
if (is.na(imgfile) || !file.exists(imgfile)) {
print("No slide image was provided and the missing_slide.jpg image file can not be found!")
}
rotation = imagerotation
missingSlide <- TRUE
} else {
rotation = imagerotation
}
## Create merged image
.mergeGraphsAndImage(antibody, prefix, path, imgfile, rotation, missingSlide, graphDimensions)
#print(paste("Finished image processing for ", antibody, sep=""))
}
else {
msg <- paste("Slide ", i, " (", antibody, ") will not be have images created due to missing or invalid RPPAFit object.", sep="")
message(msg)
write(msg, warningsFileName, append=TRUE)
}
}
#t <- proc.time() - tm
#print(paste("Combined output image file creation time:",t[3]))
}
## Write CSV files
callGeneric(summary(object,
onlynormqcgood=onlynormqcgood),
path,
prefix)
})
##-----------------------------------------------------------------------------
## Create an RPPA set from a directory of slides.
RPPASet <- function(path,
designparams,
fitparams,
spatialparams=NULL,
normparams,
doprefitqc=FALSE,
parallelClusterSize,
residualsrotation=as.integer(0),
warningsFileName="warnings.txt",
printTimings=TRUE
) {
ptm <- proc.time()
if (printTimings) { print("Starting RPPASet") }
## Check arguments
if (!is.character(path)) {
stop(sprintf("argument %s must be character",
sQuote("path")))
} else if (!(length(path) == 1)) {
stop(sprintf("argument %s must be of length 1",
sQuote("path")))
} else if (!dir.exists(path)) {
stop(sprintf("directory %s does not exist",
dQuote(path)))
}
if (!is.RPPADesignParams(designparams)) {
stop(sprintf("argument %s must be object of class %s",
sQuote("designparams"), "RPPADesignParams"))
}
if (!is.RPPAFitParams(fitparams)) {
stop(sprintf("argument %s must be object of class %s",
sQuote("fitparams"), "RPPAFitParams"))
}
if (!is.null(spatialparams)) {
if (!is.RPPASpatialParams(spatialparams)) {
stop(sprintf("argument %s must be object of class %s",
sQuote("spatialparams"), "RPPASpatialParams"))
}
}
if (!is.RPPANormalizationParams(normparams)) {
stop(sprintf("argument %s must be object of class %s",
sQuote("normparams"), "RPPANormalizationParams"))
}
if (!is.logical(doprefitqc)) {
stop(sprintf("argument %s must be logical",
sQuote("doprefitqc")))
} else if (!(length(doprefitqc) == 1)) {
stop(sprintf("argument %s must be of length 1",
sQuote("doprefitqc")))
} else if (is.na(doprefitqc)) {
doprefitqc <- FALSE
msg <- sprintf("argument %s converted from NA to FALSE", dQuote(doprefitqc))
warning(msg, immediate.=FALSE)
write(msg, warningsFileName, append=TRUE)
}
if (printTimings) {
t <- proc.time() - ptm
print(paste("Variables checked:",t[3]))
}
##-------------------------------------------------------------------------
## Returns the names of all TXT files in directory argument.
## :TBD: Should this get the list of slides from a file ('proteinAssay.tsv'
## or 'targets.txt') instead of assuming all .txt files are slides?
getQuantificationFilenames <- function(path) {
if (printTimings) {
t <- proc.time() - ptm
print(paste("Getting file names:",t[3]))
}
stopifnot(is.character(path) && length(path) == 1)
## Assumes all .txt files in the directory are slides
txt.re <- "\\.[tT][xX][tT]$"
txtfiles <- list.files(path=path, pattern=txt.re)
## If SuperCurveGUI's input and output directories refer to the same
## path, then its settings file in TEXT format could be present...
settingsfile.tf <- txtfiles %in% "rs-settings.txt"
txtfiles[!settingsfile.tf]
}
if (printTimings) {
t <- proc.time() - ptm
print(paste("Begin processing:",t[3]))
}
## Begin processing
call <- match.call()
## Get filenames of slides to process
slideFilenames <- getQuantificationFilenames(path)
if (length(slideFilenames) == 0) {
stop(sprintf("no quantification files found in directory %s",
dQuote(path)))
}
if (printTimings) {
t <- proc.time() - ptm
print(paste("Getting antibody info:",t[3]))
}
ab.list <- vector("list", length(slideFilenames))
## Fill in missing values with generated defaults
x.which <- which(sapply(ab.list, is.null))
txt.re <- "\\.[tT][xX][tT]$"
for (x in x.which) {
ab.list[[x]] <- sub(txt.re, "", slideFilenames[x])
}
if (printTimings) {
t <- proc.time() - ptm
print(paste("Making antibody names unique:",t[3]))
}
## Ensure antibody names are unique
antibodies <- make.unique(abnames <- unlist(ab.list, use.names=FALSE))
if (!identical(antibodies, abnames)) {
msg <- "Slide names were not unique - This should not be possible with current slide input method."
warning(msg)
write(msg, warningsFileName, append=TRUE)
}
remove(abnames)
## Tracking success/failure of each step
input.tf <- logical(length(slideFilenames))
prefitqc.tf <- logical(length(slideFilenames))
spatial.tf <- logical(length(slideFilenames))
fits.tf <- logical(length(slideFilenames))
## Load slides to process
message(paste("Reading slides from ", path, ".", sep=""))
if (printTimings) {
tm <- proc.time()
t <- proc.time() - ptm
#print(paste("Reading first slide to determine layout:",t[3]))
}
tracking <- NULL
if (printTimings) {
tm <- proc.time()
t <- proc.time() - ptm
print(paste("Reading slides:",t[3]))
}
firstGoodSlide <- FALSE
trackingSource <- NA
goodSlideCount <- 0
rppas <- array(list(), length(slideFilenames), list(antibodies))
for (i in seq_along(slideFilenames)) {
slideFilename <- slideFilenames[i]
antibody <- antibodies[i]
print(paste("Reading", slideFilename))
flush.console()
rppa <- tryCatch({
RPPA(slideFilename,
path=path,
antibody=antibody,
slideNumber=i,
tracking=tracking,
seriesToIgnore=designparams@seriesToIgnore,
warningsFileName
)
},
error=function(e) {
msg <- paste("Error creating RPPA object for slide ", slideFilename, ":", conditionMessage(e), sep="")
message(msg)
write(msg, warningsFileName, append=TRUE)
NULL
})
if (!is.null(rppa) && is.RPPA(rppa) && is.null(tracking)) {
firstGoodSlide <- TRUE
#print("Setting generic tracking object to one constructed using first valid slide." )
tracking <- rppa@tracking
trackingSource <- antibody
} else {
firstGoodSlide <- FALSE
}
## Update only on success
if (is.RPPA(rppa)) {
rppas[[i]] <- rppa
input.tf[i] <- TRUE
goodSlideCount <- goodSlideCount + 1
} else {
rppas[[i]] <- NULL
input.tf[i] <- FALSE
if (!is.null(tracking) ) {
msg <- paste("Slide ", i, " (", antibody, ") will not be processed due to layout mismatches with first valid slide, ", trackingSource, ".", sep="")
}
if (goodSlideCount == 0) {
msg <- paste("Slide ", i, " (", antibody, ") will not be processed due to format errors.", sep="")
}
message(msg)
warning(msg)
write(msg, warningsFileName, append=TRUE)
}
## Plot the first possible slide as a quick design check
if (firstGoodSlide)
{
print("Plotting design check graph")
dev.new(title="Design Check")
plot(rppa,
fitparams@measure)
firstGoodSlide <- FALSE
}
}
if (printTimings) {
t <- proc.time() - tm
print(paste("Slide Reading Time:",t[3]))
}
## This will trigger if no RPPAs exist.
if (length(rppa) == 0) {
stop("no slides can be processed")
}
if (printTimings) {
t <- proc.time() - ptm
print(paste("Performing pre-fit qc:",t[3]))
}
## Perform pre-fit QC, if enabled
prefitqcs <- array(list(), length(slideFilenames), list(antibodies))
doQC <- FALSE
if (doprefitqc) {
doQC <- TRUE
#Checking number of control points to see if enough available to do qc or spatial adjustments
numPosCtrlPoints <- sum(tracking$isPosCtrl, na.rm=TRUE)
numNegCtrlPoints <- sum(tracking$isNegCtrl, na.rm=TRUE)
#Must have some negative controls
#Must have at least 3 positive controls per unique dilution point value other than 0 to make a surface, but requiring at least 3
if (numNegCtrlPoints < 1) {
msg <- paste("Quality control calculations requested, but not enough NegCtrl points provided in first valid slide ", trackingSource ,". QC will not be performed.", sep="")
warning(msg)
write(msg, warningsFileName, append=TRUE)
doQC <- FALSE
}
if (numPosCtrlPoints < 3) {
msg <- paste("Quality control calculations requested, but not enough PosCtrl or PosCtrl-Noise points provided in first valid slide ", trackingSource ,". QC will not be performed.", sep="")
warning(msg)
write(msg, warningsFileName, append=TRUE)
doQC <- FALSE
}
}
if (doQC) {
for (i in seq_along(slideFilenames)) {
antibody <- antibodies[i]
rppa <- rppas[[i]]
if (!is.null(rppa)) {
print(paste("Quality checking slide ", i, " : ", antibody, ".", sep=""))
flush.console()
prefitqc <- tryCatch({
#RPPAPreFitQC(rppa, designparams@dilutionsInSeries)
RPPAPreFitQC(rppa)
},
error=function(e) {
traceback()
warning(conditionMessage(e))
write(conditionMessage(e), warningsFileName, append=TRUE)
NULL
})
## Update only on success
if (is.RPPAPreFitQC(prefitqc)) {
prefitqcs[[i]] <- prefitqc
prefitqc.tf[i] <- TRUE
}
} else {
msg <- paste("Slide ", i, " (", antibody, ") will not be assessed for quality control because of missing RPPA object.", sep="")
warning(msg)
message(msg)
write(msg, warningsFileName, append=TRUE)
}
}
if (printTimings) {
t <- proc.time() - ptm
print(paste("Plotting goodness of slide values:",t[3]))
}
## Plot 'goodness of slide' values
dev.new(title="Predicted Slide Quality Plot")
tryCatch({
qcprobs <- sapply(prefitqcs, qcprob)
qcprobs[is.na(qcprobs)] <- 0
.plotProbabilityOfGoodSlide(qcprobs)
},
error=function(e) {
msg <- paste("Cannot plot quality control graph because of following error: ", conditionMessage(e), sep="")
write(msg, warningsFileName, append=TRUE)
message(msg)
warning(conditionMessage(e), immediate.=TRUE)
})
} else {
prefitqc.tf <- rep(NA, length(prefitqc.tf))
}
if (printTimings) {
t <- proc.time() - tm
print(paste("QC Time:",t[3]))
}
##-------------------------------------------------------------------------
## Determines if spatial adjustment processing is warranted
shouldPerformSpatialAdj <- function(spatialparams, fitparams, tracking, warningsFileName) {
stopifnot(is.RPPAFitParams(fitparams))
if(is.null(spatialparams)){
FALSE
}
else
{
measures <- eval(formals(spatialCorrection)$measure)
numPosCtrlPoints <- sum(tracking$isPosCtrl, na.rm=TRUE)
numNegCtrlPoints <- sum(tracking$isNegCtrl, na.rm=TRUE)
#Must have some negative controls
#Must have at least 3 positive controls per unique dilution point value other than 0 to make a surface, but requiring at least 3
if (numNegCtrlPoints < 1) {
msg <- paste("Spatial adjustments requested, but not enough NegCtrl points provided in first valid slide, ", trackingSource, ".", sep="")
write(msg, warningsFileName, append=TRUE)
warning(msg)
}
if (numPosCtrlPoints < 3) {
msg <- paste("Spatial adjustments requested, but not enough PosCtrl or PosCtrl-Noise points provided in first valid slide, ", trackingSource, ".", sep="")
write(msg, warningsFileName, append=TRUE)
warning(msg)
}
is.RPPASpatialParams(spatialparams) && (fitparams@measure %in% measures) && (numNegCtrlPoints > 0) && (numPosCtrlPoints > 3)
}
}
if (printTimings) {
print("Checking if need to do spatial adjustment")
tm <- proc.time()
}
## Perform spatial adjustment, if enabled
doSpatialAdj <- shouldPerformSpatialAdj(spatialparams, fitparams, tracking, warningsFileName)
if (doSpatialAdj) {
if (printTimings) {
t <- proc.time() - ptm
print(paste("Doing spatial adjustment:",t[3]))
}
if (spatialparams@plotSurface) {
## Open new device if surface plots were requested
dev.new(title="Surface Plots")
message("*** watch for prompts to plot on R console ***")
}
message(paste("Performing spatial adjustments on slides."))
flush.console()
i <- 0
if (spatialparams@plotSurface == TRUE || parallelClusterSize == 1) {
#Parallel plotting of surfaces breaks, so never done in parallel if plotting surfaces.
spatiallyAdjustedSlidesData <- foreach (i=seq_along(slideFilenames)) %do% {
doSpatiallyAdjustSlide(antibody = antibodies[i], rppa = rppas[[i]], index=i,
spatialparams=spatialparams)
}
} else {
spatiallyAdjustedSlidesData <- foreach (i=seq_along(slideFilenames), .export="doSpatiallyAdjustSlide") %dopar% {
# spatiallyAdjustedSlidesData <- foreach (i=seq_along(slideFilenames)) %do% {
doSpatiallyAdjustSlide(antibody = antibodies[i], rppa = rppas[[i]], index=i,
spatialparams=spatialparams)
}
}
#Parallelizing the doSpatiallyAdjustSlide calls above causes error messages
#at the time to potentially overwrite each other in the warnings text file
#To get past this problem, the messages are being added to the return list
#and printed to the warnings file here.
j <- 0
foreach (j=seq_along(slideFilenames)) %do% {
if (!is.null(spatiallyAdjustedSlidesData[[j]]$msg)) {
msg <- paste(spatiallyAdjustedSlidesData[[j]]$msg, sep="")
warning(msg)
write(msg, warningsFileName, append=TRUE)
}
}
rppas <- as.array(lapply(spatiallyAdjustedSlidesData, function(x){x$rppa}))
spatial.tf <- as.logical(lapply(spatiallyAdjustedSlidesData, function(x){x$tf}))
remove(spatiallyAdjustedSlidesData)
if (printTimings) {
t <- proc.time() - ptm
print(paste("Saving spatial adjustment to file. : ",t[3]))
}
## Save the spatial adjustments to a file
i <- 0
tempSpatial <- foreach (i=seq_along(slideFilenames)) %do% {
if (!is.null(rppas[[i]])) {
tempAdjMean <- rppas[[i]]@data$Adj.Net.Value
if (is.null(tempAdjMean)) {
rppas[[i]]@data$Adj.Net.Value <- rppas[[i]]@data$Net.Value
msg <- paste("Slide ", i, " (", antibodies[i],
") will not be spatially adjusted due to issues with the values of the positive controls on the slide.",
sep="")
warning(msg)
write(msg, warningsFileName, append=TRUE)
}
rppas[[i]]@data$Adj.Net.Value - rppas[[i]]@data$Net.Value
}
#else {
# #Slides not properly input will have been assigned all values of NA
# as.double(0.0)
#}
}
names(tempSpatial) <- antibodies
# Write out the spatial adjustments done to each slide.
print("Writing spatial adjustments output.")
write.table(tempSpatial[spatial.tf], file=file.path("spatial_adjustments.tsv"), sep='\t')
rm(tempAdjMean)
rm(tempSpatial)
} else {
msg <- "Spatial adjustments will not be calculated."
warning(msg)
write(msg, warningsFileName, append=TRUE)
spatial.tf <- rep(NA, length(spatial.tf))
}
if (printTimings) {
t <- proc.time() - tm
print(paste("Spatial Adjustment Time:",t[3]))
}
## Create fits
tm <- proc.time()
if (printTimings) {
t <- proc.time() - ptm
print(paste("Fitting slides:",t[3]))
}
adj.fitparams <- fitparams
if (doSpatialAdj) {
message("Performing fits using spatially adjusted measure.")
adjMeasure <- paste("Adj", fitparams@measure, sep=".")
adj.fitparams@measure <- adjMeasure
} else {
message("Performing fits using original measure in file.")
}
fits <- as.array(list(), length(slideFilenames), list(antibodies))
fits.tf <- as.logical(FALSE, length(slideFilenames))
slideNamesSeq <- seq_along(slideFilenames)
tempfits <- foreach (i=slideNamesSeq, .export=c("dofitSlide")) %dopar%
{
if (!is.null(rppas[[i]])) {
tryCatch(
{
if (printTimings) {
t <- proc.time() - ptm
print(paste("Fitting:", antibodies[i], ":" ,t[3]))
}
tempfit <- dofitSlide(antibody = antibodies[i], rppa = rppas[[i]], index=i, fitparams=adj.fitparams)
if (is.null(tempfit) || !tempfit$tf){
msg <- paste("Slide ", i, " (", antibodies[i], ") will not be fitted due to the dofitSlide method not producing a proper fit.", sep="")
warning(msg)
list( index=i, fit=NA, tf=FALSE, msg=msg)
}
else {
tempfit
}
},
error=function(e) {
warning(conditionMessage(e))
write(conditionMessage(e), warningsFileName, append=TRUE)
warning(paste("Error fitting slide ", i, " ", antibody))
msg <- paste("Slide ", i, " (", antibodies[i], ") will not be fitted due to some error in the dofitSlide method.", sep="")
list( index=i, fit=NA, tf=FALSE, msg=msg)
})
}
else {
msg <- paste("Slide ", i, " (", antibodies[i], ") will not be fitted due to missing RPPA object.", sep="")
warning(msg)
list( index=i, fit=NA, tf=FALSE, msg=msg)
}
}
if (printTimings) {
t <- proc.time() - ptm
print(paste("Updating successful fit curves:",t[3]))
}
for ( fitentry in tempfits)
{
# Write warning messages created in fitting process to warning file and remove entry from tempfit object.
# Must be done in non-parallel portion of code to prevent seperate threads from overwriting warning messages.
if (!is.null(fitentry$msg)) {
msg <- paste(fitentry$msg, sep="")
warning(msg)
write(msg, warningsFileName, append=TRUE)
}
index <- fitentry[["index"]]
fit <- fitentry[["fit"]]
tf <- fitentry[["tf"]]
fits[[antibodies[index]]] <- fit
fits.tf[index] <- tf
}
remove(tempfits)
fits <- as.array(fits)
t <- proc.time() - tm
print(paste("Curve Fitting Time:",t[3]))
## Create matrix for tracking what succeeded/failed
completed <- cbind(input.tf,
prefitqc.tf,
spatial.tf,
fits.tf)
rownames(completed) <- slideFilenames
colnames(completed) <- names(getStages()[1:4])
if (printTimings) {
t <- proc.time() - ptm
print(paste("Creating RPPASet object:",t[3]))
}
## Create new class
new("RPPASet",
call=call,
design=designparams,
rppas=rppas,
spatialparams=spatialparams,
prefitqcs=prefitqcs,
fits=fits,
fitparams=fitparams,
normparams=normparams,
completed=completed,
version=packageDescription("RPPASPACE", fields="Version"),
residualsrotation=residualsrotation
)
}
dofitSlide <- function(antibody, rppa, index, fitparams) {
tf <- FALSE
fit <- NULL
print(paste("Fitting slide for ", antibody, ".", sep=""))
flush.console()
#rppa <- rppas[[i]]
if (!is.null(rppa)) {
fit <-
tryCatch({
RPPAFitFromParams(rppa,
fitparams=fitparams)
},
error=function(e) {
message(conditionMessage(e))
print(paste("Error in slide ", index, " ", antibody))
NULL
})
## Update only on success
if (!is.null(fit) && is.RPPAFit(fit)) {
#print(c("Setting tf = TRUE for index", index))
tf <- TRUE
fit.tf <- TRUE
}
else{
#print(c("Error fitting slide ", index, " ", antibody))
tf <- FALSE
fit <- NULL
fit.tf <- FALSE
}
} else {
msg <- paste("no slide to fit for", antibody)
warning(msg)
write(msg, warningsFileName, append=TRUE)
}
flush.console()
list(index=index, fit=fit, tf=tf)
}
doSpatiallyAdjustSlide <- function(antibody, rppa, index, spatialparams){
tf <- FALSE
msg <- NULL
if (!is.null(rppa)) {
print(paste("Spatially adjusting slide ", index, " : ", antibody, sep =""))
rppaNew <- tryCatch({
spatialAdjustmentFromParams(rppa, spatialparams)
},
error=function(e) {
msg <- paste("Slide ", index, " (", antibody, ") will not be spatially adjusted due to the following problem: ", conditionMessage(e),
"; If this message indicated a surface was not found, there were not at least three positive control points left to form ",
"a spatial adjustment surface for the specified dilution level after eliminating the positive control points below calculations ",
"based on the slide's negative control values.", sep="")
warning(msg)
#write(msg, warningsFileName, append=TRUE)
traceback()
NULL
})
if (!is.null(rppaNew) && is.RPPA(rppaNew)) {
ncols.list <- lapply(c(rppaNew, rppa),
function(x) {
ncol(df <- slot(x, "data"))
})
if (!do.call("identical", ncols.list)) {
## Update only on modification
rppa <- rppaNew
tf <- TRUE
}
remove(ncols.list)
}
}
else {
msg <- paste("Slide ", index, " (", antibody, ") will not be spatially adjusted because of missing RPPA object.", sep="")
message(msg)
}
list(rppa = rppa, tf = tf, msg = msg)
}
doQcDataPrefit <- function(antibody, rppa, designparams, prefitqcOld){
tf <- FALSE
prefitqc <- prefitqcOld
msg <- ""
if (!is.null(rppa)) {
prefitqcNew <- tryCatch({
#RPPAPreFitQC(rppa, designparams@dilutionsInSeries)
RPPAPreFitQC(rppa)
},
error=function(e) {
msg <- paste("Error prefitting qc data for antibody ", antibody, ":", conditionMessage(e))
message(msg)
traceback()
NULL
})
## Update only on success
if (is.RPPAPreFitQC(prefitqcNew)) {
prefitqc <- prefitqcNew
tf <- TRUE
}
else {
prefitqc <- prefitqcOld
}
}
else {
msg <- paste("No slide to quality check for", antibody)
warning(msg)
}
list(prefitqc = prefitqc, tf = tf, msg=msg)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.