From 5b0a8841901567dca32b8631a428f794571cb046 Mon Sep 17 00:00:00 2001
From: Marco Matthies <71844+marcom@users.noreply.github.com>
Date: Mon, 15 Jul 2024 17:11:09 +0200
Subject: [PATCH] Introduce an AbstracFarmPlot type and a SimpleCrop submodule

---
 src/Persefone.jl       |  2 +-
 src/core/input.jl      |  8 ++++++++
 src/core/simulation.jl | 14 ++++++++++----
 src/crop/almass.jl     |  4 ++--
 src/crop/farmplot.jl   |  2 ++
 src/crop/simplecrop.jl | 13 +++++++++++++
 test/paramscan.toml    |  2 +-
 7 files changed, 37 insertions(+), 8 deletions(-)
 create mode 100644 src/crop/simplecrop.jl

diff --git a/src/Persefone.jl b/src/Persefone.jl
index 461dd00..4e423a0 100644
--- a/src/Persefone.jl
+++ b/src/Persefone.jl
@@ -138,8 +138,8 @@ include("analysis/makieplots.jl")
 include("world/landscape.jl")
 include("world/weather.jl")
 
-include("crop/almass.jl")
 include("crop/farmplot.jl")
+include("crop/almass.jl")
 include("farm/farm.jl")
 
 include("nature/insects.jl")
diff --git a/src/core/input.jl b/src/core/input.jl
index a8bc2a4..46460cb 100644
--- a/src/core/input.jl
+++ b/src/core/input.jl
@@ -17,6 +17,11 @@ const PARAMFILE = joinpath(pkgdir(Persefone), "src/parameters.toml")
 #XXX do I need to use absolute paths for all input files in case working dir is changed?
 # (can be done with `joinpath(dirname(@__FILE__), <filename>)` )
 
+"""
+The crop models that can be used in the simulation.
+"""
+const AVAILABLE_CROPMODELS = ["almass", "simple"]
+
 """
     @param(domainparam)
 
@@ -89,6 +94,9 @@ function preprocessparameters(settings::Dict{String,Any}, defaultoutdir::String)
         Base.error("Enddate is earlier than startdate.") #TODO replace with exception
     end
     settings["world.mapresolution"] = settings["world.mapresolution"] * 1m
+    if ! (settings["crop.cropmodel"] in AVAILABLE_CROPMODELS)
+        error("crop.cropmodel = \"$(settings["crop.cropmodel"])\", but has to be one of: $AVAILABLE_CROPMODELS")
+    end
     #FIXME enable parallelisation
     # if !isempty(settings["internal.scanparams"]) && (nprocs() < 2)
     #     @warn "To parallelise multiple simulation runs, use `julia -p <n>`."
diff --git a/src/core/simulation.jl b/src/core/simulation.jl
index f745b24..70ab962 100644
--- a/src/core/simulation.jl
+++ b/src/core/simulation.jl
@@ -23,7 +23,8 @@ mutable struct AgricultureModel <: SimulationModel
     weather::Dict{Date,Weather}
     crops::Dict{String,ALMaSS.CropType}
     farmers::Vector{Farmer}
-    farmplots::Vector{ALMaSS.FarmPlot}
+    #farmplots::Vector{ALMaSS.FarmPlot}
+    farmplots::Vector{AbstractFarmPlot}
     animals::Vector{Union{Animal,Nothing}}
     migrants::Vector{Pair{Animal,Date}}
     events::Vector{FarmEvent}
@@ -117,8 +118,13 @@ function initmodel(settings::Dict{String, Any})
                                        settings["world.weatherfile"]),
                               settings["core.startdate"],
                               settings["core.enddate"])
-        crops = ALMaSS.readcropparameters(settings["crop.cropfile"],
-                                          settings["crop.growthfile"])
+        if settings["crop.cropmodel"] == "almass"
+            crops = ALMaSS.readcropparameters(settings["crop.cropfile"],
+                                              settings["crop.growthfile"])
+            farmplots = Vector{ALMaSS.FarmPlot}()
+        else
+            error("Init for crop model \"$(settings["crop.cropmodel"])\" not implemented")
+        end
         model = AgricultureModel(settings,
                                  StableRNG(settings["core.seed"]),
                                  logger,
@@ -129,7 +135,7 @@ function initmodel(settings::Dict{String, Any})
                                  weather,
                                  crops,
                                  Vector{Farmer}(),
-                                 Vector{ALMaSS.FarmPlot}(),
+                                 farmplots,
                                  Vector{Union{Animal,Nothing}}(),
                                  Vector{Pair{Animal, Date}}(),
                                  Vector{FarmEvent}())
diff --git a/src/crop/almass.jl b/src/crop/almass.jl
index e66ce77..8d26660 100644
--- a/src/crop/almass.jl
+++ b/src/crop/almass.jl
@@ -7,7 +7,7 @@
 
 module ALMaSS
 
-using Persefone: ModelAgent, EventType, SimulationModel, maxtemp, mintemp, fertiliser
+using Persefone: AbstractFarmPlot, EventType, SimulationModel, maxtemp, mintemp, fertiliser
 import Persefone: stepagent!
 using Dates: Date, month, monthday
 using CSV: CSV
@@ -136,7 +136,7 @@ end
 This represents one field, i.e. a collection of pixels with the same management.
 This is the spatial unit with which the crop growth model and the farm model work.
 """
-mutable struct FarmPlot <: ModelAgent
+mutable struct FarmPlot <: AbstractFarmPlot
     #TODO add Unitful
     const id::Int64
     pixels::Vector{Tuple{Int64, Int64}}
diff --git a/src/crop/farmplot.jl b/src/crop/farmplot.jl
index 46a563d..4bd2721 100644
--- a/src/crop/farmplot.jl
+++ b/src/crop/farmplot.jl
@@ -212,3 +212,5 @@ function cropcover(pos::Tuple{Int64,Int64}, model::SimulationModel)
               model.farmplots[model.landscape[pos...].fieldid].LAItotal
 end
 
+
+
diff --git a/src/crop/simplecrop.jl b/src/crop/simplecrop.jl
new file mode 100644
index 0000000..b903db5
--- /dev/null
+++ b/src/crop/simplecrop.jl
@@ -0,0 +1,13 @@
+
+module SimpleCrop
+
+"""
+    stepagent!(farmplot, model)
+
+Update a farm plot by one day.
+"""
+function stepagent!(farmplot::FarmPlot, model::SimulationModel)
+end
+
+end # module SimpleCrop
+
diff --git a/test/paramscan.toml b/test/paramscan.toml
index d2db42f..565e685 100644
--- a/test/paramscan.toml
+++ b/test/paramscan.toml
@@ -28,5 +28,5 @@ popoutfreq = "daily" # output frequency population-level data, daily/monthly/yea
 indoutfreq = "end" # output frequency individual-level data, daily/monthly/yearly/end/never
 	
 [crop]
-cropmodel = "linear" # crop growth model to use, "linear" or "aquacrop" (not yet implemented)
+cropmodel = "simple" # crop growth model to use, "simple" or "almass"
 
-- 
GitLab