Nothing
#' @title Download future Bioclimatic indicators (BIOs) named CMCC-BioClimInd.
#' @description Parse future CMCC-BioClimInd bioclimatic indicators obtained by
#' different Earth System Models (ESMs) optionally with a setting of boundary
#' and a few other options.
#' @param bry (\code{\link{sf}} or \code{sp}) The boundary to mask the
#' downloaded original data. If \code{NULL}, it would get global map.
#' If not \code{NULL}, it can take \code{\link{sf}}, \code{\link{sfc}},
#' \code{SpatialPolygonsDataFrame}, \code{SpatialPolygons}, etc.
#' The default is \code{NULL}.
#' @param path (\code{character}) The path to save the downloaded imagery.
#' If \code{NULL}, it would use the current working directory.
#' The default is \code{NULL}.
#' @param esm (\code{character}) The option for Earth System Models (ESMs).
#' Should be one of "CMCC-CESM", 'GFDL-ESM2M', 'HadGEM2-ES',
#' 'IPSL-CM5A-LR', 'MIROC-ESM-CHEM', 'NorESM1-M'.
#' The default is CMCC-CESM.
#' @param rcp (\code{numeric}) The option of Representative Concentration
#' Pathways (RCPs).
#' Should be 45 or 85. Only 85 is available for CMCC-CESM. The default is 85.
#' @param interval (\code{character}) The option for time interval.
#' Should be one of "2040-2079", "2060-2099". The default is "2040-2079".
#' @param nm_mark (\code{character}) the name mark of clipped images.
#' The default is "clip". It would be ignored if \code{bry} is \code{NULL}.
#' @param return_stack (\code{logical}) if \code{TRUE}, stack the imagery
#' together and return.
#' If the area is large and resolution is high, it is better not to stack them.
#' The default is \code{TRUE}.
#' @return if \code{return_stack} is \code{TRUE}, the images would be
#' returned as a \code{stars}. Otherwise, nothing to return, but the user
#' would receive a message of where the images are.
#' @references
#' Noce, Sergio, Luca
#' Caporaso, and Monia Santini."A new global dataset of bioclimatic indicators.
#' "\emph{Scientific data} 7.1 (2020): 1-12.\doi{10.1038/s41597-020-00726-5}
#'
#' @details
#' \url{https://doi.pangaea.de/10.1594/PANGAEA.904278?format=html#download}
#'
#' @note The function is experimental at the moment, because the download server
#' of this dataset is not as stable as Worldclim yet. If it fails due to slow
#' internet, try to set a larger timeout option,
#' e.g., using `options(timeout = 1e3)`.
#'
#' @import ncdf4
#' @importFrom raster stack
#' @importFrom sf st_as_sf st_make_valid st_crop
#' @importFrom stars read_stars write_stars st_as_stars st_set_dimensions
#' @importFrom utils tail download.file
#' @importFrom methods is
#' @export
#' @examples
#' \dontrun{
#' library(itsdm)
#' future_cmcc_bioclim(path = tempdir(),
#' esm = 'GFDL-ESM2M', rcp = 45,
#' interval = "2040-2079", return_stack = FALSE)
#'}
#'
future_cmcc_bioclim <- function(bry = NULL,
path = NULL,
esm = 'CMCC-CESM',
rcp = 85,
interval = "2040-2079",
nm_mark = "clip",
return_stack = TRUE) {
# Check the inputs
stopifnot(esm %in% c("CMCC-CESM", 'GFDL-ESM2M', 'HadGEM2-ES',
'IPSL-CM5A-LR', 'MIROC-ESM-CHEM', 'NorESM1-M'))
stopifnot(rcp %in% c(45, 85))
if(esm == "CMCC-CESM" & rcp == 45){
stop("There is no such var to download.")}
stopifnot(interval %in% c("2040-2079", "2060-2099"))
## bry
if (is.null(bry)) {
nm_mark <- 'global'
message("No bry set, download global map.")
} else {
if (!(is(bry, "sf") | is(bry, 'sfc') |
is(bry, "SpatialPolygonsDataFrame") |
is(bry, 'SpatialPolygons'))) {
stop("Only support sf or sp.")
}
}
## path
if (is.null(path)) {
path <- getwd()
} else {
if (!dir.exists(path)) {
stop("Path does not exist!")
}
}
# Set up
## Convert inputs
esm <- switch(esm,
`CMCC-CESM` = "CMCC",
`GFDL-ESM2M` = "GFDL",
`HadGEM2-ES` = "HADGEM",
`IPSL-CM5A-LR` = 'IPSL',
`MIROC-ESM-CHEM` = 'MIROC',
`NorESM1-M` = 'NORESM')
interval <- switch(interval,
`2040-2079` = '2040_79',
`2060-2099` = '2060_99')
## Path
path <- file.path(path, "cmcc_bioclim")
dir.create(path, showWarnings = FALSE)
# Download and extract historical variables
url_base <- "https://hs.pangaea.de/model/NoceS-etal_2019"
invisible(lapply(paste0('BIO', 1:35), function(var){
if (!file.exists(
sprintf("%s/%s_%s_%s_%s.nc",
path, var, esm, rcp, interval))){
zip_name <- sprintf("%s.zip", var)
url <- file.path(url_base, zip_name)
# Download to local
temp <- tempfile()
dl <- try(download.file(url, temp))
if (inherits(dl, "try-error")) {
Sys.sleep(10)
download.file(url, temp)
}
# Extract hist file from downloaded zip
decompression <- system2(
"unzip",
args = c("-j", "-o", temp,
sprintf("%s_%s_%s_%s.nc",
var, esm, rcp, interval),
sprintf("-d %s", path)),
stdout = TRUE)
if (grepl("Warning message", tail(decompression, 1))) {
print(decompression)
}
unlink(temp)
}
}))
####################################################
############## Deal with BIO18 #####################
imgs_in <- list.files(path, pattern = "*.nc", full.names = T)
imgs <- file.path(
path, sprintf("BIO%s_%s_%s_%s.nc", 1:35, esm, rcp, interval))
if (any(c('BIO18_CMCC_85_2040_79.nc',
'BIO18_GFDL_45_2040_79.nc',
'BIO18_GFDL_45_2060_99.nc',
'BIO18_GFDL_85_2040_79.nc',
'BIO18_GFDL_85_2060_99.nc',
'BIO18_HADGEM_85_2060_99.nc') %in%
basename(imgs))) {
warning('BIO18 does not have such product, skip it.')
# Remove it and check
imgs <- file.path(
path, sprintf("BIO%s_%s_%s_%s.nc", c(1:17, 19:35),
esm, rcp, interval))
if (length(intersect(imgs, imgs_in)) != 34) {
stop("Wrong file numbers unzipped.")}
# Read imgs
clip_imgs <- stack(imgs) %>% st_as_stars()
clip_imgs <- st_set_dimensions(
clip_imgs, 'band', values = paste0('bio', c(1:17, 19:35)))
} else {
if (length(intersect(imgs, imgs_in)) != 35) {
stop("Wrong file numbers unzipped.")}
# Read files
clip_imgs <- stack(imgs) %>% st_as_stars()
clip_imgs <- st_set_dimensions(
clip_imgs, 'band', values = paste0('bio', 1:35))
}
####################################################
####################################################
################ Original code #####################
# ## Check unzipped files
# imgs_in <- list.files(path, pattern = "*.nc", full.names = T)
# imgs <- file.path(
# path, sprintf("BIO%s_%s_%s_%s.nc", 1:35, esm, rcp, interval))
#
# if (length(intersect(imgs, imgs_in)) != 35) {
# stop("Wrong file numbers unzipped.")}
#
# # Read files
# clip_imgs <- stack(imgs) %>% st_as_stars()
# clip_imgs <- st_set_dimensions(
# clip_imgs, 'band', values = paste0('bio', 1:35))
####################################################
names(clip_imgs) <- sprintf('bioclim_%s_%s_%s',
esm, rcp, interval)
if (!is.null(bry)) {
# Read files
bry <- st_as_sf(bry) %>% st_make_valid()
clip_imgs <- st_crop(clip_imgs, bry)
}
## Save out
rst_name <- paste(nm_mark,
sprintf('bioclim_%s_%s_%s.tif', esm, rcp, interval),
sep = '_')
rst_path <- file.path(path, rst_name)
write_stars(clip_imgs, rst_path)
# Clean temporary files
unlink(imgs)
# Return
if (return_stack == TRUE) {
clip_imgs
} else {
message(sprintf("Files are written to %s.", path))
}
}
# future_cmcc_bioclim end
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.