diff --git a/R/zzz.R b/R/zzz.R index 0579b59d48a0dfe90761c8fe081625758fbf944f..381c9d3ac69ce95bc4d1b8aa6c68bde291e5437c 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -692,9 +692,11 @@ generate_sub_array_of_fri <- function(with_transform, goes_across_prime_meridian } else if (start_padding < beta) { # left side too close to border, need to go to right side sub_array_of_fri <- c((first_index - start_padding):(last_index + end_padding), (n - (beta - start_padding - 1)):n) + sub_array_of_fri <- unique(sub_array_of_fri) } else if (end_padding < beta) { # right side too close to border, need to go to left side sub_array_of_fri <- c(1: (beta - end_padding), (first_index - start_padding):(last_index + end_padding)) + sub_array_of_fri <- unique(sub_array_of_fri) } } @@ -706,6 +708,7 @@ generate_sub_array_of_fri <- function(with_transform, goes_across_prime_meridian } } } + if (print_warning) { .warning(paste0("Adding parameter transform_extra_cells = ", beta, " to the transformed index excesses ", diff --git a/tests/testthat/test-Start-transform-border.R b/tests/testthat/test-Start-transform-border.R index a84f1eca315b5929cc57da45ba3f305bbc6cdbb9..dee8b4e0582e007057df58d7deeeafbc6d66cd84 100644 --- a/tests/testthat/test-Start-transform-border.R +++ b/tests/testthat/test-Start-transform-border.R @@ -1,4 +1,6 @@ context("Transform: check with cdo") + +############################################## # This unit test checks different border situations: normal regional that doesn't touch the borders, # global situation that uses all the grids, or one side reaches the border. @@ -24,6 +26,7 @@ context("Transform: check with cdo") # The result of cdo is from CDO version 1.9.8. +############################################## test_that("1. normal regional situation", { lons.min <- 10 @@ -75,6 +78,7 @@ tolerance = 0.0001 ) }) +#--------------------------------------------- # The result is consistent with cdo result, using all the grid points to transform # and crop the region. @@ -86,8 +90,7 @@ tolerance = 0.0001 #[4,] 284.1387 287.3716 287.7389 #[5,] 285.6547 285.0194 286.1099 -#------------------------------------------------ - +############################################## test_that("2. global situation", { lons.min <- 0 @@ -145,6 +148,7 @@ tolerance = 0.0001 }) +#--------------------------------------------- #> drop(arr2$data_array)[,1:3] # [,1] [,2] [,3] #[1,] 286.4231 288.0916 285.7435 @@ -160,8 +164,7 @@ tolerance = 0.0001 #[4,] 288.6723 285.0679 279.6016 #[5,] 286.8253 282.6013 279.5081 -#----------------------------------------------- - +############################################## test_that("3. left side too close to border", { lons.min <- 0 @@ -229,7 +232,7 @@ tolerance = 0.0001 }) - +#--------------------------------------------- #drop(arr2$data_array)[,] # [,1] [,2] [,3] [,4] [,5] [,6] #[1,] 286.4231 288.0916 285.7435 284.9907 285.4820 286.1208 @@ -239,7 +242,7 @@ tolerance = 0.0001 #[5,] 284.3575 284.8728 284.6408 285.6547 285.0194 286.1099 - +############################################## test_that("4. right side too close to border", { lons.min <- 350 @@ -287,6 +290,7 @@ tolerance = 0.0001 }) +#--------------------------------------------- #> drop(arr2$data_array)[,] # [,1] [,2] #[1,] 286.3033 285.9373 @@ -295,8 +299,7 @@ tolerance = 0.0001 #[4,] 285.0679 279.6016 #[5,] 282.6013 279.5081 -#-------------------------------------------------- - +############################################## test_that("5. across meridian", { lons.min <- 170 @@ -359,6 +362,8 @@ tolerance = 0.0001 }) +#--------------------------------------------- + # cdo result is [170:190]; Start() is [-180:-170; 170:180]. # So drop(exp)[, 1:3] == drop(arr2$data_array)[, 3:5]. #drop(arr2$data_array)[,] @@ -370,6 +375,7 @@ tolerance = 0.0001 #[5,] 284.6429 284.6293 284.9630 285.7766 286.0924 +############################################## test_that("6. normal case; [-180, 180]", { # The lon range is too close to border for the original longitude [0, 360], but # is normal case for [-180, 180]. In zzz.R, it is counted as normal case, and the @@ -439,9 +445,8 @@ tolerance = 0.0001 }) -#---------------------------------------------------------- - -test_that("6. left side too close to border; [-180, 180]", { +############################################## +test_that("7. left side too close to border; [-180, 180]", { # The lon range is too close to border for the original longitude [0, 360], but # is normal case for [-180, 180]. In zzz.R, it is counted as normal case, and the # result is the same as 3. @@ -490,6 +495,7 @@ tolerance = 0.0001 }) +#--------------------------------------------- # cdo result is [181:190] #> drop(arr2$data_array)[,] # [,1] [,2] @@ -499,3 +505,208 @@ tolerance = 0.0001 #[4,] 289.5334 289.5931 #[5,] 285.7766 286.0924 + +############################################## +# Tests for global longitude: + +test_that("8. Global situation: left side too close to border; [0, 360]", { + +lats.min <- 0 +lats.max <- 10 +lons.min <- 0 +lons.max <- 359 + +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 = 'r360x180', + method = 'bilinear'), + transform_vars = c('latitude', 'longitude'), + synonims = list(latitude = c('lat','latitude'), + longitude = c('lon','longitude')), + return_vars = list(latitude = NULL, + longitude = NULL, + time = 'sdate'), + retrieve = TRUE) +) + +expect_equal( + dim(drop(exp)), + c(latitude = 10, longitude = 360) +) +expect_equal( + drop(exp)[,1], + c(299.8538, 300.0350, 300.2633, 300.4800, 300.6892, 300.2321, 300.1185, + 301.1927, 300.3126, 300.6474), + tolerance = 0.0001 +) +expect_equal( + drop(exp)[,2], + c(299.9356, 300.0557, 300.2042, 300.4571, 300.7495, 300.6388, 299.6622, + 299.2109, 299.4723, 299.5299), + tolerance = 0.0001 +) +expect_equal( + drop(exp)[,3], + c(300.0876, 300.1628, 300.2939, 300.5117, 300.6660, 300.5703, 300.0838, + 300.3170, 299.9515, 299.7573), + tolerance = 0.0001 +) +expect_equal( + drop(exp)[,4], + c(300.1547, 300.2518, 300.3484, 300.4062, 300.5299, 300.5294, 300.2701, + 300.1524, 299.4566, 299.0317), + tolerance = 0.0001 +) +expect_equal( + drop(exp)[,5], + c(300.1340, 300.1652, 300.3981, 300.5044, 300.5583, 300.5028, 300.4284, + 299.6214, 299.0601, 299.1104), + tolerance = 0.0001 +) + +}) + +#--------------------------------------------- +# The result is consistent with cdo result, using all the grid points to transform +# and crop the region: + +# path <- "/esarchive/exp/ecmwf/system5_m1/monthly_mean/tas_f6h/tas_20000101.nc" +# file <- NcOpen(path) +# 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) + +# arr3 <- s2dv::CDORemap(arr, lons = as.vector(lons), lats = as.vector(lats), +# grid = 'r360x180', method = 'bilinear', crop = c(0,359,0,10)) + +# drop(arr3$data_array)[,1:5] + +# [,1] [,2] [,3] [,4] [,5] +# [1,] 299.8538 299.9356 300.0876 300.1547 300.1340 +# [2,] 300.0350 300.0557 300.1628 300.2518 300.1652 +# [3,] 300.2633 300.2042 300.2939 300.3484 300.3981 +# [4,] 300.4800 300.4571 300.5117 300.4062 300.5044 +# [5,] 300.6892 300.7495 300.6660 300.5299 300.5583 +# [6,] 300.2321 300.6388 300.5703 300.5294 300.5028 +# [7,] 300.1185 299.6622 300.0838 300.2701 300.4284 +# [8,] 301.1927 299.2109 300.3170 300.1524 299.6214 +# [9,] 300.3126 299.4723 299.9515 299.4566 299.0601 +# [10,] 300.6474 299.5299 299.7573 299.0317 299.1104 + +############################################## +test_that("9. Global situation: right side too close to border; [0.5, 359.9]", { + +lats.min <- 0 +lats.max <- 10 +lons.min <- 0.5 +lons.max <- 359.9 + +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 = 'r360x180', + method = 'bilinear'), + transform_vars = c('latitude', 'longitude'), + synonims = list(latitude = c('lat','latitude'), + longitude = c('lon','longitude')), + return_vars = list(latitude = NULL, + longitude = NULL, + time = 'sdate'), + retrieve = TRUE) +) + + +expect_equal( + dim(drop(exp)), + c(latitude = 10, longitude = 359) +) +expect_equal( + drop(exp)[,1], + c(299.9356, 300.0557, 300.2042, 300.4571, 300.7495, 300.6388, 299.6622, + 299.2109, 299.4723, 299.5299), + tolerance = 0.0001 +) +expect_equal( + drop(exp)[,2], + c(300.0876, 300.1628, 300.2939, 300.5117, 300.6660, 300.5703, 300.0838, + 300.3170, 299.9515, 299.7573), + tolerance = 0.0001 +) +expect_equal( + drop(exp)[,3], + c(300.1547, 300.2518, 300.3484, 300.4062, 300.5299, 300.5294, 300.2701, + 300.1524, 299.4566, 299.0317), + tolerance = 0.0001 +) +expect_equal( + drop(exp)[,4], + c(300.1340, 300.1652, 300.3981, 300.5044, 300.5583, 300.5028, 300.4284, + 299.6214, 299.0601, 299.1104), + tolerance = 0.0001 +) +expect_equal( + drop(exp)[,5], + c(300.0874, 300.2558, 300.4289, 300.5256, 300.6006, 300.6316, 299.5125, + 298.8563, 299.5071, 300.0644), + tolerance = 0.0001 +) + +}) +#--------------------------------------------- + +# The result is consistent with cdo result, using all the grid points to transform +# and crop the region: + +# library(easyNCDF) +# path <- "/esarchive/exp/ecmwf/system5_m1/monthly_mean/tas_f6h/tas_20000101.nc" +# file <- NcOpen(path) +# 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) + +# arr3 <- s2dv::CDORemap(arr, lons = as.vector(lons), lats = as.vector(lats), +# grid = 'r360x180', method = 'bilinear', crop = c(0.5,359.9,0,10)) + +# drop(arr2$data_array)[,1:5] + +# [,1] [,2] [,3] [,4] [,5] +# [1,] 299.9356 300.0876 300.1547 300.1340 300.0874 +# [2,] 300.0557 300.1628 300.2518 300.1652 300.2558 +# [3,] 300.2042 300.2939 300.3484 300.3981 300.4289 +# [4,] 300.4571 300.5117 300.4062 300.5044 300.5256 +# [5,] 300.7495 300.6660 300.5299 300.5583 300.6006 +# [6,] 300.6388 300.5703 300.5294 300.5028 300.6316 +# [7,] 299.6622 300.0838 300.2701 300.4284 299.5125 +# [8,] 299.2109 300.3170 300.1524 299.6214 298.8563 +# [9,] 299.4723 299.9515 299.4566 299.0601 299.5071 +# [10,] 299.5299 299.7573 299.0317 299.1104 300.0644 +############################################## \ No newline at end of file