# loadDecadalForecast.R Load a user-defined spatio-temporal slice from decadal forecasts
#
# Copyright (C) 2016 Santander Meteorology Group (http://www.meteo.unican.es)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#' @title Load a grid from a decadal forecast
#' @description Load a user-defined spatio-temporal slice from decadal forecasts
#' @template templateParams
#' @param dictionary Default to TRUE, indicating that a dictionary is used and the .dic file is stored in the same path than the
#' dataset. If the .dic file is stored elsewhere, then the argument is the full path to the .dic file (including the extension,
#' e.g.: \code{"/path/to/the/dictionary_file.dic"}). This is the case for instance when the dataset is stored in a remote URL,
#' and we have a locally stored dictionary for that particular dataset. If FALSE no variable homogenization takes place,
#' and the raw variable, as originally stored in the dataset, will be returned. See details for dictionary specification.
#' @param members Vector of integers indicating the members to be loaded.
#' @param time A character vector indicating the temporal filtering/aggregation
#' of the output data. Default to \code{"none"}, which returns the original time
#' series as stored in the dataset. For sub-daily variables, instantantaneous data at
#' selected verification times can be filtered using one of the character strings
#' \code{"00"}, \code{"03"}, \code{"06"}, \code{"09"}, \code{"12"}, \code{"15"},
#' \code{"18"}, \code{"21"},and \code{"00"} when applicable. If daily aggregated data are
#' required use \code{"DD"}. If the requested variable is static (e.g. orography) it will be ignored.
#' See the next arguments for time aggregation options.
#' @param aggr.d Character string. Function of aggregation of sub-daily data for daily data calculation.
#' Currently accepted values are \code{"none"}, \code{"mean"}, \code{"min"}, \code{"max"} and \code{"sum"}.
#' @param aggr.m Same as \code{aggr.d}, bun indicating the aggregation function to compute monthly from daily data.
#' If \code{aggr.m = "none"} (the default), no monthly aggregation is undertaken.
#'
#' @template templateReturnGridData
#' @template templateDicDetails
#' @template templateGeolocation
#' @export
#' @author J. Bedia, S. Herrera, M. Iturbide, J.M. Gutierrez
#' @family loading.grid
#' @importFrom utils tail
#' @importFrom climate4R.UDG C4R.vocabulary
#' @importFrom rJava J
#'
#' @examples \dontrun{
#' latLim <- c(40,50)
#' lonLim <- c(-5,10)
#' season <- 3:5
#' period <- 1981:1991
#' loginUDG(username = "myuser", password = "mypassword")
#' tasDECA <- loadDecadalForecast(
#' dataset = "http://www.meteo.unican.es/tds5/dodsC/specs/gfdl_specs_decadal.ncml",
#' latLim = latLim,
#' lonLim = lonLim,
#' var = "tas",
#' years = period,
#' season = season)
#' }
loadDecadalForecast <- function(dataset,
var,
dictionary = FALSE,
members = NULL,
lonLim = NULL,
latLim = NULL,
season = NULL,
years = NULL,
time = "none",
aggr.d = "none",
aggr.m = "none") {
time <- match.arg(time, choices = c("none","00","03","06","09","12","15","18","21","DD"))
aggr.d <- match.arg(aggr.d, choices = c("none", "mean", "min", "max", "sum"))
if (time != "DD" & aggr.d != "none") {
aggr.d <- "none"
message("NOTE: Argument 'aggr.d' ignored as 'time' was set to ", time)
}
aggr.m <- match.arg(aggr.m, choices = c("none", "mean", "min", "max", "sum"))
aux.level <- findVerticalLevel(var)
var <- aux.level$var
level <- aux.level$level
if (dictionary == FALSE) {
dic <- NULL
shortName <- var
} else {
if (isTRUE(dictionary)) {
dicPath <- gsub("ncml$", "dic", dataset)
}
if (is.character(dictionary)) {
dicPath <- dictionary
}
dic <- dictionaryLookup(dicPath, var, time)
shortName <- dic$short_name
}
message("[", Sys.time(), "] ", "Opening connection with the UDG...")
gds <- tryCatch(expr = {
J("ucar.nc2.dt.grid.GridDataset")$open(dataset)
}, error = function(e) {
if (grepl("return status=503", e)) {
stop("UDG SERVICE TEMPORARILY UNAVAILABLE\nThe UDG server is temporarily unable to service your request due to maintenance downtime or capacity problems, please try again later.\n
If the problem persists after 24 h please drop a ticket (http://meteo.unican.es/trac/wiki/udg/ecoms)")
} else if (grepl("Unauthorized to open dataset", e)) {
stop("UNAUTHORIZED TO OPEN DATASET\nPlease check your login details in loginECOMS_UDG function.\nIf you don\'t have a valid username/password or OpenID please the UDG Administration Panel (http://www.meteo.unican.es/udg-tap/login)")
}
})
if (is.null(gds)) {
stop("Requested URL not found\nThe problem may be momentary. Try again and if the error persists please drop a ticket (http://meteo.unican.es/trac/wiki/udg/ecoms)")
}
message("[", Sys.time(), "] ", "Connected successfuly")
grid <- gds$findGridByShortName(shortName)
if (is.null(grid)) {
stop("Variable requested not found\nCheck available variables at http://meteo.unican.es/trac/wiki/udg/ecoms/dataserver/catalog")
}
# Forecasts
if (!is.null(members)) {
members <- sort(members)
}
# latLon <- getLatLonDomainForecast(grid, lonLim, latLim)
latLon <- getLatLonDomain(grid, lonLim, latLim)
runTimePars <- getRunTimeDomain.decadal(dataset, grid, members, season, years)
memberRangeList <- getMemberDomain(grid, dataset, members)
foreTimePars <- getForecastTimeDomain(grid, dataset, dic, runTimePars, time, aggr.d, aggr.m)
verticalPars <- getVerticalLevelPars(grid, level)
cube <- makeSubset.decadal(grid, latLon, runTimePars, memberRangeList, foreTimePars, verticalPars)
auxDates <- as.POSIXlt(cube$foreTimePars$forecastDates$start, tz = "GMT")
indMonthValid <- which(is.element(auxDates$mon + 1,season))
if (length(indMonthValid) < dim(cube$mdArray)[grep("^time$", attr(cube$mdArray,"dimensions"))]) {
dimName <- attr(cube$mdArray, "dimensions")
cube$mdArray <- cube$mdArray[,,indMonthValid,]
attr(cube$mdArray, "dimensions") <- dimName
cube$foreTimePars$forecastDates$start <- cube$foreTimePars$forecastDates$start[indMonthValid]
cube$foreTimePars$forecastDates$end <- cube$foreTimePars$forecastDates$end[indMonthValid]
}
foreTimePars <- NULL
if (!is.null(dic)) {
isStandard <- TRUE
cube$mdArray <- dictionaryTransformForecast(dic, cube$mdArray)
# var <- derInterface$origVar
} else {
isStandard <- FALSE
}
if (isTRUE(latLon$revLat)) {
cube$mdArray <- revArrayLatDim(cube$mdArray)
}
# formatting initialization dates
runTimePars$runDates <- format(as.POSIXct(runTimePars$runDates, tz = "GMT"), format = "%Y-%m-%d %H:%M:%S", usetz = TRUE)
Variable <- list("varName" = var, "level" = level)
attr(Variable, "is_standard") <- isStandard
if (isStandard) {
vocabulary <- climate4R.UDG::C4R.vocabulary()
attr(Variable, "units") <- as.character(vocabulary[grep(paste0("^", var, "$"), vocabulary$identifier), 3])
attr(Variable, "longname") <- as.character(vocabulary[grep(paste0("^", var, "$"), vocabulary$identifier), 2])
} else {
attr(Variable, "units") <- grid$getUnitsString()
attr(Variable, "longname") <- grid$getFullName()
}
attr(Variable, "daily_agg_cellfun") <- cube$foreTimePars$aggr.d
attr(Variable, "monthly_agg_cellfun") <- cube$foreTimePars$aggr.m
attr(Variable, "verification_time") <- time
out <- list("Variable" = Variable,
"Data" = cube$mdArray,
"xyCoords" = latLon$xyCoords,
"Dates" = cube$foreTimePars$forecastDates,
"InitializationDates" = runTimePars$runDates,
"Members" = names(memberRangeList))
gds$close()
message("[", Sys.time(), "]", " Done")
# So far lonlat proj is assumed
attr(out$xyCoords, "projection") <- "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0"
# attr(out, "resX") <- (tail(out$xyCoords$x, 1) - out$xyCoords$x[1]) / (length(out$xyCoords$x) - 1)
# attr(out, "resY") <- (tail(out$xyCoords$y, 1) - out$xyCoords$y[1]) / (length(out$xyCoords$y) - 1)
if (length(out$xyCoords$x) > 1){
attr(out$xyCoords, "resX") <- (tail(out$xyCoords$x, 1) - out$xyCoords$x[1]) / (length(out$xyCoords$x) - 1)
} else {
attr(out$xyCoords, "resX") <- latLon$xyCoords$resX
}
if (length(out$xyCoords$y) > 1){
attr(out$xyCoords, "resY") <- (tail(out$xyCoords$y, 1) - out$xyCoords$y[1]) / (length(out$xyCoords$y) - 1)
} else {
attr(out$xyCoords, "resY") <- latLon$xyCoords$resY
}
out$xyCoords["resX"] <- NULL
out$xyCoords["resY"] <- NULL
if("lon" %in% names(out$xyCoords)){
attr(out, "resLON") <- NA
attr(out, "resLAT") <- NA
}
# Dimension ordering
x <- attr(out$Data, "dimensions")
if (length(x) > 1) {
tab <- c("member", "time", "level", "lat", "lon")
b <- na.exclude(match(tab, x))
dimNames <- attr(out$Data, "dimensions")[b]
out$Data <- aperm(out$Data, perm = b)
attr(out$Data, "dimensions") <- dimNames
}
# Source Dataset and other metadata
attr(out, "dataset") <- dataset
attr(out, "source") <- "ECOMS User Data Gateway"
attr(out, "URL") <- "<http://meteo.unican.es/trac/wiki/udg/ecoms>"
return(out)
}
# End
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.