getx.var.ncdf= function (nc, varid = NA, start = NA, count = NA, verbose = FALSE, signedbyte = TRUE, forcevarid = NA) { if (verbose) { if (!is.na(forcevarid)) { print("get.var.ncdf: entering with forcevarid set to:") print(forcevarid) } else { print("get.var.ncdf: entering. Here is varid:") print(varid) } } have_start = (length(start) > 1) || ((length(start) == 1) && (!is.na(start))) have_count = (length(count) > 1) || ((length(count) == 1) && (!is.na(count))) if (class(nc) != "ncdf") stop("first argument (nc) is not of class ncdf!") if (signedbyte) byte_style = 1 else byte_style = 2 if (is.na(forcevarid)) { if (verbose) print("checking to see if passed varid is actually a dimvar") rvdim <- vobjtodimname(nc, varid, verbose) isdimvar <- rvdim$isdim if (isdimvar) dimidtouse <- rvdim$name if (verbose) print(paste("get.var.ncdf: isdimvar:", isdimvar)) if (isdimvar) { if (verbose) print(paste("get.var.ncdf: dimname:", dimidtouse)) varid <- nc$dim[[dimidtouse]]$dimvarid if (varid == -1) { if (!have_start) start <- 1 if (!have_count) count <- nc$dim[[dimidtouse]]$len if (count == 1) return(start) else return(start:(start + count - 1)) } } else { varid <- vobjtovarid(nc, varid, verbose = verbose) } } else { varid <- forcevarid isdimvar <- TRUE } if (verbose) print(paste("get.var.ncdf: ending up using varid=", varid)) varsize <- varsize.ncdf(nc, varid) ndims <- varndims.ncdf(nc, varid) if (verbose) { print(paste("ndims:", ndims)) print("get.var.ncdf: varsize:") print(varsize) } if (ndims == 0) { start <- 1 count <- 1 } else { if (!have_start) start <- rep(1, ndims) if (!have_count) count <- varsize - start + 1 else { count <- ifelse((count == -1), varsize - start + 1, count) } } if (verbose) { print("get.var.ncdf: start:") print(start) print("get.var.ncdf: count:") print(count) } if (ndims > 0) { if (length(start) != ndims) stop(paste("Error: variable has", ndims, "dims, but start has", length(start), "entries. They must match!")) if (length(count) != ndims) stop(paste("Error: variable has", ndims, "dims, but count has", length(count), "entries. They must match!")) } totvarsize <- prod(count) if (verbose) print(paste("get.var.ncdf: totvarsize:", totvarsize)) c.start <- start[ndims:1] - 1 c.count <- count[ndims:1] rv <- list() rv$error <- -1 precint <- vartype.ncdf(nc, varid) if (verbose) print(paste("Getting var of type", precint, " (1=short, 2=int, 3=float, 4=double, 5=char, 6=byte)")) if ((precint == 1) || (precint == 2) || (precint == 6)) { rv$data <- integer(totvarsize) rv <- .C("R_nc_get_vara_int", as.integer(nc$id), as.integer(varid - 1), as.integer(c.start), as.integer(c.count), as.integer(byte_style), data = as.integer(rv$data), error = as.integer(rv$error), PACKAGE = "ncdf", DUP = FALSE) if (rv$error != 0) stop("C function R_nc_get_var_int returned error") } else if ((precint == 3) || (precint == 4)) { rv$data <- double(totvarsize) rv <- .C("R_nc_get_vara_double", as.integer(nc$id), as.integer(varid - 1), as.integer(c.start), as.integer(c.count), data = as.double(rv$data), error = as.integer(rv$error), PACKAGE = "ncdf", DUP = FALSE) if (rv$error != 0) stop("C function R_nc_get_vara_double returned error") } else if (precint == 5) { strndims <- ndims - 1 strlen <- count[1] + 1 strdim <- 1 if (strndims >= 1) { strdim <- count[2:ndims] nstr <- prod(strdim) } else nstr <- 1 if (verbose) print(paste("ndims:", ndims, "strndims:", strndims, "strlen:", strlen, "nstr:", nstr)) stor <- blankstring.ncdf(totvarsize) stordata <- blankstring.ncdf(strlen) if (verbose) print(paste("length of stor string:", nchar(stor))) rv$tempstore <- stor rv$data <- array(stordata, dim = strdim) rv <- .C("R_nc_get_vara_text", as.integer(nc$id), as.integer(varid - 1), as.integer(c.start), as.integer(c.count), tempstore = as.character(rv$tempstore), data = as.character(rv$data), error = as.integer(rv$error), PACKAGE = "ncdf") if (rv$error != 0) stop("C function R_nc_get_var_text returned error") dim(rv$data) <- strdim } else { stop(paste("Trying to get variable of an unhandled type code: ", precint)) } if (verbose) print(paste("get.var.ncdf: C call returned", rv$error)) if (ndims > 0) { count.nodegen <- vector() foundone <- 0 for (i in 1:ndims) if (count[i] > 1) { count.nodegen <- append(count.nodegen, count[i]) foundone <- 1 } if (foundone == 0) dim(rv$data) <- (1) else { if (verbose) print(paste("count.nodegen:", count.nodegen, " Length of data:", length(rv$data))) if (precint != 5) dim(rv$data) <- count.nodegen } if (verbose) { print("get.var.ncdf: final dims of returned array:") print(dim(rv$data)) } } if (verbose) { print(paste("varid:", varid)) print(paste("nc$varid2Rindex:", nc$varid2Rindex)) print(paste("nc$varid2Rindex[varid]:", nc$varid2Rindex[varid])) } if ((!isdimvar) && (precint != 5)) { if (verbose) print("get.var.ncdf: setting missing values to NA") if ((precint == 1) || (precint == 2)) { mv <- -1.000000e+30 if (!is.na(mv)) { if (verbose) print(paste("missval:", mv)) rv$data[rv$data == mv] <- NA } } else if ((precint == 3) || (precint == 4)) { mv <- -1.000000e+30 if (!is.na(mv)) { tol <- abs(mv * 1e-05) if (verbose) print(paste("missval:", mv, " tol:", tol)) rv$data[abs(rv$data - mv) < tol] <- NA } } } if (!isdimvar) { if (verbose) print(paste("get.var.ncdf: implementing add_offset (", nc$var[[nc$varid2Rindex[varid]]]$hasAddOffset, ") and scale_factor (", nc$var[[nc$varid2Rindex[varid]]]$hasScaleFact, ")")) if (nc$var[[nc$varid2Rindex[varid]]]$hasAddOffset && nc$var[[nc$varid2Rindex[varid]]]$hasScaleFact) { if (verbose) print(paste("var has BOTH add_offset (", nc$var[[nc$varid2Rindex[varid]]]$addOffset, ") and scale_fact (", nc$var[[nc$varid2Rindex[varid]]]$scaleFact, ")")) rv$data <- rv$data * nc$var[[nc$varid2Rindex[varid]]]$scaleFact + nc$var[[nc$varid2Rindex[varid]]]$addOffset } else if (nc$var[[nc$varid2Rindex[varid]]]$hasAddOffset) { if (verbose) print(paste("var has add_offset (only):", nc$var[[nc$varid2Rindex[varid]]]$addOffset)) rv$data <- rv$data + nc$var[[nc$varid2Rindex[varid]]]$addOffset } else if (nc$var[[nc$varid2Rindex[varid]]]$hasScaleFact) { if (verbose) print(paste("var has scale_factor (only):", nc$var[[nc$varid2Rindex[varid]]]$scaleFact)) rv$data <- rv$data * nc$var[[nc$varid2Rindex[varid]]]$scaleFact } else { if (verbose) print("var has NEITHER add_offset nor scale_factor") } } return(rv$data) }