# ==========================================================================
# Runs regular OLS for all possible combinations out of 4 independent CFSs
# Picks the prediction set with max correlation as the best combination
# ***REQUIRES*** Obs and Exp to be a two dimensional array:
# where first dim is no. of year and the second is no. of exp/obs
# =========================================================================



bocm <- function(Exp, Obs) {
  
  # dealing with sea masked NA values
  if(all(is.na(Exp))==TRUE) {
    
    final_weight <- rep(NA, ncol(Exp))
    final_predict <- rep(NA, nrow(Exp))
  }
  else {
    
    # prepare dataset
    Data <- as.data.frame(cbind(Exp, Obs))
    ncol <- ncol(Data)
    colnames(Data) <- c(paste("V", seq(1, ncol, 1), sep = ""))
    
    
    # create the combinations from the 4 independent variables
    library(foreach)
    xcomb <- foreach(i=1:(ncol -1), .combine= "c") %do% { combn(colnames(Data)[-ncol], i, simplify=FALSE) }
    
    
    # create formulas
    formlist <- lapply(xcomb, function(x) formula(paste(names(Data)[ncol], paste(x, collapse="+"), sep="~")))
    
    
    # put the weights of each combination as a matrix
    coeffs <- sapply(formlist, function(x) lm(x, data = Data)$coefficients)
    weights <- as.matrix(plyr::ldply(coeffs, rbind)[-1,])
    #for combination with less than 4 models the coeff of the unused models is turned to 0
    weights[is.na(weights)] <- 0
    weights[weights < 0] <- 0 # ADDED LATER
    
    # compute the prediction based on above weight combinations
    predict <- weights %*% t(Exp)
    
    
    # compute the correlation
    library(s2dverification)
    Obs <- InsertDim(Data[,ncol(Data)], 1, 1)
    corr <- s2dverification::Corr(predict, Obs, posloop = 1, poscor = 2)
    
    
    # pick up the maximum correlation and the corresponding weights
    ind <- which.max(corr[,,2])[1]
    final_weight <- weights[ind, ]
    final_predict <- predict[ind,]
    
  }
  
  
  return(list(final_weight, final_predict))
}

#DATAPATH <- "~/2_SForecastAssessment/Data/"
DATAPATH <- "~/Desktop/BSC/Journal/Clim_Dyn_Data/"
Data <- readRDS(paste(DATAPATH,"tas/NovStartData.rds", sep = ''))
Exp <- Data$mod[1,1,,1,16,25]
Obs <- Data$obs[1,1,,1,16,25]
bocm(Exp, Obs)
    