Skip to content
Snippets Groups Projects
Commit c3fc0ac3 authored by xo30xoqa's avatar xo30xoqa
Browse files

Made output frequency configurable, wrote saveindividualdata()

parent 8c09236e
No related branches found
No related tags found
No related merge requests found
...@@ -17,6 +17,7 @@ in a single object. The model landscape consists of a matrix of pixels. ...@@ -17,6 +17,7 @@ in a single object. The model landscape consists of a matrix of pixels.
struct Pixel struct Pixel
landcover::LandCover landcover::LandCover
fieldid::Union{Missing, UInt32} fieldid::Union{Missing, UInt32}
#FIXME actually this is stupid - I don't want a field ID, I want a field object
end end
""" """
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
const LOGFILE = "simulation.log" const LOGFILE = "simulation.log"
const POPFILE = "populations.csv" const POPFILE = "populations.csv"
const INDFILE = "individuals.csv"
## Note: `setupdatadir()` was adapted from the GeMM model by Leidinger et al. ## Note: `setupdatadir()` was adapted from the GeMM model by Leidinger et al.
## (https://github.com/CCTB-Ecomods/gemm/blob/master/src/output.jl) ## (https://github.com/CCTB-Ecomods/gemm/blob/master/src/output.jl)
...@@ -55,16 +56,78 @@ function setupdatadir() ...@@ -55,16 +56,78 @@ function setupdatadir()
cp(lcmap, joinpath(param("core.outdir"), basename(lcmap)), force = true) cp(lcmap, joinpath(param("core.outdir"), basename(lcmap)), force = true)
cp(ffmap, joinpath(param("core.outdir"), basename(ffmap)), force = true) cp(ffmap, joinpath(param("core.outdir"), basename(ffmap)), force = true)
# Create the data output file(s) # Create the data output file(s)
initnaturedatafiles()
end
## NATURE MODEL OUTPUT FUNCTIONS
#XXX Should these be moved to a separate file (src/nature/natureoutput.jl)?
# At the moment I've kept them here so that all output functions are in the same place.
let nextpopout = nothing, nextindout = nothing
"""
initnaturedatafiles()
Initialise the files needed for the nature output data and set the
date for the next data output, depending on the model settings.
"""
global function initnaturedatafiles()
startdate = param("core.startdate")
popoutfreq = param("nature.popoutfreq")
indoutfreq = param("nature.indoutfreq")
if popoutfreq != "never"
open(joinpath(param("core.outdir"), POPFILE), "w") do f open(joinpath(param("core.outdir"), POPFILE), "w") do f
println(f, "Date;Species;Abundance") println(f, "Date;Species;Abundance")
end end
(popoutfreq == "daily") && (nextpopout = startdate)
(popoutfreq == "monthly") && (nextpopout = startdate+Month(1))
(popoutfreq == "yearly") && (nextpopout = startdate+Year(1))
(popoutfreq == "end") && (nextpopout = param("core.enddate"))
else nextpopout = startdate - Day(1) end
if indoutfreq != "never"
open(joinpath(param("core.outdir"), INDFILE), "w") do f
println(f, "Date;ID;X;Y;Species;Sex;Age;Energy")
end end
(indoutfreq == "daily") && (nextindout = startdate)
(indoutfreq == "monthly") && (nextindout = startdate+Month(1))
(indoutfreq == "yearly") && (nextindout = startdate+Year(1))
(indoutfreq == "end") && (nextindout = param("core.enddate"))
else nextindout = startdate - Day(1) end
end
"""
recordnaturedata(model)
Record the relevant data output from the nature model, depending on the frequency settings.
""" """
global function recordnaturedata(model::AgentBasedModel)
popoutfreq = param("nature.popoutfreq")
indoutfreq = param("nature.indoutfreq")
if model.date == nextpopout
savepopulationdata(model) savepopulationdata(model)
(popoutfreq == "daily") && (nextpopout = model.date+Day(1))
(popoutfreq == "monthly") && (nextpopout = model.date+Month(1))
(popoutfreq == "yearly") && (nextpopout = model.date+Year(1))
end
if model.date == nextindout
saveindividualdata(model)
(indoutfreq == "daily") && (nextindout = model.date+Day(1))
(indoutfreq == "monthly") && (nextindout = model.date+Month(1))
(indoutfreq == "yearly") && (nextindout = model.date+Year(1))
end
end
end
Print a comma-separated set of lines to `populations.csv`, giving the ##XXX The current method of controlling the next output date for the different
current date and population size for each animal species. ## output functions is a bit messy. If the farm model introduces similar parameters
## to popoutfreq/indoutfreq, it would be worth revising this to a cleaner hook system.
"""
savepopulationdata(model)
Print a comma-separated set of lines to `populations.csv`, giving the current date
and population size for each animal species. May be called never, daily, monthly,
yearly, or at the end of a simulation, depending on the parameter `nature.popoutfreq`.
""" """
function savepopulationdata(model::AgentBasedModel) function savepopulationdata(model::AgentBasedModel)
pops = Dict{String,Int}(s=>0 for s = param("nature.targetspecies")) pops = Dict{String,Int}(s=>0 for s = param("nature.targetspecies"))
...@@ -74,7 +137,27 @@ function savepopulationdata(model::AgentBasedModel) ...@@ -74,7 +137,27 @@ function savepopulationdata(model::AgentBasedModel)
end end
open(joinpath(param("core.outdir"), POPFILE), "a") do f open(joinpath(param("core.outdir"), POPFILE), "a") do f
for p in keys(pops) for p in keys(pops)
println(f, "$(model.date);$(p);$(pops[p])") println(f, join([model.date, p, pops[p]], ";"))
end
end
end
"""
saveindividualdata(model)
Print a comma-separated set of lines to `individuals.csv`, listing all properties
of all animal individuals in the model. May be called never, daily, monthly, yearly, or
at the end of a simulation, depending on the parameter `nature.indoutfreq`.
WARNING: Produces very big files!
"""
function saveindividualdata(model::AgentBasedModel)
data = ""
for a in allagents(model)
(typeof(a) != Animal) && continue
entry = join([model.date,a.id,a.pos[1],a.pos[2],a.species.name,a.sex,a.age,a.energy], ";")
data = data*entry*"\n"
end end
open(joinpath(param("core.outdir"), INDFILE), "a") do f
print(f, data)
end end
end end
...@@ -40,7 +40,7 @@ function stepsimulation!(model::AgentBasedModel) ...@@ -40,7 +40,7 @@ function stepsimulation!(model::AgentBasedModel)
#The animal may have been killed, so we need a try/catch #The animal may have been killed, so we need a try/catch
try stepagent!(getindex(model, a), model) catch keyerror end try stepagent!(getindex(model, a), model) catch keyerror end
end end
savepopulationdata(model) recordnaturedata(model)
model.date += Day(1) model.date += Day(1)
end end
......
...@@ -22,6 +22,8 @@ enddate = 2020-01-31 ...@@ -22,6 +22,8 @@ enddate = 2020-01-31
[nature] [nature]
targetspecies = ["Wolpertinger", "Wyvern"] # list of target species to simulate targetspecies = ["Wolpertinger", "Wyvern"] # list of target species to simulate
popoutfreq = "daily" # output frequency population-level data, daily/monthly/yearly/end/never
indoutfreq = "end" # output frequency individual-level data, daily/monthly/yearly/end/never
[crop] [crop]
cropmodel = "linear" # crop growth model to use, "linear" or "aquacrop" (not yet implemented) cropmodel = "linear" # crop growth model to use, "linear" or "aquacrop" (not yet implemented)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment