library(multiApply)          # Apply() function
library(startR)              # Start() to load data
packageVersion("startR")
packageVersion("multiApply")

######
# rm(list=ls())
# source("./R/ByChunks.R")
# source("./R/Compute.R")
# source("./R/Start.R")
source("./R/SelectorChecker.R")
source("./R/Utils.R")
source("./R/NcVarReader.R")
source("./R/NcDataReader.R")
source("./R/NcDimReader.R")
source("./R/Sort.R")
source("./R/Subset.R")
source("./R/Step.R")
source("./R/Collect.R")
source("./R/CDORemapper.R")
source("./R/AddStep.R")
 



exp_path = paste0('/esarchive/exp/ncep/cfs-v2/weekly_mean/s2s/$var$_f24h/',
                 '$var$_$sdate$.nc')
obs_path <- paste0("/esarchive/recon/ecmwf/era5/weekly_mean/",
          "$var$_f1h/$var$_$file_date$.nc")

hcst.sdates<-c( "19990104", "19990107", "19990111", "19990114", "19990118", "19990121", "19990125", "19990128", "20000104", "20000107", "20000111", "20000114",
"20000118", "20000121", "20000125", "20000128")

var_name <- 'tas'


exp <- Start(dat = exp_path, 
             var = var_name,
             sdate = hcst.sdates,   #YYYYMMDD
             time = indices(1 : 4),
             latitude =  indices(1), #values(list(lats.min, lats.max)),
             longitude = indices(1), #values(list(lons.min, lons.max)),
             ensemble = 'all',
             return_vars = list(lat = NULL,
                                lon = NULL,
                                 time = c('sdate')),
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('lon', 'longitude')), 
             retrieve = F)

dates <- attr(exp, 'Variables')$common$time
file_date <- sapply(dates, format, '%Y%m%d')
dim(file_date) <- dim(dates)

obs <- Start(dat = obs_path, 
             var = var_name,
             file_date= file_date,   # dim('sdate','time') 
             latitude = indices(1),#values(list(lats.min, lats.max)),
             longitude = indices(1),#values(list(lons.min, lons.max)),
             return_vars = list(latitude = 'dat',
                                     longitude = 'dat',
                                     time = 'file_date'),
             split_multiselected_dims = TRUE,
             retrieve=F)


score_calc <- function(forecast, reference){
	em <- Apply(forecast,'ensemble', mean, na.rm = TRUE)[[1]]
	bias <- Apply(reference,c('sdate'), function(x) x - em)[[1]]
        dim(bias) <- c(length(bias))
      return(bias)
}

step <- Step(score_calc, 
             target_dims = list(forecast = c('sdate','ensemble'),
                                reference = c('sdate')),
             output_dims = list(bias = c('sdate')),
             use_attributes = list(forecast = 'Variables', reference = 'Variables'),
             use_libraries = c('multiApply'))

wf <- AddStep(list(exp, obs), step)

# No resulve el problema y quitar time de los chunks tampocom
#attributes(wf$inputs[[2]]) <- attributes(wf$inputs[[2]])[-6]
#names(attributes(wf$inputs[[2]]))
#attr(wf$inputs[[2]], 'SplitDims')

res <- Compute(workflow = wf,    
              chunks = list(time = 4, latitude=1,
                            longitude=1))#

# Error from function chunk in Utils.R

chunk <- chunks_indices_split_dims
n_chunks <- chunks_split_dims
selectors <- eval(start_call[[names(split_dims)[k]]])

chunk(chunk, n_chunks, selectors)

(!attr(selectors, 'values')) # NULL so it fails

split_dims # $file_date sdate  time   16     4 


# Resulta que el primer elemento de cube headers no tiene split dims pero el segundo si:
> names(attributes(workflow$input[[1]]))
[1] "Dimensions"    "Variables"     "ExpectedFiles" "FileSelectors"
[5] "PatternDim"    "class"        
> names(attributes(workflow$input[[2]]))
[1] "Dimensions"    "Variables"     "ExpectedFiles" "FileSelectors"
[5] "PatternDim"    "SplitDims"     "class"       
> attributes(workflow$input[[2]])$SplitDims
$file_date
sdate  time 
   16     4 

#El error sucede para 
input = 2
attributes(wf$input[[2]]) <- attributes(wf$input[[2]])[-1]
names(attributes(wf$input[[2]])
res <- Compute(workflow = wf,
              chunks = list(time=4,
                            latitude=1,
                     longitude=1))#

 

# ---------------------------------
# Now check different configuration of the score_calc function:

em_calc <- function(forecast) {#, reference){
        em <- Apply(forecast,'ensemble', mean, na.rm = TRUE)[[1]]
        #bias <- Apply(reference,c('sdate'), function(x) x - em)[[1]]
        #dim(bias) <- c(length(bias))
        return(em)
}
step <- Step(em_calc,
             target_dims = list(forecast = c('ensemble')),
             output_dims = NULL)

wf <- AddStep(list(obs), step)


res <- Compute(workflow = wf,
              chunks = list(#time=4,
                            latitude=1,
                            longitude=1))#
dim(res$output1)
 str(res$output1)

##  No funciona
bia_calc <- function(forecast) {#, reference){
        em <- Apply(forecast, 'ensemble', mean, na.rm = TRUE)[[1]]
        bias <- Apply(forecast, c('sdate'), 
                      function(x) x - em)[[1]]
        #dim(bias) <- c(length(bias))
        return(bias)
}
step <- Step(bia_calc,
             target_dims = list(forecast = c('ensemble', 'sdate')),
             output_dims = list(bias = c('d1', 'd2')))

wf <- AddStep(list(exp), step)

res <- Compute(workflow = wf,
              chunks = list(time=4,
                            latitude=1,
                            longitude=1))#
dim(res$output1)
str(res$output1)




## Test for using function from different package: doesn't work
test_lib <- function(forecast) {
               test = forecast + 1
               Kendall(forecast, test)[[1]]
}
## Test function test_lib:
forecast <- 1 : (3 * 4 * 10)
dim(forecast) <- c(a = 3, b = 4, c = 10)
Apply(list(forecast), target_dims = list(c("a", "b")), fun = test_lib)

step <- Step(test_lib,
             target_dims = list(forecast = c('ensemble', 'sdate')),
             output_dims = NULL,
             use_libraries = c('Kendall'))

wf <- AddStep(list(exp), step)

res <- Compute(workflow = wf,
              chunks = list(time=4,
                            latitude=1,
                            longitude=1))#



# debug compute:
threads_load = 1
threads_compute = 1
cluster = NULL
ecflow_suite_dir = NULL
ecflow_server = NULL
silent = FALSE
debug = FALSE
wait = TRUE
# debug bychunks:
step_fun = operation
cube_headers = workflow$inputs 
