forked from GenXProject/GenX.jl
-
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.
Allow writing of multistage stats during optimization
- Loading branch information
Showing
6 changed files
with
228 additions
and
55 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
@doc raw""" | ||
write_multi_stage_outputs(stats_d::Dict, | ||
outpath::String, | ||
settings_d::Dict, | ||
inputs_dict::Dict) | ||
This function calls various methods which write multi-stage modeling outputs as .csv files. | ||
# Arguments: | ||
* stats\_d: Dictionary which contains the run time, upper bound, and lower bound of each DDP iteration. | ||
* outpath: String which represents the path to the Results directory. | ||
* settings\_d: Dictionary containing settings configured in the GenX settings `genx_settings.yml` file as well as the multi-stage settings file `multi_stage_settings.yml`. | ||
* inputs\_dict: Dictionary containing the input data for the multi-stage model. | ||
""" | ||
function write_multi_stage_outputs(stats_d::Dict, | ||
outpath::String, | ||
settings_d::Dict, | ||
inputs_dict::Dict) | ||
multi_stage_settings_d = settings_d["MultiStageSettingsDict"] | ||
|
||
write_multi_stage_capacities_discharge(outpath, multi_stage_settings_d) | ||
write_multi_stage_capacities_charge(outpath, multi_stage_settings_d) | ||
write_multi_stage_capacities_energy(outpath, multi_stage_settings_d) | ||
if settings_d["NetworkExpansion"] == 1 | ||
write_multi_stage_network_expansion(outpath, multi_stage_settings_d) | ||
end | ||
write_multi_stage_costs(outpath, multi_stage_settings_d, inputs_dict) | ||
multi_stage_settings_d["Myopic"] == 0 && write_multi_stage_stats(outpath, stats_d) | ||
write_multi_stage_settings(outpath, settings_d) | ||
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,99 @@ | ||
module TestWritingStatsMs | ||
|
||
using Test | ||
using CSV, DataFrames | ||
using GenX | ||
|
||
|
||
# create temporary directory for testing | ||
mkpath("writing_outputs/multi_stage_stats_tmp") | ||
outpath = "writing_outputs/multi_stage_stats_tmp" | ||
filename = GenX._get_multi_stage_stats_filename() | ||
|
||
function test_header() | ||
# Note: if this test fails, it means that the header in the function _get_multi_stage_stats_header() has been changed. | ||
# Make sure to check that the code is consistent with the new header, and update the test accordingly. | ||
header = GenX._get_multi_stage_stats_header() | ||
@test header == ["Iteration_Number", "Seconds", "Upper_Bound", "Lower_Bound", "Relative_Gap"] | ||
end | ||
|
||
function test_skip_existing_file() | ||
touch(joinpath(outpath, filename)) | ||
# If the file already exists, don't overwrite it | ||
write_multi_stage_stats = GenX.write_multi_stage_stats(outpath, Dict()) | ||
@test isnothing(write_multi_stage_stats) | ||
rm(joinpath(outpath, filename)) | ||
end | ||
|
||
function test_write_multi_stage_stats(iter::Int64 = 10) | ||
# test writing stats to file for `iter` number of iterations | ||
times_a, upper_bounds_a, lower_bounds_a = rand(iter), rand(iter), rand(iter) | ||
stats_d = Dict("TIMES" => times_a, "UPPER_BOUNDS" => upper_bounds_a, "LOWER_BOUNDS" => lower_bounds_a) | ||
|
||
@test isnothing(GenX.write_multi_stage_stats(outpath, stats_d)) | ||
df_stats = CSV.read(joinpath(outpath, filename), DataFrame) | ||
header = GenX._get_multi_stage_stats_header() | ||
@test size(df_stats) == (iter, length(header)) | ||
for i in 1:iter | ||
test_stats_d(df_stats, i, times_a[i], upper_bounds_a[i], lower_bounds_a[i], (upper_bounds_a[i] - lower_bounds_a[i]) / lower_bounds_a[i]) | ||
end | ||
rm(joinpath(outpath, filename)) | ||
end | ||
|
||
function test_create_multi_stage_stats_file() | ||
GenX.create_multi_stage_stats_file(outpath) | ||
df_stats = CSV.read(joinpath(outpath, filename), DataFrame) | ||
@test size(df_stats, 1) == 0 | ||
@test size(df_stats, 2) == 5 | ||
@test names(df_stats) == GenX._get_multi_stage_stats_header() | ||
rm(joinpath(outpath, filename)) | ||
end | ||
|
||
function test_update_multi_stage_stats_file(iter::Int64 = 10) | ||
# test updating the stats file with new values | ||
header = GenX._get_multi_stage_stats_header() | ||
GenX.create_multi_stage_stats_file(outpath) | ||
lower_bound = rand() | ||
iteration_time = rand() | ||
for i in 1:iter | ||
# upper bound is updated | ||
upper_bound = rand() | ||
GenX.update_multi_stage_stats_file(outpath, i, upper_bound, lower_bound, iteration_time, new_row=true) | ||
df_stats = CSV.read(joinpath(outpath, filename), DataFrame) | ||
test_stats_d(df_stats, i, iteration_time, upper_bound, lower_bound, (upper_bound - lower_bound) / lower_bound) | ||
# lower bound is updated | ||
lower_bound = rand() | ||
GenX.update_multi_stage_stats_file(outpath, i, upper_bound, lower_bound, iteration_time) | ||
df_stats = CSV.read(joinpath(outpath, filename), DataFrame) | ||
test_stats_d(df_stats, i, iteration_time, upper_bound, lower_bound, (upper_bound - lower_bound) / lower_bound) | ||
# iteration time is updated | ||
iteration_time = rand() | ||
GenX.update_multi_stage_stats_file(outpath, i, upper_bound, lower_bound, iteration_time) | ||
df_stats = CSV.read(joinpath(outpath, filename), DataFrame) | ||
test_stats_d(df_stats, i, iteration_time, upper_bound, lower_bound, (upper_bound - lower_bound) / lower_bound) | ||
# test size | ||
@test size(df_stats) == (i, length(header)) | ||
end | ||
rm(joinpath(outpath, filename)) | ||
end | ||
|
||
function test_stats_d(df_stats, i, iteration_time, upper_bound, lower_bound, relative_gap) | ||
header = GenX._get_multi_stage_stats_header() | ||
@test df_stats[i, header[1]] == i | ||
@test df_stats[i, header[2]] == iteration_time | ||
@test df_stats[i, header[3]] == upper_bound | ||
@test df_stats[i, header[4]] == lower_bound | ||
@test df_stats[i, header[5]] == relative_gap | ||
end | ||
|
||
@testset "Test writing multi-stage stats" begin | ||
test_header() | ||
test_skip_existing_file() | ||
test_write_multi_stage_stats() | ||
test_create_multi_stage_stats_file() | ||
test_update_multi_stage_stats_file() | ||
end | ||
|
||
rm(outpath) | ||
|
||
end # module TestWritingStatsMs |