\HeaderA{updateCel}{Updates a CEL file}{updateCel}
\keyword{file}{updateCel}
\keyword{IO}{updateCel}
\begin{Description}\relax
Updates a CEL file.
\end{Description}
\begin{Usage}
\begin{verbatim}updateCel(filename, indices=NULL, intensities=NULL, stdvs=NULL, pixels=NULL, ..., verbose=0)\end{verbatim}
\end{Usage}
\begin{Arguments}
\begin{ldescription}
\item[\code{filename}] The filename of the CEL file.
\item[\code{indices}] A \code{\LinkA{numeric}{numeric}} \code{\LinkA{vector}{vector}} of cell (probe) indices specifying
which cells to updated.  If \code{\LinkA{NULL}{NULL}}, all indices are considered.
\item[\code{intensities}] A \code{\LinkA{numeric}{numeric}} \code{\LinkA{vector}{vector}} of intensity values to be stored.
Alternatively, it can also be a named \code{\LinkA{data.frame}{data.frame}} or \code{\LinkA{matrix}{matrix}} (or \code{\LinkA{list}{list}})
where the named columns (elements) are the fields to be updated.
\item[\code{stdvs}] A optional \code{\LinkA{numeric}{numeric}} \code{\LinkA{vector}{vector}}.
\item[\code{pixels}] A optional \code{\LinkA{numeric}{numeric}} \code{\LinkA{vector}{vector}}.
\item[\code{...}] Not used.
\item[\code{verbose}] An \code{\LinkA{integer}{integer}} specifying how much verbose details are
outputted.
\end{ldescription}
\end{Arguments}
\begin{Details}\relax
Currently only binary (v4) CEL files are supported.
The current version of the method does not make use of the Fusion SDK,
but its own code to navigate and update the CEL file.
\end{Details}
\begin{Value}
Returns (invisibly) the pathname of the file updated.
\end{Value}
\begin{Author}\relax
Henrik Bengtsson (\url{http://www.braju.com/R/})
\end{Author}
\begin{Examples}
\begin{ExampleCode}

for (zzz in 0) {  # Only so that 'break' can be used

# Scan current directory for CEL files
files <- list.files(pattern="[.](c|C)(e|E)(l|L)$")
if (length(files) == 0)
  break

# Create tempory copy of the CEL file
filename <- file.path(tempdir(), sprintf("%s.tmp.cel", files[1]))
if (file.exists(filename))
  file.remove(filename)
file.copy(from=files[1], to=filename)

fields <- c("intensities", "stdvs", "pixels")

# Cells to be updated
idxs <- 1:2

# Get CEL header
hdr <- readCelHeader(filename)

# Get the original data
cel <- readCel(filename, indices=idxs, readStdvs=TRUE, readPixels=TRUE)
print(cel[fields])
cel0 <- cel

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Square-root the intensities
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
updateCel(filename, indices=idxs, intensities=sqrt(cel$intensities))
cel <- readCel(filename, indices=idxs, readStdvs=TRUE, readPixels=TRUE)
print(cel[fields])

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Update a few cell values by a data frame
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
data <- data.frame(
  intensities=cel0$intensities,
  stdvs=c(201.1, 3086.1)+0.5,
  pixels=c(9,9+1)
)
updateCel(filename, indices=idxs, data)

# Assert correctness of update
cel <- readCel(filename, indices=idxs, readStdvs=TRUE, readPixels=TRUE)
print(cel[fields])
for (ff in fields) {
#  stopifnot(all.equal(cel[[ff]], data[[ff]], .Machine$double.eps^0.25))
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Update a region of the CEL file
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Load pre-defined data
side <- 306
pathname <- system.file("extras/easternEgg.gz", package="affxparser")
con <- gzfile(pathname, open="rb")
z <- readBin(con=con, what="integer", size=1, signed=FALSE, n=side^2)
close(con)
z <- matrix(z, nrow=side)
side <- min(hdr$cols - 2*22, side)
z <- as.double(z[1:side,1:side])
x <- matrix(22+0:(side-1), nrow=side, ncol=side, byrow=TRUE)
idxs <- as.vector((1 + x) + hdr$cols*t(x))
# Load current data in the same region
z0 <- readCel(filename, indices=idxs)$intensities
# Mix the two data sets
z <- (0.3*z^2 + 0.7*z0)
# Update the CEL file
updateCel(filename, indices=idxs, intensities=z)

# Make some spatial changes
rotate270 <- function(x, ...) {
  x <- t(x)
  nc <- ncol(x)
  if (nc < 2) return(x)
  x[,nc:1,drop=FALSE]
}

# Display a spatial image of the updated CEL file
cel <- readCelRectangle(filename, xrange=c(0,350), yrange=c(0,350))
z <- rotate270(cel$intensities)
sub <- paste("Chip type:", cel$header$chiptype)
image(z, col=gray.colors(256), axes=FALSE, main=basename(filename), sub=sub)
text(x=0, y=1, labels="(0,0)", adj=c(0,-0.7), cex=0.8, xpd=TRUE)
text(x=1, y=0, labels="(350,350)", adj=c(1,1.2), cex=0.8, xpd=TRUE)

# Clean up
file.remove(filename)
rm(files, cel, cel0, idxs, data, ff, fields, rotate270)

} # for (zzz in 0)
\end{ExampleCode}
\end{Examples}

