diff --git a/src/crop/almass.jl b/src/crop/almass.jl index 4c7dff6d4ce2b19b292679f49c3b6e4812e24ef2..dbc316b564b1d5725f45ceca38b1909ed6cb0966 100644 --- a/src/crop/almass.jl +++ b/src/crop/almass.jl @@ -14,9 +14,9 @@ using Persefone: m, SimulationModel, fertiliser, - initfields_fill_with!, maxtemp, mintemp + import Persefone: stepagent!, croptype, @@ -24,6 +24,7 @@ import Persefone: cropheight, cropcover, cropyield + using Dates: Date, month, monthday using CSV: CSV @@ -166,22 +167,6 @@ function readcropparameters(generalcropfile::String, growthfile::String) croptypes end -""" - initfields!(model) - -Initialise the model with its farm plots. -""" -function initfields!(model::SimulationModel) - initfields_fill_with!(model) do model, x, y - month(model.date) < 3 ? phase = ALMaSS.janfirst : phase = ALMaSS.marchfirst - FarmPlot(length(model.farmplots) + 1, [(x,y)], - CropState(model.crops["natural grass"], - phase, - 0.0, 0.0m, 0.0, 0.0, Vector{EventType}()) - ) - end -end - """ stepagent!(farmplot, model) diff --git a/src/crop/cropmodels.jl b/src/crop/cropmodels.jl index 6b47594555aa9cedcea5e964b2d61600e53ad977..0a16bc5e6fa292e51b7717f8ac6ef7e59b52906e 100644 --- a/src/crop/cropmodels.jl +++ b/src/crop/cropmodels.jl @@ -1,6 +1,6 @@ ### Persefone.jl - a model of agricultural landscapes and ecosystems in Europe. ### -### Crop model helper functions. +### Functions for switchable crop models. ### function initcropmodel(cropmodel::AbstractString, cropfile::AbstractString, growthfile::AbstractString) @@ -19,12 +19,58 @@ function initcropmodel(cropmodel::AbstractString, cropfile::AbstractString, grow return crops, Tcroptype, Tcropstate end +""" + initfields!(model) + +Initialise the model with its farm plots. +""" function initfields!(model::SimulationModel, cropmodel::AbstractString) + n = 0 + convertid = Dict{Int64,Int64}() + width, height = size(model.landscape) + for x in 1:width + for y in 1:height + # for each pixel, we need to extract the field ID given by the map input + # file, and convert it into the internal object ID used by Agents.jl, + # creating a new agent object if necessary + rawid = model.landscape[x,y].fieldid + (ismissing(rawid)) && continue + if rawid in keys(convertid) + objectid = convertid[rawid] + model.landscape[x,y].fieldid = objectid + push!(model.farmplots[objectid].pixels, (x,y)) + else + cropstate = make_cropstate(model, cropmodel) + fp = FarmPlot( + length(model.farmplots) + 1, + [(x, y)], + cropstate + ) + push!(model.farmplots, fp) + model.landscape[x,y].fieldid = fp.id + convertid[rawid] = fp.id + n += 1 + end + end + end + @info "Initialised $n farm plots." +end + +function make_cropstate(model::SimulationModel, cropmodel::AbstractString) if cropmodel == "almass" - ALMaSS.initfields!(model) + phase = (month(model.date) < 3 ? ALMaSS.janfirst : ALMaSS.marchfirst) + cs = ALMaSS.CropState( + model.crops["natural grass"], + phase, + 0.0, 0.0m, 0.0, 0.0, Vector{EventType}() + ) elseif cropmodel == "simple" - SimpleCrop.initfields!(model) + cs = SimpleCrop.CropState( + model.crops["natural grass"], + 0.0m + ) else - error("initfields! for crop model '$cropmodel'") + error("Unhandled crop model '$cropmodel' in make_cropstate") end + return cs end diff --git a/src/crop/farmplot.jl b/src/crop/farmplot.jl index 0758219930808ccf43be5b89a669f8040c16d445..49a100d01ff393fb1e142c8b9c2d61284d4e5d11 100644 --- a/src/crop/farmplot.jl +++ b/src/crop/farmplot.jl @@ -15,40 +15,6 @@ cropheight(f::FarmPlot{T}) where {T} = cropheight(f.crop_state) cropcover(f::FarmPlot{T}) where {T} = cropcover(f.crop_state) cropyield(f::FarmPlot{T}) where {T} = cropyield(f.crop_state) -""" - initfields_fill_with!(make_farmplot_fn, model) - -Initialise the model with its farm plots, using the -`make_farmplot_fn(model, x, y)` function to create new farmplots. -""" -function initfields_fill_with!(make_farmplot_fn::Function, model::SimulationModel) - n = 0 - convertid = Dict{Int64,Int64}() - width, height = size(model.landscape) - for x in 1:width - for y in 1:height - # for each pixel, we need to extract the field ID given by the map input - # file, and convert it into the internal object ID used by Agents.jl, - # creating a new agent object if necessary - rawid = model.landscape[x,y].fieldid - (ismissing(rawid)) && continue - if rawid in keys(convertid) - objectid = convertid[rawid] - model.landscape[x,y].fieldid = objectid - push!(model.farmplots[objectid].pixels, (x,y)) - else - fp = make_farmplot_fn(model, x, y) - push!(model.farmplots, fp) - model.landscape[x,y].fieldid = fp.id - convertid[rawid] = fp.id - n += 1 - end - end - end - @info "Initialised $n farm plots." -end - - ## UTILITY FUNCTIONS """ diff --git a/src/crop/simplecrop.jl b/src/crop/simplecrop.jl index c653390c49d5ee5c80b2c6f5ca58a0007df2d32f..dead41ffbfd5e13d109ee368668e6c94ebe64505 100644 --- a/src/crop/simplecrop.jl +++ b/src/crop/simplecrop.jl @@ -4,8 +4,8 @@ using Persefone: FarmPlot, Length, m, - SimulationModel, - initfields_fill_with! + SimulationModel + import Persefone: stepagent!, croptype, @@ -41,15 +41,4 @@ function stepagent!(farmplot::FarmPlot{CropState}, model::SimulationModel) # TODO: do something simple end -""" - initfields!(model) - -Initialise the model with its farm plots. -""" -function initfields!(model::SimulationModel) - initfields_fill_with!(model) do model, x, y - FarmPlot(length(model.farmplots) + 1, [(x,y)], CropState(model.crops["natural grass"], 0.0m)) - end -end - end # module SimpleCrop diff --git a/test/landscape_tests.jl b/test/landscape_tests.jl index fc6ae84b6b0f5ca8adaa411b0cbfd9031dbd8f19..d2d3f02c05acfc029ac621b6a1d765c312fe46b8 100644 --- a/test/landscape_tests.jl +++ b/test/landscape_tests.jl @@ -6,7 +6,8 @@ @testset "Landscape initialisation" begin model = inittestmodel(false) # these tests are specific to the Jena maps - @test_logs (:info, "Initialised 2092 farm plots.") match_mode=:any Ps.ALMaSS.initfields!(model) + cropmodel = "almass" + @test_logs (:info, "Initialised 2092 farm plots.") match_mode=:any Ps.initfields!(model, cropmodel) @test size(model.landscape) == (1754, 1602) @test Ps.landcover((100,100), model) == Ps.forest @test Ps.landcover((300,1), model) == Ps.soil