Using an Existing Cropbox Model
This tutorial will teach you how to use an existing Cropbox model. For this tutorial, we will be importing and utilizing a Cropbox model from a julia package called SimpleCrop.
Installing a Cropbox Model
Often times, the Cropbox model that you want to use will be part of a Julia package.
If the package you want to install is under the official Julia package registry, you can simply install the package using the following command.
using Pkg
Pkg.add("SimpleCrop")
You can also install any Julia package using a GitHub link.
using Pkg
Pkg.add("https://github.com/cropbox/SimpleCrop.jl")
Importing a Cropbox Model
To start using a Julia package containing your desired model, you must first load the package into your environment.
This can be done by using this simple command.
using SimpleCrop
Let's not forget to load Cropbox as well.
using Cropbox
Inspecting the Model
The model is implemented as a system named Model
defined in SimpleCrop module. We can inspect the model with the @look
macro, which will show us all the variables in the system.
@look SimpleCrop.Model
[doc]
[system]
Model
context
config
DATE
DOY
DOYP (planting_day_of_year)
TMAX (maximum_temperature)
TMIN (minimum_temperature)
TMN (mean_temperature)
PAR (photosynthetically_active_radiation)
SWFAC (soil_water_stress_factor)
EMP1 (LAI_coeff1)
EMP2 (LAI_coeff2)
Fc (canopy_fraction)
sla (specific_leaf_area)
INTOT (duration_of_reproductive_stage)
LAI0 (initial_leaf_area_index)
Lfmax (maximum_leaf_number)
N0 (initial_leaf_number)
nb (LAI_coeff)
p1 (leaf_senescence_rate)
PD (plant_density)
rm (maximum_leaf_appearance_rate)
tb (base_temperature)
W0 (initial_plant_dry_matter)
Wc0 (initial_canopy_dry_matter)
Wr0 (initial_root_dry_matter)
PT (photosynthesis_reduction_factor_for_temp)
RUE (radiation_use_efficiency)
Pg (potential_growth_rate)
ROWSPC (row_spacing)
Y1 (canopy_light_extinction_coeff)
P (planted)
VP (vegetative_phase)
RP (reproductive_phase)
FL (development_phase_code)
dN (leaf_number_increase)
N (leaf_number)
di (daily_accumulated_temperature)
INT (accumulated_temperature_during_reproductive_stage)
_a
dLAI1
dLAI2
dLAI (leaf_area_index_increase)
LAI (leaf_area_index)
E (CH2O_conversion_efficiency)
dW
W (plant_dry_matter)
Wc (canopy_dry_matter)
Wr (root_dry_matter)
Wf (fruit_dry_matter)
endsim (end_of_simulation)
Δt (timestep)
SRAD (solar_radiation)
RAIN (rainfall)
calendar
_i (irrigation_data)
IRR
CN (runoff_curve_number)
DP (soil_profile_depth)
DRNp (daily_drainage)
WPp (soil_water_portion_at_wilting_point)
FCp (soil_water_portion_at_field_capacity)
STp (soil_water_portion_at_saturation)
SWC0 (initial_soil_water_content)
WP (soil_water_content_at_wilting_point)
FC (soil_water_content_at_field_capacity)
ST (soil_water_content_at_saturation)
S (potential_maximum_soil_moisture_retention_after_runoff)
POTINF (potential_infiltration)
ROF (runoff)
INF (infiltration)
THE (soil_water_content_threshold)
TRAIN (cumulative_rainfall)
TIRR (cumulative_irrigation)
TESa (cumulative_soil_evaporation)
TEPa (cumulative_plant_transpiration)
TROF (cumulative_runoff)
TDRN (cumulative_vertical_drainage)
TINF (cumulative_infiltration)
DRN (vertical_drainage)
αs (soil_albedo)
αc (crop_albedo)
ALB (surface_albedo)
Tmed
EEQ (equilibrium_evaporation)
f
ETp (potential_evapotranspiration)
ESp (potential_soil_evaporation)
EPp (potential_plant_transpiration)
_a
ESa (soil_evaporation)
EPa (plant_transpiration)
dSWC
dROF_extra
dSWC_ADJ
SWC_ADJ
SWC (soil_water_content)
ΔSWC (storage_change)
Fi
Fo
WATBAL
CHECK
SWFAC1 (drought_stress_factor)
WTABLE (water_table_thickness)
DWT (water_table_depth)
STRESS_DEPTH (water_table_depth_threshold)
SWFAC2 (excess_stress_factor)
_w (weather_data)
@look can also be used to inspect individual state variables.
@look SimpleCrop.Model.W
[doc]
[code]
W(dW):plant_dry_matter ~ accumulate(u"g/m^2", init = W0, when = P)
The relationship between the variables in the model can be visualized using a dependency graph.
Cropbox.dependency(SimpleCrop.Model)
If an arrow points from one variable to a second variable, then the value of the second variable depends on, or is calculated with, the value of the first.
We can view the values of all the parameters of the model with the following command.
parameters(SimpleCrop.Model; alias = true)
Config for 1 system:
Model | ||
weather_data | = | nothing |
planting_day_of_year | = | 121 d |
LAI_coeff1 | = | 0.104 m^2 |
LAI_coeff2 | = | 0.64 |
canopy_fraction | = | 0.85 |
duration_of_reproductive_stage | = | 300.0 d K |
initial_leaf_area_index | = | 0.013 |
maximum_leaf_number | = | 12.0 |
initial_leaf_number | = | 2.0 |
LAI_coeff | = | 5.3 |
leaf_senescence_rate | = | 0.03 g K^-1 |
plant_density | = | 5.0 m^-2 |
maximum_leaf_appearance_rate | = | 0.1 d^-1 |
base_temperature | = | 10.0 °C |
initial_plant_dry_matter | = | 0.3 g m^-2 |
initial_canopy_dry_matter | = | 0.045 g m^-2 |
initial_root_dry_matter | = | 0.255 g m^-2 |
radiation_use_efficiency | = | 2.1 g MJ^-1 |
row_spacing | = | 60.0 cm |
CH2O_conversion_efficiency | = | 1.0 |
irrigation_data | = | nothing |
runoff_curve_number | = | 55 |
soil_profile_depth | = | 145 cm |
daily_drainage | = | 0.1 d^-1 |
soil_water_portion_at_wilting_point | = | 0.06 |
soil_water_portion_at_field_capacity | = | 0.17 |
soil_water_portion_at_saturation | = | 0.28 |
initial_soil_water_content | = | 246.5 mm |
soil_albedo | = | 0.1 |
crop_albedo | = | 0.2 |
water_table_depth_threshold | = | 250 mm |
Running a Simulation
As many parameters are already defined in the model, we only need to prepare time-series data for daily weather and irrigation, which are included in the package for convenience.
using CSV
using DataFrames
using Dates
using TimeZones
loaddata(f) = CSV.File(joinpath(dirname(pathof(SimpleCrop)), "../test/data", f)) |> DataFrame
config = @config (
:Clock => :step => 1u"d",
:Calendar => :init => ZonedDateTime(1987, 1, 1, tz"UTC"),
:Weather => :weather_data => loaddata("weather.csv"),
:SoilWater => :irrigation_data => loaddata("irrigation.csv"),
)
Let's run a simulation with the model using configuration we just created. Stop condition for simulation is defined in a flag variable named endsim
which coincides with plant maturity or the end of reproductive stage.
r = simulate(SimpleCrop.Model; config, stop = :endsim)
Visualizing the Results
The output of simulation is now contained in a data frame from which we generate multiple plots. The number of leaf (N
) went from initial_leaf_number
(= 2) to maximum_leaf_number
(= 12) as indicated in the default set of parameters.
visualize(r, :DATE, :N; ylim = (0, 15), kind = :line)
Thermal degree days (INT
) started accumulating from mid-August with the onset of reproductive stage until late-October when it reaches the maturity indicated by duration_of_reproductive_stage
(= 300 K d).
visualize(r, :DATE, :INT; kind = :line)
Assimilated carbon (W
) was partitioned into multiple parts of the plant as shown in the plot of dry biomass.
visualize(r, :DATE, [:W, :Wc, :Wr, :Wf];
names = ["Total", "Canopy", "Root", "Fruit"], kind = :line)
Leaf area index (LAI
) reached its peak at the end of vegetative stage then began declining throughout reproductive stage.
visualize(r, :DATE, :LAI; kind = :line)
For soil water balance, here is a plot showing water runoff (ROF
), infiltration (INF
), and vertical drainage (DRN
).
visualize(r, :DATE, [:ROF, :INF, :DRN]; kind = :line)
Soil water status has influence on potential evapotranspiration (ETp
), actual soil evaporation (ESa
), and actual plant transpiration (ESp
).
visualize(r, :DATE, [:ETp, :ESa, :EPa]; kind = :line)
The resulting soil water content (SWC
) is shown here.
visualize(r, :DATE, :SWC; ylim = (0, 400), kind = :line)
Which, in turn, determines soil water stress factor (SWFAC
) in this model.
visualize(r, :DATE, [:SWFAC, :SWFAC1, :SWFAC2]; ylim = (0, 1), kind = :line)