From c1e4cf0985685acf94db04c7ce56cf1130c6c045 Mon Sep 17 00:00:00 2001 From: Nicholas Potter Date: Wed, 9 Sep 2015 00:28:54 -0700 Subject: [PATCH 1/4] Add functions to access GEFS ensemble forecasts. * Add R/gefs.R containing functionality to access GEFS forecasts and several helper functions. * Add tests/testthat/test-gefs.R to test new gefs functions. * modify package files: * DESCRIPTION now includes ncdf4 package in suggests, * NAMESPACE exports gefs function, * rnoaa-package.r updated to include reference to ncdf4 --- DESCRIPTION | 5 +- NAMESPACE | 1 + R/gefs.R | 211 +++++++++++++++++++++++++++++++++++++ R/rnoaa-package.r | 6 +- tests/testthat/test-gefs.R | 79 ++++++++++++++ 5 files changed, 299 insertions(+), 3 deletions(-) create mode 100644 R/gefs.R create mode 100644 tests/testthat/test-gefs.R diff --git a/DESCRIPTION b/DESCRIPTION index 1b0922c0..261f3ba9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -33,10 +33,11 @@ Imports: scales, rgdal, XML, - jsonlite + jsonlite, Suggests: testthat, roxygen2, knitr, taxize, - ncdf + ncdf, + ncdf4, diff --git a/NAMESPACE b/NAMESPACE index c2586f45..666ce06b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -26,6 +26,7 @@ export(erddap_grid) export(erddap_info) export(erddap_search) export(erddap_table) +export(gefs) export(ghcnd) export(ghcnd_clear_cache) export(ghcnd_countries) diff --git a/R/gefs.R b/R/gefs.R new file mode 100644 index 00000000..3c353935 --- /dev/null +++ b/R/gefs.R @@ -0,0 +1,211 @@ +#' Get GEFS ensemble forecast data for a specific lat/lon. +#' +#' Fetches GEFS forecast data for every 6 hours out to 384 hours past selected date. GEFS +#' is an ensemble of 21 models that can be summarized to estimate likelihoods of forecasts. +#' +#' @importFrom ncdf4 nc_open ncvar_get +#' @importFrom tidyr gather +#' @export +#' +#' @param var the variable to get. Must be one of the variables listed in \code{gefs_variables()}. +#' @param lat,lon the longitude. Will be converted to the nearest GEFS available +#' longitude. If lon is a list of vlaues, it must be a sequential list, and +#' data are returned for the number of longitudes in the list starting with +#' the maximum value and incrementing through the indexed values for the +#' length of the list. +#' @param date A date/string formatted as YYYYMMDD. +#' @param forecast_time a string indicating which time of day UTC the forecast is from. Options are "0000", "0600", "1200", "1800". +#' @param ens_idx sequential list of ensembles to fetch. Default is all 21. Note that the ensembles are labelled 0-20, so ens_idx=1:3 will return ensembles 0, 1, and 2. +#' @param time_idx sequential list of time increments to return. List is the index +#' of times, which are in 6 hour increments. (e.g. c(1,2) fetches the 6 and 12 hour forecast.) +#' @param raw logical to indicate whether to return raw data matrix or reshaped data frame. +#' @param ... additional parameters passed to \code{ncvar_get}. +#' @return a list containing metadata and accompanying data frame of forecast +#' values. If lat/lon are not specified, the $data is an unprocessed matrix. +#' +#' @author Nicholas Potter \email{potterzot@@gmail.com} +#' @examples \dontrun{ +#' +#' #avialable latitudes and longitudes +#' gefs_latitudes() +#' gefs_longitudes() +#' +#' #get a list of all gefs variables +#' gefs_variables() +#' +#' #All GEFS dimensions +#' gefs_dimensions() +#' +#' #values for a specific dimension +#' gefs_dimension_values("height_above_ground") +#' +#' #example location. +#' lat = 46.28125 +#' lon = -116.2188 +#' +#' #Get forecast for a certain variable. +#' forecast = gefs("Total_precipitation_surface_6_Hour_Accumulation_ens", lat, lon) +#' +#' #Fetch a different date (available up to 10 days prior to today) +#' forecast_yesterday_prec = gefs("Total_precipitation_surface_6_Hour_Accumulation_ens", +#' lat, +#' lon, +#' date=format(as.Date(Sys.time()) - 1, "%Y%m%d")) +#' +#' #specific ensemble and times, for the 1800 forecast. +#' # here ensembles 1-3 (ensembles are numbered starting with 0) +#' # and time for 2 days from today at 1800 +#' gefs(var, lat, lon, forecast_time = "1800", ens_idx=2:4, time_idx=1:8) +#' +#' #One ensemble, all latitudes and longitudes (this is a big file) for the +#' # next 3 days. +#' gefs(var, ens=1, time=1:12) +#' } +#' +gefs <- function(var, lat, lon, ...) { + gefs_GET(var, lat, lon, ...) +} + +#' @importFrom ncdf4 nc_open +#' @rdname gefs +gefs_CONNECT <- function(date = format(Sys.time(), "%Y%m%d"), + forecast_time = c("0000", "0600", "1200", "1800")) { + + #forecast time + forecast_time = match.arg(forecast_time) + + #url parts + gefs_url_pre = 'http://motherlode.ucar.edu/thredds/dodsC/grib/NCEP/GEFS/Global_1p0deg_Ensemble/members/GEFS_Global_1p0deg_Ensemble_' + gefs_url_suf = ".grib2" + + #final url + gefs_url = paste0(gefs_url_pre, date, "_", forecast_time, gefs_url_suf) + + #open the connection + nc_open(gefs_url) +} + +#' @importFrom ncdf4 ncvar_get +#' @rdname gefs +gefs_GET <- function(var, lat, lon, + date = format(Sys.time(), "%Y%m%d"), + forecast_time = c("0000", "0600", "1200", "1800"), + ens_idx = 1:21, + time_idx = 1:65, + dims = NULL, + raw = FALSE, + ...) { + + #Sanity Checks + if (missing(var)) stop("Need to specify the variable to get. A list of variables is available from gefs_variables().") + + #get a connection + con = gefs_CONNECT(date, forecast_time) + + #Get a subset of data to speed up access + v = con$var[[var]] # lon, lat, height_above_ground, ens (ensemble), time1 + varsize = v$varsize + ndims = v$ndims + n_time = varsize[ndims] #time is always the last dimension + dims = c() + for (i in 1:length(v$dim)) { dims[i] = v$dim[[i]]$name } + + #get lat/lon indices + lon_start_idx = if(!missing(lon)) which(v$dim[[1]]$vals==round(max(lon) %% 360, 0)) else 1 + lat_start_idx = if(!missing(lat)) which(v$dim[[2]]$vals==round(max(lat), 0)) else 1 + + #indices of dimensions to read from data + start = rep(1,ndims) #number of dims + start[1] = lon_start_idx #first is always longitude + start[2] = lat_start_idx #first is always latitude + start[ndims - 1] = ens_idx[1] #first ensemble + start[ndims] = time_idx[1] #first time + + count_n = rep(1,ndims) + + #if not specified, get all locations. + count_n[1] = if(missing(lon)) -1 else length(lon) + count_n[2] = if(missing(lat)) -1 else length(lat) + + #ensemble is always the 2nd to last dimension. Take either the variable + #max or the last value indicated by the parameter ens + count_n[ndims-1] = min(varsize[ndims-1], length(ens_idx)) + + #time is always the last dimension + #take the minimum of the variable max or the value indicated by the parameter time + count_n[ndims] = min(varsize[ndims], length(time_idx)) + + # actual data + # Do not modify the data, so don't convert (- 273.15) * 1.8 + 32. #convert from K to F + d = ncvar_get(con, v, start = start, count = count_n, ...) + + #create the data frame + #For now, if lat/lon are not specified, just return a matrix. + if (raw==FALSE) { + d = gather(as.data.frame(d)) + + for (i in 1:length(count_n)) { + dim_vals = v$dim[[i]]$vals + if(count_n[i]==1) { + d[dims[i]] = dim_vals[start[i]] + } + else { + d[dims[i]] = dim_vals[0:(count_n[i]-1) + start[i]] + } + } + names(d) = c("key", var, dims) + d = d[,c(dims, var)] + } + + fname = strsplit(con$filename, "_")[[1]] + date = fname[7] + forecast_time = strsplit(fname, ".grib2")[[8]] + list(forecast_date = date, + forecast_time = forecast_time, + dimensions = dims, + data = d) +} + +######################## +# helper functions + +#' @export +#' +#' @param con an ncdf4 connection. +#' @rdname gefs +gefs_latitudes <- function(con = NULL, ...) { + gefs_dimension_values("lat", con) +} + +#' @export +#' @rdname gefs +gefs_longitudes <- function(con = NULL, ...) { + gefs_dimension_values("lon", con) +} + +#' @export +#' @rdname gefs +gefs_variables <- function(con = NULL, ...) { + if (is.null(con)) con = gefs_CONNECT(...) + names(con$var) +} + +#' @export +#' @rdname gefs +gefs_dimensions <- function(con = NULL, ...) { + if (is.null(con)) con = gefs_CONNECT(...) + names(con$dim) +} + +#' @export +#' +#' @param dim (character) the dimension. +#' @rdname gefs +gefs_dimension_values <- function(dim, con = NULL, ...) { + if (is.null(dim) || missing(dim)) stop("dim cannot be NULL or missing.") + if (is.null(con)) con = gefs_CONNECT(...) + con$dim[[dim]]$vals +} + + + diff --git a/R/rnoaa-package.r b/R/rnoaa-package.r index 697dee13..309a37df 100644 --- a/R/rnoaa-package.r +++ b/R/rnoaa-package.r @@ -11,6 +11,7 @@ #' #' \itemize{ #' \item \code{buoy_*} - NOAA Buoy data from the National Buoy Data Center +#' \item \code{gefs} - GEFS forecast ensemble data #' \item \code{ghcnd_*} - GHCND daily data from NOAA #' \item \code{isd_*} - ISD/ISH data from NOAA #' \item \code{homr_*} - Historical Observing Metadata Repository (HOMR) vignette @@ -21,7 +22,7 @@ #' \item \code{tornadoes} - From the NOAA Storm Prediction Center #' } #' -#' @section A note about ncdf: +#' @section A note about ncdf/ncdf4: #' #' Functions to work with buoy data use netcdf files. You'll need the \code{ncdf} #' package for those functions, and those only. \code{ncdf} is in Suggests in @@ -29,6 +30,9 @@ #' functions. You'll get an informative error telling you to install \code{ncdf} #' if you don't have it and you try to use the buoy functions. #' +#' The gefs function uses \code{ncdf4}, which is available on CRAN and should be +#' straightfoward to install. +#' #' Installation of \code{ncdf} should be straightforward on Mac and Windows, but #' on Linux you may have issues. See http://cran.r-project.org/web/packages/ncdf/INSTALL #' diff --git a/tests/testthat/test-gefs.R b/tests/testthat/test-gefs.R new file mode 100644 index 00000000..4ea30ac7 --- /dev/null +++ b/tests/testthat/test-gefs.R @@ -0,0 +1,79 @@ +context("gefs") + +#set a location +lat = 46.28125 +lon = -116.2188 + +#variable +var = "Temperature_height_above_ground_ens" + +test_that("gefs errors", { + + expect_error(gefs(lat=lat, lon=lon), "Need to specify the variable to get. A list of variables is available from gefs_variables().") +}) + +test_that("gefs time and ensemble selection returns correct indices.", { + ens_idx = 2:4 + time_idx = 5:10 + d = gefs(var, lat, lon, ens_idx = ens_idx, time_idx = time_idx) + + expect_equal(dim(d$data), c(length(ens_idx) * length(time_idx), 6)) + expect_equal(unique(d$data$ens), ens_idx-1) + expect_equal(unique(d$data$time), (time_idx-1) * 6) +}) + +test_that("gefs metadata", { + today = format(as.Date(Sys.time()) - 1, "%Y%m%d") + forecast_time = "0600" + d = gefs(var, lat, lon, ens=1, date=today, forecast_time=forecast_time) + + expect_equal(d$forecast_date, today) + expect_equal(d$forecast_time, forecast_time) + expect_equal(d$dimensions, c("lon", "lat", "height_above_ground", "ens", "time1")) +}) + +test_that("gefs_variables returns characters.", { + skip_on_cran() + + vars = gefs_variables() + + expect_is(vars, "character") + expect_is(vars[1], "character") +}) + +test_that("gefs_latitudes returns numeric.", { + skip_on_cran() + + lats = gefs_latitudes() + expect_is(lats, "array") + expect_is(lats[1], "numeric") +}) + +test_that("gefs_longitudes returns numeric.", { + skip_on_cran() + + lats = gefs_longitudes() + expect_is(lats, "array") + expect_is(lats[1], "numeric") +}) + +test_that("gefs_dimensions returns character list.", { + skip_on_cran() + + dims = gefs_dimensions() + expect_is(dims, "character") + expect_is(dims[1], "character") +}) + +test_that("gefs_dimension_values returns numeric array.", { + skip_on_cran() + + vals = gefs_dimension_values("lat") + expect_is(vals, "array") + expect_is(vals[1], "numeric") + + #expect_error(gefs_dimension_values(dim=NULL), "dim cannot be NULL or missing.") +}) + + + From bc6f2ee37a1587ed4d084a58915f483ccfd5948b Mon Sep 17 00:00:00 2001 From: Nicholas Potter Date: Wed, 9 Sep 2015 12:56:21 -0700 Subject: [PATCH 2/4] Fixes to gefs pull request Changes include: * switch from ncdf4 to ncdf * add function check for ncdf (from bouy.R) * generate documentation and namespace exports for gefs functions * roll back rnoaa-package doc to remove ncdf4 references * include link to gefs web page in documentation * include skip_on_cran() where tests make a web api call * minor fixes (trailing commas, etc...) --- DESCRIPTION | 5 +- NAMESPACE | 5 ++ R/gefs.R | 22 ++++++-- R/rnoaa-package.r | 5 +- man/gefs.Rd | 113 +++++++++++++++++++++++++++++++++++++ man/rnoaa-package.Rd | 1 + tests/testthat/test-gefs.R | 6 ++ 7 files changed, 145 insertions(+), 12 deletions(-) create mode 100644 man/gefs.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 261f3ba9..1b0922c0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -33,11 +33,10 @@ Imports: scales, rgdal, XML, - jsonlite, + jsonlite Suggests: testthat, roxygen2, knitr, taxize, - ncdf, - ncdf4, + ncdf diff --git a/NAMESPACE b/NAMESPACE index 666ce06b..30ceb645 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -27,6 +27,11 @@ export(erddap_info) export(erddap_search) export(erddap_table) export(gefs) +export(gefs_dimension_values) +export(gefs_dimensions) +export(gefs_latitudes) +export(gefs_longitudes) +export(gefs_variables) export(ghcnd) export(ghcnd_clear_cache) export(ghcnd_countries) diff --git a/R/gefs.R b/R/gefs.R index 3c353935..7316234e 100644 --- a/R/gefs.R +++ b/R/gefs.R @@ -3,7 +3,6 @@ #' Fetches GEFS forecast data for every 6 hours out to 384 hours past selected date. GEFS #' is an ensemble of 21 models that can be summarized to estimate likelihoods of forecasts. #' -#' @importFrom ncdf4 nc_open ncvar_get #' @importFrom tidyr gather #' @export #' @@ -22,6 +21,8 @@ #' @param ... additional parameters passed to \code{ncvar_get}. #' @return a list containing metadata and accompanying data frame of forecast #' values. If lat/lon are not specified, the $data is an unprocessed matrix. +#' +#' @references \url{https://www.ncdc.noaa.gov/data-access/model-data/model-datasets/global-ensemble-forecast-system-gefs} #' #' @author Nicholas Potter \email{potterzot@@gmail.com} #' @examples \dontrun{ @@ -55,6 +56,7 @@ #' #specific ensemble and times, for the 1800 forecast. #' # here ensembles 1-3 (ensembles are numbered starting with 0) #' # and time for 2 days from today at 1800 +#' var = "Temperature_height_above_ground_ens" #' gefs(var, lat, lon, forecast_time = "1800", ens_idx=2:4, time_idx=1:8) #' #' #One ensemble, all latitudes and longitudes (this is a big file) for the @@ -63,10 +65,10 @@ #' } #' gefs <- function(var, lat, lon, ...) { + check4ncdf() gefs_GET(var, lat, lon, ...) } -#' @importFrom ncdf4 nc_open #' @rdname gefs gefs_CONNECT <- function(date = format(Sys.time(), "%Y%m%d"), forecast_time = c("0000", "0600", "1200", "1800")) { @@ -82,10 +84,10 @@ gefs_CONNECT <- function(date = format(Sys.time(), "%Y%m%d"), gefs_url = paste0(gefs_url_pre, date, "_", forecast_time, gefs_url_suf) #open the connection - nc_open(gefs_url) + #nc_open(gefs_url) #ncdf4 version + open.ncdf(gefs_url) } -#' @importFrom ncdf4 ncvar_get #' @rdname gefs gefs_GET <- function(var, lat, lon, date = format(Sys.time(), "%Y%m%d"), @@ -137,7 +139,8 @@ gefs_GET <- function(var, lat, lon, # actual data # Do not modify the data, so don't convert (- 273.15) * 1.8 + 32. #convert from K to F - d = ncvar_get(con, v, start = start, count = count_n, ...) + #d = ncvar_get(con, v, start = start, count = count_n, ...) #ncdf4 version + d = get.var.ncdf(con, v, start = start, count = count_n, ...) #create the data frame #For now, if lat/lon are not specified, just return a matrix. @@ -207,5 +210,14 @@ gefs_dimension_values <- function(dim, con = NULL, ...) { con$dim[[dim]]$vals } +#Check that ncdf is installed +check4ncdf <- function() { + if (!requireNamespace("ncdf", quietly = TRUE)) { + stop("Please install ncdf", call. = FALSE) + } else { + invisible(TRUE) + } +} + diff --git a/R/rnoaa-package.r b/R/rnoaa-package.r index 309a37df..88481f3e 100644 --- a/R/rnoaa-package.r +++ b/R/rnoaa-package.r @@ -22,7 +22,7 @@ #' \item \code{tornadoes} - From the NOAA Storm Prediction Center #' } #' -#' @section A note about ncdf/ncdf4: +#' @section A note about ncdf: #' #' Functions to work with buoy data use netcdf files. You'll need the \code{ncdf} #' package for those functions, and those only. \code{ncdf} is in Suggests in @@ -30,9 +30,6 @@ #' functions. You'll get an informative error telling you to install \code{ncdf} #' if you don't have it and you try to use the buoy functions. #' -#' The gefs function uses \code{ncdf4}, which is available on CRAN and should be -#' straightfoward to install. -#' #' Installation of \code{ncdf} should be straightforward on Mac and Windows, but #' on Linux you may have issues. See http://cran.r-project.org/web/packages/ncdf/INSTALL #' diff --git a/man/gefs.Rd b/man/gefs.Rd new file mode 100644 index 00000000..4597c7f8 --- /dev/null +++ b/man/gefs.Rd @@ -0,0 +1,113 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/gefs.R +\name{gefs} +\alias{gefs} +\alias{gefs_CONNECT} +\alias{gefs_GET} +\alias{gefs_dimension_values} +\alias{gefs_dimensions} +\alias{gefs_latitudes} +\alias{gefs_longitudes} +\alias{gefs_variables} +\title{Get GEFS ensemble forecast data for a specific lat/lon.} +\usage{ +gefs(var, lat, lon, ...) + +gefs_CONNECT(date = format(Sys.time(), "\%Y\%m\%d"), + forecast_time = c("0000", "0600", "1200", "1800")) + +gefs_GET(var, lat, lon, date = format(Sys.time(), "\%Y\%m\%d"), + forecast_time = c("0000", "0600", "1200", "1800"), ens_idx = 1:21, + time_idx = 1:65, dims = NULL, raw = FALSE, ...) + +gefs_latitudes(con = NULL, ...) + +gefs_longitudes(con = NULL, ...) + +gefs_variables(con = NULL, ...) + +gefs_dimensions(con = NULL, ...) + +gefs_dimension_values(dim, con = NULL, ...) +} +\arguments{ +\item{var}{the variable to get. Must be one of the variables listed in \code{gefs_variables()}.} + +\item{lat,lon}{the longitude. Will be converted to the nearest GEFS available +longitude. If lon is a list of vlaues, it must be a sequential list, and +data are returned for the number of longitudes in the list starting with +the maximum value and incrementing through the indexed values for the +length of the list.} + +\item{...}{additional parameters passed to \code{ncvar_get}.} + +\item{date}{A date/string formatted as YYYYMMDD.} + +\item{forecast_time}{a string indicating which time of day UTC the forecast is from. Options are "0000", "0600", "1200", "1800".} + +\item{ens_idx}{sequential list of ensembles to fetch. Default is all 21. Note that the ensembles are labelled 0-20, so ens_idx=1:3 will return ensembles 0, 1, and 2.} + +\item{time_idx}{sequential list of time increments to return. List is the index +of times, which are in 6 hour increments. (e.g. c(1,2) fetches the 6 and 12 hour forecast.)} + +\item{raw}{logical to indicate whether to return raw data matrix or reshaped data frame.} + +\item{con}{an ncdf4 connection.} + +\item{dim}{(character) the dimension.} +} +\value{ +a list containing metadata and accompanying data frame of forecast + values. If lat/lon are not specified, the $data is an unprocessed matrix. +} +\description{ +Fetches GEFS forecast data for every 6 hours out to 384 hours past selected date. GEFS +is an ensemble of 21 models that can be summarized to estimate likelihoods of forecasts. +} +\examples{ +\dontrun{ + +#avialable latitudes and longitudes +gefs_latitudes() +gefs_longitudes() + +#get a list of all gefs variables +gefs_variables() + +#All GEFS dimensions +gefs_dimensions() + +#values for a specific dimension +gefs_dimension_values("height_above_ground") + +#example location. +lat = 46.28125 +lon = -116.2188 + +#Get forecast for a certain variable. +forecast = gefs("Total_precipitation_surface_6_Hour_Accumulation_ens", lat, lon) + +#Fetch a different date (available up to 10 days prior to today) +forecast_yesterday_prec = gefs("Total_precipitation_surface_6_Hour_Accumulation_ens", + lat, + lon, + date=format(as.Date(Sys.time()) - 1, "\%Y\%m\%d")) + +#specific ensemble and times, for the 1800 forecast. +# here ensembles 1-3 (ensembles are numbered starting with 0) +# and time for 2 days from today at 1800 +var = "Temperature_height_above_ground_ens" +gefs(var, lat, lon, forecast_time = "1800", ens_idx=2:4, time_idx=1:8) + +#One ensemble, all latitudes and longitudes (this is a big file) for the +# next 3 days. +gefs(var, ens=1, time=1:12) +} +} +\author{ +Nicholas Potter \email{potterzot@gmail.com} +} +\references{ +\url{https://www.ncdc.noaa.gov/data-access/model-data/model-datasets/global-ensemble-forecast-system-gefs} +} + diff --git a/man/rnoaa-package.Rd b/man/rnoaa-package.Rd index 4488adf7..931985aa 100644 --- a/man/rnoaa-package.Rd +++ b/man/rnoaa-package.Rd @@ -20,6 +20,7 @@ are: \itemize{ \item \code{buoy_*} - NOAA Buoy data from the National Buoy Data Center + \item \code{gefs} - GEFS forecast ensemble data \item \code{ghcnd_*} - GHCND daily data from NOAA \item \code{isd_*} - ISD/ISH data from NOAA \item \code{homr_*} - Historical Observing Metadata Repository (HOMR) vignette diff --git a/tests/testthat/test-gefs.R b/tests/testthat/test-gefs.R index 4ea30ac7..f54ff0a4 100644 --- a/tests/testthat/test-gefs.R +++ b/tests/testthat/test-gefs.R @@ -8,11 +8,15 @@ lon = -116.2188 var = "Temperature_height_above_ground_ens" test_that("gefs errors", { + #not needed because no web API call is/should be made. + #skip_on_cran() expect_error(gefs(lat=lat, lon=lon), "Need to specify the variable to get. A list of variables is available from gefs_variables().") }) test_that("gefs time and ensemble selection returns correct indices.", { + skip_on_cran() + ens_idx = 2:4 time_idx = 5:10 d = gefs(var, lat, lon, ens_idx = ens_idx, time_idx = time_idx) @@ -23,6 +27,8 @@ test_that("gefs time and ensemble selection returns correct indices.", { }) test_that("gefs metadata", { + skip_on_cran() + today = format(as.Date(Sys.time()) - 1, "%Y%m%d") forecast_time = "0600" d = gefs(var, lat, lon, ens=1, date=today, forecast_time=forecast_time) From 7735e5631950e476d93958b1ba86f1fb15ae6d1e Mon Sep 17 00:00:00 2001 From: Nicholas Potter Date: Wed, 9 Sep 2015 13:30:53 -0700 Subject: [PATCH 3/4] add hard reference to ncdf functions to pass tests. --- R/gefs.R | 5 +++-- man/gefs.Rd | 2 ++ tests/testthat/test-gefs.R | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/R/gefs.R b/R/gefs.R index 7316234e..10e9c36e 100644 --- a/R/gefs.R +++ b/R/gefs.R @@ -17,6 +17,7 @@ #' @param ens_idx sequential list of ensembles to fetch. Default is all 21. Note that the ensembles are labelled 0-20, so ens_idx=1:3 will return ensembles 0, 1, and 2. #' @param time_idx sequential list of time increments to return. List is the index #' of times, which are in 6 hour increments. (e.g. c(1,2) fetches the 6 and 12 hour forecast.) +#' @param dims (not implemented) indices for additional dimensions to be included between lat, lon, ens, and time. #' @param raw logical to indicate whether to return raw data matrix or reshaped data frame. #' @param ... additional parameters passed to \code{ncvar_get}. #' @return a list containing metadata and accompanying data frame of forecast @@ -85,7 +86,7 @@ gefs_CONNECT <- function(date = format(Sys.time(), "%Y%m%d"), #open the connection #nc_open(gefs_url) #ncdf4 version - open.ncdf(gefs_url) + ncdf::open.ncdf(gefs_url) } #' @rdname gefs @@ -140,7 +141,7 @@ gefs_GET <- function(var, lat, lon, # actual data # Do not modify the data, so don't convert (- 273.15) * 1.8 + 32. #convert from K to F #d = ncvar_get(con, v, start = start, count = count_n, ...) #ncdf4 version - d = get.var.ncdf(con, v, start = start, count = count_n, ...) + d = ncdf::get.var.ncdf(con, v, start = start, count = count_n, ...) #create the data frame #For now, if lat/lon are not specified, just return a matrix. diff --git a/man/gefs.Rd b/man/gefs.Rd index 4597c7f8..87912df1 100644 --- a/man/gefs.Rd +++ b/man/gefs.Rd @@ -50,6 +50,8 @@ length of the list.} \item{time_idx}{sequential list of time increments to return. List is the index of times, which are in 6 hour increments. (e.g. c(1,2) fetches the 6 and 12 hour forecast.)} +\item{dims}{(not implemented) indices for additional dimensions to be included between lat, lon, ens, and time.} + \item{raw}{logical to indicate whether to return raw data matrix or reshaped data frame.} \item{con}{an ncdf4 connection.} diff --git a/tests/testthat/test-gefs.R b/tests/testthat/test-gefs.R index f54ff0a4..cbba372e 100644 --- a/tests/testthat/test-gefs.R +++ b/tests/testthat/test-gefs.R @@ -78,7 +78,7 @@ test_that("gefs_dimension_values returns numeric array.", { expect_is(vals, "array") expect_is(vals[1], "numeric") - #expect_error(gefs_dimension_values(dim=NULL), "dim cannot be NULL or missing.") + expect_error(gefs_dimension_values(dim = NULL), "dim cannot be NULL or missing.") }) From 243e76a5c99442e6082dee9c69ffcc0e9ebe1c23 Mon Sep 17 00:00:00 2001 From: Nicholas Potter Date: Wed, 9 Sep 2015 15:02:36 -0700 Subject: [PATCH 4/4] fix example that can give error if 1800UTC forecast is not up yet. Add date for previous day so that the example may be run at any time. Previously the example could give an error if the 1800UTC forecast link was not up yet. --- R/gefs.R | 3 ++- man/gefs.Rd | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/R/gefs.R b/R/gefs.R index 10e9c36e..5047d479 100644 --- a/R/gefs.R +++ b/R/gefs.R @@ -57,8 +57,9 @@ #' #specific ensemble and times, for the 1800 forecast. #' # here ensembles 1-3 (ensembles are numbered starting with 0) #' # and time for 2 days from today at 1800 +#' date=format(as.Date(Sys.time()) - 1, "%Y%m%d") #' var = "Temperature_height_above_ground_ens" -#' gefs(var, lat, lon, forecast_time = "1800", ens_idx=2:4, time_idx=1:8) +#' gefs(var, lat, lon, date = date, forecast_time = "1800", ens_idx=2:4, time_idx=1:8) #' #' #One ensemble, all latitudes and longitudes (this is a big file) for the #' # next 3 days. diff --git a/man/gefs.Rd b/man/gefs.Rd index 87912df1..b671fe46 100644 --- a/man/gefs.Rd +++ b/man/gefs.Rd @@ -98,8 +98,9 @@ forecast_yesterday_prec = gefs("Total_precipitation_surface_6_Hour_Accumulation_ #specific ensemble and times, for the 1800 forecast. # here ensembles 1-3 (ensembles are numbered starting with 0) # and time for 2 days from today at 1800 +date=format(as.Date(Sys.time()) - 1, "\%Y\%m\%d") var = "Temperature_height_above_ground_ens" -gefs(var, lat, lon, forecast_time = "1800", ens_idx=2:4, time_idx=1:8) +gefs(var, lat, lon, date = date, forecast_time = "1800", ens_idx=2:4, time_idx=1:8) #One ensemble, all latitudes and longitudes (this is a big file) for the # next 3 days.