Corr <- function(var_exp, var_obs, posloop = 1, poscor = 2, compROW = NULL, 
                 limits = NULL, siglev = 0.95, method = 'pearson', 
                 conf = TRUE, pval = TRUE, parallel = FALSE, ncores = NULL) {
  #
  #  Remove data along compROW dim if there is at least one NA between limits
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  #
  if (!is.null(compROW)) {
    if (is.null(limits)) {
      limits <- c(1, dim(var_obs)[compROW])
    }
    outrows <- (is.na(Mean1Dim(var_obs, compROW, narm = FALSE, limits))) 
    outrows <- InsertDim(outrows, compROW, dim(var_obs)[compROW])
    var_obs[which(outrows)] <- NA
  }
  #
  #  Enlarge var_exp & var_obs to 10 dim + move posloop & poscor to 1st & 2nd 
  #  pos 
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # 
  dim_names <- names(dim(var_exp))
  dimsvar <- dim(var_exp)
  for (iind in 1:length(dimsvar)) {
    if (iind != posloop & dim(var_obs)[iind] != dimsvar[iind]) { 
      stop("var_exp & var_obs must have same dimensions except along posloop")
    }
  }
  if (dimsvar[poscor] < 3 ) {
    stop("At least 3 values required to compute correlation")
  }
  var_exp <- aperm(var_exp, c(poscor, posloop, c(1:length(dim(var_exp)))[-c(poscor,posloop)]))
  var_obs <- aperm(var_obs, c(poscor, c(1 :length(dim(var_obs)))[-poscor]))
  if (length(dim(var_exp)) <= 2) {     
    margins <- NULL   
  } else {     
    margins <- list(c(2 : length(dim(var_exp))), c(2 : length(dim(var_obs))))   
  }
 CORR <- Apply(list(var_exp, var_obs), margins = margins, AtomicFun = ".Corr", 
               siglev = siglev, method = method, conf = conf, pval = pval)
  #  Output
  # ~~~~~~~~
  #
 names(dim(CORR))[2 : length(dim(CORR))] <- dim_names[-poscor]
  CORR
}

.Corr <- function(exp, obs, siglev = 0.95, method = 'pearson', 
                  conf = TRUE, pval = TRUE) {

  # Check 'method'
  if (!(method %in% c("kendall", "spearman", "pearson"))) {
    stop("Parameter 'method' must be one of 'kendall', 'spearman' or 'pearson'.")
    #  Check 'siglev'
    if (siglev > 1 || siglev < 0) {
      stop("Parameter 'siglev' must be higher than O and lower than 1.")
    }
  }

  p_val <- NULL
  conflow <- NULL
  confhigh <- NULL
  if (is.matrix(exp)) {
    ens_mean <- rowMeans(exp)
  } else {
    ens_mean <- exp
  }
  CORR <- cor(obs, ens_mean, use = "pairwise.complete.obs", method = method)
  if (pval || conf) {
    if (method == "kendall" || method == "spearman") {
      eno <- Eno(rank(obs), 1)                          
    } else if (method == "pearson") {
      eno <- Eno(obs, 1)                          
    }
  }
  if (pval && (method == "pearson")) {
    t <-sqrt(CORR * CORR * (eno - 2) / (1 - (CORR ^ 2)))
    p_val <- pt(t, eno - 2, lower.tail = FALSE)
  } 
  if (conf && (method == "pearson")) {
    conf_low <- (1 - siglev) / 2
    conf_high <- 1 - conf_low
    conf_int <- c(tanh(atanh(CORR) + qnorm(conf_low) / sqrt(eno - 3)), 
                  tanh(atanh(CORR) + qnorm(conf_high) / sqrt(eno - 3)))
    conf_int <- conf_int[!is.na(CORR)]
    conflow <- conf_int[1]
    confhigh <- conf_int[2]
  } 
  #  Output
  invisible(result <- list(conf_high = confhigh, corr = CORR, conf_low = conflow, p_val = p_val))
}
