
source("modules/Saving/Saving.R")
source("https://earth.bsc.es/gitlab/es/sunset/-/raw/dev-test_CERISE/modules/Skill/R/tmp/RPS.R")
source("https://earth.bsc.es/gitlab/es/sunset/-/raw/dev-test_CERISE/modules/Skill/R/RPS_clim.R")
source("https://earth.bsc.es/gitlab/es/sunset/-/raw/dev-test_CERISE/RPSS.R")
source("https://earth.bsc.es/gitlab/es/sunset/-/raw/dev-test_CERISE/RandomWalkTest.R")
source("https://earth.bsc.es/gitlab/es/sunset/-/raw/dev-test_CERISE/modules/Skill/R/tmp/Corr.R")
source("https://earth.bsc.es/gitlab/es/s2dv/-/raw/dev-sigBias/R/Bias.R")
source("https://earth.bsc.es/gitlab/es/s2dv/-/raw/dev-spread_error_ratio/R/SprErr.R")
source("https://earth.bsc.es/gitlab/es/s2dv/-/raw/dev-spread_error_ratio/R/Eno.R")

## data_crossval is the result from function full_crossval_anomalies or similar.
## this is a list with the required elements:
  ## probs is a list with
    ## probs$hcst_ev and probs$obs_ev 
    ## probs$hcst_ev will have as many elements in the $Probabilities$percentiles
    ## each element will be an array with 'cat' dimension
    ## the same for probs$obs_ev
  ## hcst is a s2dv_cube for the post-processed hindcast for the evalutaion indices
    ## in this case cross validated anomalies
  ## obs is a s2dv_cube for the post-processed obs 
    ## in this case cross validated anomalies
  ## fcst is a s2dv_cube for the post-processed fcst
    ## in this case cross anomalies with the full hindcast period
    ## this object is not required for skill assessment
  ## hcst.full_val and obs.full_val are the original data to compute mean bias
  ## cat_lims used to compute the probabilities
    ## this object is not required for skill assessment
  ## ref_obs_tr is an array with the cross-validate observed anomalies
    ## to be used as reference forecast in the CRPSS and CRPS_clim
    ## it is computed from the training indices
## the recipe could be used to read the Percentiles 
## if fair is TRUE, the nmemb used to compute the probabilities is needed
  ## nmemb_ref is the number of year - 1 in case climatological forecast is the reference
skill_full_crossval <- function(recipe, data_crossval,
                                fair = FALSE, nmemb = NULL, nmemb_ref = NULL) {
  ## START SKILL ASSESSMENT:
  # RPS
  rps <- RPS(exp = res$probs$hcst_ev[[1]], obs = res$probs$obs_ev[[1]], memb_dim = NULL,
           cat_dim = 'cat', cross.val = FALSE, time_dim = 'syear',
	   Fair = fair, nmemb = nmemb,
           ncores = recipe$Analysis$ncores)
  rps_clim <- Apply(list(res$probs$obs_ev[[1]]),
                    target_dims = c('cat', 'syear'),
                    RPS_clim, bin_dim_abs = 'cat', Fair = fair,
  		    cross.val = FALSE, ncores = recipe$Analysis$ncores)$output1
  # RPSS
  rpss <- RPSS(exp = res$probs$hcst_ev[[1]], obs = res$probs$obs_ev[[1]],
                   time_dim = 'syear', memb_dim = NULL,
                   cat_dim = 'cat', Fair = fair, nmemb = nmemb,
                   cross.val = FALSE, 
                   ncores = recipe$Analysis$ncores)

  # CRPS
  crps <- CRPS(exp  = res$hcst$data, obs = res$obs$data,
             time_dim = 'syear', memb_dim = 'ensemble',
	     Fair = fair,
             ncores = recipe$Analysis$ncores)
  crps_clim <- CRPS(exp = res$ref_obs_tr, obs = res$obs$data,
                  time_dim = 'syear', memb_dim = 'ensemble',
		  Fair = fair,
                  ncores = recipe$Analysis$ncores) 

  # CRPSS
    crpss <- CRPSS(exp = res$hcst$data, obs = res$obs$data, ref = res$ref_obs_tr,
                 memb_dim = 'ensemble', Fair = fair,
                 time_dim = 'syear', clim.cross.val = FALSE,
                 ncores = recipe$Analysis$ncores)

  # Corr
  enscorr <- Corr(res$hcst$data, res$obs$data, 
                          dat_dim = NULL, 
                          time_dim = 'syear', 
                          method = 'pearson', 
                          memb_dim = 'ensemble',
                          memb = F,
                          conf = F,
                          pval = F,
                          sign = T,
                          alpha = 0.05,
                          ncores = recipe$Analysis$ncores)

  # Mean Bias
  mean_bias <- Bias(res$hcst.full_val$data, res$obs.full_val$data,
                   time_dim = 'syear',
                   memb_dim = 'ensemble',
                   alpha = 0.05,
                   ncores = recipe$Analysis$ncores)

  # Spread error ratio
  enssprerr <- SprErr(exp = res$hcst$data, obs = res$obs$data,
  	            memb_dim = 'ensemble', dat_dim = NULL,
                    time_dim = 'syear', pval = TRUE,
		    ncores = recipe$Analysis$ncores)
  enssprerr_sign <- enssprerr$p.val
  enssprerr_sign <- enssprerr_sign <= 0.05
  enssprerr <- enssprerr$ratio

  # RMSE
  rms <- RMS(exp = res$hcst$data, obs = res$obs$data,
           memb_dim = 'ensemble', dat_dim = NULL,
           time_dim = 'syear', alpha = 0.05,
           ncores = recipe$Analysis$ncores)

  # RMSS
  rmss <- RMSSS(exp = res$hcst$data, obs = res$obs$data,
             ref = res$ref_obs_tr,
             memb_dim = 'ensemble', dat_dim = NULL,
             time_dim = 'syear', alpha = 0.05, sign = TRUE,
             ncores = recipe$Analysis$ncores)

  skill_metrics <- list(mean_bias = mean_bias$bias,
  		      mean_bias_significance = mean_bias$sig,
 		      enscorr = enscorr$corr,
                      enscorr_significance = enscorr$sign,
		      enssprerr = enssprerr,
                      enssprerr_significance = enssprerr_sign,
                      rps = rps, rps_clim = rps_clim, crps = crps, crps_clim = crps_clim,
                      rpss = rpss$rpss, rpss_significance = rpss$sign, #crps = crps,
                      crpss = crpss$crpss, crpss_significance = crpss$sign,
		      rms = rms$rms, rmsss = rmss$rmsss, rmsss_significance = rmss$sign)
  original <- recipe$Run$output_dir
  recipe$Run$output_dir <- paste0(original, "/outputs/Skill/")

  skill_metrics <- lapply(skill_metrics, function(x) {
  		   if (is.logical(x)) {
		     dims <- dim(x)
		     res <- as.numeric(x)
		     dim(res) <- dims
		   } else {
		     res <- x
		   }
		   return(res)
		      })
  # Save metrics
      save_metrics(recipe = recipe,
                   metrics = skill_metrics,
                   data_cube = data$hcst, agg = 'global',
                   outdir = recipe$Run$output_dir)

  recipe$Run$output_dir <- original
  # reduce dimension to work with Visualization module:
  skill_metrics <- lapply(skill_metrics, function(x) {drop(x)})
  skill_metrics <- lapply(test, function(x){InsertDim(x, pos = 1, len = 1, name = 'var')})
  return(skill_metrics)
}

