diff --git a/R/AMV.R b/R/AMV.R index 1895fa6d9949f1cda46979f78c68b51ee2e63ac9..a51a819def8e8b163e10b01eb36cad4673692b13 100644 --- a/R/AMV.R +++ b/R/AMV.R @@ -6,13 +6,13 @@ #'time scales. The AMV index is computed as the difference of weighted-averaged #'SST anomalies over the North Atlantic region (0ºN-60ºN, 280ºE-360ºE) and the #'weighted-averaged SST anomalies over 60ºS-60ºN, 0ºE-360ºE (Trenberth & -#'Dennis, 2005; Doblas-Reyes et al., 2013). +#'Dennis, 2005; Doblas-Reyes et al., 2013). If different members and/or datasets are provided, +#'the climatology (used to calculate the anomalies) is computed individually for all of them. #' -#'@param data A numerical array to be used for the index computation with the -#' dimensions: 1) latitude, longitude, start date, forecast month, and member -#' (in case of decadal predictions), 2) latitude, longitude, year, month and -#' member (in case of historical simulations), or 3) latitude, longitude, year -#' and month (in case of observations or reanalyses). This data has to be +#'@param data A numerical array to be used for the index computation with, at least, the +#' dimensions: 1) latitude, longitude, start date and forecast month +#' (in case of decadal predictions), 2) latitude, longitude, year and month +#' (in case of historical simulations or observations). This data has to be #' provided, at least, over the whole region needed to compute the index. #'@param data_lats A numeric vector indicating the latitudes of the data. #'@param data_lons A numeric vector indicating the longitudes of the data. @@ -45,23 +45,22 @@ #' anomalies, set it to FALSE. The default value is NULL.\cr #' In case of parameter 'type' is 'dcpp', 'indices_for_clim' must be relative #' to the first forecast year, and the climatology is automatically computed -#' over the actual common period for the different forecast years. +#' over the common calendar period for the different forecast years. #'@param year_dim A character string indicating the name of the year dimension #' The default value is 'year'. Only used if parameter 'type' is 'hist' or #' 'obs'. #'@param month_dim A character string indicating the name of the month #' dimension. The default value is 'month'. Only used if parameter 'type' is #' 'hist' or 'obs'. -#'@param member_dim A character string indicating the name of the member -#' dimension. The default value is 'member'. Only used if parameter 'type' is -#' 'dcpp' or 'hist'. +#'@param na.rm A logical value indicanting whether to remove NA values. The default +#' value is TRUE. #'@param ncores An integer indicating the number of cores to use for parallel #' computation. The default value is NULL. #' -#'@return A numerical array of the AMV index with the dimensions of: -#' 1) sdate, forecast year, and member (in case of decadal predictions); -#' 2) year and member (in case of historical simulations); or -#' 3) year (in case of observations or reanalyses). +#'@return A numerical array with the AMV index with the same dimensions as data except +#' the lat_dim, lon_dim and fmonth_dim (month_dim) in case of decadal predictions +#' (historical simulations or observations). In case of decadal predictions, a new dimension +#' 'fyear' is added. #' #'@examples #' ## Observations or reanalyses @@ -88,7 +87,7 @@ AMV <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'lon', mask = NULL, monini = 11, fmonth_dim = 'fmonth', sdate_dim = 'sdate', indices_for_clim = NULL, year_dim = 'year', month_dim = 'month', - member_dim = 'member', ncores = NULL) { + na.rm = TRUE, ncores = NULL) { ## Input Checks # data @@ -209,16 +208,11 @@ AMV <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'lo stop("Parameter 'month_dim' is not found in 'data' dimension.") } } - # member_dim - if (type == 'hist' | type == 'dcpp') { - if (!(is.character(member_dim) & length(member_dim) == 1)) { - stop("Parameter 'member_dim' must be a character string.") - } - if (!member_dim %in% names(dim(data))) { - stop("Parameter 'member_dim' is not found in 'data' dimension.") - } + # na.rm + if (!na.rm %in% c(TRUE,FALSE)) { + stop("Parameter 'na.rm' must be TRUE or FALSE") } - + ## Regions for AMV (Doblas-Reyes et al., 2013) lat_min_1 <- 0; lat_max_1 <- 60 lon_min_1 <- 280; lon_max_1 <- 359.9 @@ -239,9 +233,16 @@ AMV <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'lo data <- ClimProjDiags::CombineIndices(indices = list(mean_1,mean_2), weights = NULL, operation = 'subtract') # (mean_1 - mean_2) - INDEX <- .Indices(data = data, type = type, monini = monini, - indices_for_clim = indices_for_clim, fmonth_dim = fmonth_dim, - sdate_dim = sdate_dim, year_dim = year_dim, - month_dim = month_dim, member_dim = member_dim) + if (type == 'dcpp'){ + target_dims <- c(sdate_dim, fmonth_dim) + } else if (type %in% c('hist','obs')){ + target_dims <- c(year_dim, month_dim) + } + + INDEX <- multiApply::Apply(data = data, target_dims = target_dims, fun = .Indices, + type = type, monini = monini, indices_for_clim = indices_for_clim, + fmonth_dim = fmonth_dim, sdate_dim = sdate_dim, + year_dim = year_dim, month_dim = month_dim, + na.rm = na.rm, ncores = ncores)$output1 return(INDEX) } diff --git a/R/GMST.R b/R/GMST.R index 4a0193a78028f1e4679ee922bf2ef6009b68b033..a1d8d85dc7cb0e1e5823e006c95add74a9089591 100644 --- a/R/GMST.R +++ b/R/GMST.R @@ -2,24 +2,23 @@ #' #'The Global Mean Surface Temperature (GMST) anomalies are computed as the #'weighted-averaged surface air temperature anomalies over land and sea surface -#'temperature anomalies over the ocean. +#'temperature anomalies over the ocean. If different members and/or datasets are provided, +#'the climatology (used to calculate the anomalies) is computed individually for all of them. #' -#'@param data_tas A numerical array indicating the surface air temperature data -#' to be used for the index computation with the dimensions: 1) latitude, -#' longitude, start date, forecast month, and member (in case of decadal -#' predictions), 2) latitude, longitude, year, month and member (in case of -#' historical simulations), or 3) latitude, longitude, year and month (in case -#' of observations or reanalyses). This data has to be provided, at least, -#' over the whole region needed to compute the index. The dimensions must be -#' identical to those of data_tos. -#'@param data_tos A numerical array indicating the sea surface temperature data -#' to be used for the index computation with the dimensions: 1) latitude, -#' longitude, start date, forecast month, and member (in case of decadal -#' predictions), 2) latitude, longitude, year, month and member (in case of -#' historical simulations), or 3) latitude, longitude, year and month (in case -#' of observations or reanalyses). This data has to be provided, at least, -#' over the whole region needed to compute the index. The dimensions must be -#' identical to those of data_tas. +#'@param data_tas A numerical array with the surface air temperature data +#' to be used for the index computation with, at least, the +#' dimensions: 1) latitude, longitude, start date and forecast month +#' (in case of decadal predictions), 2) latitude, longitude, year and month +#' (in case of historical simulations or observations). This data has to be +#' provided, at least, over the whole region needed to compute the index. +#' The dimensions must be identical to thos of data_tos. +#' #'@param data_tos A numerical array with the sea surface temperature data +#' to be used for the index computation with, at least, the +#' dimensions: 1) latitude, longitude, start date and forecast month +#' (in case of decadal predictions), 2) latitude, longitude, year and month +#' (in case of historical simulations or observations). This data has to be +#' provided, at least, over the whole region needed to compute the index. +#' The dimensions must be identical to thos of data_tas. #'@param data_lats A numeric vector indicating the latitudes of the data. #'@param data_lons A numeric vector indicating the longitudes of the data. #'@param mask_sea_land An array with dimensions [lat_dim = data_lats, lon_dim = @@ -55,23 +54,22 @@ #' anomalies, set it to FALSE. The default value is NULL.\cr #' In case of parameter 'type' is 'dcpp', 'indices_for_clim' must be relative #' to the first forecast year, and the climatology is automatically computed -#' over the actual common period for the different forecast years. +#' over the common calendar period for the different forecast years. #'@param year_dim A character string indicating the name of the year dimension #' The default value is 'year'. Only used if parameter 'type' is 'hist' or #' 'obs'. #'@param month_dim A character string indicating the name of the month #' dimension. The default value is 'month'. Only used if parameter 'type' is #' 'hist' or 'obs'. -#'@param member_dim A character string indicating the name of the member -#' dimension. The default value is 'member'. Only used if parameter 'type' is -#' 'dcpp' or 'hist'. +#'@param na.rm A logical value indicanting whether to remove NA values. The default +#' value is TRUE. #'@param ncores An integer indicating the number of cores to use for parallel #' computation. The default value is NULL. #' -#'@return A numerical array of the GMST anomalies with the dimensions of: -#' 1) sdate, forecast year, and member (in case of decadal predictions); -#' 2) year and member (in case of historical simulations); or -#' 3) year (in case of observations or reanalyses). +#'@return A numerical array with the GMST anomalies with the same dimensions as data_tas except +#' the lat_dim, lon_dim and fmonth_dim (month_dim) in case of decadal predictions +#' (historical simulations or observations). In case of decadal predictions, a new dimension +#' 'fyear' is added. #' #'@examples #' ## Observations or reanalyses @@ -113,7 +111,7 @@ GMST <- function(data_tas, data_tos, data_lats, data_lons, mask_sea_land, sea_value, type, mask = NULL, lat_dim = 'lat', lon_dim = 'lon', monini = 11, fmonth_dim = 'fmonth', sdate_dim = 'sdate', indices_for_clim = NULL, - year_dim = 'year', month_dim = 'month', member_dim = 'member', ncores = NULL) { + year_dim = 'year', month_dim = 'month', na.rm = TRUE, ncores = NULL) { ## Input Checks # data_tas and data_tos @@ -236,14 +234,9 @@ GMST <- function(data_tas, data_tos, data_lats, data_lons, mask_sea_land, sea_va stop("Parameter 'month_dim' is not found in 'data_tas' or 'data_tos' dimension.") } } - # member_dim - if (type == 'hist' | type == 'dcpp') { - if (!(is.character(member_dim) & length(member_dim) == 1)) { - stop("Parameter 'member_dim' must be a character string.") - } - if (!member_dim %in% names(dim(data_tas)) | !member_dim %in% names(dim(data_tos))) { - stop("Parameter 'member_dim' is not found in 'data_tas' or 'data_tos' dimension.") - } + # na.rm + if (!na.rm %in% c(TRUE,FALSE)) { + stop("Parameter 'na.rm' must be TRUE or FALSE") } # ncores if (!is.null(ncores)) { @@ -253,7 +246,6 @@ GMST <- function(data_tas, data_tos, data_lats, data_lons, mask_sea_land, sea_va } } - ## combination of tas and tos (data) mask_tas_tos <- function(data_tas, data_tos, mask_sea_land, sea_value) { data <- data_tas @@ -284,9 +276,16 @@ GMST <- function(data_tas, data_tos, data_lats, data_lons, mask_sea_land, sea_va londim = which(names(dim(data)) == lon_dim), latdim = which(names(dim(data)) == lat_dim)) - INDEX <- .Indices(data = data, type = type, monini = monini, - indices_for_clim = indices_for_clim, fmonth_dim = fmonth_dim, - sdate_dim = sdate_dim, year_dim = year_dim, - month_dim = month_dim, member_dim = member_dim) + if (type == 'dcpp'){ + target_dims <- c(sdate_dim, fmonth_dim) + } else if (type %in% c('hist','obs')){ + target_dims <- c(year_dim, month_dim) + } + + INDEX <- multiApply::Apply(data = data, target_dims = target_dims, fun = .Indices, + type = type, monini = monini, indices_for_clim = indices_for_clim, + fmonth_dim = fmonth_dim, sdate_dim = sdate_dim, + year_dim = year_dim, month_dim = month_dim, + na.rm = na.rm, ncores = ncores)$output1 return(INDEX) } diff --git a/R/GSAT.R b/R/GSAT.R index 0c50a3460eac5d06112c7edf20483163831bf16d..1774bd684533081137b75961907dac3750ad9a21 100644 --- a/R/GSAT.R +++ b/R/GSAT.R @@ -1,13 +1,14 @@ #'Compute the Global Surface Air Temperature (GSAT) anomalies #' #'The Global Surface Air Temperature (GSAT) anomalies are computed as the -#'weighted-averaged surface air temperature anomalies over the global region. +#'weighted-averaged surface air temperature anomalies over the global region. +#'If different members and/or datasets are provided, the climatology (used to +#'calculate the anomalies) is computed individually for all of them. #' -#'@param data A numerical array to be used for the index computation with the -#' dimensions: 1) latitude, longitude, start date, forecast month, and member -#' (in case of decadal predictions), 2) latitude, longitude, year, month and -#' member (in case of historical simulations), or 3) latitude, longitude, year -#' and month (in case of observations or reanalyses). This data has to be +#'@param data A numerical array to be used for the index computation with, at least, the +#' dimensions: 1) latitude, longitude, start date and forecast month +#' (in case of decadal predictions), 2) latitude, longitude, year and month +#' (in case of historical simulations or observations). This data has to be #' provided, at least, over the whole region needed to compute the index. #'@param data_lats A numeric vector indicating the latitudes of the data. #'@param data_lons A numeric vector indicating the longitudes of the data. @@ -40,23 +41,22 @@ #' anomalies, set it to FALSE. The default value is NULL.\cr #' In case of parameter 'type' is 'dcpp', 'indices_for_clim' must be relative #' to the first forecast year, and the climatology is automatically computed -#' over the actual common period for the different forecast years. +#' over the common calendar period for the different forecast years. #'@param year_dim A character string indicating the name of the year dimension #' The default value is 'year'. Only used if parameter 'type' is 'hist' or #' 'obs'. #'@param month_dim A character string indicating the name of the month #' dimension. The default value is 'month'. Only used if parameter 'type' is #' 'hist' or 'obs'. -#'@param member_dim A character string indicating the name of the member -#' dimension. The default value is 'member'. Only used if parameter 'type' is -#' 'dcpp' or 'hist'. +#'@param na.rm A logical value indicanting whether to remove NA values. The default +#' value is TRUE. #'@param ncores An integer indicating the number of cores to use for parallel #' computation. The default value is NULL. #' -#'@return A numerical array of the GSAT anomalies with the dimensions of: -#' 1) sdate, forecast year, and member (in case of decadal predictions); -#' 2) year and member (in case of historical simulations); or -#' 3) year (in case of observations or reanalyses). +#'@return A numerical array with the GSAT anomalies with the same dimensions as data except +#' the lat_dim, lon_dim and fmonth_dim (month_dim) in case of decadal predictions +#' (historical simulations or observations). In case of decadal predictions, a new dimension +#' 'fyear' is added. #' #'@examples #' ## Observations or reanalyses @@ -83,7 +83,7 @@ GSAT <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'lon', mask = NULL, monini = 11, fmonth_dim = 'fmonth', sdate_dim = 'sdate', indices_for_clim = NULL, year_dim = 'year', month_dim = 'month', - member_dim = 'member', ncores = NULL) { + na.rm = TRUE, ncores = NULL) { ## Input Checks # data @@ -204,14 +204,9 @@ GSAT <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'l stop("Parameter 'month_dim' is not found in 'data' dimension.") } } - # member_dim - if (type == 'hist' | type == 'dcpp') { - if (!(is.character(member_dim) & length(member_dim) == 1)) { - stop("Parameter 'member_dim' must be a character string.") - } - if (!member_dim %in% names(dim(data))) { - stop("Parameter 'member_dim' is not found in 'data' dimension.") - } + # na.rm + if (!na.rm %in% c(TRUE,FALSE)) { + stop("Parameter 'na.rm' must be TRUE or FALSE") } data <- ClimProjDiags::WeightedMean(data = data, lon = data_lons, lat = data_lats, @@ -219,9 +214,16 @@ GSAT <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'l londim = which(names(dim(data)) == lon_dim), latdim = which(names(dim(data)) == lat_dim)) - INDEX <- .Indices(data = data, type = type, monini = monini, - indices_for_clim = indices_for_clim, fmonth_dim = fmonth_dim, - sdate_dim = sdate_dim, year_dim = year_dim, - month_dim = month_dim, member_dim = member_dim) + if (type == 'dcpp'){ + target_dims <- c(sdate_dim, fmonth_dim) + } else if (type %in% c('hist','obs')){ + target_dims <- c(year_dim, month_dim) + } + + INDEX <- multiApply::Apply(data = data, target_dims = target_dims, fun = .Indices, + type = type, monini = monini, indices_for_clim = indices_for_clim, + fmonth_dim = fmonth_dim, sdate_dim = sdate_dim, + year_dim = year_dim, month_dim = month_dim, + na.rm = na.rm, ncores = ncores)$output1 return(INDEX) } diff --git a/R/SPOD.R b/R/SPOD.R index 5e8812d4561289bd7508b6962202f8619b6b50c7..51717b31ee05cedb757347e3bcf7b02ba644c75b 100644 --- a/R/SPOD.R +++ b/R/SPOD.R @@ -4,13 +4,14 @@ #'Nino-Southern Oscillation (ENSO) and the Inderdecadal Pacific Oscillation #'(IPO). The SPOD index is computed as the difference of weighted-averaged SST #'anomalies over 20ºS-48ºS, 165ºE-190ºE (NW pole) and the weighted-averaged SST -#' anomalies over 44ºS-65ºS, 220ºE-260ºE (SE pole) (Saurral et al., 2020). +#'anomalies over 44ºS-65ºS, 220ºE-260ºE (SE pole) (Saurral et al., 2020). +#'If different members and/or datasets are provided, the climatology (used to +#'calculate the anomalies) is computed individually for all of them. #' -#'@param data A numerical array to be used for the index computation with the -#' dimensions: 1) latitude, longitude, start date, forecast month, and member -#' (in case of decadal predictions), 2) latitude, longitude, year, month and -#' member (in case of historical simulations), or 3) latitude, longitude, year -#' and month (in case of observations or reanalyses). This data has to be +#'@param data A numerical array to be used for the index computation with, at least, the +#' dimensions: 1) latitude, longitude, start date and forecast month +#' (in case of decadal predictions), 2) latitude, longitude, year and month +#' (in case of historical simulations or observations). This data has to be #' provided, at least, over the whole region needed to compute the index. #'@param data_lats A numeric vector indicating the latitudes of the data. #'@param data_lons A numeric vector indicating the longitudes of the data. @@ -43,23 +44,22 @@ #' anomalies, set it to FALSE. The default value is NULL.\cr #' In case of parameter 'type' is 'dcpp', 'indices_for_clim' must be relative #' to the first forecast year, and the climatology is automatically computed -#' over the actual common period for the different forecast years. +#' over the common calendar period for the different forecast years. #'@param year_dim A character string indicating the name of the year dimension #' The default value is 'year'. Only used if parameter 'type' is 'hist' or #' 'obs'. #'@param month_dim A character string indicating the name of the month #' dimension. The default value is 'month'. Only used if parameter 'type' is #' 'hist' or 'obs'. -#'@param member_dim A character string indicating the name of the member -#' dimension. The default value is 'member'. Only used if parameter 'type' is -#' 'dcpp' or 'hist'. +#'@param na.rm A logical value indicanting whether to remove NA values. The default +#' value is TRUE. #'@param ncores An integer indicating the number of cores to use for parallel #' computation. The default value is NULL. #' -#'@return A numerical array of the SPOD index with the dimensions of: -#' 1) sdate, forecast year, and member (in case of decadal predictions); -#' 2) year and member (in case of historical simulations); or -#' 3) year (in case of observations or reanalyses). +#'@return A numerical array with the SPOD index with the same dimensions as data except +#' the lat_dim, lon_dim and fmonth_dim (month_dim) in case of decadal predictions +#' (historical simulations or observations). In case of decadal predictions, a new dimension +#' 'fyear' is added. #' #'@examples #' ## Observations or reanalyses @@ -86,7 +86,7 @@ SPOD <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'lon', mask = NULL, monini = 11, fmonth_dim = 'fmonth', sdate_dim = 'sdate', indices_for_clim = NULL, year_dim = 'year', month_dim = 'month', - member_dim = 'member', ncores = NULL) { + na.rm = TRUE, ncores = NULL) { ## Input Checks # data @@ -207,14 +207,9 @@ SPOD <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'l stop("Parameter 'month_dim' is not found in 'data' dimension.") } } - # member_dim - if (type == 'hist' | type == 'dcpp') { - if (!(is.character(member_dim) & length(member_dim) == 1)) { - stop("Parameter 'member_dim' must be a character string.") - } - if (!member_dim %in% names(dim(data))) { - stop("Parameter 'member_dim' is not found in 'data' dimension.") - } + # na.rm + if (!na.rm %in% c(TRUE,FALSE)) { + stop("Parameter 'na.rm' must be TRUE or FALSE") } ## Regions for IPO_SPOD (Saurral et al., 2020) @@ -238,9 +233,16 @@ SPOD <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'l data <- ClimProjDiags::CombineIndices(indices = list(mean_1,mean_2), weights = NULL, operation = 'subtract') # (mean_1 - mean_2) - INDEX <- .Indices(data = data, type = type, monini = monini, - indices_for_clim = indices_for_clim, fmonth_dim = fmonth_dim, - sdate_dim = sdate_dim, year_dim = year_dim, - month_dim = month_dim, member_dim = member_dim) + if (type == 'dcpp'){ + target_dims <- c(sdate_dim, fmonth_dim) + } else if (type %in% c('hist','obs')){ + target_dims <- c(year_dim, month_dim) + } + + INDEX <- multiApply::Apply(data = data, target_dims = target_dims, fun = .Indices, + type = type, monini = monini, indices_for_clim = indices_for_clim, + fmonth_dim = fmonth_dim, sdate_dim = sdate_dim, + year_dim = year_dim, month_dim = month_dim, + na.rm = na.rm, ncores = ncores)$output1 return(INDEX) } diff --git a/R/TPI.R b/R/TPI.R index e127ab1ccdae8347958eb92e97e827b98dc87a65..80d958ea2fb27d20acbceb26f0f4a00e29ba0f3d 100644 --- a/R/TPI.R +++ b/R/TPI.R @@ -3,13 +3,14 @@ #'The Tripole Index (TPI) for the Interdecadal Pacific Oscillation (IPO) is #'computed as the difference of weighted-averaged SST anomalies over 10ºS-10ºN, #'170ºE-270ºE minus the mean of the weighted-averaged SST anomalies over -#'25ºN-45ºN, 140ºE-215ºE and 50ºS-15ºS, 150ºE-200ºE (Henley et al., 2015). +#'25ºN-45ºN, 140ºE-215ºE and 50ºS-15ºS, 150ºE-200ºE (Henley et al., 2015). +#'If different members and/or datasets are provided, the climatology (used to +#'calculate the anomalies) is computed individually for all of them. #' -#'@param data A numerical array to be used for the index computation with the -#' dimensions: 1) latitude, longitude, start date, forecast month, and member -#' (in case of decadal predictions), 2) latitude, longitude, year, month and -#' member (in case of historical simulations), or 3) latitude, longitude, year -#' and month (in case of observations or reanalyses). This data has to be +#'@param data A numerical array to be used for the index computation with, at least, the +#' dimensions: 1) latitude, longitude, start date and forecast month +#' (in case of decadal predictions), 2) latitude, longitude, year and month +#' (in case of historical simulations or observations). This data has to be #' provided, at least, over the whole region needed to compute the index. #'@param data_lats A numeric vector indicating the latitudes of the data. #'@param data_lons A numeric vector indicating the longitudes of the data. @@ -42,23 +43,22 @@ #' anomalies, set it to FALSE. The default value is NULL.\cr #' In case of parameter 'type' is 'dcpp', 'indices_for_clim' must be relative #' to the first forecast year, and the climatology is automatically computed -#' over the actual common period for the different forecast years. +#' over the common calendar period for the different forecast years. #'@param year_dim A character string indicating the name of the year dimension #' The default value is 'year'. Only used if parameter 'type' is 'hist' or #' 'obs'. #'@param month_dim A character string indicating the name of the month #' dimension. The default value is 'month'. Only used if parameter 'type' is #' 'hist' or 'obs'. -#'@param member_dim A character string indicating the name of the member -#' dimension. The default value is 'member'. Only used if parameter 'type' is -#' 'dcpp' or 'hist'. +#'@param na.rm A logical value indicanting whether to remove NA values. The default +#' value is TRUE. #'@param ncores An integer indicating the number of cores to use for parallel #' computation. The default value is NULL. #' -#'@return A numerical array of the TPI index with the dimensions of: -#' 1) sdate, forecast year, and member (in case of decadal predictions); -#' 2) year and member (in case of historical simulations); or -#' 3) year (in case of observations or reanalyses). +#'@return A numerical array with the TPI index with the same dimensions as data except +#' the lat_dim, lon_dim and fmonth_dim (month_dim) in case of decadal predictions +#' (historical simulations or observations). In case of decadal predictions, a new dimension +#' 'fyear' is added. #' #'@examples #' ## Observations or reanalyses @@ -85,7 +85,7 @@ TPI <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'lon', mask = NULL, monini = 11, fmonth_dim = 'fmonth', sdate_dim = 'sdate', indices_for_clim = NULL, year_dim = 'year', month_dim = 'month', - member_dim = 'member', ncores = NULL) { + na.rm = TRUE, ncores = NULL) { ## Input Checks # data @@ -206,14 +206,9 @@ TPI <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'lo stop("Parameter 'month_dim' is not found in 'data' dimension.") } } - # member_dim - if (type == 'hist' | type == 'dcpp') { - if (!(is.character(member_dim) & length(member_dim) == 1)) { - stop("Parameter 'member_dim' must be a character string.") - } - if (!member_dim %in% names(dim(data))) { - stop("Parameter 'member_dim' is not found in 'data' dimension.") - } + # na.rm + if (!na.rm %in% c(TRUE,FALSE)) { + stop("Parameter 'na.rm' must be TRUE or FALSE") } # Regions for IPO_TPI (psl.noaa.gov/data/timeseries/IPOTPI) @@ -247,9 +242,16 @@ TPI <- function(data, data_lats, data_lons, type, lat_dim = 'lat', lon_dim = 'lo data <- ClimProjDiags::CombineIndices(indices = list(mean_2, mean_1_3), weights = NULL, operation = 'subtract') # mean_2 - ((mean_1 + mean_3)/2) - INDEX <- .Indices(data = data, type = type, monini = monini, - indices_for_clim = indices_for_clim, fmonth_dim = fmonth_dim, - sdate_dim = sdate_dim, year_dim = year_dim, - month_dim = month_dim, member_dim = member_dim) + if (type == 'dcpp'){ + target_dims <- c(sdate_dim, fmonth_dim) + } else if (type %in% c('hist','obs')){ + target_dims <- c(year_dim, month_dim) + } + + INDEX <- multiApply::Apply(data = data, target_dims = target_dims, fun = .Indices, + type = type, monini = monini, indices_for_clim = indices_for_clim, + fmonth_dim = fmonth_dim, sdate_dim = sdate_dim, + year_dim = year_dim, month_dim = month_dim, + na.rm = na.rm, ncores = ncores)$output1 return(INDEX) } diff --git a/R/Utils.R b/R/Utils.R index 6e781e1a9d0d527db76b5bea8f3a875e7e686c15..03439dd9510e0c6b6c4f0b45c37fbc2de11d2bbd 100644 --- a/R/Utils.R +++ b/R/Utils.R @@ -1670,107 +1670,58 @@ } # to be used in AMV.R, TPI.R, SPOD.R, GSAT.R and GMST.R -.Indices <- function(data, type, monini, indices_for_clim, - fmonth_dim, sdate_dim, year_dim, month_dim, member_dim) { +.Indices <- function(data, type, monini, indices_for_clim, + fmonth_dim, sdate_dim, year_dim, month_dim, na.rm) { - data = drop(data) - - if(member_dim %in% names(dim(data))){ - if (type == 'dcpp'){ - data = s2dv::Reorder(data = data, order = c(sdate_dim,fmonth_dim,member_dim)) - } else if (type %in% c('hist','obs')){ - data = s2dv::Reorder(data = data, order = c(year_dim,month_dim,member_dim)) - } - } - - if (type == 'dcpp'){ + if (type == 'dcpp') { - data = s2dv::Season(data = data, time_dim = fmonth_dim, - monini = monini, moninf = 1, monsup = 12, - method = mean, na.rm = FALSE) - names(dim(data))[which(names(dim(data))==fmonth_dim)] = 'fyear' - if (member_dim %in% names(dim(data))){ - data = s2dv::Reorder(data = data, order = c('fyear',sdate_dim,member_dim)) - } else { - data = s2dv::Reorder(data = data, order = c('fyear',sdate_dim)) - } + fyear_dim <- 'fyear' + data <- s2dv::Season(data = data, time_dim = fmonth_dim, + monini = monini, moninf = 1, monsup = 12, + method = mean, na.rm = na.rm) + names(dim(data))[which(names(dim(data))==fmonth_dim)] <- fyear_dim - if (is.logical(indices_for_clim)) { - if(!any(indices_for_clim)) { - # indices_for_clim == FALSE -> anomalies are directly given - anom = data - } + if (identical(indices_for_clim, FALSE)) { ## data is already anomalies - } else { - - ## Different indices_for_clim for each forecast year (same actual years) + anom <- data - n_fyears = as.numeric(dim(data)['fyear']) - n_sdates = as.numeric(dim(data)[sdate_dim]) + } else { ## Different indices_for_clim for each forecast year (to use the same calendar years) - if (is.null(indices_for_clim)){ - - # indices_for_clim == NULL -> anomalies based on the whole (common) period - first_years_for_clim = n_fyears : 1 - last_years_for_clim = n_sdates : (n_sdates - n_fyears + 1) - - } else { - - first_years_for_clim = seq(from = indices_for_clim[1], by = -1, length.out = n_fyears) - last_years_for_clim = seq(from = indices_for_clim[length(indices_for_clim)], by = -1, length.out = n_fyears) - - } - - anom = array(data = NA, dim = dim(data)) - if (member_dim %in% names(dim(data))){ - clim = array(data = NA, dim = c(dim(data)['fyear'],dim(data)[member_dim])) - } else { - clim = array(data = NA, dim = c(dim(data)['fyear'])) + n_fyears <- as.numeric(dim(data)[fyear_dim]) + n_sdates <- as.numeric(dim(data)[sdate_dim]) + + if (is.null(indices_for_clim)) { ## climatology over the whole (common) period + first_years_for_clim <- n_fyears : 1 + last_years_for_clim <- n_sdates : (n_sdates - n_fyears + 1) + } else { ## indices_for_clim specified as a numeric vector + first_years_for_clim <- seq(from = indices_for_clim[1], by = -1, length.out = n_fyears) + last_years_for_clim <- seq(from = indices_for_clim[length(indices_for_clim)], by = -1, length.out = n_fyears) } - for (i in 1:n_fyears){ - if (member_dim %in% names(dim(data))){ - for (m in 1:as.numeric(dim(data)[member_dim])){ - clim[i,m] = mean(data[i,first_years_for_clim[i]:last_years_for_clim[i],m]) - anom[i,,m] = data[i,,m] - clim[i,m] - } - } else { - clim = mean(data[i,first_years_for_clim[i]:last_years_for_clim[i]]) - anom[i,] = data[i,] - clim - } + + data <- s2dv::Reorder(data = data, order = c(fyear_dim, sdate_dim)) + anom <- array(data = NA, dim = dim(data)) + for (i in 1:n_fyears) { + clim <- mean(data[i,first_years_for_clim[i]:last_years_for_clim[i]], na.rm = na.rm) + anom[i,] <- data[i,] - clim } } - } else if (type %in% c('obs','hist')){ + } else if (type %in% c('obs','hist')) { - data = multiApply::Apply(data = data, target_dims = month_dim, fun = mean)$output1 + data <- multiApply::Apply(data = data, target_dims = month_dim, fun = mean, na.rm = na.rm)$output1 - if (is.logical(indices_for_clim)) { - if(!any(indices_for_clim)) { - anom = data - } - - } else { - - if (is.null(indices_for_clim)){ - - clim = multiApply::Apply(data = data, target_dims = year_dim, fun = mean)$output1 - - } else { - - if (member_dim %in% names(dim(data))){ - target_dims = c(year_dim,member_dim) - } else { - target_dims = year_dim - } - clim = multiApply::Apply(data = ClimProjDiags::Subset(x = data, along = year_dim, indices = indices_for_clim), - target_dims = target_dims, fun = mean)$output1 - } - anom = multiApply::Apply(data = data, target_dims = year_dim, - fun = function(data,clim){data-clim}, clim = clim)$output1 + if (identical(indices_for_clim, FALSE)) { ## data is already anomalies + clim <- 0 + } else if (is.null(indices_for_clim)) { ## climatology over the whole period + clim <- multiApply::Apply(data = data, target_dims = year_dim, fun = mean, na.rm = na.rm)$output1 + } else { ## indices_for_clim specified as a numeric vector + clim <- multiApply::Apply(data = ClimProjDiags::Subset(x = data, along = year_dim, indices = indices_for_clim), + target_dims = year_dim, fun = mean, na.rm = na.rm)$output1 } + anom <- data - clim + } else {stop('type must be dcpp, hist or obs')} return(anom) } -