From 140ea1172f46d889ece6d45667dde769e1569371 Mon Sep 17 00:00:00 2001 From: pedroripper Date: Thu, 23 Nov 2023 15:15:53 -0300 Subject: [PATCH 1/2] Handle relations using element name --- src/OpenStudy/relations.jl | 37 ++++++++ src/OpenStudy/study_openinterface.jl | 32 +++++++ src/modification_api.jl | 71 +++++++++++++++ test/modification_api.jl | 54 +++++++++++- test/relations.jl | 126 +++++++++++++++++++++++++++ 5 files changed, 316 insertions(+), 4 deletions(-) diff --git a/src/OpenStudy/relations.jl b/src/OpenStudy/relations.jl index d6da8264..42c3aeb6 100644 --- a/src/OpenStudy/relations.jl +++ b/src/OpenStudy/relations.jl @@ -363,6 +363,11 @@ function _get_element_related(data::Data, collection::String, index::Integer) return relations_as_source, relations_as_target end +function _get_element_related(data::Data, collection::String, name::String) + idx = _get_index(data, collection, name) + return _get_element_related(data, collection, idx) +end + """ has_relations(data::Data, collection::String) @@ -391,6 +396,11 @@ function has_relations(data::Data, collection::String, index::Int) return false end +function has_relations(data::Data, collection::String, name::String) + idx = _get_index(data, collection, name) + return has_relations(data, collection, idx) +end + """ relations_summary(data::Data, collection::String, index::Integer) @@ -427,6 +437,11 @@ function relations_summary(data::Data, collection::String, index::Integer) return end +function relations_summary(data::Data, collection::String, name::String) + idx = _get_index(data, collection, name) + return relations_summary(data, collection, idx) +end + """ check_relation_scalar(relation_type::PMD.RelationType) @@ -859,6 +874,17 @@ function get_related( return 0 # for type stability end +function get_related( + data::Data, + source::String, + target::String, + source_name::String; + relation_type::PMD.RelationType = PMD.RELATION_1_TO_1, +) + idx = _get_index(data, source, source_name) + return get_related(data, source, target, idx; relation_type = relation_type) +end + function get_vector_related( data::Data, source::String, @@ -893,3 +919,14 @@ function get_vector_related( return target_index_list end + +function get_vector_related( + data::Data, + source::String, + target::String, + source_name::String, + relation_type::PMD.RelationType = PMD.RELATION_1_TO_N, +) + idx = _get_index(data, source, source_name) + return get_vector_related(data, source, target, idx, relation_type) +end diff --git a/src/OpenStudy/study_openinterface.jl b/src/OpenStudy/study_openinterface.jl index 66c6566d..37248984 100644 --- a/src/OpenStudy/study_openinterface.jl +++ b/src/OpenStudy/study_openinterface.jl @@ -223,6 +223,38 @@ function _merge_psr_transformer_and_psr_serie!(data::Data) return nothing end +""" + _get_index(data::Data, collection::String, name::String) + + Returns the index of an element from a collection, based on its name attribute +""" +function _get_index(data::Data, collection::String, name::String) + elements = data.raw[collection] + for idx in eachindex(elements) + if elements[idx]["name"] == name + return idx + end + end + return error( + "Element from collection $(collection) with name $(name) not found.", + ) +end + +""" + _has_name(data::Data, collection::String, name::String) + + Returns true if there is an element in collection with the given name +""" +function _has_name(data::Data, collection::String, name::String) + elements = data.raw[collection] + for idx in eachindex(elements) + if elements[idx]["name"] == name + return true + end + end + return false +end + function load_study( ::OpenInterface; data_path = "", diff --git a/src/modification_api.jl b/src/modification_api.jl index b002ceba..757c667d 100644 --- a/src/modification_api.jl +++ b/src/modification_api.jl @@ -314,6 +314,27 @@ function set_related!( return nothing end +function set_related!( + data::Data, + source::String, + target::String, + source_name::String, + target_name::String; + relation_type::PMD.RelationType = PMD.RELATION_1_TO_1, +) + source_idx = _get_index(data, source, source_name) + target_idx = _get_index(data, target, target_name) + + return set_related!( + data, + source, + target, + source_idx, + target_idx; + relation_type = relation_type, + ) +end + function set_related_by_code!( data::Data, source::String, @@ -355,6 +376,29 @@ function set_vector_related!( return nothing end +function set_vector_related!( + data::Data, + source::String, + target::String, + source_name::String, + target_names::Vector{T}, + relation_type::PMD.RelationType = PMD.RELATION_1_TO_N, +) where {T <: String} + source_idx = _get_index(data, source, source_name) + target_indices = Vector{Integer}() + for target_name in target_names + push!(target_indices, _get_index(data, target, target_name)) + end + return set_vector_related!( + data, + source, + target, + source_idx, + target_indices, + relation_type, + ) +end + function delete_relation!( data::Data, source::String, @@ -382,6 +426,18 @@ function delete_relation!( return nothing end +function delete_relation!( + data::Data, + source::String, + target::String, + source_name::String, + target_name::String, +) + source_idx = _get_index(data, source, source_name) + target_idx = _get_index(data, target, target_name) + return delete_relation!(data, source, target, source_idx, target_idx) +end + function delete_vector_relation!( data::Data, source::String, @@ -412,6 +468,21 @@ function delete_vector_relation!( return nothing end +function delete_vector_relation!( + data::Data, + source::String, + target::String, + source_name::String, + target_names::Vector{String}, +) + source_idx = _get_index(data, source, source_name) + target_indices = Vector{Int}() + for target_name in target_names + push!(target_indices, _get_index(data, target, target_name)) + end + return delete_vector_relation!(data, source, target, source_idx, target_indices) +end + function Base.show(io::IO, data::Data) return summary(io, data) end diff --git a/test/modification_api.jl b/test/modification_api.jl index 5fc902ee..8cb80e04 100644 --- a/test/modification_api.jl +++ b/test/modification_api.jl @@ -271,10 +271,10 @@ function test_api8() #tests delete_relation! data = PSRI.create_study(PSRI.OpenInterface(); data_path = temp_path) - index1 = PSRI.create_element!(data, "PSRBus") - index2 = PSRI.create_element!(data, "PSRBus") + index1 = PSRI.create_element!(data, "PSRBus", "name" => "Bus1") + index2 = PSRI.create_element!(data, "PSRBus", "name" => "Bus2") - index3 = PSRI.create_element!(data, "PSRSerie") + index3 = PSRI.create_element!(data, "PSRSerie", "name" => "Serie1") PSRI.set_related!( data, @@ -309,7 +309,7 @@ function test_api8() #tests delete_relation! @test PSRI.get_map(data, "PSRSerie", "PSRBus"; relation_type = PSRI.PMD.RELATION_TO) == [1] - PSRI.delete_relation!(data, "PSRSerie", "PSRBus", index3, index1) + PSRI.delete_relation!(data, "PSRSerie", "PSRBus", "Serie1", "Bus1") PSRI.delete_relation!(data, "PSRSerie", "PSRBus", index3, index2) PSRI.write_data(data) @@ -375,6 +375,51 @@ function test_api9() #tests delete_vector_relation! @test map_vec_copy == Vector{Int32}[[]] end +function test_api10() #tests delete_vector_relation! + temp_path = joinpath(tempdir(), "PSRI_10") + json_path = joinpath(temp_path, "psrclasses.json") + + mkpath(temp_path) + + data = PSRI.create_study(PSRI.OpenInterface(); data_path = temp_path) + + PSRI.create_element!( + data, + "PSRThermalPlant", + "ShutDownCost" => 1.0, + "name" => "Thermal1", + ) + PSRI.create_element!(data, "PSRFuel", "name" => "Fuel1") + PSRI.create_element!(data, "PSRFuel", "name" => "Fuel2") + PSRI.create_element!(data, "PSRFuel", "name" => "Fuel3") + + PSRI.set_vector_related!( + data, + "PSRThermalPlant", + "PSRFuel", + "Thermal1", + ["Fuel1", "Fuel2", "Fuel3"], + ) + map_vec = PSRI.get_vector_map(data, "PSRThermalPlant", "PSRFuel") + @test map_vec == Vector{Int32}[[1, 2, 3]] + PSRI.write_data(data) + + PSRI.delete_vector_relation!( + data, + "PSRThermalPlant", + "PSRFuel", + "Thermal1", + ["Fuel1", "Fuel2", "Fuel3"], + ) + + PSRI.write_data(data) + + data_copy = PSRI.load_study(PSRI.OpenInterface(); data_path = temp_path) + + map_vec_copy = PSRI.get_vector_map(data_copy, "PSRThermalPlant", "PSRFuel") + @test map_vec_copy == Vector{Int32}[[]] +end + test_api(PATH_CASE_0) test_api2() test_api3() @@ -384,3 +429,4 @@ test_api6() test_api7() test_api8() test_api9() +test_api10() diff --git a/test/relations.jl b/test/relations.jl index c966fd9b..a3743610 100644 --- a/test/relations.jl +++ b/test/relations.jl @@ -206,8 +206,134 @@ function test_relations5() end end +function test_relations6() + mktempdir() do temp_path + data = PSRI.create_study(PSRI.OpenInterface(); data_path = temp_path) + + PSRI.create_element!(data, "PSRSerie", "name" => "Serie1") + + PSRI.create_element!(data, "PSRBus", "name" => "Bus1") + PSRI.create_element!(data, "PSRBus", "name" => "Bus2") + + PSRI.set_related!( + data, + "PSRSerie", + "PSRBus", + "Serie1", + "Bus1"; + relation_type = PSRI.PMD.RELATION_TO, + ) + + PSRI.set_related!( + data, + "PSRSerie", + "PSRBus", + "Serie1", + "Bus2"; + relation_type = PSRI.PMD.RELATION_FROM, + ) + + @test PSRI.has_relations( + data, "PSRSerie", "Serie1", + ) == true + + @test PSRI.has_relations( + data, "PSRBus", "Bus1", + ) == true + + @test PSRI.has_relations( + data, "PSRBus", "Bus2", + ) == true + + PSRI.relations_summary( + data, "PSRSerie", "Serie1", + ) + + @test PSRI.get_related( + data, + "PSRSerie", + "PSRBus", + Int32(1); + relation_type = PSRI.PMD.RELATION_TO, + ) == PSRI.get_related( + data, + "PSRSerie", + "PSRBus", + "Serie1"; + relation_type = PSRI.PMD.RELATION_TO, + ) + + @test PSRI.get_related( + data, + "PSRSerie", + "PSRBus", + Int32(1); + relation_type = PSRI.PMD.RELATION_FROM, + ) == PSRI.get_related( + data, + "PSRSerie", + "PSRBus", + "Serie1"; + relation_type = PSRI.PMD.RELATION_FROM, + ) + end +end + +function test_relations7() + mktempdir() do temp_path + data = PSRI.create_study(PSRI.OpenInterface(); data_path = temp_path) + + PSRI.create_element!( + data, + "PSRReserveGenerationConstraintData", + "name" => "Reserve1", + ) + PSRI.create_element!(data, "PSRThermalPlant", "name" => "Thermal1") + PSRI.create_element!(data, "PSRThermalPlant", "name" => "Thermal2") + PSRI.create_element!(data, "PSRThermalPlant", "name" => "Thermal3") + PSRI.create_element!(data, "PSRThermalPlant", "name" => "Thermal4") + + PSRI.set_vector_related!( + data, + "PSRReserveGenerationConstraintData", + "PSRThermalPlant", + "Reserve1", + ["Thermal1", "Thermal2"], + ) + PSRI.set_vector_related!( + data, + "PSRReserveGenerationConstraintData", + "PSRThermalPlant", + "Reserve1", + ["Thermal3", "Thermal4"], + PSRI.PMD.RELATION_BACKED, + ) + + @test PSRI.get_vector_related( + data, + "PSRReserveGenerationConstraintData", + "PSRThermalPlant", + 1, + ) == PSRI.get_vector_related( + data, + "PSRReserveGenerationConstraintData", + "PSRThermalPlant", + "Reserve1", + ) + @test PSRI.get_vector_related( + data, + "PSRReserveGenerationConstraintData", + "PSRThermalPlant", + 1, + PSRI.PMD.RELATION_BACKED, + ) == [3, 4] + end +end + test_relations1() test_relations2() test_relations3() test_relations4() test_relations5() +test_relations6() +test_relations7() From 7fede0c2d05cd95479481a4c579b067f06a35a35 Mon Sep 17 00:00:00 2001 From: pedroripper Date: Thu, 23 Nov 2023 15:29:46 -0300 Subject: [PATCH 2/2] Remove `has_name` --- src/OpenStudy/study_openinterface.jl | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/OpenStudy/study_openinterface.jl b/src/OpenStudy/study_openinterface.jl index 37248984..49c89109 100644 --- a/src/OpenStudy/study_openinterface.jl +++ b/src/OpenStudy/study_openinterface.jl @@ -240,21 +240,6 @@ function _get_index(data::Data, collection::String, name::String) ) end -""" - _has_name(data::Data, collection::String, name::String) - - Returns true if there is an element in collection with the given name -""" -function _has_name(data::Data, collection::String, name::String) - elements = data.raw[collection] - for idx in eachindex(elements) - if elements[idx]["name"] == name - return true - end - end - return false -end - function load_study( ::OpenInterface; data_path = "",