|
| 1 | +## Tests for align.met() |
| 2 | +## |
| 3 | +## The bug fixed in this PR (line 431, ensemble source path): |
| 4 | +## rep(dat.tem, each = stamps.hr) |
| 5 | +## where stamps.hr is a numeric *vector*. R silently takes stamps.hr[1] |
| 6 | +## and truncates to an integer. |
| 7 | +## |
| 8 | +## For hourly training data, stamps.hr = c(0.5) (the first centred hour stamp). |
| 9 | +## Truncating 0.5 to 0 makes rep() return an empty vector, so dat.source |
| 10 | +## ends up with zero rows -- silently discarding all source data. |
| 11 | +## |
| 12 | +## Fix: rep(dat.tem, each = length(stamps.hr)) |
| 13 | +## The single-time-series source path (line 304) already used length() correctly. |
| 14 | + |
| 15 | +## Helper: create a minimal single-variable NetCDF with a given number of |
| 16 | +## time steps placed in outdir/filename. Time dimension is in fractional days |
| 17 | +## since 2001-01-01, matching the step size implied by n_time. |
| 18 | +make_align_nc <- function(n_time, outdir, filename) { |
| 19 | + time_dim <- ncdf4::ncdim_def( |
| 20 | + name = "time", |
| 21 | + units = "days since 2001-01-01", |
| 22 | + vals = seq(0, by = 1 / (n_time / 365), length.out = n_time) |
| 23 | + ) |
| 24 | + temp_var <- ncdf4::ncvar_def( |
| 25 | + name = "air_temperature", |
| 26 | + units = "K", |
| 27 | + dim = list(time_dim), |
| 28 | + missval = -9999 |
| 29 | + ) |
| 30 | + nc <- ncdf4::nc_create(file.path(outdir, filename), vars = list(air_temperature = temp_var)) |
| 31 | + on.exit(ncdf4::nc_close(nc), add = TRUE) |
| 32 | + ncdf4::ncatt_put(nc, 0, "description", "synthetic data for align.met test") |
| 33 | + ncdf4::ncvar_put(nc, temp_var, vals = seq(280, length.out = n_time, by = 0.01)) |
| 34 | + invisible(file.path(outdir, filename)) |
| 35 | +} |
| 36 | + |
| 37 | +test_that("align.met ensemble source path produces non-empty source data (bug: each=0 from stamps.hr truncation)", { |
| 38 | + train_dir <- withr::local_tempdir() |
| 39 | + source_dir <- withr::local_tempdir() |
| 40 | + |
| 41 | + ## Hourly training (8760 steps) produces stamps.hr[1] == 0.5, intentionally |
| 42 | + ## chosen so that any truncation of the step count to integer yields 0. |
| 43 | + make_align_nc(n_time = 8760, outdir = train_dir, filename = "2001.nc") |
| 44 | + |
| 45 | + ## Source: daily (365 steps), placed inside an ensemble subfolder. |
| 46 | + ens_dir <- file.path(source_dir, "ens001") |
| 47 | + dir.create(ens_dir) |
| 48 | + make_align_nc(n_time = 365, outdir = ens_dir, filename = "2001.nc") |
| 49 | + |
| 50 | + result <- align.met( |
| 51 | + train.path = train_dir, |
| 52 | + source.path = source_dir, |
| 53 | + n.ens = 1, |
| 54 | + seed = 20260602 |
| 55 | + ) |
| 56 | + |
| 57 | + ## 8760 hourly training rows; 365 source rows (one per day, repeated once each). |
| 58 | + expect_equal(nrow(result$dat.train$air_temperature), 8760) |
| 59 | + expect_equal(nrow(result$dat.source$air_temperature), 365) |
| 60 | +}) |
| 61 | + |
| 62 | +test_that("align.met single-series source matches training row count when already aligned", { |
| 63 | + train_dir <- withr::local_tempdir() |
| 64 | + source_dir <- withr::local_tempdir() |
| 65 | + |
| 66 | + ## Both training and source at the same 3-hourly resolution (2920 steps for 2001). |
| 67 | + make_align_nc(n_time = 2920, outdir = train_dir, filename = "2001.nc") |
| 68 | + make_align_nc(n_time = 2920, outdir = source_dir, filename = "2001.nc") |
| 69 | + |
| 70 | + result <- align.met( |
| 71 | + train.path = train_dir, |
| 72 | + source.path = source_dir, |
| 73 | + n.ens = 1, |
| 74 | + seed = 20260602 |
| 75 | + ) |
| 76 | + |
| 77 | + expect_equal(nrow(result$dat.source$air_temperature), |
| 78 | + nrow(result$dat.train$air_temperature)) |
| 79 | +}) |
0 commit comments