Skip to content
Snippets Groups Projects
Commit dbfad2f7 authored by Marco Matthies's avatar Marco Matthies
Browse files

Add initial scaffolding for AquaCrop crop model

parent df5dce82
No related branches found
No related tags found
No related merge requests found
...@@ -147,6 +147,7 @@ include("crop/farmplot.jl") ...@@ -147,6 +147,7 @@ include("crop/farmplot.jl")
include("crop/cropmodels.jl") include("crop/cropmodels.jl")
include("crop/almass.jl") include("crop/almass.jl")
include("crop/simplecrop.jl") include("crop/simplecrop.jl")
include("crop/aquacrop.jl")
include("farm/farm.jl") include("farm/farm.jl")
include("farm/farmdata.jl") include("farm/farmdata.jl")
......
...@@ -20,7 +20,7 @@ const PARAMFILE = joinpath(pkgdir(Persefone), "src/parameters.toml") ...@@ -20,7 +20,7 @@ const PARAMFILE = joinpath(pkgdir(Persefone), "src/parameters.toml")
""" """
The crop models that can be used in the simulation. The crop models that can be used in the simulation.
""" """
const AVAILABLE_CROPMODELS = ["almass", "simple"] const AVAILABLE_CROPMODELS = ["almass", "simple", "aquacrop"]
""" """
@param(domainparam) @param(domainparam)
......
struct AquaCropType
name::String
group::String
minsowdate::Union{Missing,AnnualDate}
maxsowdate::Union{Missing,AnnualDate}
end
cropname(ct::AquaCropType) = ct.name
mutable struct AquaCropState
croptype::AquaCropType
height::Length{Float64}
end
croptype(cs::AquaCropState) = cs.croptype
cropname(cs::AquaCropState) = cropname(croptype(cs))
cropheight(cs::AquaCropState) = cs.height
cropcover(cs::AquaCropState) = 0.0 # TODO: implement
cropyield(cs::AquaCropState) = 0.0 # TODO: implement, units?
isharvestable(cs::AquaCropState) = true # TODO: implement this correctly
"""
stepagent!(cropstate, model)
Update a crop state by one day.
"""
function stepagent!(cs::AquaCropState, model::SimulationModel)
# TODO: call into AquaCrop.jl to simulate one day
end
"""
sow!(cropstate, model, cropname)
Change the cropstate to sow the specified crop.
"""
function sow!(cs::AquaCropState, model::SimulationModel, cropname::String)
cs.croptype = model.crops[cropname]
cs.height = 0.0cm
# TODO: other things needed for AquaCrop?
end
"""
harvest!(cropstate, model)
Harvest the crop of this cropstate.
"""
function harvest!(cs::AquaCropState, model::SimulationModel)
# TODO: implement this
return 0.0u"g/m^2"
end
...@@ -20,6 +20,13 @@ function initcropmodel(cropmodel::AbstractString, cropfile::AbstractString, grow ...@@ -20,6 +20,13 @@ function initcropmodel(cropmodel::AbstractString, cropfile::AbstractString, grow
crops_almass = ALMaSS.readcropparameters(cropfile, growthfile) crops_almass = ALMaSS.readcropparameters(cropfile, growthfile)
crops = Dict(name => SimpleCrop.CropType(ct.name, ct.group, ct.minsowdate, ct.maxsowdate) crops = Dict(name => SimpleCrop.CropType(ct.name, ct.group, ct.minsowdate, ct.maxsowdate)
for (name, ct) in crops_almass) for (name, ct) in crops_almass)
elseif cropmodel == "aquacrop"
Tcroptype = AquaCropType
Tcropstate = AquaCropState
# TODO: temporarily using ALMaSS crop types
crops_almass = ALMaSS.readcropparameters(cropfile, growthfile)
crops = Dict(name => AquaCropType(ct.name, ct.group, ct.minsowdate, ct.maxsowdate)
for (name, ct) in crops_almass)
else else
error("initcropmodel: no implementation for crop model '$cropmodel'") error("initcropmodel: no implementation for crop model '$cropmodel'")
end end
...@@ -74,6 +81,8 @@ function makecropstate(model::SimulationModel) ...@@ -74,6 +81,8 @@ function makecropstate(model::SimulationModel)
model.crops["natural grass"], model.crops["natural grass"],
0.0m 0.0m
) )
elseif @param(crop.cropmodel) == "aquacrop"
cs = AquaCropState(model.crops["natural grass"], 0.0m)
else else
Base.error("Unhandled crop model '$(@param(crop.cropmodel))' in makecropstate().") Base.error("Unhandled crop model '$(@param(crop.cropmodel))' in makecropstate().")
end end
......
...@@ -5,8 +5,9 @@ ...@@ -5,8 +5,9 @@
const TESTPARAM_ALMASS = joinpath(pkgdir(Persefone), "test", "test_parameters_almass.toml") const TESTPARAM_ALMASS = joinpath(pkgdir(Persefone), "test", "test_parameters_almass.toml")
const TESTPARAM_SIMPLECROP = joinpath(pkgdir(Persefone), "test", "test_parameters_simplecrop.toml") const TESTPARAM_SIMPLECROP = joinpath(pkgdir(Persefone), "test", "test_parameters_simplecrop.toml")
const TESTPARAM_AQUACROP = joinpath(pkgdir(Persefone), "test", "test_parameters_aquacrop.toml")
@testset for paramfile in (TESTPARAM_ALMASS, TESTPARAM_SIMPLECROP) @testset for paramfile in (TESTPARAM_ALMASS, TESTPARAM_SIMPLECROP, TESTPARAM_AQUACROP)
@testset "Model initialisation" begin @testset "Model initialisation" begin
model = initialise(paramfile) model = initialise(paramfile)
@test model isa AgricultureModel @test model isa AgricultureModel
...@@ -18,7 +19,7 @@ const TESTPARAM_SIMPLECROP = joinpath(pkgdir(Persefone), "test", "test_parameter ...@@ -18,7 +19,7 @@ const TESTPARAM_SIMPLECROP = joinpath(pkgdir(Persefone), "test", "test_parameter
end end
end end
@testset "Submodule ALMaSS" begin @testset "Crop model ALMaSS" begin
ct = Ps.ALMaSS.CropType("olive tree", "no_crop_group", ct = Ps.ALMaSS.CropType("olive tree", "no_crop_group",
missing, missing, missing, missing, missing, missing, missing) missing, missing, missing, missing, missing, missing, missing)
id = 0 id = 0
...@@ -37,7 +38,7 @@ end ...@@ -37,7 +38,7 @@ end
@test cropyield(fp) isa Float64 @test cropyield(fp) isa Float64
end end
@testset "Submodule SimpleCrop" begin @testset "Crop model SimpleCrop" begin
ct = Ps.SimpleCrop.CropType("olive tree", "no_crop_group", AnnualDate(4, 1), AnnualDate(5, 1)) ct = Ps.SimpleCrop.CropType("olive tree", "no_crop_group", AnnualDate(4, 1), AnnualDate(5, 1))
id = 0 id = 0
pixels = [(0, 0)] pixels = [(0, 0)]
...@@ -51,3 +52,19 @@ end ...@@ -51,3 +52,19 @@ end
@test cropcover(fp) isa Float64 @test cropcover(fp) isa Float64
@test cropyield(fp) isa Float64 @test cropyield(fp) isa Float64
end end
@testset "Crop model AquaCrop" begin
ct = Ps.AquaCropType("olive tree", "no_crop_group", AnnualDate(4, 1), AnnualDate(5, 1))
id = 0
pixels = [(0, 0)]
farmer = 0
fp = FarmPlot(id, pixels, farmer, Ps.AquaCropState(ct, 0.0cm))
@test fp isa FarmPlot
@test fp isa FarmPlot{Ps.AquaCropState}
@test croptype(fp) isa Ps.AquaCropType
@test cropname(fp) isa String
@test cropheight(fp) isa Length{Float64}
@test cropcover(fp) isa Float64
@test cropyield(fp) isa Float64
# TODO: test stepagent!(), sow!(), harvest!()
end
### Persefone.jl - a model of agricultural landscapes and ecosystems in Europe.
###
### This configuration file is used for the test suite.
###
#XXX remember that changes here may break tests!
[core]
configfile = "test_parameters_aquacrop.toml" # location of the configuration file
outdir = "results_testsuite" # location and name of the output folder
logoutput = "both"
overwrite = true # overwrite the output directory? (true/false/"ask")
csvoutput = true # save collected data in CSV files
visualise = true # generate result graphs
storedata = true # keep collected data in memory
loglevel = "warn" # verbosity level: "debug", "info", "warn"
processors = 6 # number of processors to use on parallel runs
seed = 1 # seed value for the RNG (0 -> random value)
# dates to start and end the simulation
startdate = 2022-02-01
enddate = 2022-03-31
[world]
mapdirectory = "." # the directory in which all geographic data are stored
mapresolution = 10 # map resolution in meters
landcovermap = "landcover_jena.tif" # location of the landcover map
farmfieldsmap = "fields_jena.tif" # location of the field geometry map
weatherfile = "weather_jena.csv" # location of the weather data file
[farm]
farmmodel = "BasicFarmer" # which version of the farm model to use
setaside = 0.04 # proportion of farm area set aside as fallow
fieldoutfreq = "daily" # output frequency for crop/field data, daily/monthly/yearly/end/never
[nature]
targetspecies = ["Wolpertinger", "Wyvern"] # list of target species to simulate - example species
#targetspecies = ["Skylark"] # list of target species to simulate
popoutfreq = "daily" # output frequency population-level data, daily/monthly/yearly/end/never
indoutfreq = "daily" # output frequency individual-level data, daily/monthly/yearly/end/never
insectmodel = ["season", "habitat", "pesticides"] # which factors affect insect growth ("weather" is not yet implemented)
[crop]
cropmodel = "aquacrop" # crop growth model to use, "almass", "aquacrop", or "simple"
# TODO: these two files below are ALMaSS parameters
cropfile = "crop_data_general.csv" # file with general crop parameters
growthfile = "almass_crop_growth_curves.csv" # file with crop growth parameters
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment