Skip to content

Commit d0b5a83

Browse files
authored
Merge pull request #494 from NREL-Sienna/issue-493
Fix reading results with time slices
2 parents 4d4645f + 8ae32e1 commit d0b5a83

File tree

3 files changed

+48
-26
lines changed

3 files changed

+48
-26
lines changed

src/Optimization/Optimization.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Dates
1010
import CSV
1111
import DataFrames
1212
import DataFrames: DataFrame, innerjoin, select, select!
13-
import DataFramesMeta: @chain, @combine, @transform
13+
import DataFramesMeta: @chain, @combine, @subset, @transform
1414

1515
import ..InfrastructureSystems
1616
const IS = InfrastructureSystems

src/Optimization/optimization_problem_results.jl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,13 +317,17 @@ function _read_results(
317317
container_keys = container_keys === nothing ? existing_keys : container_keys
318318
_validate_keys(existing_keys, container_keys)
319319
results = Dict{OptimizationContainerKey, DataFrame}()
320-
IS.@assert_op time_ids == collect(1:length(timestamps))
320+
IS.@assert_op length(time_ids) == length(timestamps)
321321
df_timestamps = DataFrame(:DateTime => timestamps, :time_index => time_ids)
322+
filter_timestamps = timestamps != base_timestamps
322323

323324
for (key, df) in result_values
324325
if !in(key, container_keys)
325326
continue
326327
end
328+
if filter_timestamps
329+
df = @subset(df, :time_index .∈ Ref(time_ids))
330+
end
327331
first_dim_col = get_first_dimension_result_column_name(key)
328332
second_dim_col = get_second_dimension_result_column_name(key)
329333
component_cols = [first_dim_col]
@@ -343,7 +347,7 @@ function _read_results(
343347
)
344348
end
345349
num_rows_per_component = num_rows ÷ num_components
346-
if num_rows_per_component == length(time_ids) == length(base_timestamps)
350+
if num_rows_per_component == length(time_ids) == length(timestamps)
347351
tmp_df = innerjoin(df, df_timestamps; on = :time_index)
348352
if DataFrames.nrow(tmp_df) != DataFrames.nrow(df)
349353
error(
@@ -861,6 +865,7 @@ function read_results_with_keys(
861865
)
862866
isempty(result_keys) && return Dict{OptimizationContainerKey, DataFrame}()
863867
(timestamp_ids, timestamps) = _process_timestamps(res, start_time, len)
868+
864869
base_timestamps = get_timestamps(res)
865870
return _read_results(
866871
get_result_values(res, first(result_keys)),

test/test_optimization_results.jl

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const IS = InfrastructureSystems
1717
StepRange(
1818
DateTime("2024-01-01T00:00:00"),
1919
Millisecond(3600000),
20-
DateTime("2024-01-01T01:00:00"),
20+
DateTime("2024-01-01T03:00:00"),
2121
)
2222
timestamp_vec = collect(timestamp_range)
2323
data = IS.SystemData()
@@ -27,16 +27,16 @@ const IS = InfrastructureSystems
2727
@test IS.Optimization.convert_result_to_natural_units(MockVariable2)
2828
var_key1 = VariableKey(MockVariable, IS.TestComponent)
2929
var_key2 = VariableKey(MockVariable2, IS.TestComponent)
30-
vals = [1.0, 2.0, 3.0, 4.0]
30+
vals = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
3131
variable_values = Dict(
3232
var_key1 => DataFrame(
33-
"time_index" => [1, 2, 1, 2],
34-
"name" => ["c1", "c1", "c2", "c2"],
33+
"time_index" => [1, 2, 3, 4, 1, 2, 3, 4],
34+
"name" => ["c1", "c1", "c1", "c1", "c2", "c2", "c2", "c2"],
3535
"value" => vals,
3636
),
3737
var_key2 => DataFrame(
38-
"time_index" => [1, 2, 1, 2],
39-
"name" => ["c1", "c1", "c2", "c2"],
38+
"time_index" => [1, 2, 3, 4, 1, 2, 3, 4],
39+
"name" => ["c1", "c1", "c1", "c1", "c2", "c2", "c2", "c2"],
4040
"value" => vals,
4141
),
4242
)
@@ -49,13 +49,13 @@ const IS = InfrastructureSystems
4949
# Expression only 1 time-step
5050
expression_values = Dict(
5151
exp_key1 => DataFrame(
52-
"time_index" => [1, 2, 1, 2],
53-
"name" => ["c1", "c1", "c2", "c2"],
52+
"time_index" => [1, 2, 3, 4, 1, 2, 3, 4],
53+
"name" => ["c1", "c1", "c1", "c1", "c2", "c2", "c2", "c2"],
5454
"value" => vals,
5555
),
5656
exp_key2 => DataFrame(
57-
"time_index" => [1, 2, 1, 2],
58-
"custom_name" => ["c1", "c1", "c2", "c2"],
57+
"time_index" => [1, 2, 3, 4, 1, 2, 3, 4],
58+
"custom_name" => ["c1", "c1", "c1", "c1", "c2", "c2", "c2", "c2"],
5959
"value" => vals,
6060
),
6161
)
@@ -95,11 +95,9 @@ const IS = InfrastructureSystems
9595
mktempdir(),
9696
mktempdir(),
9797
)
98-
timestamp_vec2 = deepcopy(timestamp_vec)
99-
pop!(timestamp_vec2)
10098
opt_res3 = OptimizationProblemResults(
10199
base_power,
102-
timestamp_vec2,
100+
[timestamp_vec[1]],
103101
data,
104102
uuid,
105103
aux_variable_values,
@@ -116,26 +114,45 @@ const IS = InfrastructureSystems
116114

117115
var_res = read_variable(opt_res1, var_key1)
118116
@test sort!(unique(var_res.DateTime)) == timestamp_vec
119-
@test @rsubset(var_res, :name == "c1")[!, :value] == [1.0, 2.0]
120-
@test @rsubset(var_res, :name == "c2")[!, :value] == [3.0, 4.0]
117+
@test @rsubset(var_res, :name == "c1")[!, :value] == [1.0, 2.0, 3.0, 4.0]
118+
@test @rsubset(var_res, :name == "c2")[!, :value] == [5.0, 6.0, 7.0, 8.0]
121119

122120
var_res = read_variable(opt_res1, var_key2)
123-
@test @rsubset(var_res, :name == "c1")[!, :value] == [10.0, 20.0]
124-
@test @rsubset(var_res, :name == "c2")[!, :value] == [30.0, 40.0]
121+
@test @rsubset(var_res, :name == "c1")[!, :value] == [10.0, 20.0, 30.0, 40.0]
122+
@test @rsubset(var_res, :name == "c2")[!, :value] == [50.0, 60.0, 70.0, 80.0]
123+
124+
var_res2 = read_variable(
125+
opt_res1,
126+
var_key1;
127+
start_time = DateTime("2024-01-01T01:00:00"),
128+
len = 2,
129+
)
130+
@test @rsubset(var_res2, :name == "c1")[!, :value] == [2.0, 3.0]
131+
@test @rsubset(var_res2, :name == "c2")[!, :value] == [6.0, 7.0]
132+
133+
var_res2 = read_variable(
134+
opt_res1,
135+
var_key2;
136+
start_time = DateTime("2024-01-01T01:00:00"),
137+
len = 2,
138+
)
139+
@test @rsubset(var_res2, :name == "c1")[!, :value] == [20.0, 30.0]
140+
@test @rsubset(var_res2, :name == "c2")[!, :value] == [60.0, 70.0]
125141

126142
var_res = read_variable(opt_res1, var_key2; table_format = IS.TableFormat.WIDE)
127-
@test var_res[!, :c1] == [10.0, 20.0]
128-
@test var_res[!, :c2] == [30.0, 40.0]
143+
@test var_res[!, :c1] == [10.0, 20.0, 30.0, 40.0]
144+
@test var_res[!, :c2] == [50.0, 60.0, 70.0, 80.0]
129145

130146
exp_res = read_expression(opt_res2, exp_key1)
131-
@test @rsubset(exp_res, :name == "c1")[!, :value] == [1.0, 2.0]
132-
@test @rsubset(exp_res, :name == "c2")[!, :value] == [3.0, 4.0]
147+
@test @rsubset(exp_res, :name == "c1")[!, :value] == [1.0, 2.0, 3.0, 4.0]
148+
@test @rsubset(exp_res, :name == "c2")[!, :value] == [5.0, 6.0, 7.0, 8.0]
133149
exp_res = read_expression(opt_res2, exp_key2)
134-
@test @rsubset(exp_res, :custom_name == "c1")[!, :value] == [10.0, 20.0]
135-
@test @rsubset(exp_res, :custom_name == "c2")[!, :value] == [30.0, 40.0]
150+
@test @rsubset(exp_res, :custom_name == "c1")[!, :value] == [10.0, 20.0, 30.0, 40.0]
151+
@test @rsubset(exp_res, :custom_name == "c2")[!, :value] == [50.0, 60.0, 70.0, 80.0]
136152

137153
@test IS.Optimization.get_resolution(opt_res1) == Millisecond(3600000)
138154
@test IS.Optimization.get_resolution(opt_res2) == Millisecond(3600000)
155+
@show IS.Optimization.get_resolution(opt_res3)
139156
@test isnothing(IS.Optimization.get_resolution(opt_res3))
140157
end
141158

0 commit comments

Comments
 (0)