context("Compute()/ByChunks(): dimension consistence check")
# If dataset are more than 1 (e.g., exp and obs), ByChunks() checks if 
# they have consistent dimensions in favor of Apply() computation. However,
# only margin dimensions need to be identical. Target dimensions can have
# different lengths.

test_that("ex2_11", {
path.exp <- '/esarchive/exp/ecmwf/system5c3s/monthly_mean/$var$_f6h/$var$_$sdate$.nc'
path.obs <- '/esarchive/recon/ecmwf/era5/monthly_mean/$var$_f1h-r1440x721cds/$var$_$date$.nc'

var <- 'tos'
y1 <- 1981
y2 <- 1983

lons.min <- 220
lons.max <- 240
lats.min <- -5
lats.max <- 5

sdate <- paste0(y1:y2, '1201')

suppressWarnings(
exp <- Start(data = path.exp,
             var = var,
             member = indices(1:2),
             sdate = sdate,
             time = 1:3,
             latitude = values(list(lats.min, lats.max)),
             latitude_reorder = Sort(decreasing = TRUE),
             longitude = values(list(lons.min, lons.max)),
             synonims = list(longitude = c('lon', 'longitude'),
                             latitude = c('lat', 'latitude'),
                             member = c('member', 'ensemble')),
             return_vars = list(longitude = NULL,
                                latitude = NULL,
                                time = 'sdate'),
             retrieve = FALSE)
)
lons.exp <- attr(exp, 'Variables')$common$longitude
lats.exp <- attr(exp, 'Variables')$common$latitude
dates.exp <- attr(exp, 'Variables')$common$time

# Manually create date/ime
dates.obs <- c(paste0(y1:y2, '1201'),
               paste0((y1 + 1):(y2 + 1), '01', '01'),
               paste0((y1 + 1):(y2 + 1), '02', '01'))
time.obs <- as.POSIXct(dates.obs, "%Y%m%d",
                       origin = "1981-12", tz = 'UTC')
dim(time.obs) <- c(dim(dates.exp)['sdate'], dim(dates.exp)['time'])

suppressWarnings(
obs <- Start(data = path.obs,
             var = var,
             date = unique(format(time.obs, '%Y%m')),
             time = values(time.obs),
             latitude = values(list(lats.min, lats.max)),
             latitude_reorder = Sort(decreasing = TRUE),
             longitude = values(list(lons.min, lons.max)),
             time_across = 'date',
             merge_across_dims = TRUE,
             split_multiselected_dims = TRUE,
             synonims = list(longitude = c('lon', 'longitude'),
                             latitude = c('lat', 'latitude')),
             return_vars = list(longitude = NULL,
                                latitude = NULL,
                                time = 'date'),
             retrieve = FALSE)
)

lons.obs <- attr(obs, 'Variables')$common$longitude
lats.obs <- attr(obs, 'Variables')$common$latitude
dates.obs <- attr(obs, 'Variables')$common$time

lons_exp <- as.vector(lons.exp)
lats_exp <- as.vector(lats.exp)
lons_obs <- as.vector(lons.obs)
lats_obs <- as.vector(lats.obs)


fun <- function(exp, obs, path.output,  
                lons_exp = lons_exp, lats_exp = lats_exp,
                lons_obs = lons_obs, lats_obs = lats_obs) {

        e <- s2dv::MeanDims(drop(exp), c('member', 'time'))
        sst.e <- ClimProjDiags::WeightedMean(e, lons_exp, lats_exp,
                              londim = which(names(dim(e)) == 'longitude'),
                              latdim = which(names(dim(e)) == 'latitude'))
        index.exp <- (sst.e - mean(sst.e))/sd(sst.e)

        o <- s2dv::MeanDims(drop(obs), 'time')
        sst.o <- ClimProjDiags::WeightedMean(o, lons_obs, lats_obs,
                              londim = which(names(dim(o)) == 'longitude'),
                              latdim = which(names(dim(o)) == 'latitude'))
        index.obs <- (sst.o - mean(sst.o))/sd(sst.o)

        # give dim name
        dim(index.exp) <- c(sdate = length(index.exp))
        dim(index.obs) <- c(sdate = length(index.obs))

        return(list(ind_exp = index.exp, ind_obs = index.obs))

}

step <- Step(fun,
             target_dims = list(exp = c('member', 'sdate', 'time', 'latitude', 'longitude'),
                                obs = c('sdate', 'time', 'latitude', 'longitude')),
             output_dims = list(ind_exp = 'sdate', ind_obs = 'sdate'))

workflow <- AddStep(list(exp = exp, obs = obs), step,
                    lons_exp = lons_exp, lats_exp = lats_exp,
                    lons_obs = lons_obs, lats_obs = lats_obs)

suppressWarnings(
res <- Compute(workflow$ind_exp,
               chunks = list(var = 1))
)

expect_equal(
attr(exp, 'Dimensions'),
c(data = 1, var = 1, member = 2, sdate = 3, time = 3, latitude = 11, longitude = 21)
)
expect_equal(
attr(obs, 'Dimensions'),
c(data = 1, var = 1, sdate = 3, time = 3, latitude = 41, longitude = 81)
)
expect_equal(
names(res),
c('ind_exp', 'ind_obs')
)
expect_equal(
mean(res$ind_exp)*10^18,
-9.251859,
tolerance = 0.00001
)
expect_equal(
mean(res$ind_obs)*10^15,
-9.584944,
tolerance = 0.00001
)

})
