Skip to content

Commit

Permalink
ComponentSelector: make scope_limiter an optional first argument
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielKS committed Jan 17, 2025
1 parent 55ff080 commit 3332ff4
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 49 deletions.
38 changes: 11 additions & 27 deletions src/component_selector.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
# Most of this is implemented by wrapping the IS versions, replacing
# InfrastructureSystemsComponent with Component and SystemData with System
# Most of the `ComponentSelector` functionality in PowerSystems.jl is implemented by
# wrapping the InfrastructureSystems.jl versions (that wrapping occurs in
# `get_components_interface.jl`). An exception is `TopologyComponentSelector`, which is
# wholly implemented in PSY rather than in IS because it depends on
# `PSY.AggregationTopology`.

#=
PowerSystems-specific `ComponentSelector` extension notes:
See InfrastructureSystems.jl for the main interface.
=#

# TopologyComponentSelector
# This one is wholly implemented in PowerSystems rather than in InfrastructureSystems because it depends on `PSY.AggregationTopology`
"""
`PluralComponentSelector` represented by an `AggregationTopology` and a type of `Component`.
"""
Expand Down Expand Up @@ -71,28 +67,16 @@ make_selector(

# Contents
function IS.get_components(
scope_limiter::Union{Function, Nothing},
selector::TopologyComponentSelector,
sys::System;
kwargs...,
sys::System,
)
agg_topology = get_component(selector.topology_type, sys, selector.topology_name)
isnothing(agg_topology) && return IS._make_empty_iterator(selector.component_type)

scope_limiter = get(kwargs, :scope_limiter, nothing)
combo_filter = if isnothing(scope_limiter)
x -> is_component_in_aggregation_topology(x, agg_topology)
else
x -> scope_limiter(x) && is_component_in_aggregation_topology(x, agg_topology)
end
combo_filter = IS.optional_and_fns(
scope_limiter,
Base.Fix2(is_component_in_aggregation_topology, agg_topology),
)
return IS.get_components(combo_filter, selector.component_type, sys)
end

# Alternative functions for only available components
IS.get_available_components(selector::ComponentSelector, sys::System) =
IS.get_components(selector, sys; scope_limiter = get_available)

IS.get_available_component(selector::SingularComponentSelector, sys::System) =
IS.get_component(selector, sys; scope_limiter = get_available)

IS.get_available_groups(selector::ComponentSelector, sys::System) =
get_groups(selector, sys; scope_limiter = get_available)
83 changes: 73 additions & 10 deletions src/get_components_interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,23 @@ get_components(
) where {T <: Component} =
IS.get_components(filter_func, T, sys; subsystem_name = subsystem_name)

"""
get_components(scope_limiter, selector, sys)
Get the components of the `System` that make up the `ComponentSelector`.
"""
get_components(
scope_limiter::Union{Function, Nothing},
selector::ComponentSelector,
sys::System,
) =
IS.get_components(scope_limiter, selector, sys)

"""
get_components(selector, sys)
Get the components of the `System` that make up the `ComponentSelector`.
"""
get_components(selector::ComponentSelector, sys::System; kwargs...) =
IS.get_components(selector, sys; kwargs...)
get_components(selector::ComponentSelector, sys::System) =
IS.get_components(selector, sys)

# get_component
"""
Expand All @@ -93,13 +104,25 @@ Throws ArgumentError if T is not a concrete type and there is more than one comp
get_component(::Type{T}, sys::System, name::AbstractString) where {T <: Component} =
IS.get_component(T, sys, name)

"""
get_component(scope_limiter, selector, sys)
Get the component of the `System` that makes up the `SingularComponentSelector`; `nothing`
if there is none.
"""
get_component(
scope_limiter::Union{Function, Nothing},
selector::SingularComponentSelector,
sys::System,
) =
IS.get_component(scope_limiter, selector, sys)

"""
get_component(selector, sys)
Get the component of the `System` that makes up the `SingularComponentSelector`; `nothing`
if there is none.
"""
get_component(selector::SingularComponentSelector, sys::System; kwargs...) =
IS.get_component(selector, sys; kwargs...)
get_component(selector::SingularComponentSelector, sys::System) =
IS.get_component(selector, sys)

# get_available_components
"""
Expand All @@ -123,6 +146,17 @@ get_available_components(
) where {T <: Component} =
IS.get_available_components(filter_func, T, sys; subsystem_name = subsystem_name)

"""
get_available_components(scope_limiter, selector, sys)
Get the available components of the collection that make up the `ComponentSelector`.
"""
get_available_components(
scope_limiter::Union{Function, Nothing},
selector::ComponentSelector,
sys::System,
) =
IS.get_available_components(scope_limiter, selector::ComponentSelector, sys::System)

"""
get_available_components(selector, sys)
Get the available components of the collection that make up the `ComponentSelector`.
Expand All @@ -148,22 +182,51 @@ get_available_component(::Type{T}, sys::System, args...; kwargs...) where {T <:
Like [`get_component`](@ref) but also returns `nothing` if the component is not `get_available`.
"""
get_available_component(
arg1::IS.SingularComponentSelector,
scope_limiter::Union{Function, Nothing},
selector::IS.SingularComponentSelector,
sys::System,
) =
IS.get_available_component(scope_limiter, selector, sys)

"""
Like [`get_component`](@ref) but also returns `nothing` if the component is not `get_available`.
"""
get_available_component(
selector::IS.SingularComponentSelector,
sys::System,
args...;
kwargs...,
) =
IS.get_available_component(arg1, sys, args...; kwargs...)
IS.get_available_component(selector, sys)

# get_groups
"""
get_groups(scope_limiter, selector, sys)
Get the groups that make up the `ComponentSelector`.
"""
get_groups(
scope_limiter::Union{Function, Nothing},
selector::ComponentSelector,
sys::System,
) =
IS.get_groups(scope_limiter, selector, sys)

"""
get_groups(selector, sys)
Get the groups that make up the `ComponentSelector`.
"""
get_groups(selector::ComponentSelector, sys::System; kwargs...) =
IS.get_groups(selector, sys; kwargs...)
get_groups(selector::ComponentSelector, sys::System) =
IS.get_groups(selector, sys)

# get_available_groups
"""
Like [`get_groups`](@ref) but as if the `System` only contained its available components.
"""
get_available_groups(
scope_limiter::Union{Function, Nothing},
selector::ComponentSelector,
sys::System,
) =
IS.get_available_groups(scope_limiter, selector, sys)

"""
Like [`get_groups`](@ref) but as if the `System` only contained its available components.
"""
Expand Down
22 changes: 10 additions & 12 deletions test/test_component_selector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,17 @@ end
@test get_name(first(the_components)) == "Solitude"
@test collect(
get_components_rt(
get_available,
make_selector(gen_sundance),
test_sys;
scope_limiter = get_available,
test_sys,
),
) ==
Vector{Component}()
@test collect(get_available_components(make_selector(gen_sundance), test_sys)) ==
Vector{Component}()
@test get_component(test_gen_ent, test_sys; scope_limiter = x -> true) ==
@test get_component(x -> true, test_gen_ent, test_sys) ==
first(the_components)
@test isnothing(get_component(test_gen_ent, test_sys; scope_limiter = x -> false))
@test isnothing(get_component(x -> false, test_gen_ent, test_sys))
@test isnothing(get_available_component(make_selector(gen_sundance), test_sys))

@test only(get_groups(test_gen_ent, test_sys)) == test_gen_ent
Expand Down Expand Up @@ -130,7 +130,7 @@ end
@test all(the_components .== answer)
@test !(
gen_sundance in
collect(get_components_rt(test_sub_ent, test_sys; scope_limiter = get_available)))
collect(get_components_rt(get_available, test_sub_ent, test_sys)))
@test !(gen_sundance in collect(get_available_components(test_sub_ent, test_sys)))

# Grouping inherits from `DynamicallyGroupedComponentSelector` and is tested elsewhere
Expand Down Expand Up @@ -188,10 +188,10 @@ end

the_components = get_components_rt(ent, test_sys2)
@test all(sort_name!(the_components) .== ans)
@test Set(collect(get_components_rt(ent, test_sys2; scope_limiter = x -> true))) ==
@test Set(collect(get_components_rt(x -> true, ent, test_sys2))) ==
Set(the_components)
@test length(
collect(get_components_rt(ent, test_sys2; scope_limiter = x -> false)),
collect(get_components_rt(x -> false, ent, test_sys2)),
) ==
0
end
Expand Down Expand Up @@ -240,7 +240,7 @@ end
@test !(
gen_sundance in
collect(
get_components_rt(test_filter_ent, test_sys; scope_limiter = get_available),
get_components_rt(get_available, test_filter_ent, test_sys),
))
@test !(gen_sundance in collect(get_available_components(test_filter_ent, test_sys)))
end
Expand Down Expand Up @@ -282,16 +282,14 @@ end
))
@test length(
collect(
get_groups(each_selector, test_sys2;
scope_limiter = x -> length(get_name(x)) == 8),
get_groups(x -> length(get_name(x)) == 8, each_selector, test_sys2),
),
) == 2
@test Set(get_name.(get_groups(partition_selector, test_sys2))) ==
Set(["true", "false"])
@test length(
collect(
get_groups(partition_selector, test_sys2;
scope_limiter = x -> length(get_name(x)) == 8),
get_groups(x -> length(get_name(x)) == 8, partition_selector, test_sys2),
),
) == 1

Expand Down

0 comments on commit 3332ff4

Please sign in to comment.