context("Compute: Transform and chunk values()")
# Using values() to assign lat and lon, and transform the data. 
# Also test transform + chunk along lat/lon.

#####################################################################
#####################################################################
#####################################################################

test_that("1. Global", {

lons.min <- 0
lons.max <- 359.9
lats.min <- -90
lats.max <- 90

# crop = region
suppressWarnings(
exp <- Start(dat = '/esarchive/exp/ecmwf/system5_m1/monthly_mean/$var$_f6h/$var$_$sdate$.nc',
             var = 'tas',
             sdate = '20000101',
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(lats.min, lats.max)),
             latitude_reorder = Sort(),
             longitude = values(list(lons.min, lons.max)),
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50', 
                                     method = 'con',
                                     crop = c(lons.min, lons.max, lats.min, lats.max)),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 8,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = NULL,
                                longitude = NULL,
                                time = 'sdate'),
             retrieve= F)
)
func <- function(exp) {
  return(exp)
}
step <- Step(func,
             target_dims = 'sdate', output_dims = 'sdate')
wf <- AddStep(exp, step)
suppressWarnings(
res1 <- Compute(wf, chunks = list(latitude = 2, longitude = 2))$output1
)
suppressWarnings(
res2 <- Compute(wf, chunks = list(ensemble = 1))$output1
)
suppressWarnings(
res3 <- Compute(wf, chunks = list(longitude = 3))$output1
)

expect_equal(
dim(res1),
c(sdate = 1, dat = 1, var = 1, ensemble = 1, time = 1, latitude = 50, longitude = 100)
)
expect_equal(
res1,
res2
)
expect_equal(
res1,
res3
)

expect_equal(
drop(res1)[1:5, 1],
c(241.8592, 243.7243, 248.7337, 247.9308, 252.0744),
tolerance = 0.001
)
expect_equal(
drop(res1)[23:28, 2],
c(298.0772, 299.4716, 299.7746, 300.2744, 300.3914, 299.5223),
tolerance = 0.001
)
expect_equal(
mean(res1),
276.3901,
tolerance = 0.001
)

#-------------------------------------------------------

# crop = FALSE
suppressWarnings(
exp <- Start(dat = '/esarchive/exp/ecmwf/system5_m1/monthly_mean/$var$_f6h/$var$_$sdate$.nc',
             var = 'tas',
             sdate = '20000101', 
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(lats.min, lats.max)),
             latitude_reorder = Sort(),
             longitude = values(list(lons.min, lons.max)),
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50', 
                                     method = 'con',
                                     crop = FALSE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 8,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = NULL, 
                                longitude = NULL,
                                time = 'sdate'),
             retrieve= F)
)
func <- function(exp) {
  return(exp)
}
step <- Step(func,
             target_dims = 'sdate', output_dims = 'sdate')
wf <- AddStep(exp, step)
suppressWarnings(
res_crop_F_1 <- Compute(wf, chunks = list(latitude = 2, longitude = 2))$output1
)
suppressWarnings(
res_crop_F_2 <- Compute(wf, chunks = list(ensemble = 1))$output1
)
suppressWarnings(
res_crop_F_3 <- Compute(wf, chunks = list(longitude = 3))$output1
)

expect_equal(
res1,
res_crop_F_1
)
expect_equal(
res_crop_F_1,
res_crop_F_2
)
expect_equal(
res_crop_F_1,
res_crop_F_3
)

#-------------------------------------------------------
#!!!!!!!!!!!!!!!!!!!!Problem when global + crop = T + chunk along lon!!!!!!!!!!!!!!!!

# crop = TRUE
suppressWarnings(
exp <- Start(dat = '/esarchive/exp/ecmwf/system5_m1/monthly_mean/$var$_f6h/$var$_$sdate$.nc',
             var = 'tas',
             sdate = '20000101', 
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(lats.min, lats.max)),
             latitude_reorder = Sort(),
             longitude = values(list(lons.min, lons.max)),
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50', 
                                     method = 'con',
                                     crop = TRUE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 8,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = NULL, 
                                longitude = NULL,
                                time = 'sdate'),
             retrieve= F)
)
func <- function(exp) {
  return(exp)
}
step <- Step(func,
             target_dims = 'sdate', output_dims = 'sdate')
wf <- AddStep(exp, step)
#WRONG
#suppressWarnings(
#res_crop_T_1 <- Compute(wf, chunks = list(latitude = 2, longitude = 2))$output1
#)
suppressWarnings(
res_crop_T_2 <- Compute(wf, chunks = list(ensemble = 1))$output1
)
#WRONG
#suppressWarnings(
#res_crop_T_3 <- Compute(wf, chunks = list(longitude = 3))$output1
#)
suppressWarnings(
res_crop_T_4 <- Compute(wf, chunks = list(latitude = 3))$output1
)

#expect_equal(
#res1,
#res_crop_T_1
#)
expect_equal(
res1,
res_crop_T_2
)
#expect_equal(
#res1,
#res_crop_T_3
#)
expect_equal(
res1,
res_crop_T_4
)

})

############################################################################
############################################################################
############################################################################

# The numbers below are consistent with the result of this script.
#pathh <- "/esarchive/exp/ecmwf/system5_m1/monthly_mean/tas_f6h/tas_20000101.nc"
#file <- NcOpen(pathh)
#arr <- NcToArray(file,
#                 dim_indices = list(time = 1, ensemble = 1,
#                                    latitude = 171:257, longitude = 30:81),
#                 vars_to_read = 'tas')
#lats <- NcToArray(file,
#                  dim_indices = list(latitude = 171:257), vars_to_read = 'latitude')
#lons <- NcToArray(file,
#                  dim_indices = list(longitude = 30:81), vars_to_read = 'longitude')
#NcClose(file)
#
#arr2 <- s2dv::CDORemap(arr, lons = as.vector(lons), lats = as.vector(lats),
#                       grid = 'r100x50', method = 'con', crop = c(10, 20, 20, 40))

test_that("2. Regional, no border", {

lons.min <- 10
lons.max <- 20
lats.min <- 20
lats.max <- 40

# crop = region
suppressWarnings(
exp <- Start(dat = '/esarchive/exp/ecmwf/system5_m1/monthly_mean/$var$_f6h/$var$_$sdate$.nc',
             var = 'tas',
             sdate = '20000101', #paste0(2000:2001, '0101'),
             ensemble = indices(1), #'all',
             time = indices(1),
             latitude = values(list(lats.min, lats.max)),
             latitude_reorder = Sort(),
             longitude = values(list(lons.min, lons.max)),
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50', 
                                     method = 'con',
                                     crop = c(lons.min, lons.max, lats.min, lats.max)),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 8,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = NULL, #'dat',
                                longitude = NULL, #'dat',
                                time = 'sdate'),
             retrieve= F)
)
func <- function(exp) {
  return(exp)
}
step <- Step(func,
             target_dims = 'sdate', output_dims = 'sdate')
wf <- AddStep(exp, step)
suppressWarnings(
res1 <- Compute(wf, chunks = list(latitude = 2, longitude = 2))$output1
)
suppressWarnings(
res2 <- Compute(wf, chunks = list(ensemble = 1))$output1
)
suppressWarnings(
res3 <- Compute(wf, chunks = list(longitude = 3))$output1
)

expect_equal(
dim(res1),
c(sdate = 1, dat = 1, var = 1, ensemble = 1, time = 1, latitude = 5, longitude = 3)
)
expect_equal(
res1,
res2
)
expect_equal(
res1,
res3
)

expect_equal(
drop(res1)[, 1],
c(284.9907, 282.9883, 281.2574, 284.1387, 285.6547),
tolerance = 0.0001
)
expect_equal(
drop(res1)[, 2],
c(285.4820, 282.9362, 282.6088, 287.3716, 285.0194),
tolerance = 0.0001
)
expect_equal(
drop(res1)[, 3],
c(286.1208, 284.3523, 285.9198, 287.7389, 286.1099),
tolerance = 0.0001
)

#-------------------------------------------------------

# crop = FALSE
suppressWarnings(
exp <- Start(dat = '/esarchive/exp/ecmwf/system5_m1/monthly_mean/$var$_f6h/$var$_$sdate$.nc',
             var = 'tas',
             sdate = '20000101', 
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(lats.min, lats.max)),
             latitude_reorder = Sort(),
             longitude = values(list(lons.min, lons.max)),
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50', 
                                     method = 'con',
                                     crop = FALSE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 8,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = NULL, 
                                longitude = NULL,
                                time = 'sdate'),
             retrieve= F)
)
func <- function(exp) {
  return(exp)
}
step <- Step(func,
             target_dims = 'sdate', output_dims = 'sdate')
wf <- AddStep(exp, step)
suppressWarnings(
res_crop_F_1 <- Compute(wf, chunks = list(latitude = 2, longitude = 2))$output1
)
suppressWarnings(
res_crop_F_2 <- Compute(wf, chunks = list(ensemble = 1))$output1
)
suppressWarnings(
res_crop_F_3 <- Compute(wf, chunks = list(longitude = 3))$output1
)

expect_equal(
res1,
res_crop_F_1
)
expect_equal(
res_crop_F_1,
res_crop_F_2
)
expect_equal(
res_crop_F_1,
res_crop_F_3
)

#-------------------------------------------------------

# crop = TRUE
suppressWarnings(
exp <- Start(dat = '/esarchive/exp/ecmwf/system5_m1/monthly_mean/$var$_f6h/$var$_$sdate$.nc',
             var = 'tas',
             sdate = '20000101', 
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(lats.min, lats.max)),
             latitude_reorder = Sort(),
             longitude = values(list(lons.min, lons.max)),
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50', 
                                     method = 'con',
                                     crop = TRUE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 8,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = NULL, 
                                longitude = NULL,
                                time = 'sdate'),
             retrieve= F)
)
func <- function(exp) {
  return(exp)
}
step <- Step(func,
             target_dims = 'sdate', output_dims = 'sdate')
wf <- AddStep(exp, step)
suppressWarnings(
res_crop_T_1 <- Compute(wf, chunks = list(latitude = 2, longitude = 2))$output1
)
suppressWarnings(
res_crop_T_2 <- Compute(wf, chunks = list(ensemble = 1))$output1
)
suppressWarnings(
res_crop_T_3 <- Compute(wf, chunks = list(longitude = 3))$output1
)

expect_equal(
res1,
res_crop_T_1
)
expect_equal(
res_crop_T_1,
res_crop_T_2
)
expect_equal(
res_crop_T_1,
res_crop_T_3
)

})

############################################################################
############################################################################
############################################################################

# The numbers below are consistent with the result of this script.
#pathh <- "/esarchive/exp/ecmwf/system5_m1/monthly_mean/tas_f6h/tas_20000101.nc"
#file <- NcOpen(pathh)
#arr <- NcToArray(file,
#                 dim_indices = list(time = 1, ensemble = 1,
#                                    latitude = 171:257, longitude = c(1:81, 1289:1296)),
#                 vars_to_read = 'tas')
#lats <- NcToArray(file,
#                  dim_indices = list(latitude = 171:257), vars_to_read = 'latitude')
#lons <- NcToArray(file,
#                  dim_indices = list(longitude = c(1:81, 1289:1296)), vars_to_read = 'longitude')
#NcClose(file)
#
#arr2 <- s2dv::CDORemap(arr, lons = as.vector(lons), lats = as.vector(lats),
#                       grid = 'r100x50', method = 'con', crop = c(0, 20, 20, 40))


test_that("3. Regional, at lon border", {

lons.min <- 0
lons.max <- 20
lats.min <- 20
lats.max <- 40

# crop = region
suppressWarnings(
exp <- Start(dat = '/esarchive/exp/ecmwf/system5_m1/monthly_mean/$var$_f6h/$var$_$sdate$.nc',
             var = 'tas',
             sdate = '20000101',
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(lats.min, lats.max)),
             latitude_reorder = Sort(),
             longitude = values(list(lons.min, lons.max)),
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50', 
                                     method = 'con',
                                     crop = c(lons.min, lons.max, lats.min, lats.max)),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 8,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = NULL,
                                longitude = NULL, 
                                time = 'sdate'),
             retrieve= F)
)
func <- function(exp) {
  return(exp)
}
step <- Step(func,
             target_dims = 'sdate', output_dims = 'sdate')
wf <- AddStep(exp, step)
suppressWarnings(
res1 <- Compute(wf, chunks = list(latitude = 2, longitude = 2))$output1
)
suppressWarnings(
res2 <- Compute(wf, chunks = list(ensemble = 1))$output1
)
suppressWarnings(
res3 <- Compute(wf, chunks = list(longitude = 3))$output1
)

expect_equal(
dim(res1),
c(sdate = 1, dat = 1, var = 1, ensemble = 1, time = 1, latitude = 5, longitude = 6)
)
expect_equal(
res1,
res2
)
expect_equal(
res1,
res3
)

expect_equal(
drop(res1)[, 1],
c(286.4231, 283.8847, 280.4234, 277.7688, 284.3575),
tolerance = 0.001
)
expect_equal(
drop(res1)[, 2],
c(288.0916, 283.9386, 280.9974, 278.4432, 284.8728),
tolerance = 0.001
)
expect_equal(
drop(res1)[, 3],
c(285.7436, 283.1867, 281.7465, 280.2615, 284.6408),
tolerance = 0.001
)
expect_equal(
drop(res1)[, 4],
c(284.9907, 282.9883, 281.2574, 284.1387, 285.6547),
tolerance = 0.001
)
expect_equal(
drop(res1)[, 5],
c(285.4820, 282.9362, 282.6088, 287.3716, 285.0194),
tolerance = 0.001
)
expect_equal(
drop(res1)[, 6],
c(286.1208, 284.3523, 285.9198, 287.7389, 286.1099),
tolerance = 0.001
)

#-------------------------------------------------------

# crop = FALSE
suppressWarnings(
exp <- Start(dat = '/esarchive/exp/ecmwf/system5_m1/monthly_mean/$var$_f6h/$var$_$sdate$.nc',
             var = 'tas',
             sdate = '20000101', 
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(lats.min, lats.max)),
             latitude_reorder = Sort(),
             longitude = values(list(lons.min, lons.max)),
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50', 
                                     method = 'con',
                                     crop = FALSE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 8,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = NULL, 
                                longitude = NULL,
                                time = 'sdate'),
             retrieve= F)
)
func <- function(exp) {
  return(exp)
}
step <- Step(func,
             target_dims = 'sdate', output_dims = 'sdate')
wf <- AddStep(exp, step)
suppressWarnings(
res_crop_F_1 <- Compute(wf, chunks = list(latitude = 2, longitude = 2))$output1
)
suppressWarnings(
res_crop_F_2 <- Compute(wf, chunks = list(ensemble = 1))$output1
)
suppressWarnings(
res_crop_F_3 <- Compute(wf, chunks = list(longitude = 3))$output1
)

expect_equal(
res1,
res_crop_F_1
)
expect_equal(
res_crop_F_1,
res_crop_F_2
)
expect_equal(
res_crop_F_1,
res_crop_F_3
)

#-------------------------------------------------------

# crop = TRUE
suppressWarnings(
exp <- Start(dat = '/esarchive/exp/ecmwf/system5_m1/monthly_mean/$var$_f6h/$var$_$sdate$.nc',
             var = 'tas',
             sdate = '20000101', 
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(lats.min, lats.max)),
             latitude_reorder = Sort(),
             longitude = values(list(lons.min, lons.max)),
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50', 
                                     method = 'con',
                                     crop = TRUE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 8,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = NULL, 
                                longitude = NULL,
                                time = 'sdate'),
             retrieve= F)
)
func <- function(exp) {
  return(exp)
}
step <- Step(func,
             target_dims = 'sdate', output_dims = 'sdate')
wf <- AddStep(exp, step)
suppressWarnings(
res_crop_T_1 <- Compute(wf, chunks = list(latitude = 2, longitude = 2))$output1
)
suppressWarnings(
res_crop_T_2 <- Compute(wf, chunks = list(ensemble = 1))$output1
)
suppressWarnings(
res_crop_T_3 <- Compute(wf, chunks = list(longitude = 3))$output1
)

expect_equal(
res1,
res_crop_T_1
)
expect_equal(
res_crop_T_1,
res_crop_T_2
)
expect_equal(
res_crop_T_1,
res_crop_T_3
)

})
