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.
struct Pixel
landcover::LandCover
fieldid::Union{Missing, UInt32}
#FIXME actually this is stupid - I don't want a field ID, I want a field object
end
"""
......
......@@ -5,6 +5,7 @@
const LOGFILE = "simulation.log"
const POPFILE = "populations.csv"
const INDFILE = "individuals.csv"
## Note: `setupdatadir()` was adapted from the GeMM model by Leidinger et al.
## (https://github.com/CCTB-Ecomods/gemm/blob/master/src/output.jl)
......@@ -55,16 +56,78 @@ function setupdatadir()
cp(lcmap, joinpath(param("core.outdir"), basename(lcmap)), force = true)
cp(ffmap, joinpath(param("core.outdir"), basename(ffmap)), force = true)
# Create the data output file(s)
open(joinpath(param("core.outdir"), POPFILE), "w") do f
println(f, "Date;Species;Abundance")
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
println(f, "Date;Species;Abundance")
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
(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)
(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
##XXX The current method of controlling the next output date for the different
## 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.
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)
pops = Dict{String,Int}(s=>0 for s = param("nature.targetspecies"))
......@@ -74,7 +137,27 @@ function savepopulationdata(model::AgentBasedModel)
end
open(joinpath(param("core.outdir"), POPFILE), "a") do f
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
open(joinpath(param("core.outdir"), INDFILE), "a") do f
print(f, data)
end
end
......@@ -40,7 +40,7 @@ function stepsimulation!(model::AgentBasedModel)
#The animal may have been killed, so we need a try/catch
try stepagent!(getindex(model, a), model) catch keyerror end
end
savepopulationdata(model)
recordnaturedata(model)
model.date += Day(1)
end
......
......@@ -22,7 +22,9 @@ enddate = 2020-01-31
[nature]
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]
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 register or to comment