Skip to contents

This article describes how to structure a similar wcswatin project with your own data. The São Lourenço basin area in Mato Grosso, Brazil, is used in the package website as a test region, but the same workflow applies to any basin or region of interest with compatible raster, vector, and station inputs.

Data source

The gridded part of the case uses ERA5-Land hourly data for 2025-10-01 to 2025-12-31.

Variable ERA5-Land name Original unit SWAT unit
u10 10m u component of wind m s^-1 m s^-1
v10 10m v component of wind m s^-1 m s^-1
d2m 2m dewpoint temperature K deg C
t2m 2m temperature K deg C
ssrd surface solar radiation downwards J m^-2 MJ m^-2
tp total precipitation m mm
ws10 wind speed derived m s^-1
rh2m relative humidity derived %

The NetCDF files can be downloaded with any CDS workflow. The companion cds-downloader CLI is optional and can help create repeatable download requests:

cds-downloader --help

Tool page: https://github.com/reginalexavier/cds-downloader

Suggested directory layout

Keep raw inputs, intermediate outputs, and final SWAT-ready files in explicit project folders. One simple pattern is:

Sys.setenv(WCSWATIN_CASE_ROOT = "/path/to/your_case")
case_root <- Sys.getenv("WCSWATIN_CASE_ROOT")
data/
  input/
    nc_files/
      hourly/
      daily/
    raster/
    weather-station-data/
  output/

In the São Lourenço test run, the input files were about 94 MB and the complete output folder was about 193 MB with intermediates. The final daily SWAT-style gridded outputs were much smaller, around 200-381 KB per variable.

Choose the time resolution

Start by inspecting the NetCDF metadata. raster_info() shows the data variables, units, layer count, date range, and time resolution, which are the main details needed to choose the processing route.

raster_info(file.path(case_root, "data/input/nc_files/hourly/t2m.nc"))
raster_info(file.path(case_root, "data/input/nc_files/daily/t2m_daily.nc"))

There are three practical starting points:

Starting point Main path Consequence
Hourly NetCDF cube2table() -> layervalues2pixel() -> daily_aggregation() Full control over daily statistics and timestamp rules
Daily NetCDF from CDS or cds-downloader cube2table() -> layervalues2pixel() Faster extraction and no table aggregation step
Hourly NetCDF reduced locally datacube_aggregation() -> cube2table() -> layervalues2pixel() Faster extraction after daily aggregation or value-at-hour selection

For accumulated variables timestamped at a specific hour, datacube_aggregation(mode = "value_at_hour") can reduce the hourly cube before extraction. For ERA5-Land accumulated values timestamped at 00:00, use value_hour = 0 and date_shift_days = -1; set drop_first_layer = TRUE only when the first selected layer belongs to the day before the requested period.

Workflow checklist

The case workflow can be implemented with ordinary R scripts or notebooks. The important part is the order of operations:

Step Main functions Purpose
1 study_area_records() Build study_area.csv from raster grid, basin, and DEM
2 main_input_var() Create one mainFile.csv per variable
3 cube2table() Extract NetCDF cubes into long layer tables
4 layervalues2pixel() Write one hourly time series per pixel
5 unit_converter(), daily_aggregation() Convert units and aggregate hourly files to daily files
6 windspeed_calculator(), rh_calculator() Derive wind speed and relative humidity
7 files_to_table(), fill_gap(), point_to_daily() Prepare station observations for interpolation
8 ts_to_area(), ts_to_point(), ts_point_to_files() Interpolate station values to rasters or target points
9 tbl_from_references() Prepare extracted raster tables for validation workflows

Parallel extraction

cube2table() is the part of the workflow where parallel execution usually pays off the most, because the extraction work can be split by raster layer. The function follows the future model: users select the backend with future::plan(), and the extraction call itself does not need to change.

# Debug or reproduce in one R process
future::plan(future::sequential)

# Portable local parallelism
future::plan("multisession", workers = 8)

# Unix-like terminal sessions
future::plan("multicore", workers = 8)

In the benchmarked run with 2,208 layers and 229 grid cells:

Mode Workers Time per variable
multicore 10 about 6.6 minutes
multicore 8 about 7.0 minutes
multisession 10 about 7.0 minutes
multisession 8 about 7.1 minutes
sequential 1 about 39.5 minutes

This keeps wcswatin from hard-coding a parallel backend. A local workstation, an RStudio session, a server, or a scheduler-backed setup can use the same workflow with the future backend that fits that environment. See the future overview for backend details: https://cran.r-project.org/web/packages/future/vignettes/future-1-overview.html.

Adapting the case

For a new region, replace the basin boundary, DEM, station metadata, and NetCDF files, then keep the same processing order. The exact variable list and daily aggregation mode should follow the source product semantics. For accumulated ERA5-Land variables, values timestamped at 00:00 represent the previous day, so use mode = "value_at_hour" with value_hour = 0 after selecting an input period that includes the closing midnight records.