Skip to content

Commit

Permalink
rename model files (#690)
Browse files Browse the repository at this point in the history
Fixes a large part of #638. Not entirely, I listed two follow-ups that
are probably best done after #630 in that issue.
This also removes the model name from the model, as before the only
thing it did was name the TOML and GeoPackage.
That meant I had to adapt `ribasim_testmodels` a bit to expose a
`constructors` dict which maps the test model names to the constructor
functions.


https://github.com/Deltares/Ribasim/compare/names?expand=1#diff-b223bf31f9400e170f97d95fa1d8b22393e5d37cfd810a4a5aa7bf480915ac52

This doesn't just change the file names but also updates the
documentation to stop talking about GeoPackage so much and consistently
refer to the database. Also QGIS panel names are updated, function,
class and variable names.

TOML section names are updated, so this is breaking. Specifically, the
`geopackage` key is now called `database`, and the `[output]` section is
now called `[results]`. The default output folder is now also called
results.
  • Loading branch information
visr authored Oct 21, 2023
1 parent 047fce0 commit c710ed2
Show file tree
Hide file tree
Showing 58 changed files with 280 additions and 342 deletions.
2 changes: 1 addition & 1 deletion build/create_binaries/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@

using Ribasim, Dates, TOML

toml_path = normpath(@__DIR__, "../../generated_testmodels/basic/basic.toml")
toml_path = normpath(@__DIR__, "../../generated_testmodels/basic/ribasim.toml")
Ribasim.run(toml_path)
2 changes: 1 addition & 1 deletion build/libribasim/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ In [3]: argument = create_string_buffer(0)
...: c_dll.init_julia(c_int(0), byref(argument))
Out[3]: 1

In [4]: config_path = "run.toml"
In [4]: config_path = "ribasim.toml"

In [5]: c_dll.initialize(c_char_p(config_path.encode()))
Out[5]: 0
Expand Down
4 changes: 2 additions & 2 deletions build/ribasim_cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ If you have installed Julia and Ribasim, a simulation can also be started from t
line as follows:

```
julia --eval 'using Ribasim; Ribasim.run("path/to/config.toml")'
julia --eval 'using Ribasim; Ribasim.run("path/to/model/ribasim.toml")'
```

With a Ribasim CLI build this becomes:

```
ribasim path/to/config.toml
ribasim path/to/model/ribasim.toml
```
2 changes: 1 addition & 1 deletion build/ribasim_cli/src/ribasim_cli.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ using Ribasim

function help(x)::Cint
println(x)
println("Usage: ribasim path/to/config.toml")
println("Usage: ribasim path/to/model/ribasim.toml")
return 1
end

Expand Down
12 changes: 6 additions & 6 deletions build/ribasim_cli/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@


@pytest.mark.parametrize(
"model_constructor",
map(ribasim_testmodels.__dict__.get, ribasim_testmodels.__all__),
"model_name,model_constructor",
ribasim_testmodels.constructors.items(),
)
def test_ribasim_cli(model_constructor, tmp_path):
def test_ribasim_cli(model_name, model_constructor, tmp_path):
model = model_constructor()
assert isinstance(model, ribasim.Model)
model.write(tmp_path)
model.write(tmp_path / model_name)

executable = (
Path(__file__).parents[2]
Expand All @@ -22,10 +22,10 @@ def test_ribasim_cli(model_constructor, tmp_path):
/ "bin"
/ "ribasim.exe"
)
config_file = str(tmp_path / f"{model.modelname}.toml")
config_file = str(tmp_path / "ribasim.toml")
result = subprocess.run([executable, config_file])

if model.modelname.startswith("invalid"):
if model_name.startswith("invalid_"):
assert result.returncode != 0
else:
assert result.returncode == 0
30 changes: 15 additions & 15 deletions core/src/bmi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@ Initialize a [`Model`](@ref) from a [`Config`](@ref).
"""
function BMI.initialize(T::Type{Model}, config::Config)::Model
alg = algorithm(config.solver)
gpkg_path = input_path(config, config.geopackage)
if !isfile(gpkg_path)
throw(SystemError("GeoPackage file not found: $gpkg_path"))
db_path = input_path(config, config.database)
if !isfile(db_path)
throw(SystemError("Database file not found: $db_path"))
end

# Setup timing logging
if config.logging.timing
TimerOutputs.enable_debug_timings(Ribasim) # causes recompilation (!)
end

# All data from the GeoPackage that we need during runtime is copied into memory,
# All data from the database that we need during runtime is copied into memory,
# so we can directly close it again.
db = SQLite.DB(gpkg_path)
db = SQLite.DB(db_path)
local parameters, state, n, tstops
try
parameters = Parameters(db, config)
Expand Down Expand Up @@ -83,7 +83,7 @@ function BMI.initialize(T::Type{Model}, config::Config)::Model
state = load_structvector(db, config, BasinStateV1)
n = length(get_ids(db, "Basin"))
finally
# always close the GeoPackage, also in case of an error
# always close the database, also in case of an error
close(db)
end
@debug "Read database into memory."
Expand Down Expand Up @@ -156,29 +156,29 @@ end
"""
BMI.finalize(model::Model)::Model
Write all output to the configured output files.
Write all results to the configured files.
"""
function BMI.finalize(model::Model)::Model
(; config) = model
(; output) = model.config
compress = get_compressor(output)
(; results) = model.config
compress = get_compressor(results)

# basin
table = basin_table(model)
path = output_path(config, output.basin)
path = results_path(config, results.basin)
write_arrow(path, table, compress)

# flow
table = flow_table(model)
path = output_path(config, output.flow)
path = results_path(config, results.flow)
write_arrow(path, table, compress)

# discrete control
table = discrete_control_table(model)
path = output_path(config, output.control)
path = results_path(config, results.control)
write_arrow(path, table, compress)

@debug "Wrote output."
@debug "Wrote results."
return model
end

Expand All @@ -203,7 +203,7 @@ function set_initial_discrete_controlled_parameters!(
end

"""
Create the different callbacks that are used to store output
Create the different callbacks that are used to store results
and feed the simulation with new data. The different callbacks
are combined to a CallbackSet that goes to the integrator.
Returns the CallbackSet and the SavedValues for flow.
Expand Down Expand Up @@ -566,7 +566,7 @@ BMI.get_time_step(model::Model) = get_proposed_dt(model.integrator)
run(config::Config)::Model
Run a [`Model`](@ref), given a path to a TOML configuration file, or a Config object.
Running a model includes initialization, solving to the end with `[`solve!`](@ref)` and writing output with [`BMI.finalize`](@ref).
Running a model includes initialization, solving to the end with `[`solve!`](@ref)` and writing results with [`BMI.finalize`](@ref).
"""
run(config_file::AbstractString)::Model = run(Config(config_file))

Expand Down
18 changes: 9 additions & 9 deletions core/src/config.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ using Logging: LogLevel, Debug, Info, Warn, Error
using ..Ribasim: Ribasim, isnode, nodetype
using OrdinaryDiffEq

export Config, Solver, Output, Logging
export Config, Solver, Results, Logging
export algorithm, snake_case, zstd, lz4

const schemas =
Expand Down Expand Up @@ -108,10 +108,10 @@ function Base.convert(::Type{Compression}, str::AbstractString)
end

# Separate struct, as basin clashes with nodetype
@option struct Output <: TableOption
basin::String = "output/basin.arrow"
flow::String = "output/flow.arrow"
control::String = "output/control.arrow"
@option struct Results <: TableOption
basin::String = "results/basin.arrow"
flow::String = "results/flow.arrow"
control::String = "results/control.arrow"
outstate::Union{String, Nothing} = nothing
compression::Compression = "zstd"
compression_level::Int = 6
Expand All @@ -132,13 +132,13 @@ end
# optional, when Config is created from a TOML file, this is its directory
relative_dir::String = "." # ignored(!)
input_dir::String = "."
output_dir::String = "."
results_dir::String = "."

# input, required
geopackage::String
database::String

# output, required
output::Output = Output()
# results, required
results::Results = Results()

solver::Solver = Solver()

Expand Down
12 changes: 6 additions & 6 deletions core/src/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ datetime_since(t::Real, t0::DateTime)::DateTime = t0 + Millisecond(round(1000 *
"""
load_data(db::DB, config::Config, nodetype::Symbol, kind::Symbol)::Union{Table, Query, Nothing}
Load data from Arrow files if available, otherwise the GeoPackage.
Load data from Arrow files if available, otherwise the database.
Returns either an `Arrow.Table`, `SQLite.Query` or `nothing` if the data is not present.
"""
function load_data(
Expand Down Expand Up @@ -78,7 +78,7 @@ end
"""
load_structvector(db::DB, config::Config, ::Type{T})::StructVector{T}
Load data from Arrow files if available, otherwise the GeoPackage.
Load data from Arrow files if available, otherwise the database.
Always returns a StructVector of the given struct type T, which is empty if the table is
not found. This function validates the schema, and enforces the required sort order.
"""
Expand All @@ -95,7 +95,7 @@ function load_structvector(

nt = Tables.columntable(table)
if table isa Query && haskey(nt, :time)
# time has type timestamp and is stored as a String in the GeoPackage
# time has type timestamp and is stored as a String in the database
# currently SQLite.jl does not automatically convert it to DateTime
nt = merge(
nt,
Expand Down Expand Up @@ -127,9 +127,9 @@ function input_path(config::Config, path::String)
return normpath(config.relative_dir, config.input_dir, path)
end

"Construct a path relative to both the TOML directory and the optional `output_dir`"
function output_path(config::Config, path::String)
return normpath(config.relative_dir, config.output_dir, path)
"Construct a path relative to both the TOML directory and the optional `results_dir`"
function results_path(config::Config, path::String)
return normpath(config.relative_dir, config.results_dir, path)
end

"""
Expand Down
2 changes: 1 addition & 1 deletion core/src/lib.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Initialize a Model.
The Model struct is an initialized model, combined with the [`Config`](@ref) used to create it and saved outputs.
The Model struct is an initialized model, combined with the [`Config`](@ref) used to create it and saved results.
The Basic Model Interface ([BMI](https://github.com/Deltares/BasicModelInterface.jl)) is implemented on the Model.
A Model can be created from the path to a TOML configuration file, or a Config object.
"""
Expand Down
2 changes: 1 addition & 1 deletion core/src/solve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ greater_than: The threshold value in the condition
condition_value: The current value of each condition
control_state: Dictionary: node ID => (control state, control state start)
logic_mapping: Dictionary: (control node ID, truth state) => control state
record: Namedtuple with discrete control information for output
record: Namedtuple with discrete control information for results
"""
struct DiscreteControl <: AbstractParameterNode
node_id::Vector{Int}
Expand Down
8 changes: 4 additions & 4 deletions core/src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -466,10 +466,10 @@ function basin_bottoms(
return bottom_a, bottom_b
end

"Get the compressor based on the Output"
function get_compressor(output::Output)::TranscodingStreams.Codec
compressor = output.compression
level = output.compression_level
"Get the compressor based on the Results section"
function get_compressor(results::Results)::TranscodingStreams.Codec
compressor = results.compression
level = results.compression_level
c = if compressor == lz4
LZ4FrameCompressor(; compressionlevel = level)
elseif compressor == zstd
Expand Down
2 changes: 1 addition & 1 deletion core/src/validation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ end
"""
Depending on if a table can be sorted, either sort it or assert that it is sorted.
Tables loaded from GeoPackage into memory can be sorted.
Tables loaded from the database into memory can be sorted.
Tables loaded from Arrow files are memory mapped and can therefore not be sorted.
"""
function sorted_table!(
Expand Down
6 changes: 3 additions & 3 deletions core/test/allocation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ using SQLite
using JuMP: value

@testset "Allocation solve" begin
toml_path = normpath(@__DIR__, "../../generated_testmodels/subnetwork/subnetwork.toml")
toml_path = normpath(@__DIR__, "../../generated_testmodels/subnetwork/ribasim.toml")
@test ispath(toml_path)
cfg = Ribasim.Config(toml_path)
gpkg_path = Ribasim.input_path(cfg, cfg.geopackage)
db = SQLite.DB(gpkg_path)
db_path = Ribasim.input_path(cfg, cfg.database)
db = SQLite.DB(db_path)

p = Ribasim.Parameters(db, cfg)
close(db)
Expand Down
2 changes: 1 addition & 1 deletion core/test/bmi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ using Test
using Ribasim
import BasicModelInterface as BMI

toml_path = normpath(@__DIR__, "../../generated_testmodels/basic/basic.toml")
toml_path = normpath(@__DIR__, "../../generated_testmodels/basic/ribasim.toml")

@testset "adaptive timestepping" begin
model = BMI.initialize(Ribasim.Model, toml_path)
Expand Down
2 changes: 1 addition & 1 deletion core/test/cli.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ end

@testset "toml_path" begin
model_path = normpath(@__DIR__, "../../generated_testmodels/basic/")
toml_path = normpath(model_path, "basic.toml")
toml_path = normpath(model_path, "ribasim.toml")
@test ispath(toml_path)
empty!(ARGS)
push!(ARGS, toml_path)
Expand Down
18 changes: 9 additions & 9 deletions core/test/config.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ using CodecZstd: ZstdCompressor
@test_throws UndefKeywordError Ribasim.Config(
startime = now(),
endtime = now(),
geopackage = "",
database = "",
foo = "bar",
)

Expand All @@ -21,22 +21,22 @@ using CodecZstd: ZstdCompressor
@test config.update_timestep == 86400.0
@test config.endtime > config.starttime
@test config.solver == Ribasim.Solver(; saveat = 86400.0)
@test config.output.compression == Ribasim.zstd
@test config.output.compression_level == 6
@test config.results.compression == Ribasim.zstd
@test config.results.compression_level == 6
end

@testset "output" begin
o = Ribasim.Output()
@test o isa Ribasim.Output
@testset "results" begin
o = Ribasim.Results()
@test o isa Ribasim.Results
@test o.compression === Ribasim.zstd
@test o.compression_level === 6
@test_throws ArgumentError Ribasim.Output(compression = "lz5")
@test_throws ArgumentError Ribasim.Results(compression = "lz5")

@test Ribasim.get_compressor(
Ribasim.Output(; compression = "lz4", compression_level = 2),
Ribasim.Results(; compression = "lz4", compression_level = 2),
) isa LZ4FrameCompressor
@test Ribasim.get_compressor(
Ribasim.Output(; compression = "zstd", compression_level = 3),
Ribasim.Results(; compression = "zstd", compression_level = 3),
) isa ZstdCompressor
end

Expand Down
Loading

0 comments on commit c710ed2

Please sign in to comment.