Skip to content

Commit

Permalink
Merge pull request #205 from jread-usgs/master
Browse files Browse the repository at this point in the history
conversions for units
  • Loading branch information
Luke Winslow committed Mar 28, 2016
2 parents d46c149 + 388bf91 commit 075ac42
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 3 deletions.
7 changes: 4 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Package: glmtools
Type: Package
Title: glmtools
Version: 0.13.2
Date: 2016-01-15
Version: 0.14.0
Date: 2016-03-28
Authors@R: c( person("Jordan", "Read", role = c("aut","cre"),
email = "jread@usgs.gov"),
person("Luke", "Winslow", role = "aut",
Expand All @@ -21,7 +21,8 @@ Depends:
Imports:
ncdf4,
tools,
akima
akima,
lazyeval
Suggests:
testthat,
knitr,
Expand Down
6 changes: 6 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ S3method(print,nml)
S3method(summary,nml)
export(.compare_to_field)
export(compare_to_field)
export(convert_sim_var)
export(epi.temperature)
export(get_evaporation)
export(get_hypsography)
Expand Down Expand Up @@ -41,7 +42,12 @@ import(GLMr)
import(rLakeAnalyzer)
import(tools)
importFrom(akima,interp)
importFrom(lazyeval,lazy_dots)
importFrom(lazyeval,lazy_eval)
importFrom(ncdf4,nc_close)
importFrom(ncdf4,nc_open)
importFrom(ncdf4,ncatt_get)
importFrom(ncdf4,ncvar_add)
importFrom(ncdf4,ncvar_def)
importFrom(ncdf4,ncvar_get)
importFrom(ncdf4,ncvar_put)
78 changes: 78 additions & 0 deletions R/convert_sim_var.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@

#' 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')
#'
#'temp2f <- function(c) c/5*9+32
#'convert_sim_var(nc_file, tempf = temp2f(temp), unit='degF',longname='temperature degrees Farenheit')
#' }
#'
convert_sim_var <- function(nc_file='output.nc', ..., unit='', longname='', overwrite=FALSE){


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)
var.exists <- var.name %in% sim.vars
if (var.exists & !overwrite)
stop(var.name, ' cannot be added, it already exists and overwrite = FALSE.', call. = FALSE)

fun.string <- deparse(convert[[1]]$expr)
variables <- strsplit(fun.string,"[^a-zA-Z_]")[[1]]
variables <- variables[variables != '']
nc.vars <- variables[variables %in% sim.vars]

data <- lapply(nc.vars, function(v) get_raw(nc_file, v))
names(data) <- nc.vars
vals <- lazyeval::lazy_eval(convert, data=data)[[1]]

nc <- nc_open(nc_file, readunlim=TRUE, write=TRUE)


if (!var.exists){
#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)
} else {
var_new <- var.name
}


ncvar_put(nc, var_new, vals=vals)
nc_close(nc)
}
37 changes: 37 additions & 0 deletions man/convert_sim_var.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions tests/testthat/test-convert_sim_var.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
context("convert variables in netcdf output")

test_that("errors with poor matches", {
sim_folder <- run_example_sim(verbose = FALSE)
nc_file <<- file.path(sim_folder, 'output.nc')
expect_error(convert_sim_var(nc_file, temp = temp*2), "temp cannot be added, it already exists.")
expect_error(convert_sim_var(nc_file, temp.new = garbage))
})

test_that("can add variable", {
convert_sim_var(nc_file, temp.new = temp*2)
expect_true('temp.new' %in% sim_vars(nc_file)$name)
expect_is(get_var(nc_file, var_name = 'temp.new'), 'data.frame')
})

test_that("errors when you try to add it again", {
expect_error(convert_sim_var(nc_file, temp.new = temp*2))
})

test_that("can modify variable with more than one variable function", {

convert_sim_var(nc_file, crazy_var = temp-u_mean*1000)
expect_true('crazy_var' %in% sim_vars(nc_file)$name)
})

test_that("can modify variable with a function", {

temp2f <- function(c) c/5*9+32
convert_sim_var(nc_file, tempf = temp2f(temp), unit='degF',longname='temperature degrees Farenheit')
expect_true('tempf' %in% sim_vars(nc_file)$name)
expect_error(convert_sim_var(nc_file, tempf2 = garbagefun(temp)))

})

test_that("can overwrite existing variable", {

temp2f <- function(c) c/5*9+32
tempf <- get_raw(nc_file, 'tempf')
convert_sim_var(nc_file, tempf = temp2f(temp), overwrite = TRUE)
expect_equal(tempf, get_raw(nc_file, 'tempf'))
convert_sim_var(nc_file, tempf = temp2f(temp)+5, overwrite = TRUE)
expect_equal(tempf, get_raw(nc_file, 'tempf')-5)
})

0 comments on commit 075ac42

Please sign in to comment.