Something went wrong on our end
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
output.jl 12.28 KiB
### Persefone.jl - a model of agricultural landscapes and ecosystems in Europe.
###
### This file contains functions for saving the model output. This includes logging
### facilities, but also functions for collecting and outputting data from the
### different submodels.
###
"Log output is saved to `simulation.log` in the output directory"
const LOGFILE = "simulation.log"
"All input data are copied to the `inputs` folder within the output directory"
const RECORDDIR = "inputs"
## Much of this code was adapted from the GeMM model by Leidinger et al.
## (https://github.com/CCTB-Ecomods/gemm/blob/master/src/output.jl)
"""
createdatadir(outdir, overwrite)
Creates the output directory, dealing with possible conflicts.
"""
function createdatadir(outdir::String, overwrite::Union{Bool,String})
if isdir(outdir)
if overwrite == "ask"
println("The chosen output directory $(outdir) already exists.")
println("Type 'yes' to overwrite this directory. Otherwise, the simulation will abort.")
print("Overwrite? ")
answer = readline()
overwrite = (answer == "yes" || answer == "y")
end
!overwrite ? Base.error("Output directory exists, will not overwrite. Aborting.") :
@warn "Overwriting existing output directory $(outdir)."
#TODO replace with exception
end
@debug "Setting up output directory $outdir."
mkpath(outdir)
end
"""
modellogger(loglevel, outdir, output="both")
Create a logger object that writes output to screen and/or a logfile.
This object is stored as `model.logger` and can then be used with `with_logger()`.
Note: requires [`createdatadir`](@ref) to be run first.
"""
function modellogger(loglevel::String, outdir::String, output::String="both")
!isdir(outdir) && #TODO replace with exception
Base.error("$(outdir) does not exist. Call `createdatadir()` before `modellogger()`.")
loglevel == "debug" ? loglevel = Logging.Debug :
loglevel == "warn" ? loglevel = Logging.Warn :
loglevel == "info" ? loglevel = Logging.Info :
Base.error("Invalid loglevel $loglevel, should be debug/info/warn.") #TODO make exception
(output in ["file", "both"]) && (logfile = open(joinpath(outdir, LOGFILE), "w+"))
if output == "both"
return TeeLogger(ConsoleLogger(logfile, loglevel),
ConsoleLogger(stdout, loglevel))
elseif output == "file"
return ConsoleLogger(logfile, loglevel)
elseif output == "screen"
return ConsoleLogger(stdout, loglevel)
elseif output == "none"
return NullLogger()
else
Base.error("Invalid log output target $output, should be file/screen/both.")
end
end
"""
withtestlogger(model)