# This unit test uses values() to do the transformation and tests "lat_reorder".
# The results should be identical and consistent with cdo result (with precision difference). 
# The lon range is all the grids here.
# "lon_reorder = CircularSort(0, 360)" are used in all the tests.
# Test 1 & 2 are global: test 1 uses values(list(-90, 90)) and test 2 uses values(list(90, -90)).
# Test 3 & 4 are regional: test 3 uses values(list(-90, -80)) and test 4 uses values(list(-80, -90)).
# Each of them contains three calls: lat_reorder = Sort(), no lat_reorder, and lat_reorder = Sort(decreasing = T). 
# Note that the original latitude is descending [90:-90]. cdo result is ascending [-90:90].

context("Transform and lat_reorder test: values")

#---------------------------------------------------------------
# cdo is used to verify the data values
library(easyNCDF)
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 = 1:640, longitude = 1:1296),
                 vars_to_read = 'tas')
lats <- NcToArray(file,
                  dim_indices = list(latitude = 1:640), vars_to_read = 'latitude')
lons <- NcToArray(file,
                  dim_indices = list(longitude = 1:1296), vars_to_read = 'longitude')
NcClose(file)
suppressWarnings(
arr2 <- s2dv::CDORemap(arr, lons = as.vector(lons), lats = as.vector(lats),
                       grid = 'r100x50', method = 'con', crop = FALSE)$data_array
)
#---------------------------------------------------------------

path <- '/esarchive/exp/ecmwf/system5_m1/monthly_mean/$var$_f6h/$var$_$sdate$.nc'

test_that("1. values(list(-90, 90))", {

# lat should be ascending
suppressWarnings(
res1 <- Start(dat = path,
             var = 'tas',
             sdate = '20000101',
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(-90, 90)),
             latitude_reorder = Sort(),
             longitude = values(list(0, 359.9)), 
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50',
                                     method = 'con',
                                     crop = FALSE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 2,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = 'dat',
                                longitude = 'dat',
                                time = 'sdate'),
             retrieve = T)
)

# lat should be ascending
suppressWarnings(
res2 <- Start(dat = path,
             var = 'tas',
             sdate = '20000101',
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(-90, 90)), 
#             latitude_reorder = Sort(),
             longitude = values(list(0, 359.9)), 
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50',
                                     method = 'con',
                                     crop = FALSE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 2,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = 'dat',
                                longitude = 'dat',
                                time = 'sdate'),
             retrieve = T)
)

# lat should be descending
suppressWarnings(
res3 <- Start(dat = path,
             var = 'tas',
             sdate = '20000101',
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(-90, 90)), 
             latitude_reorder = Sort(decreasing = T),
             longitude = values(list(0, 359.9)), 
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50',
                                     method = 'con',
                                     crop = FALSE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 2,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = 'dat',
                                longitude = 'dat',
                                time = 'sdate'),
             retrieve = T)
)

expect_equal(
as.vector(res1),
as.vector(arr2),
tolerance = 0.0001
)
expect_equal(
as.vector(res2),
as.vector(arr2),
tolerance = 0.0001
)
expect_equal(
as.vector(drop(res3)[50:1, ]),
as.vector(arr2),
tolerance = 0.0001
)

})

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

test_that("2. values(list(90, -90))", {

# lat should be ascending
suppressWarnings(
res1 <- Start(dat = path,
             var = 'tas',
             sdate = '20000101',
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(90, -90)),
             latitude_reorder = Sort(),
             longitude = values(list(0, 359.9)), 
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50',
                                     method = 'con',
                                     crop = FALSE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 2,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = 'dat',
                                longitude = 'dat',
                                time = 'sdate'),
             retrieve = T)
)

# lat should be descending
suppressWarnings(
res2 <- Start(dat = path,
             var = 'tas',
             sdate = '20000101',
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(90, -90)), 
#             latitude_reorder = Sort(),
             longitude = values(list(0, 359.9)), 
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50',
                                     method = 'con',
                                     crop = FALSE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 2,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = 'dat',
                                longitude = 'dat',
                                time = 'sdate'),
             retrieve = T)
)

# lat should be descending
suppressWarnings(
res3 <- Start(dat = path,
             var = 'tas',
             sdate = '20000101',
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(90, -90)), 
             latitude_reorder = Sort(decreasing = T),
             longitude = values(list(0, 359.9)), 
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50',
                                     method = 'con',
                                     crop = FALSE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 2,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = 'dat',
                                longitude = 'dat',
                                time = 'sdate'),
             retrieve = T)
)


expect_equal(
as.vector(res1),
as.vector(arr2),
tolerance = 0.0001
)
expect_equal(
as.vector(drop(res2)[50:1, ]),
as.vector(arr2),
tolerance = 0.0001
)
expect_equal(
as.vector(drop(res3)[50:1, ]),
as.vector(arr2),
tolerance = 0.0001
)

})


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

#NOTE: The numbers at lat = 3 are different with cdo if transform_extra_cells = 2.

test_that("3. values(list(-90, -80))", {

# lat should be ascending
suppressWarnings(
res1 <- Start(dat = path,
             var = 'tas',
             sdate = '20000101',
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(-90, -80)),
             latitude_reorder = Sort(),
             longitude = values(list(0, 359.9)), 
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50',
                                     method = 'con',
                                     crop = T),  # note that crop = T here
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 8,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = 'dat',
                                longitude = 'dat',
                                time = 'sdate'),
             retrieve = T)
)

# lat should be ascending
suppressWarnings(
res2 <- Start(dat = path,
             var = 'tas',
             sdate = '20000101',
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(-90, -80)), 
#             latitude_reorder = Sort(),
             longitude = values(list(0, 359.9)), 
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50',
                                     method = 'con',
                                     crop = TRUE), #FALSE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 8,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = 'dat',
                                longitude = 'dat',
                                time = 'sdate'),
             retrieve = T)
)

# lat should be descending
suppressWarnings(
res3 <- Start(dat = path,
             var = 'tas',
             sdate = '20000101',
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(-90, -80)), 
             latitude_reorder = Sort(decreasing = T),
             longitude = values(list(0, 359.9)), 
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50',
                                     method = 'con',
                                     crop = TRUE), #FALSE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 8,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = 'dat',
                                longitude = 'dat',
                                time = 'sdate'),
             retrieve = T)
)

expect_equal(
as.vector(res1),
as.vector(drop(arr2)[1:3, ]),
tolerance = 0.0001
)
expect_equal(
as.vector(res2),
as.vector(drop(arr2)[1:3, ]),
tolerance = 0.0001
)
expect_equal(
as.vector(res3),
as.vector(drop(arr2)[3:1, ]),
tolerance = 0.0001
)

})

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


#NOTE: The numbers at lat = 3 are different with cdo if transform_extra_cells = 2.

test_that("4. values(list(-80, -90))", {

# lat should be ascending
suppressWarnings(
res1 <- Start(dat = path,
             var = 'tas',
             sdate = '20000101',
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(-80, -90)),
             latitude_reorder = Sort(),
             longitude = values(list(0, 359.9)), 
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50',
                                     method = 'con',
                                     crop = T),  # note that crop = T here
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 8,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = 'dat',
                                longitude = 'dat',
                                time = 'sdate'),
             retrieve = T)
)

# lat should be descending
suppressWarnings(
res2 <- Start(dat = path,
             var = 'tas',
             sdate = '20000101',
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(-80, -90)), 
#             latitude_reorder = Sort(),
             longitude = values(list(0, 359.9)), 
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50',
                                     method = 'con',
                                     crop = TRUE), #FALSE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 8,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = 'dat',
                                longitude = 'dat',
                                time = 'sdate'),
             retrieve = T)
)

# lat should be descending
suppressWarnings(
res3 <- Start(dat = path,
             var = 'tas',
             sdate = '20000101',
             ensemble = indices(1),
             time = indices(1),
             latitude = values(list(-80, -90)), 
             latitude_reorder = Sort(decreasing = T),
             longitude = values(list(0, 359.9)), 
             longitude_reorder = CircularSort(0, 360),
             transform = CDORemapper,
             transform_params = list(grid = 'r100x50',
                                     method = 'con',
                                     crop = TRUE), #FALSE),
             transform_vars = c('latitude', 'longitude'),
             transform_extra_cells = 8,
             synonims = list(latitude = c('lat', 'latitude'),
                             longitude = c('longitude', 'lon')),
             return_vars = list(latitude = 'dat',
                                longitude = 'dat',
                                time = 'sdate'),
             retrieve = T)
)

expect_equal(
as.vector(res1),
as.vector(drop(arr2)[1:3, ]),
tolerance = 0.0001
)
expect_equal(
as.vector(res2),
as.vector(drop(arr2)[3:1, ]),
tolerance = 0.0001
)
expect_equal(
as.vector(res3),
as.vector(drop(arr2)[3:1, ]),
tolerance = 0.0001
)

})

