From aa25f0e9431ca960229578e5f0c00276b22f1622 Mon Sep 17 00:00:00 2001
From: Daniel Vedder <daniel.vedder@idiv.de>
Date: Fri, 25 Nov 2022 11:22:23 +0100
Subject: [PATCH] Wrote the `setupdatadir()` function, changed `setting()` to
 `param()`

---
 src/core/input.jl      | 30 +++++++++++++++++++++---------
 src/core/output.jl     | 40 ++++++++++++++++++++++++++++++++++++++++
 src/core/simulation.jl |  6 +++---
 3 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/src/core/input.jl b/src/core/input.jl
index 7463dd9..2c97dae 100644
--- a/src/core/input.jl
+++ b/src/core/input.jl
@@ -3,7 +3,7 @@
 ### This file includes functions for configuring the model and reading in map files.
 ###
 
-## Note: some of this code was adapted from the GeMM model
+## Note: much of this code was adapted from the GeMM model by Leidinger et al.
 ## (https://github.com/CCTB-Ecomods/gemm/blob/master/src/input.jl)
 
 let settings::Dict{String, Dict{String, Any}}
@@ -15,15 +15,27 @@ let settings::Dict{String, Dict{String, Any}}
     global function initsettings(configfile::String)
         settings = getsettings(configfile)
     end
-
+    
     """
-        setting(domain, param)
+        param(domainparam)
 
     Return a configuration parameter from the global settings.
-    Domain may be any of "core", "ecology", "farm", or "crop".
+    The argument should be in the form `"<domain>.<parameter>"`,
+    for example `param("core.outdir")`. Possible values for
+    <domain> are "core", "ecology", "farm", or "crop".
+    """
+    global function param(domainparam::String)
+        domain, paramname = split(domainparam, ".")
+        settings[domain][paramname]
+    end
+
+    """
+        astoml(io)
+
+    Print all settings in TOML format to the given output stream.
     """
-    global function setting(domain::String, param::String)
-        settings[domain][param]
+    global function astoml(stream::IO=stdout)
+        TOML.print(stream, settings)
     end
 end
 
@@ -94,11 +106,11 @@ function parsecommandline()
             arg_type = String
             required = false
         "--loglevel", "-l"
-            help = "amount of logging: \"debug\", \"normal\", or \"errors\""
+            help = "verbosity: \"debug\", \"normal\", or \"errors\""
             arg_type = String
             required = false
         "--quietmode", "-q"
-            help = "quiet mode. Don't print output to screen."
+            help = "don't print output to screen"
             action = :store_true
         "--runtime", "-r"
            help = "duration in days that the simulation will run"
@@ -118,5 +130,5 @@ end
 Read in a TIFF map file and return it as an array.
 """
 function readtiffmapfile(filename)
-    #TODO
+    #TODO this requires GeoArrays
 end
diff --git a/src/core/output.jl b/src/core/output.jl
index e69de29..a811e66 100644
--- a/src/core/output.jl
+++ b/src/core/output.jl
@@ -0,0 +1,40 @@
+### Persephone - a socio-economic-ecological model of European agricultural landscapes.
+###
+### This file includes functions for saving the model output.
+###
+
+## Note: some of this code was adapted from the GeMM model by Leidinger et al.
+## (https://github.com/CCTB-Ecomods/gemm/blob/master/src/output.jl)
+
+"""
+    setupdatadir()
+
+Creates the output directory and copies relevant files into it.
+"""
+function setupdatadir()
+    # Check whether the output directory already exists and handle conflicts
+    if isdir(param("core.outdir"))
+        @warn "The chosen output directory $(param("core.outdir")) already exists."
+        println("Type 'yes' to overwrite this directory. Otherwise, the simulation will abort.")
+        print("Overwrite? ")
+        answer = readline()
+        (answer != "yes") && Base.error("Output directory exists, will not overwrite. Aborting.")
+    else
+        mkpath(param("core.outdir"))
+    end
+    @info "Setting up output directory $(param("core.outdir"))"
+    # Export a copy of the current parameter settings to the output folder.
+    # This can be used to replicate this exact run in future, and also
+    # records the current time and git commit.
+    open(joinpath(param("core.outdir"), basename(param("core.configfile"))), "w") do f
+        println(f, "#\n# --- Persephone configuration parameters ---")
+        println(f, "# This file was generated automatically.")
+        println(f, "# Simulation run on $(string(Dates.format(Dates.now(), "d u Y HH:MM:SS"))),")
+        println(f, "# with git commit $(read(`git rev-parse HEAD`, String))#\n")
+        astoml(f)
+    end
+    # Copy the map file to the output folder
+    mapf = param("core.mapfile")
+    !(isfile(mapf)) && @error "The map file $(mapf) doesn't exist."
+    cp(mapf, joinpath(param("core.outdir"), basename(mapf)), force = true)
+end
diff --git a/src/core/simulation.jl b/src/core/simulation.jl
index 3314005..c0c0216 100644
--- a/src/core/simulation.jl
+++ b/src/core/simulation.jl
@@ -5,8 +5,8 @@
 
 function initsim(config::String)
     initsettings(config)
-    Random.seed!(setting("core", "seed"))
-    #TODO create output folder
+    Random.seed!(param("core.seed"))
+    setupdatadir()
     #TODO create world
 end
 
@@ -22,7 +22,7 @@ end
 
 function simulate(config::String=paramfile)
     initsim(config)
-    for day in 1:setting("core", "runtime")
+    for day in 1:param("core.runtime")
         stepsim()
     end
     finalisesim()
-- 
GitLab