R/readCel.R
8cab2c70
 readCel <- function(filename,
ddd48129
                     indices = NULL,
                     readHeader = TRUE,
8cab2c70
                     readXY = FALSE,
ddd48129
                     readIntensities = TRUE,
8cab2c70
                     readStdvs = FALSE,
ddd48129
                     readPixels = FALSE,
                     readOutliers = TRUE,
8cab2c70
                     readMasked = TRUE,
                     readMap = NULL,
ddd48129
                     verbose = 0,
                     .checkArgs = TRUE) {
00472b76
     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     # Local functions
     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     qsort <- function(x) {
   ##    o0 <- .Internal(qsort(x, TRUE));
   ##    o <- sort.int(x, index.return=TRUE, method="quick");
   ##    stopifnot(identical(o, o0));
       sort.int(x, index.return=TRUE, method="quick");
     } # qsort()
 
 
ddd48129
     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     # Validate arguments
     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
886f672a
     readAll <- is.null(indices);
 
ddd48129
     if (.checkArgs) {
       # Argument 'filename':
       if(length(filename) != 1) {
8cab2c70
         stop("Argument 'filename' should be a single file: ",
ddd48129
                                               paste(filename, collapse=", "));
       }
       # Expand '~' pathnames to full pathnames.
       filename <- file.path(dirname(filename), basename(filename));
       if (!file.exists(filename)) {
         stop("Cannot read CEL file. File not found: ", filename);
       }
8cab2c70
 
ddd48129
       # Argument 'indices':
       header <- readCelHeader(filename);
       nbrOfCells <- header$total;
886f672a
       if (readAll) {
ddd48129
         # Read all cells
         indices <- 1:nbrOfCells;
       } else {
         indices <- as.integer(indices);
         if (any(is.na(indices))) {
           stop("Argument 'indices' contains NAs.");
         }
         if (any(indices < 1) || any(indices > nbrOfCells)) {
           stop("Argument 'indices' is out of range [1,", nbrOfCells, "].");
         }
       }
8cab2c70
 
ddd48129
       # Argument 'readMap':
       if (!is.null(readMap)) {
63b4c964
         readMap <- .assertMap(readMap, nbrOfCells);
ddd48129
       }
8cab2c70
 
ddd48129
       # Argument 'verbose':
       if (length(verbose) != 1) {
         stop("Argument 'verbose' must be a single integer.");
       }
       if (!is.finite(as.integer(verbose))) {
         stop("Argument 'verbose' must be an integer: ", verbose);
       }
ad4b2701
 
ddd48129
     } # if (.checkArgs)
ad4b2701
 
 
ddd48129
     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     # Remapping cell indices?
     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
886f672a
     if (is.null(readMap)) {
       # If not read map and no indices very given, then all cells are read
       # and already in order an no need to sort them.
       # *all cells are read
       reorder <- FALSE;
     } else {
ddd48129
       indices <- readMap[indices];
7e675541
       reorder <- TRUE;
ddd48129
     }
ad4b2701
 
886f672a
     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     # Order cell indices for optimal speed when reading, i.e. minimizing
     # jumping around in the file.
     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     if (reorder) {
00472b76
       # qsort() is about 10-15 times faster than using order()!
       # WAS: o <- .Internal(qsort(indices, TRUE));  # From base::sort.int()
       o <- qsort(indices);
886f672a
       indices <- o$x;
00472b76
       # WAS: o <- .Internal(qsort(o$ix, TRUE))$ix;  # From base::sort.int()
       o <- qsort(o$ix)$ix;
886f672a
     }
 
ddd48129
     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     # Reading CEL file
     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8cab2c70
     # UNSUPPORTED CASE?
     if (!is.null(indices) && length(indices) == 0L) {
       stop("readCel(..., indices=integer(0)) is not supported.")
     }
 
886f672a
     cel <- .Call("R_affx_get_cel_file", filename,
                   readHeader,
                   readIntensities, readXY, readXY, readPixels, readStdvs,
                   readOutliers, readMasked,
                   indices,
                   as.integer(verbose), PACKAGE="affxparser");
 
4bd60283
     # Sanity check
     if (is.null(cel)) {
       stop("Failed to read CEL file: ", filename);
     }
 
886f672a
     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     # Re-reordering the cell values
     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     if (reorder) {
       fields <- setdiff(names(cel), c("header", "outliers", "masked"));
       for (name in fields) {
         cel[[name]] <- cel[[name]][o];
       }
     }
8cab2c70
 
886f672a
     cel;
ddd48129
 } # readCel()
 
 ############################################################################
 # HISTORY:
00472b76
 # 2012-05-22 [HB]
 # o CRAN POLICY: readCel() and readCelUnits() are no longer calling
 #   .Internal(qsort(...)).
4bd60283
 # 2011-11-18
 # o ROBUSTNESS: Added sanity check that the native code did not return NULL.
7e675541
 # 2007-12-01
 # o Removed argument 'reorder' from readCel().
63b4c964
 # 2007-01-04
8cab2c70
 # o Now 'readMap' is validate using internal .assertMap(), which also
63b4c964
 #   coerces it to an integer vector.
 # o BUG FIX: Using read maps for readCel() would give an error saying
 #   the read map is invalid even when it is not.
886f672a
 # 2006-04-01
 # o Added argument 'reorder'.
ddd48129
 # 2006-03-29
 # o Added argument '.checkArgs' so that when arguments have already been
 #   checked, for instance by readCelUnits(), we pay less overhead when
 #   calling this function.  file.exists() is a bit slow. /HB
 # 2006-03-28
 # o Unit and cell indices are now one-based. /HB
 ############################################################################