Statistics <- function(recipe, data, agg = 'global') {
  # data$hcst: s2dv_cube containing the hindcast 
  # data$obs: s2dv_cube containing the observations
  # recipe: auto-s2s recipe as provided by read_yaml
  # agg: data aggregation
  
  time_dim <- 'syear'
  ncores <- recipe$Analysis$ncores

  ## Calculate ensemble mean
  hcst_ensmean <- Apply(data$hcst$data,
                        target_dims = 'ensemble',
                        fun = 'mean')$output1
  obs_ensmean <- Apply(data$obs$data,
                       target_dims = 'ensemble',
                       fun = 'mean')$output1
  
  ## Remove unwanted dimensions
  ## TODO: Apply .drop_dims() function instead?
  hcst_ensmean <- Subset(hcst_ensmean,
                         along = c('dat', 'sday', 'sweek'),
                         indices = list(1, 1, 1),
                         drop = 'selected')
  obs_ensmean <- Subset(obs_ensmean,
                        along = c('dat', 'sday', 'sweek'),
                        indices = list(1, 1, 1),
                        drop = 'selected')

  statistics_list <- tolower(recipe$Analysis$Workflow$Statistics$metric)
  statistics <- list()
  # Compute statistics in the list
  for (stat in strsplit(statistics_list, ", | |,")[[1]]) {
    if (stat %in% c('cov', 'covariance')) {
    ## Calculate covariance
     covariance <- Apply(data = list(x = obs_ensmean, y = hcst_ensmean), 
                         target_dims = time_dim,
                         fun = function(x,y) {cov(as.vector(x),as.vector(y),
                                                 use = "everything", 
                                                 method = "pearson")})$output1
      
     statistics[[ stat ]] <- covariance
    } ## close if on covariance
    if (stat %in% c('std', 'standard_deviation')) {
      ## Calculate standard deviation 
      std_hcst <- Apply(data = hcst_ensmean, 
                        target_dims = c(time_dim), 
                        fun = 'sd')$output1
      
      std_obs <- Apply(data = obs_ensmean, 
                       target_dims = c(time_dim), 
                       fun = 'sd')$output1
      
      statistics[['std_hcst']] <- std_hcst
      statistics[['std_obs']] <- std_obs
      
    } ## close if on std
    if (stat %in% c('var', 'variance')) {
      ## Calculate variance
      var_hcst <- (Apply(data = hcst_ensmean, 
                         target_dims = c(time_dim), 
                         fun = 'sd')$output1)^2
      
      var_obs <- (Apply(data = obs_ensmean, 
                        target_dims = c(time_dim), 
                        fun = 'sd')$output1)^2
      
      statistics[['var_hcst']] <- var_hcst
      statistics[['var_obs']] <- var_obs
    } ## close if on variance
    if (stat == 'n_eff') {   
      ## Calculate degrees of freedom
      n_eff <- s2dv::Eno(data = obs_ensmean,
                         time_dim = time_dim,
                         na.action = na.pass,
                         ncores = ncores)
      statistics[['n_eff']] <- n_eff
    } ## close on n_eff  
  }
  
  info(recipe$Run$logger, "##### STATISTICS COMPUTATION COMPLETE #####")
  .log_memory_usage(recipe$Run$logger, when = "After statistics computation")
 
   # Save outputs
  if (recipe$Analysis$Workflow$Skill$save != 'none') {
    info(recipe$Run$logger, "##### START SAVING STATISTICS #####")
  }
  recipe$Run$output_dir <- file.path(recipe$Run$output_dir,
                                     "outputs", "Statistics")
  
  if (recipe$Analysis$Workflow$Statistics$save == 'all') {
    # Save all statistics
    save_metrics(recipe = recipe, metrics = statistics,
                 data_cube = data$hcst, agg = agg,
                 module = "statistics")
  }
  # Return results
  return(statistics)
}  

