Skip to content
Snippets Groups Projects
Commit 59e9670f authored by Florian Atteneder's avatar Florian Atteneder
Browse files

dg1d: allow parameter overriding on cmd line...

dg1d:  allow parameter overriding on cmd line (!193)

Allows to use `main(parfile, "Mesh.n" => "1")` to override the value given in the parfile.

---

To do this we
- parse the TOML file
- flatten the dict-of-dicts to a single dict with the keys joined by a `.`
- insert the parameters
- unflatten the dict to a dict-of-dicts
- write this to the output directory

Unfortunately, `TOML.jl` does not allow to parse into `OrderedDict`.
This causes the newly written parfiles to be messed up.
Furthermore, by manually re-writing the parfiles we also do not preserve any comments or formatting.
parent 762c7062
No related branches found
No related tags found
1 merge request!193dg1d: allow parameter overriding on cmd line
Pipeline #7103 passed
...@@ -41,24 +41,27 @@ end ...@@ -41,24 +41,27 @@ end
Run program specified by a `parfile` in TOML format. Run program specified by a `parfile` in TOML format.
""" """
function main(parfile) function main(parfile, parameter_overrides::Pair{String,String}...)
parfile = abspath(parfile) parfile = abspath(parfile)
prms = TOML.parsefile(parfile)
flat_prms = flatten(prms)
for (k,v) in parameter_overrides
flat_prms[k] = v
end
prms = unflatten(flat_prms)
dir = dirname(parfile) dir = dirname(parfile)
dummy_parfile = parfile
if basename(dir) == splitext(basename(parfile))[1] if basename(dir) == splitext(basename(parfile))[1]
# we are running parameter file contained in an output folder # we are running parameter file contained in an output folder
# so we backup that folder and run the parameter file one directory above # so we backup that folder and run the parameter file one directory above
dummy_parfile = string(dir, ".toml") parfile = string(dir, ".toml")
end end
# backup any previous output dir and set up a fresh one # backup any previous output dir and set up a fresh one
outputdir = make_outputdir(dummy_parfile) outputdir = make_outputdir(parfile)
if dummy_parfile != parfile parfile = joinpath(outputdir, basename(parfile))
# we moved the initial parfile with the backup of the output folder open(parfile, "w") do file
cp(joinpath(string(dir,".previous"),string(basename(dir),".toml")), TOML.print(file, prms)
joinpath(outputdir, basename(parfile)))
else
cp(parfile, joinpath(outputdir, basename(parfile)))
end end
cp(joinpath(@__DIR__,"..","Manifest.toml"), joinpath(outputdir,"Manifest.toml")) cp(joinpath(@__DIR__,"..","Manifest.toml"), joinpath(outputdir,"Manifest.toml"))
open(joinpath(outputdir, "dirty"), "w") do file open(joinpath(outputdir, "dirty"), "w") do file
...@@ -104,7 +107,8 @@ function main(parfile) ...@@ -104,7 +107,8 @@ function main(parfile)
return return
end end
main(id::Integer) = main(normalize_parfile(id)) main(id::Integer, parameter_overrides::Pair{String,String}...) =
main(normalize_parfile(id); parameter_overrides)
load_parameters(parfile::AbstractString) = parse_parameters(TOML.parsefile(parfile)) load_parameters(parfile::AbstractString) = parse_parameters(TOML.parsefile(parfile))
......
...@@ -221,8 +221,8 @@ end ...@@ -221,8 +221,8 @@ end
Flatten a dictionary `d` and concatenate all keys with `prefix_delim`. Flatten a dictionary `d` and concatenate all keys with `prefix_delim`.
Returned dictionary is of type `Dict{Symbol,<:Any}`. Returned dictionary is of type `Dict{Symbol,<:Any}`.
""" """
function flatten(d::AbstractDict{T,<:Any}, prefix_delim = ".") where T function flatten(d::AbstractDict{String,<:Any}, prefix_delim::String=".")
new_d = Dict{T,Any}() new_d = Dict{String,Any}()
for (key, value) in pairs(d) for (key, value) in pairs(d)
if isa(value, Dict) if isa(value, Dict)
flattened_value = flatten(value, prefix_delim) flattened_value = flatten(value, prefix_delim)
...@@ -236,6 +236,32 @@ function flatten(d::AbstractDict{T,<:Any}, prefix_delim = ".") where T ...@@ -236,6 +236,32 @@ function flatten(d::AbstractDict{T,<:Any}, prefix_delim = ".") where T
return new_d return new_d
end end
function unflatten(d::AbstractDict{String,<:Any}, prefix_delim::String=".")
uf_d = d
while true
prefixes = String[]
for k in keys(uf_d)
parts = split(k, prefix_delim)
if length(parts) > 1
push!(prefixes, join(parts[1:end-1],prefix_delim))
end
end
unique!(prefixes)
length(prefixes) == 0 && break
uf_d, tmp_d = Dict{String,Any}(), uf_d
for pre in prefixes
sub_dict = Dict{String,Any}()
for (k,v) in pairs(tmp_d)
if startswith(k, string(pre,prefix_delim))
sub_dict[last(split(k,prefix_delim))] = v
end
end
uf_d[pre] = sub_dict
end
end
return uf_d
end
""" """
dirname_path(path) dirname_path(path)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment