-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create a new structure called ModelParameters. Add a model_parameters field to EnergyProblem. Create constructors for ModelParameters for reading a file, and for obtaining some default values from the connection. Pass the model_parameters to create_model. Closes #802
- Loading branch information
1 parent
550a1c6
commit 1210744
Showing
11 changed files
with
137 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
export ModelParameters | ||
|
||
""" | ||
ModelParameters(;key = value, ...) | ||
ModelParameters(path; ...) | ||
ModelParameters(connection; ...) | ||
ModelParameters(connection, path; ...) | ||
Structure to hold the model parameters. | ||
Some values are defined by default and some required explicit definition. | ||
If `path` is passed, it is expected to be a string pointing to a TOML file with | ||
a `key = value` list of parameters. Explicit keyword arguments take precedence. | ||
If `connection` is passed, the default `discount_year` is set to the | ||
minimum of all milestone years. In other words, we check for the table | ||
`year_data` for the column `year` where the column `is_milestone` is true. | ||
Explicit keyword arguments take precedence. | ||
If both are passed, then `path` has preference. Explicit keyword arguments take precedence. | ||
## Parameters | ||
- `discount_rate::Float64 = 0.0`: The model discount rate. | ||
- `discount_year::Int`: The model discount year. | ||
""" | ||
Base.@kwdef mutable struct ModelParameters | ||
discount_rate::Float64 = 0.0 | ||
discount_year::Int # Explicit definition expected | ||
end | ||
|
||
# Using `@kwdef` defines a default constructor based on keywords | ||
|
||
function _read_model_parameters(path) | ||
if length(path) > 0 && !isfile(path) | ||
throw(ArgumentError("path `$path` does not contain a file")) | ||
end | ||
|
||
file_data = length(path) > 0 ? TOML.parsefile(path) : Dict{String,Any}() | ||
file_parameters = Dict(Symbol(k) => v for (k, v) in file_data) | ||
|
||
return file_parameters | ||
end | ||
|
||
function ModelParameters(path::String; kwargs...) | ||
file_parameters = _read_model_parameters(path) | ||
|
||
return ModelParameters(; file_parameters..., kwargs...) | ||
end | ||
|
||
function ModelParameters(connection::DuckDB.DB, path::String = ""; kwargs...) | ||
discount_year = minimum( | ||
row.year for | ||
row in DuckDB.query(connection, "SELECT year FROM year_data WHERE is_milestone = true") | ||
) | ||
# This can't be naively refactored to reuse the function above because of | ||
# the order of preference of the parameters. | ||
file_parameters = _read_model_parameters(path) | ||
|
||
return ModelParameters(; discount_year, file_parameters..., kwargs...) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
discount_rate = 0.03 | ||
discount_year = 2020 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
@testset "Testing Model Parameters" begin | ||
path = joinpath(@__DIR__, "inputs", "model-parameters-example.toml") | ||
|
||
@testset "Basic usage" begin | ||
mp = ModelParameters(; discount_rate = 0.1, discount_year = 2018) | ||
@test mp.discount_rate == 0.1 | ||
@test mp.discount_year == 2018 | ||
end | ||
|
||
@testset "Errors when missing required parameters" begin | ||
@test_throws UndefKeywordError ModelParameters() | ||
end | ||
|
||
@testset "Read from file" begin | ||
mp = ModelParameters(path) | ||
data = TOML.parsefile(path) | ||
for (key, value) in data | ||
@test value == getfield(mp, Symbol(key)) | ||
end | ||
|
||
@testset "explicit keywords take precedence" begin | ||
mp = ModelParameters(path; discount_year = 2019) | ||
@test mp.discount_year == 2019 | ||
end | ||
|
||
@testset "Errors if path does not exist" begin | ||
@test_throws ArgumentError ModelParameters("nonexistent.toml") | ||
end | ||
end | ||
|
||
@testset "Read from DuckDB" begin | ||
connection = DBInterface.connect(DuckDB.DB) | ||
read_csv_folder(connection, joinpath(@__DIR__, "inputs", "Norse")) | ||
mp = ModelParameters(connection) | ||
@test mp.discount_year == 2030 | ||
|
||
@testset "path has precedence" begin | ||
mp = ModelParameters(connection, path) | ||
data = TOML.parsefile(path) | ||
for (key, value) in data | ||
@test value == getfield(mp, Symbol(key)) | ||
end | ||
end | ||
|
||
@testset "explicit keywords take precedence" begin | ||
mp = ModelParameters(connection, path; discount_year = 2019) | ||
@test mp.discount_year == 2019 | ||
end | ||
end | ||
end |