Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PowerAnalytics Entity-Metric Redesign #19

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
a1f49b6
Implement ComponentEntity
GabrielKS Nov 14, 2023
a1c77c7
Implement ListEntitySet
GabrielKS Nov 20, 2023
b79af54
Implement SubtypeEntitySet
GabrielKS Nov 20, 2023
77cca74
Implement TopologyEntitySet
GabrielKS Nov 20, 2023
adb9570
Implement FilterEntitySet
GabrielKS Nov 21, 2023
6501843
Make test simulations more interesting
GabrielKS Nov 22, 2023
f7e9b51
Implement the very basics of Metrics
GabrielKS Nov 28, 2023
b035e85
Refactor test setup into its own file
GabrielKS Nov 28, 2023
8c315e4
Implement some input convenience functions
GabrielKS Nov 29, 2023
27f1936
Minor create_problem_results_dict bugfix
GabrielKS Nov 30, 2023
331e715
Add metrics wrapper functions and compute_all
GabrielKS Nov 30, 2023
4dee92e
Make entities only return available components
GabrielKS Dec 1, 2023
24944d6
More gracefully handle missing data (draft)
GabrielKS Dec 2, 2023
8c7d9b6
Add some Metric creation infrastructure and built-in Metrics
GabrielKS Dec 2, 2023
e60a9f2
Add metadata columns feature
GabrielKS Dec 22, 2023
c70bf85
Add aggregate_time function
GabrielKS Dec 23, 2023
2149c0d
Add hcat_timed and calc_discharge_cycles
GabrielKS Dec 27, 2023
0a657b0
Add SystemTimedMetrics
GabrielKS Dec 28, 2023
ad33606
Add some more built-in metrics
GabrielKS Dec 28, 2023
aa3efb8
Add ResultsTimelessMetrics
GabrielKS Dec 29, 2023
910103b
Add CustomTimedMetric (untested), more built-in metrics
GabrielKS Jan 4, 2024
25870b4
Implement compose_metrics
GabrielKS Jan 5, 2024
1fec2cb
Give metrics control over aggregation functions
GabrielKS Jan 5, 2024
cb3552c
Add more built-in metrics!
GabrielKS Jan 5, 2024
e86b03b
Add another way to call compute_all
GabrielKS Jan 6, 2024
1c7d2a2
Add aggregation metadata, etc. (see details)
GabrielKS Jan 17, 2024
0321ffb
Fix calc_capacity_factor
GabrielKS Jan 17, 2024
ba08dbd
Increment version number, add author
GabrielKS Jan 18, 2024
9f0773d
Merge branch 'main' into gks/entity-metric-redesign
GabrielKS Jan 18, 2024
e5080b7
Implement compute_set
GabrielKS Jan 23, 2024
da1444c
Resolve domain knowledge issues in builtin_metrics.jl
GabrielKS Jan 24, 2024
715a270
Add documentation for input, metrics
GabrielKS Jan 24, 2024
2d8f530
Merge branch 'main' into gks/entity-metric-redesign
GabrielKS Jan 24, 2024
87bea26
Fix metrics documentation formatting
GabrielKS Jan 31, 2024
bbec46d
Fix compute_all kwargs bug
GabrielKS Jan 31, 2024
71312b7
Merge branch 'main' into gks/entity-metric-redesign
GabrielKS Feb 19, 2024
bf99927
Replace get_populated_decision_problem_results
tengis-nrl Feb 24, 2024
8cb2ba9
run the formatter
tengis-nrl Feb 24, 2024
236607c
Add built-in entities for load, storage, fuel types
GabrielKS Feb 27, 2024
7d4627f
Rename `Entity` to `ComponentSelector`, handle the ensuing carnage
GabrielKS Feb 28, 2024
09ca5f4
Make use of caching in `read_component_result` for massive speedup
GabrielKS Mar 6, 2024
87ce18a
Accommodate `psy4` cost function refactor
GabrielKS Mar 7, 2024
cdfbec3
Merge branch 'gks/entity-metric-redesign' into Replace-get_populated_…
GabrielKS Mar 7, 2024
3aa8d80
Merge pull request #1 from GabrielKS/Replace-get_populated_decision_p…
GabrielKS Mar 7, 2024
d23f181
Rename Entity-related files to refer to ComponentSelector instead
GabrielKS Mar 18, 2024
c9398d1
Remove ComponentSelector files for move to IS and PSY
GabrielKS Mar 18, 2024
5aed377
make PA tests pass
tengis-nrl Mar 24, 2024
f52c8bd
run formatter
tengis-nrl Mar 25, 2024
1fc1674
Update storage naming for `psy4`
GabrielKS Jun 11, 2024
c6d9d14
Reevaluate `ComponentSelector`-related imports and exports
GabrielKS Jun 11, 2024
88b2d6e
Merge pull request #2 from GabrielKS/gks/td/component_selector_port
GabrielKS Jun 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "PowerAnalytics"
uuid = "56ce1300-00bc-47e4-ba8c-b166ccc19f51"
authors = ["cbarrows <[email protected]>"]
version = "0.6.1"
authors = ["Gabriel Konar-Steenberg <[email protected]>", "cbarrows <[email protected]>"]
version = "0.7.0"

[deps]
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Expand All @@ -11,13 +11,14 @@ InfrastructureSystems = "2cd47ed4-ca9b-11e9-27f2-ab636a7671f1"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
PowerSimulations = "e690365d-45e2-57bb-ac84-44ba829e73c4"
PowerSystems = "bcd98974-b02a-5e2f-9ee0-a103f5c450dd"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
TimeSeries = "9e3dc215-6440-5c97-bce1-76c03772f85e"
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"

[compat]
Dates = "1"
DataFrames = "1"
DataStructures = "0.18"
Dates = "1"
InfrastructureSystems = "1"
InteractiveUtils = "1"
PowerSimulations = "^0.27.1"
Expand Down
38 changes: 38 additions & 0 deletions src/PowerAnalytics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,46 @@ export get_service_data
export categorize_data
export no_datetime

export ComponentSelector, ComponentSelectorElement, ComponentSelectorSet
export select_components, get_name, get_subselectors
export Metric, TimedMetric, TimelessMetric, ComponentSelectorTimedMetric,
ComponentTimedMetric,
SystemTimedMetric, ResultsTimelessMetric, CustomTimedMetric
export DATETIME_COL, META_COL_KEY, SYSTEM_COL, RESULTS_COL, AGG_META_KEY
export is_col_meta, set_col_meta, set_col_meta!, time_df, time_vec, data_cols, data_df,
data_vec, data_mat, get_description, get_component_agg_fn, get_time_agg_fn,
with_component_agg_fn, with_time_agg_fn, metric_selector_to_string, get_agg_meta,
set_agg_meta!
export compute, compute_set, compute_all, hcat_timed, aggregate_time, compose_metrics
export create_problem_results_dict
export load_component_selector, storage_component_selector, generator_selectors_by_fuel
export calc_active_power, calc_production_cost, calc_startup_cost, calc_shutdown_cost,
calc_discharge_cycles, calc_system_slack_up, calc_load_forecast, calc_active_power_in,
calc_active_power_out, calc_stored_energy, calc_active_power_forecast, calc_curtailment,
calc_sum_objective_value, calc_sum_solve_time, calc_sum_bytes_alloc, calc_total_cost,
make_calc_is_slack_up, calc_is_slack_up, calc_system_load_forecast,
calc_net_load_forecast, calc_curtailment_frac, calc_load_from_storage,
calc_system_load_from_storage, calc_integration, calc_capacity_factor
export mean, weighted_mean, unweighted_sum

#I/O Imports
import Dates
import TimeSeries
import Statistics
import Statistics: mean
import DataFrames
import DataFrames: DataFrame, metadata, metadata!, colmetadata, colmetadata!
import YAML
import DataStructures: OrderedDict, SortedDict
import PowerSystems
import PowerSystems:
Component,
ComponentSelector, ComponentSelectorElement, ComponentSelectorSet,
select_components, get_name, get_subselectors,
get_component, get_components,
get_available,
NAME_DELIMETER

import InfrastructureSystems
import PowerSimulations
import InteractiveUtils
Expand All @@ -26,6 +59,11 @@ include("definitions.jl")
include("get_data.jl")
include("fuel_results.jl")

include("metrics.jl")
include("input.jl")
include("builtin_component_selectors.jl")
include("builtin_metrics.jl")

greet() = print("Hello World!")

end # module PowerAnalytics
62 changes: 62 additions & 0 deletions src/builtin_component_selectors.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"A ComponentSelector representing all the electric load in a System"
load_component_selector = select_components(PSY.ElectricLoad)

"A ComponentSelector representing all the storage in a System"
storage_component_selector = select_components(PSY.Storage)

FUEL_TYPES_DATA_FILE =
joinpath(dirname(dirname(pathof(PowerAnalytics))), "deps", "generator_mapping.yaml")

# Parse the strings in generator_mapping.yaml into types and enum items
function parse_fuel_category(category_spec::Dict)
# Use reflection to look up the type corresponding the generator type string (this isn't a security risk, is it?)
gen_type = getproperty(PowerSystems, Symbol(get(category_spec, "gentype", Component)))
(gen_type === Any) && (gen_type = Component)
@assert gen_type <: Component

pm = get(category_spec, "primemover", nothing)
isnothing(pm) || (pm = PowerSystems.parse_enum_mapping(PowerSystems.PrimeMovers, pm))

fc = get(category_spec, "fuel", nothing)
isnothing(fc) || (fc = PowerSystems.parse_enum_mapping(PowerSystems.ThermalFuels, fc))

return gen_type, pm, fc
end

function make_fuel_component_selector(category_spec::Dict)
parse_results = parse_fuel_category(category_spec)
(gen_type, prime_mover, fuel_category) = parse_results

function filter_closure(comp::Component)
comp_sig = Tuple{typeof(comp)}
if !isnothing(prime_mover)
hasmethod(PowerSystems.get_prime_mover_type, comp_sig) || return false
(PowerSystems.get_prime_mover_type(comp) == prime_mover) || return false
end
if !isnothing(fuel_category)
hasmethod(PowerSystems.get_fuel, comp_sig) || return false
(PowerSystems.get_fuel(comp) == fuel_category) || return false
end
return true
end

# Create a nice name that is guaranteed to never collide with fully-qualified component names
selector_name = join(ifelse.(isnothing.(parse_results), "", string.(parse_results)),
NAME_DELIMETER)

return select_components(filter_closure, gen_type, selector_name)
end

# Based on old PowerAnalytics' get_generator_mapping
function load_generator_fuel_mappings(filename = FUEL_TYPES_DATA_FILE)
in_data = open(YAML.load, filename)
mappings = OrderedDict{String, ComponentSelector}()
for top_level in in_data |> keys |> collect |> sort
subselectors = make_fuel_component_selector.(in_data[top_level])
mappings[top_level] = select_components(subselectors...; name = top_level)
end
return mappings
end

"A dictionary of nested `ComponentSelector`s representing all the generators in a System categorized by fuel type"
generator_selectors_by_fuel = load_generator_fuel_mappings()
Loading
Loading