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

Implemented config file reading and commandline argument parsing

Borrowed quite a bit of code from GeMM here, that made it easier...
parent 191d1a81
Branches
Tags
No related merge requests found
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
julia_version = "1.8.2" julia_version = "1.8.2"
manifest_format = "2.0" manifest_format = "2.0"
project_hash = "3c3cc3b9de5c42b80fd17ce2f0cc11a00abed995" project_hash = "72816161d7cf94aaf2f40b7992f0ee1d99e390ce"
[[deps.Agents]] [[deps.Agents]]
deps = ["CSV", "DataFrames", "DataStructures", "Distributed", "Downloads", "Graphs", "JLD2", "LazyArtifacts", "LightOSM", "LinearAlgebra", "Pkg", "ProgressMeter", "Random", "Requires", "Scratch", "StatsBase"] deps = ["CSV", "DataFrames", "DataStructures", "Distributed", "Downloads", "Graphs", "JLD2", "LazyArtifacts", "LightOSM", "LinearAlgebra", "Pkg", "ProgressMeter", "Random", "Requires", "Scratch", "StatsBase"]
......
...@@ -6,4 +6,7 @@ version = "0.0.1" ...@@ -6,4 +6,7 @@ version = "0.0.1"
[deps] [deps]
Agents = "46ada45e-f475-11e8-01d0-f70cc89e6671" Agents = "46ada45e-f475-11e8-01d0-f70cc89e6671"
ArgParse = "c7e460c6-2fb9-53a9-8c5b-16f535851c63" ArgParse = "c7e460c6-2fb9-53a9-8c5b-16f535851c63"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
...@@ -16,10 +16,11 @@ It is currently in the very early stages of development. ...@@ -16,10 +16,11 @@ It is currently in the very early stages of development.
Install the latest version of the [Julia](https://julialang.org/downloads/) programming Install the latest version of the [Julia](https://julialang.org/downloads/) programming
language. The recommended editors are [VSCode](https://www.julia-vscode.org/) or language. The recommended editors are [VSCode](https://www.julia-vscode.org/) or
[Emacs](https://www.emacswiki.org/emacs/JuliaProgrammingLanguage) (see `docs/editors.md`). [Emacs](https://www.emacswiki.org/emacs/JuliaProgrammingLanguage) (see `docs/editors.md`).
To install package dependencies, open a Julia REPL and run
`using Pkg; Pkg.activate("."); Pkg.instantiate()`.
Run the simulation by executing `run.jl` from the commandline, or loading it from Run the simulation by executing `run.jl` from the commandline, or loading it from
within a Julia REPL with `include("run.jl")`. All dependencies should be within a Julia REPL with `include("run.jl")`.
automatically installed.
This model uses the [Agents.jl](https://juliadynamics.github.io/Agents.jl/stable/) framework. This model uses the [Agents.jl](https://juliadynamics.github.io/Agents.jl/stable/) framework.
......
...@@ -15,23 +15,28 @@ module Persephone ...@@ -15,23 +15,28 @@ module Persephone
using using
Agents, Agents,
ArgParse, ArgParse,
Logging Dates,
Logging,
Random,
TOML
## define exported functions and variables ## define exported functions and variables
export export
simulate simulate,
initsim,
runsim
## The file that stores all default parameters
const paramfile = "src/parameters.toml"
## (DO NOT CHANGE THIS VALUE! Instead, specify simulation-specific configuration files
## by using the "--configfile" commandline argument, or when invoking simulate().)
## include all module files ## include all module files
include("core/input.jl") include("core/input.jl")
include("core/output.jl") include("core/output.jl")
include("crop/crops.jl") include("crop/crops.jl")
include("ecology/ecology.jl") include("ecology/ecology.jl")
include("farm/farm.jl") include("farm/farm.jl")
include("core/simulation.jl") include("core/simulation.jl")
end end
### Persephone - a socio-economic-ecological model of European agricultural landscapes.
###
### This file includes functions for configuring the model and reading in map files.
###
## Note: some of this code was adapted from the GeMM model
## (https://github.com/CCTB-Ecomods/gemm/blob/master/src/input.jl)
"""
getsettings(configfile)
Combines all configuration options to produce a single settings dict.
Precedence: commandline parameters - user config file - default values
"""
function getsettings(configfile::String)
# read in and merge configurations from the commandline, the default config file
# and a user-supplied config file
defaults = TOML.parsefile(configfile)
commandline = parsecommandline()
if haskey(commandline, "configfile") && isfile(commandline["configfile"])
configs = TOML.parsefile(commandline["configfile"])
else
configs = nothing
end
settings = deepcopy(defaults)
for domain in keys(defaults)
for param in keys(defaults[domain])
if param in keys(commandline)
settings[domain][param] = commandline[param]
elseif !isnothing(configs) && param in keys(configs[domain])
settings[domain][param] = configs[domain][param]
end
end
end
# pre-process certain parameters
if settings["core"]["seed"] == 0
settings["core"]["seed"] = abs(rand(RandomDevice(), Int32))
end
defaultoutdir = defaults["core"]["outdir"]
if settings["core"]["outdir"] == defaultoutdir
outdir = defaultoutdir*"_"*string(Dates.today())*"_s"*string(settings["core"]["seed"])
settings["core"]["outdir"] = outdir
end
# Flags are automatically set to false by ArgParse if they are not given -
# this should not override a given config file value
if !commandline["quietmode"] && !isnothing(configs) && "quietmode" in keys(configs["core"]) && configs["core"]["quietmode"]
settings["core"]["quietmode"] = true
end
settings
end
"""
parsecommandline()
Certain software parameters can be set via the commandline.
"""
function parsecommandline()
s = ArgParseSettings()
@add_arg_table! s begin
"--configfile", "-c"
help = "name of the config file"
arg_type = String
required = false
"--seed", "-s"
help = "inital random seed"
arg_type = Int
"--mapfile", "-m"
help = "name of the map file"
arg_type = String
required = false
"--outdir", "-o"
help = "location of the output directory"
arg_type = String
required = false
"--loglevel", "-l"
help = "amount of logging: \"debug\", \"normal\", or \"errors\""
arg_type = String
required = false
"--quietmode", "-q"
help = "quiet mode. Don't print output to screen."
action = :store_true
"--runtime", "-r"
help = "duration in days that the simulation will run"
arg_type = Int
required = false
end
args = parse_args(s)
for a in keys(args)
(args[a] == nothing) && delete!(args, a)
end
args
end
...@@ -3,7 +3,10 @@ ...@@ -3,7 +3,10 @@
### This file includes the core functions for initialising and running simulations. ### This file includes the core functions for initialising and running simulations.
### ###
function initsim() function initsim(config::String)
settings = getsettings(config)
TOML.print(settings)
Random.seed!(settings["core"]["seed"])
#TODO #TODO
end end
...@@ -11,10 +14,9 @@ function runsim() ...@@ -11,10 +14,9 @@ function runsim()
#TODO #TODO
end end
function simulate() function simulate(config::String=paramfile)
initsim() initsim(config)
runsim() runsim()
println("Simulation ran. Nothing happened. But it will!") println("Simulation ran. Nothing happened. But it will!")
println("Simulation complete :-)")
#TODO #TODO
end end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment