-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adjusted checks based on EMB changes (#14)
- Loading branch information
Showing
6 changed files
with
236 additions
and
19 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,15 @@ | ||
name = "EnergyModelsGeography" | ||
uuid = "3f775d88-a4da-46c4-a2cc-aa9f16db6708" | ||
authors = ["Espen Flo Bødal <[email protected]>"] | ||
version = "0.8.2" | ||
version = "0.8.3" | ||
|
||
[deps] | ||
EnergyModelsBase = "5d7e687e-f956-46f3-9045-6f5a5fd49f50" | ||
JuMP = "4076af6c-e467-56ae-b986-b466b2749572" | ||
TimeStruct = "f9ed5ce0-9f41-4eaa-96da-f38ab8df101c" | ||
|
||
[compat] | ||
EnergyModelsBase = "^0.6.0" | ||
EnergyModelsBase = "^0.6.7" | ||
JuMP = "1.5" | ||
julia = "^1.6" | ||
TimeStruct = "^0.7.0" |
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 |
---|---|---|
@@ -1,24 +1,125 @@ | ||
|
||
function check_data(case, modeltype) | ||
""" | ||
check_data(case, modeltype, check_timeprofiles::Bool) | ||
Check if the case data is consistent. Use the `@assert_or_log` macro when testing. | ||
Currently, not checking data except that the case dictionary follows the required structure. | ||
""" | ||
function check_data(case, modeltype, check_timeprofiles::Bool) | ||
|
||
global EMB.logs = [] | ||
log_by_element = Dict() | ||
|
||
# Check the case data. If the case data is not in the correct format, the overall check | ||
# is cancelled as extractions would not be possible | ||
check_case_data(case) | ||
log_by_element["Case data"] = EMB.logs | ||
if EMB.ASSERTS_AS_LOG | ||
EMB.compile_logs(case, log_by_element) | ||
end | ||
|
||
𝒜 = case[:areas] | ||
ℒᵗʳᵃⁿˢ = case[:transmission] | ||
ℒ = case[:links] | ||
𝒩 = case[:nodes] | ||
𝒫 = case[:products] | ||
𝒯 = case[:T] | ||
|
||
for a ∈ 𝒜 | ||
check_area(a, 𝒩, ℒ, 𝒯, 𝒫, modeltype) | ||
check_area(a, 𝒯, 𝒫, modeltype, check_timeprofiles) | ||
# Put all log messages that emerged during the check, in a dictionary with the | ||
# area as key. | ||
log_by_element[a] = EMB.logs | ||
end | ||
for l ∈ ℒᵗʳᵃⁿˢ | ||
check_transmission(l, 𝒩, 𝒯, 𝒫, modeltype) | ||
check_transmission(l, 𝒯, 𝒫, modeltype, check_timeprofiles) | ||
|
||
ℳ = modes(l) | ||
for m ∈ ℳ | ||
check_mode(m, 𝒯, 𝒫, modeltype, check_timeprofiles) | ||
if check_timeprofiles | ||
check_time_structure(m, 𝒯) | ||
end | ||
# Put all log messages that emerged during the check, in a dictionary with the | ||
# corridor as key. | ||
log_by_element[l] = EMB.logs | ||
end | ||
end | ||
|
||
if EMB.ASSERTS_AS_LOG | ||
EMB.compile_logs(case, log_by_element) | ||
end | ||
end | ||
|
||
""" | ||
check_case_data(case) | ||
Checks the `case` dictionary is in the correct format. The function is only checking the | ||
new, additional data as we do not yet consider dispatch on the case data. | ||
## Checks | ||
- The dictionary requires the keys `:areas` and `:transmission`. | ||
- The individual keys are of the correct type, that is | ||
- `:areas::Area` and | ||
- `:transmission::Vector{<:Transmission}`. | ||
""" | ||
function check_case_data(case) | ||
|
||
case_keys = [:areas, :transmission] | ||
key_map = Dict( | ||
:areas => Vector{<:Area}, | ||
:transmission => Vector{<:Transmission}, | ||
) | ||
for key ∈ case_keys | ||
@assert_or_log( | ||
haskey(case, key), | ||
"The `case` dictionary requires the key `:" * string(key) * "` which is " * | ||
"not included." | ||
) | ||
if haskey(case, key) | ||
@assert_or_log( | ||
isa(case[key], key_map[key]), | ||
"The key `" * string(key) * "` in the `case` dictionary contains " * | ||
"other types than the allowed." | ||
) | ||
end | ||
end | ||
end | ||
|
||
""" | ||
check_area(a::Area, 𝒯, 𝒫, modeltype::EnergyModel, check_timeprofiles::Bool) | ||
Check that the fields of an `Area` corresponds to required structure. | ||
""" | ||
function check_area(a::Area, 𝒯, 𝒫, modeltype::EnergyModel, check_timeprofiles::Bool) | ||
end | ||
|
||
""" | ||
check_transmission(l::Transmission, 𝒯, 𝒫, modeltype::EnergyModel, check_timeprofiles::Bool) | ||
function check_area(a::Area, 𝒩, ℒ, 𝒯, 𝒫, modeltype) | ||
Check that the fields of a `Transmission` corridor corresponds to required structure. | ||
""" | ||
function check_transmission(l::Transmission, 𝒯, 𝒫, modeltype::EnergyModel, check_timeprofiles::Bool) | ||
end | ||
|
||
function check_transmission(l::Transmission, 𝒩, 𝒯, 𝒫, modeltype) | ||
|
||
""" | ||
check_mode(m::TransmissionMode, 𝒯, 𝒫, modeltype::EnergyModel, check_timeprofiles::Bool) | ||
Check that the fields of a `TransmissionMode` corresponds to required structure. | ||
""" | ||
function check_mode(l::TransmissionMode, 𝒯, 𝒫, modeltype::EnergyModel, check_timeprofiles::Bool) | ||
end | ||
|
||
""" | ||
check_time_structure(m::TransmissionMode, 𝒯) | ||
Check that all fields of a `TransmissionMode` that are of type `TimeProfile` correspond to | ||
the time structure `𝒯`. | ||
""" | ||
function check_time_structure(m::TransmissionMode, 𝒯) | ||
for fieldname ∈ fieldnames(typeof(m)) | ||
value = getfield(m, fieldname) | ||
if isa(value, TimeProfile) | ||
EMB.check_profile(fieldname, value, 𝒯) | ||
end | ||
end | ||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
# Set the global to true to suppress the error message | ||
EMB.TEST_ENV = true | ||
|
||
@testset "Test checks - case dictionary" begin | ||
# Resources used in the analysis | ||
Power = ResourceCarrier("Power", 0.0) | ||
CO2 = ResourceEmit("CO2", 1.0) | ||
|
||
function small_graph() | ||
products = [Power, CO2] | ||
|
||
# Creation of the source and sink module as well as the arrays used for nodes and links | ||
source = RefSource( | ||
"src", | ||
FixedProfile(25), | ||
FixedProfile(10), | ||
FixedProfile(5), | ||
Dict(Power => 1), | ||
) | ||
sink = RefSink( | ||
"sink", | ||
FixedProfile(20), | ||
Dict(:surplus => FixedProfile(0), :deficit => FixedProfile(1e6)), | ||
Dict(Power => 1), | ||
) | ||
|
||
nodes = [ | ||
GeoAvailability(1, products), | ||
EMG.GeoAvailability(2, products), | ||
source, | ||
sink, | ||
] | ||
links = [ | ||
Direct(31, nodes[3], nodes[1], Linear()), | ||
Direct(24, nodes[2], nodes[4], Linear()), | ||
] | ||
|
||
# Creation of the two areas and potential transmission lines | ||
areas = [ | ||
RefArea(1, "Factory", 10.751, 59.921, nodes[1]), | ||
RefArea(2, "North Sea", 10.398, 63.4366, nodes[2]), | ||
] | ||
|
||
transmission_line = RefStatic( | ||
"Transline", | ||
Power, | ||
FixedProfile(30.0), | ||
FixedProfile(0.05), | ||
FixedProfile(0.05), | ||
FixedProfile(0.05), | ||
1, | ||
) | ||
transmissions = [Transmission(areas[1], areas[2], [transmission_line])] | ||
|
||
# Creation of the time structure and the used global data | ||
T = TwoLevel(4, 1, SimpleTimes(4, 1)) | ||
modeltype = OperationalModel( | ||
Dict(CO2 => StrategicProfile([450, 400, 350, 300])), | ||
Dict(CO2 => FixedProfile(0)), | ||
CO2 | ||
) | ||
|
||
|
||
# Creation of the case dictionary | ||
case = Dict(:nodes => nodes, | ||
:links => links, | ||
:products => products, | ||
:areas => areas, | ||
:transmission => transmissions, | ||
:T => T, | ||
) | ||
return case, modeltype | ||
end | ||
|
||
# Check that the keys are present | ||
# - EMG.check_case_data(case) | ||
case, model = small_graph() | ||
for key ∈ [:areas, :transmission] | ||
case_test = deepcopy(case) | ||
pop!(case_test, key) | ||
@test_throws AssertionError EMG.create_model(case_test, model) | ||
end | ||
|
||
# Check that the keys are of the correct format and do not include any unwanted types | ||
# - EMG.check_case_data(case) | ||
case_test = deepcopy(case) | ||
case_test[:areas] = [case[:areas], case[:areas], 10] | ||
@test_throws AssertionError EMG.create_model(case_test, model) | ||
case_test = deepcopy(case) | ||
case_test[:transmission] = [case[:transmission], case[:transmission], 10] | ||
@test_throws AssertionError EMG.create_model(case_test, model) | ||
end | ||
|
||
# Set the global again to false | ||
EMB.TEST_ENV = false |
db44cf5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JuliaRegistrator register
db44cf5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Registration pull request created: JuliaRegistries/General/103412
Tip: Release Notes
Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.
To add them here just re-invoke and the PR will be updated.
Tagging
After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.
This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via: