| Title: | R Implementation of the FAO CropWat Model |
|---|---|
| Description: | This package implements the functions describing water balance on an irrigated crop as described in FAO publications of the Irrigation and Drainage Series, namely, No. 56 "Crop Evapotranspiration - Guidelines for computing crop water requirements” and No. 33 titled "Yield response to water". |
| Authors: | David Dorchies [aut, cre] (ORCID: <https://orcid.org/0000-0002-6595-7984>), Myriam Soutif-Bellenger [aut] (ORCID: <https://orcid.org/0000-0001-6116-3899>), Claire Richert [aut] (ORCID: <https://orcid.org/0000-0001-7456-6689>), Guillaume Thirel [ctb] (ORCID: <https://orcid.org/0000-0002-1444-1830>) |
| Maintainer: | David Dorchies <[email protected]> |
| License: | AGPL (>= 3) |
| Version: | 0.3.0 |
| Built: | 2026-09-26 09:41:12 UTC |
| Source: | https://forge.inrae.fr/umr-g-eau/cropwat |
Compute cycle period extend during the year
calc_isCycle(cp, DatesR, sowing_date = cp$sowing_date)calc_isCycle(cp, DatesR, sowing_date = cp$sowing_date)
cp |
Crop parameters (See get_crop_params) |
DatesR |
A vector of continuous lubridate::Date
If |
sowing_date |
Sowing date in format "MM-DD" |
A vector of logical of the crop cycle for each day of the year.
DatesR <- seq(as.Date("2010-03-01"), as.Date("2010-10-31"), by = "1 day") isCycle <- calc_isCycle(get_crop_params("SB2023-soja"), DatesR) plot(isCycle)DatesR <- seq(as.Date("2010-03-01"), as.Date("2010-10-31"), by = "1 day") isCycle <- calc_isCycle(get_crop_params("SB2023-soja"), DatesR) plot(isCycle)
These functions compute the following parameters:
calc_Kc(cp, DatesR = NULL, sowing_date = cp$sowing_date) calc_RAW(TAW, p) calc_TAW( cp, AWC, soil_depth, DatesR = NULL, sowing_date = cp$sowing_date, root_depth = calc_root_depth(cp, soil_depth, DatesR, sowing_date) ) calc_p(cp, DatesR = NULL, sowing_date = cp$sowing_date) calc_root_depth(cp, soil_depth, DatesR = NULL, sowing_date = cp$sowing_date)calc_Kc(cp, DatesR = NULL, sowing_date = cp$sowing_date) calc_RAW(TAW, p) calc_TAW( cp, AWC, soil_depth, DatesR = NULL, sowing_date = cp$sowing_date, root_depth = calc_root_depth(cp, soil_depth, DatesR, sowing_date) ) calc_p(cp, DatesR = NULL, sowing_date = cp$sowing_date) calc_root_depth(cp, soil_depth, DatesR = NULL, sowing_date = cp$sowing_date)
cp |
Crop parameters (See get_crop_params) |
DatesR |
A vector of continuous lubridate::Date
If |
sowing_date |
Sowing date in format "MM-DD" |
TAW |
Total Available Water (mm). See calc_TAW |
p |
fraction of Readily Available Water time series. See calc_p |
AWC |
Available Water Capacity (mm) |
soil_depth |
Soil depth (m) |
root_depth |
Root depth time series (m). See calc_root_depth |
Calc_Kc: crop coefficient $K_c$
calc_p: critical depletion fraction $p=RAW/TAW$
calc_root_depth: root depth in m
calc_RAW: Readily Available Water (RAW) in mm
calc_TAW: Total Available Water (TAW) in mm
For calc_TAW, parameters cp, year, and sowing_date are useless if root_depth is
provided.
A vector of the parameter for each day of the crop cycle or the period defined by DatesR.
# Compute Kc for the crop cycle Kc <- calc_Kc(get_crop_params("SB2023-soja")) plot(Kc, type = "l") # Compute Kc for a given period (less than one year) # with default sowing date defined in crop parameters DatesR <- seq(as.Date("2010-03-01"), as.Date("2010-10-31"), by = "1 day") Kc <- calc_Kc(get_crop_params("SB2023-soja"), DatesR = DatesR) plot(Kc, type = "l") # Compute Kc for a given period with user defined sowing date Kc <- calc_Kc(get_crop_params("FAO-MAIZE"), DatesR = DatesR, sowing_date = "05-01") plot(Kc, type = "l")# Compute Kc for the crop cycle Kc <- calc_Kc(get_crop_params("SB2023-soja")) plot(Kc, type = "l") # Compute Kc for a given period (less than one year) # with default sowing date defined in crop parameters DatesR <- seq(as.Date("2010-03-01"), as.Date("2010-10-31"), by = "1 day") Kc <- calc_Kc(get_crop_params("SB2023-soja"), DatesR = DatesR) plot(Kc, type = "l") # Compute Kc for a given period with user defined sowing date Kc <- calc_Kc(get_crop_params("FAO-MAIZE"), DatesR = DatesR, sowing_date = "05-01") plot(Kc, type = "l")
Compute relative yield
calc_relative_yield(ETc, ETc_adj, ky) calc_yield_stagewise(ETc, ETc_adj, cp) calc_yield_for_cycle(cycle_id, cw_output, cp)calc_relative_yield(ETc, ETc_adj, ky) calc_yield_stagewise(ETc, ETc_adj, cp) calc_yield_for_cycle(cycle_id, cw_output, cp)
ETc |
vector of maximum evapotranspiration of the crop considered, for the whole season (mm.day-1) |
ETc_adj |
vector of actual evapotranspiration of the crop considered, for the whole season (mm.day-1) |
ky |
yield response factor (-) |
cp |
parameters of the crop (vector) |
cycle_id |
numeric identifier of the crop cycle considered. |
cw_output |
A tibble with at least 4 columns: ETc, ETc_adj, cycle_id, isCycle |
calc_relative_yield returns the relative
yields for the period considered.
calc_yield_stagewise returns a named vector with the relative yield for
each stage (compared to biomass accumulation during the stage) and for
the whole cycle.
calc_yield_for_cycle returns a named vector with cycle_id,
relative_yield_cycle, and relative_yield_{stage} (for stage in
(ini, dev, mid, end)) and relative_yield_cycle_stagewise
for the crop cycle considered.
calc_relative_yield(): Compute relative yield that depends on
water stress for a given period.
Reference: Crop Yield Response to Water.
FAO Irrigation and Drainage Paper 66 (2012), equation 1.
calc_yield_stagewise(): Compute relative yield that depends on water
stress at each growth stage.
Reference: Garg, N. K., and Sushmita M. Dadhich.
"A proposed method to determine yield response factors of different crops
under deficit irrigation using inverse formulation approach."
Agricultural Water Management 137 (2014): 68-74., equation 3.
calc_yield_for_cycle(): Compute relative yield for a given crop
cycle directly over the whole cycle and using the stagewise method.
example("CW_run_simulation", "CropWat")example("CW_run_simulation", "CropWat")
Create CropWat model input
CW_create_input( crop, DatesR, ETo, P, soil_depth, AWC, cp = get_crop_params(crop), sowing_date = cp$sowing_date )CW_create_input( crop, DatesR, ETo, P, soil_depth, AWC, cp = get_crop_params(crop), sowing_date = cp$sowing_date )
crop |
The code of the crop |
DatesR |
Simulation period (vector of lubridate::Date) |
ETo |
Potential Evaporation (mm/day) |
P |
Precipitation (mm/day) |
soil_depth |
soil depth (mm) |
AWC |
Available Water Capacity (mm) |
cp |
crop parameter (vector) |
sowing_date |
sowing date at the format 'mm-dd' |
The crop cycle begins at the first matching sowing date in the simulation period. So, first time steps of simulation if are not in a crop cycle even if they occur during the crop cycle.
A tibble containing the input times series.
# Import example climate dataset data(ZH_3_clim) str(ZH_3_clim) # Selecting years 2010 and 2011 meteo <- ZH_3_clim[ZH_3_clim$Date >= as.Date("2010-01-01") & ZH_3_clim$Date <= as.Date("2011-12-31"), ] # Create model input cw_input <- CW_create_input("SB2023-soja", DatesR = meteo$Date, ETo = meteo$ETP, P = meteo$Ptot, soil_depth = 1.2, AWC = 140) str(cw_input) plot(cw_input)# Import example climate dataset data(ZH_3_clim) str(ZH_3_clim) # Selecting years 2010 and 2011 meteo <- ZH_3_clim[ZH_3_clim$Date >= as.Date("2010-01-01") & ZH_3_clim$Date <= as.Date("2011-12-31"), ] # Create model input cw_input <- CW_create_input("SB2023-soja", DatesR = meteo$Date, ETo = meteo$ETP, P = meteo$Ptot, soil_depth = 1.2, AWC = 140) str(cw_input) plot(cw_input)
CropWat model state initiation
CW_create_state( Dr = 0, cw_input = NULL, iTS = 1, isCycle = cw_input$isCycle[iTS], TAW = cw_input$TAW[iTS] )CW_create_state( Dr = 0, cw_input = NULL, iTS = 1, isCycle = cw_input$isCycle[iTS], TAW = cw_input$TAW[iTS] )
Dr |
Initial root zone depletion (-) |
cw_input |
Model input |
iTS |
Time step to pick up in |
isCycle |
logical defining if the time step is in the crop cycle |
TAW |
Total Available Water (mm) |
A list with items:
Dr: Root zone depletion (-)
isCycle: logical indicating if the state stands during the crop cycle
TAW: Total Available Water (m)
example(CW_create_input, "CropWat") X <- CW_create_state(cw_input = cw_input) str(X)example(CW_create_input, "CropWat") X <- CW_create_state(cw_input = cw_input) str(X)
Retrieve the path of internal package data
CW_data(file)CW_data(file)
file |
File name |
The path of the file stored in the package dataset
CW_data("crop_params.tsv")CW_data("crop_params.tsv")
Built-in irrigation management functions for use in CW_model. For custom irrigation strategies, see CW_irrig_fun_factory.
CW_irrig_0(X, input, Dr) CW_irrig_Dr(X, input, Dr)CW_irrig_0(X, input, Dr) CW_irrig_Dr(X, input, Dr)
X |
Model state at previous time step |
input |
Model input for the current time step |
Dr |
Current soil moisture depletion |
The amount of the daily irrigation (m)
CW_irrig_0(): simulates the absence of irrigation
(returns 0 for all time steps).
CW_irrig_Dr(): simulates an irrigation system that fills the
soil's moisture depletion on a daily basis.
CW_irrig_0() example(CW_create_state, "CropWat") CW_irrig_Dr(X, cw_input[1, ], 0.1) CW_irrig_Dr(X, cw_input[100, ], 0.1)CW_irrig_0() example(CW_create_state, "CropWat") CW_irrig_Dr(X, cw_input[1, ], 0.1) CW_irrig_Dr(X, cw_input[100, ], 0.1)
This function is a helper for generating irrigation management based on
thresholds calculated from fixed ratios of RAW and/or TAW.
The generated threshold is computed as RAW_ratio * RAW + TAW_ratio * TAW,
where RAW (calc_RAW) is the Readily Available Water and TAW (calc_TAW)
is the Total Available Water in the root zone.
CW_irrig_fun_factory( RAW_ratio, TAW_ratio = 0, apply_Dr = FALSE, dates_irrig = NULL )CW_irrig_fun_factory( RAW_ratio, TAW_ratio = 0, apply_Dr = FALSE, dates_irrig = NULL )
RAW_ratio |
Numeric multiplier applied to RAW (Readily Available Water) for computing the irrigation trigger threshold. When soil depletion (Dr) exceeds this threshold, irrigation is triggered. |
TAW_ratio |
Numeric multiplier applied to TAW (Total Available Water)
for computing the irrigation trigger threshold. Added to |
apply_Dr |
When the threshold is reached, should the irrigation dose fill
the soil's moisture depletion?
If |
dates_irrig |
vector of lubridate::Date when irrigation occurs (By default, irrigation is applied during the crop cycle) |
A function which computes the irrigation dose for the current day.
# An irrigation management function which triggers an irrigation when # Dr < 0.5 * RAW with a dose filling until 0.5 * RAW fun_irrig_half_RAW <- CW_irrig_fun_factory(0.5) fun_irrig_half_RAW str(as.list(environment(fun_irrig_half_RAW)))# An irrigation management function which triggers an irrigation when # Dr < 0.5 * RAW with a dose filling until 0.5 * RAW fun_irrig_half_RAW <- CW_irrig_fun_factory(0.5) fun_irrig_half_RAW str(as.list(environment(fun_irrig_half_RAW)))
Run CropWat model for one time step
CW_model(X, input, FUN_IRRIG = CW_irrig_Dr, is_irrigable_day = TRUE)CW_model(X, input, FUN_IRRIG = CW_irrig_Dr, is_irrigable_day = TRUE)
X |
Initial state (See CW_create_state) |
input |
Model input (See CW_create_input) |
FUN_IRRIG |
Irrigation management function. Built-in options include those documented in CW_irrig (no irrigation, full depletion refill). Custom functions can be generated with CW_irrig_fun_factory. |
is_irrigable_day |
logical |
A named numeric vector of class "CW_model" with items:
Ks: Water stress coefficient (0-1, where 1 = no stress)
ETc_adj: Adjusted crop evapotranspiration (mm/day)
Dr: Root zone depletion at the end of the time step (mm)
Ir: Irrigation dose for the current day (mm)
The returned value has an attribute "state" which contains the final state
of the model at the end of the day (See CW_create_state).
data(ZH_3_clim) meteo <- ZH_3_clim[ZH_3_clim$Date >= as.Date("2010-01-01") & ZH_3_clim$Date <= as.Date("2010-12-31"), ] cw_input <- CW_create_input("SB2023-soja", DatesR = meteo$Date, ETo = meteo$ETP, P = meteo$Ptot, soil_depth = 1.2, AWC = 140) X0 <- CW_create_state(cw_input = cw_input) X1 <- CW_model(X0, cw_input[1, ]) str(X1)data(ZH_3_clim) meteo <- ZH_3_clim[ZH_3_clim$Date >= as.Date("2010-01-01") & ZH_3_clim$Date <= as.Date("2010-12-31"), ] cw_input <- CW_create_input("SB2023-soja", DatesR = meteo$Date, ETo = meteo$ETP, P = meteo$Ptot, soil_depth = 1.2, AWC = 140) X0 <- CW_create_state(cw_input = cw_input) X1 <- CW_model(X0, cw_input[1, ]) str(X1)
Run a simulation with the CropWat model
CW_run_simulation(X, cw_input, FUN_IRRIG = CW_irrig_Dr)CW_run_simulation(X, cw_input, FUN_IRRIG = CW_irrig_Dr)
X |
Initial state (See CW_create_state) |
cw_input |
Model input (See CW_create_input) |
FUN_IRRIG |
Irrigation management function. Built-in options include those documented in CW_irrig (no irrigation, full depletion refill). Custom functions can be generated with CW_irrig_fun_factory. |
A tibble with the daily time series of the model output, with one row by time step and the following columns:
DatesR: Dates of the simulation
Ks: Water stress coefficient (0-1, where 1 = no stress)
ETc_adj: Adjusted evapotranspiration (mm/day)
ETc: Potential evapotranspiration (mm/day)
Dr: Root zone depletion (mm)
Ir: Irrigation (mm)
cycle_id: Crop cycle identifier (i.e year number of sowing)
isCycle: Indicator if the row belongs to a crop cycle (i.e between sowing
and harvest)
It also has the following attributes:
final_state: the final state of the model after the simulation
relative_yield: a data.frame with the relative yield for each crop
cycle, one row by cycle, with columns cycle_id, relative_yield_cycle,
and relative_yield_stagewise, where the latter two are computed with
calc_yield_for_cycle
example("CW_create_state", "CropWat") cw_output <- CW_run_simulation(X, cw_input) str(cw_output) plot(cw_output, which = c("daily", "yields"))example("CW_create_state", "CropWat") cw_output <- CW_run_simulation(X, cw_input) str(cw_output) plot(cw_output, which = c("daily", "yields"))
load_crop_params: load the parameters for all the crops
get_crop_params: returns the parameters of a given crop
load_crop_params(file = CW_data("crop_params.tsv")) get_crop_params(crop, crop_params = load_crop_params())load_crop_params(file = CW_data("crop_params.tsv")) get_crop_params(crop, crop_params = load_crop_params())
file |
Path of the table of crop parameters |
crop |
The code of the crop |
crop_params |
data.frame of crop parameters (See load_crop_params) |
The file to read should have the following columns and format:
crop: crop code
Lini: Length of initial stage of crop development
Ldev: Length of crop development stage
Lmid: Length of mid season
Lend: Length of late season
Kini: Initial Kc at the beginning of the crop cycle during Lini days (-)
Kmax: Maximum Kc during Lmid day of the cycle (-)
Kend: Final Kc at the end of the cycle (-)
Zini: Initial root depth at the beginning of the crop cycle (m)
Zend: Final root depth at the end of the crop cycle (m)
p_ini: Initial fraction of readily available water (-)
p_mid: Fraction of readily available water at Lmid day of the cycle (-)
p_end: Final Initial fraction of readily available water at Lend day of the cycle (-)
Yini: Yield response factor (Ky, not used yet)
Ydev: Yield response factor (Ky, not used yet)
Ymid: Yield response factor (Ky, not used yet)
Yend: Yield response factor (Ky, not used yet)
Ytot: Yield response factor (Ky, not used yet)
h: crop height (m) (not used)
sowing_date: Sowing date in format "MM-DD"
The default crop parameters provided in the package come from a variety of sources.
Crop names starting with "KURN-" or "FAO-" are imported from the CRO files provided with the CropWat 8.0 installation. "KURN-" are crop parameters calibrated at "Kurnool, Andhra Pradesh, India".
Crop names starting with "SB2023-" are crop parameters coming from a calibration performed on outputs of the AqYield model for the Aveyron catchment (Soutif-Bellenger, 2023).
Soutif-Bellenger, Myriam, Guillaume Thirel, Olivier Therond, et Jean Villerd. 2023. As Simple as Possible but Not Simpler?: The Case of Irrigation Modeling at Catchment Scale in Southwestern France. Irrigation Science 41 (5): 713‑36.
A tibble, see details for the column formats.
# Get available crops in the package cp <- load_crop_params() cp$crop str(cp) # Get parameters for sugar beet from FAO get_crop_params("FAO-SUGARBET")# Get available crops in the package cp <- load_crop_params() cp$crop str(cp) # Get parameters for sugar beet from FAO get_crop_params("FAO-SUGARBET")
Load CropWat v8.0 crop parameter CRO file
load_CW8_CRO(file)load_CW8_CRO(file)
file |
Path of the CRO file |
Crop parameters formatted as
load_CW8_CRO(system.file("extdata/TOMATO.CRO", package = "CropWat"))load_CW8_CRO(system.file("extdata/TOMATO.CRO", package = "CropWat"))
Generic plotting function for objects of class CW_TS (including
CW_input and CW_output). Dispatches to internal plotting functions
based on the which argument.
## S3 method for class 'CW_TS' plot(x, which = "daily", ...) plot_daily(x, ...) plot_yields(x, which_yields = NULL, ...)## S3 method for class 'CW_TS' plot(x, which = "daily", ...) plot_daily(x, ...) plot_yields(x, which_yields = NULL, ...)
x |
An object of class |
which |
Character vector that lists the kind of outputs to display.
It can be |
... |
Additional arguments passed to the internal plotting functions.
When |
which_yields |
A character vector with the relative yield types to plot.
It can contain |
See CW_create_input and CW_run_simulation for examples.
A list of ggplot2::ggplot() objects, one for each element in which.
plot_daily(): Plot daily inputs and outputs as faceted line plots.
Each variable in the input/output object is displayed in a separate panel
with dates on the x-axis.
plot_yields(): Plot estimated relative yields as faceted bar plots.
Each yield type is displayed in a separate panel, with cycle IDs on the x-axis.
Requires the input object to have a relative_yield attribute
(typically produced by CW_run_simulation).
A data.frame with 3 columns:
Date: the date
Prtot: precipitation (mm/day)
ETP: Potential evaporation (mm/day)
ZH_3_climZH_3_clim
An object of class spec_tbl_df (inherits from tbl_df, tbl, data.frame) with 2922 rows and 3 columns.