-
Notifications
You must be signed in to change notification settings - Fork 31
/
convert_sim_var.R
70 lines (60 loc) · 2.47 KB
/
convert_sim_var.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#' convert an existing simulation variable into a different one
#'
#' allows you to provide specific variable or unit conversions to create a new variable
#' that can be used with \code{\link{plot_var_compare}}, and others.
#'
#' @param nc_file the netcdf output file
#' @param \dots an expression to convert variable based on other variables or offsets
#' @param unit the units for the new variable
#' @param longname the longname for the new variable
#' @export
#' @importFrom lazyeval lazy_dots lazy_eval
#' @importFrom ncdf4 ncvar_def ncvar_put ncvar_add
#' @examples
#' \dontrun{
#'sim_folder <- run_example_sim(verbose = FALSE)
#'nc_file <- file.path(sim_folder, 'output.nc')
#'convert_sim_var(nc_file, tempF = temp/5*9+32, unit='degF',longname='temperature degrees Farenheit')
#'plot_var(nc_file, 'tempF')
#'convert_sim_var(nc_file, crazy_var = temp-u_mean*1000)
#'plot_var(nc_file, 'crazy_var')
#'
#' }
#'
convert_sim_var <- function(nc_file='output.nc', ..., unit='', longname=''){
sim.vars <- sim_vars(nc_file)$name
message('convert_sim_var is untested and in development')
# // here, vals would be defined by the function passed in by `...`. Probably captured w/ lazyeval?
# lazyeval::lazy_eval(convert, data=list(temp=ncvar_get(nc, 'temp')))
convert <- lazyeval::lazy_dots(...)
if (length(convert) > 1)
stop('not yet ready to handle multi-var expressions')
var.name <- names(convert)
if (var.name %in% sim.vars)
stop(var.name, ' cannot be added, it already exists.', call. = FALSE)
fun.string <- deparse(convert[[1]]$expr)
variables <- strsplit(fun.string,"[^a-zA-Z_]")[[1]]
variables <- variables[variables != '']
vars.not.in <- variables[!variables %in% sim.vars]
if (length(vars.not.in) > 0)
stop(paste(vars.not.in, collapse=', '), ' do not exist in simulation vars', call. = FALSE)
data <- lapply(variables, function(v) get_raw(nc_file, v))
names(data) <- variables
vals <- lazyeval::lazy_eval(convert, data=data)[[1]]
nc <- nc_open(nc_file, readunlim=TRUE, write=TRUE)
#depending on conversion, dims can be [time], [lon,lat,time], or [lon,lat,z,time]
lon <- nc$dim$lon
lat <- nc$dim$lon
time <- nc$dim$time
if (length(dim(vals)) > 1){
z <- nc$dim$z
dim = list(lon,lat,z,time)
} else {
dim = list(lon,lat,time)
}
missval = 9.96920996838687e36
var_new <- ncvar_def(name=var.name, unit, dim = dim, missval, prec="double")
nc <- ncvar_add(nc, var_new)
ncvar_put(nc, var_new, vals=vals)
nc_close(nc)
}