Public API Reference
ComponentSelector
PowerAnalytics depends heavily on the ComponentSelector feature of PowerSystems.jl. ComponentSelector documentation can be found here. PowerAnalytics provides some built-in selectors, but much of the power of PowerAnalytics comes from the ability to operate on custom ComponentSelectors.
Input Utilities
PowerAnalytics.create_problem_results_dict — Function
create_problem_results_dict(
results_dir::AbstractString,
problem::String;
...
) -> DataStructures.SortedDict{_A, _B, Base.Order.ForwardOrdering} where {_A, _B}
create_problem_results_dict(
results_dir::AbstractString,
problem::String,
scenarios::Union{Nothing, Vector{<:AbstractString}};
populate_system,
kwargs...
) -> DataStructures.SortedDict{_A, _B, Base.Order.ForwardOrdering} where {_A, _B}
Accept a directory that contains several results subdirectories (that each contain results, problems, etc. sub-subdirectories) and construct a sorted dictionary from String to PowerSimulations.SimulationProblemResults where the keys are the subdirectory names and the values are loaded results datasets.
Arguments
results_dir::AbstractString: the directory where results subdirectories can be foundproblem::String: the name of the problem to load (e.g.,UC,ED)scenarios::Union{Vector{AbstractString}, Nothing} = nothing: a list of scenario subdirectories to load, ornothingto load all the subdirectoriespopulate_system::Bool = false: whether to automatically load and attach the system; errors iftrueand the system has not been saved with the results. This keyword argument isfalseby default for backwards compatibility, but most PowerAnalytics functionality requires results to have an attached system, so users should typically passpopulate_system = true.kwargs...: further keyword arguments to pass through toget_decision_problem_results
Examples
Suppose we have the directory data_root with subdirectories results1, results2, and results3, where each of these subdirectories contains problems/UC. Then:
# Load results for only `results1` and `results2`:
create_problem_results_dict(data_root, "UC", ["results1", "results2"]; populate_system = true)
# Load results for all three scenarios:
create_problem_results_dict(data_root, "UC"; populate_system = true)See also
create_problem_results_dict is a convenience function that calls public interface in PowerSimulations.jl. To read one results set, or several of them that are not all in the same parent directory, invoke that interface directly as needed:
# Load a single results set
PowerSimulations.get_decision_problem_results(
PowerSimulations.SimulationResults(path_to_individual_results),
problem_name; populate_system = true)Basic Metric Interface
The basic Metric interface consists of calling a Metric itself, for computing one Metric at a time, and the compute_all function for bulk computation. Combined with PowerAnalytics' built-in metrics, this is enough to execute many common computations. See Advanced Metrics Interface for the interface to create custom Metrics.
PowerAnalytics.Metric — Type
A PowerAnalytics Metric specifies how to compute a useful quantity, like active power or curtailment, from a set of results. Many but not all Metrics require a ComponentSelector to specify which available components of the system the quantity should be computed on, and many but not all Metrics return time series results. In addition to how to compute the output — which may be as simple as looking up a variable or parameter in the results but may involve actual computation — Metrics encapsulate default component-wise and time-wise aggregation behaviors. Metrics can be "called" like functions.
PowerAnalytics provides a library of pre-built Metrics, PowerAnalytics.Metrics; users may also build their own. In most cases of custom metric creation, it should suffice to instantiate one of the concrete Metric subtypes PowerAnalytics provides; in special cases, the user can create their own subtype that implements compute.
Examples
Given a PowerSimulations.SimulationProblemResults results:
using PowerAnalytics.Metrics
# Call the built-in `Metric` `calc_active_power` on a `ComponentSelector` to get a
# `DataFrame` of results, where the columns are the groups in the `ComponentSelector` and
# the rows are time:
calc_active_power(make_selector(RenewableDispatch), results)
# Call the built-in `Metric` `calc_system_slack_up`, which refers to the whole system so
# doesn't need a `ComponentSelector`:
calc_system_slack_up(results)PowerAnalytics.TimedMetric — Type
Metrics that return time series.
PowerAnalytics.TimelessMetric — Type
Metrics that do not return time series.
PowerAnalytics.compute_all — Function
compute_all(
results::InfrastructureSystems.Results,
metrics::Vector{<:TimelessMetric};
...
) -> Any
compute_all(
results::InfrastructureSystems.Results,
metrics::Vector{<:TimelessMetric},
selectors::Union{Nothing, ComponentSelector, Component, Vector};
...
) -> Any
compute_all(
results::InfrastructureSystems.Results,
metrics::Vector{<:TimelessMetric},
selectors::Union{Nothing, ComponentSelector, Component, Vector},
col_names::Union{Nothing, Vector{<:Union{Nothing, AbstractString}}};
kwargs...
) -> Any
Methods of compute_all for TimelessMetrics. For each (metric, selector, col_name) tuple in zip(metrics, selectors, col_names), call compute and collect the results in a DataFrame. All selectors must yield exactly one group.
Arguments
results::IS.Results: the results from which to fetch datametrics::Vector{<:TimelessMetric}: the metrics to computeselectors: either a scalar or vector ofNothing/Component/ComponentSelector: the selectors on which to compute the metrics, or nothing for system/results metrics; broadcast if scalarcol_names::Union{Nothing, Vector{<:Union{Nothing, AbstractString}}} = nothing: a vector of names for the columns of output data. Entries ofnothingdefault to the result ofmetric_selector_to_string;names = nothingis equivalent to an entire vector ofnothingkwargs...: pass through to eachcomputecall
Examples
Given a results with the proper data:
using PowerAnalytics.Metrics
compute_all(results,
[calc_sum_objective_value, calc_sum_solve_time],
[nothing, nothing],
["objective_value", "solve_time"]
) # returns an 1x2 DataFrame with columns `objective_value` and `solve_time`See also: compute_all tuple-based interface
PowerAnalytics.compute_all — Function
compute_all(
results::InfrastructureSystems.Results,
metrics::Vector{<:TimedMetric};
...
) -> Any
compute_all(
results::InfrastructureSystems.Results,
metrics::Vector{<:TimedMetric},
selectors::Union{Nothing, ComponentSelector, Component, Vector};
...
) -> Any
compute_all(
results::InfrastructureSystems.Results,
metrics::Vector{<:TimedMetric},
selectors::Union{Nothing, ComponentSelector, Component, Vector},
col_names::Union{Nothing, Vector{<:Union{Nothing, AbstractString}}};
kwargs...
) -> Any
Methods of compute_all for TimedMetrics. For each (metric, selector, col_name) tuple in zip(metrics, selectors, col_names), call compute and collect the results in a DataFrame with a single DateTime column. All selectors must yield exactly one group.
Arguments
results::IS.Results: the results from which to fetch datametrics::Vector{<:TimedMetric}: the metrics to computeselectors: either a scalar or vector ofNothing/Component/ComponentSelector: the selectors on which to compute the metrics, or nothing for system/results metrics; broadcast if scalarcol_names::Union{Nothing, Vector{<:Union{Nothing, AbstractString}}} = nothing: a vector of names for the columns of output data. Entries ofnothingdefault to the result ofmetric_selector_to_string;names = nothingis equivalent to an entire vector ofnothingkwargs...: pass through to eachcomputecall
Examples
Given a results with the proper data:
using PowerAnalytics.Metrics
compute_all(results,
[calc_active_power, calc_curtailment],
[make_selector(ThermalStandard; groupby = :all), make_selector(RenewableDispatch; groupby = :all)],
["thermal_power", "renewable_curtailment"]
) # returns an 8760x3 DataFrame with columns `DateTime`, `thermal_power`, and `renewable_curtailment`See also: compute_all tuple-based interface
PowerAnalytics.compute_all — Function
compute_all takes several metrics, single-group ComponentSelectors if relevant, and optionally column names and produces a single table with all the output for a given results set. It can be useful to quickly put together a summary statistics table.
Examples
See the methods.
PowerAnalytics.compute_all — Method
compute_all(
results::InfrastructureSystems.Results,
computations::Tuple{Union{TimedMetric, TimelessMetric}, Any, Any}...;
kwargs...
) -> Any
For convenience, a variant signature of compute_all where the metrics, selectors, and column names are specified as a list of tuples rather than three separate lists.
Arguments
results::IS.Results: the results from which to fetch datacomputations::(Tuple{<:T, Any, Any} where T <: Union{TimedMetric, TimelessMetric})...: a list of the computations to perform, where each element is a(metric, selector, col_name)wheremetricis the metric to compute,selectoris theComponentSelectoron which to compute the metric ornothingif not relevant, andcol_nameis the name for the output column of data or nothing to use the defaultkwargs...: pass through to eachcomputecall
Examples
Given a results with the proper data:
my_computations = [
(calc_active_power, make_selector(ThermalStandard; groupby = :all), "thermal_power"),
(calc_curtailment, make_selector(RenewableDispatch; groupby = :all), "renewable_curtailment")
]
compute_all(results, my_computations...)
# The above is equivalent to
compute_all(results,
[calc_active_power, calc_curtailment],
[make_selector(ThermalStandard; groupby = :all), make_selector(RenewableDispatch; groupby = :all)],
["thermal_power", "renewable_curtailment"]
)See also: compute_all non-tuple-based interface
Built-in Metrics
Metrics Submodule
Here is defined a "library" of built-in metrics to execute many common power systems post-processing calculations.
PowerAnalytics.Metrics — Module
PowerAnalytics built-in Metrics. Use names to list what is available.
Examples
using PowerAnalytics
names(PowerAnalytics.Metrics) # lists built-in Metrics
PowerAnalytics.Metrics.calc_active_power # by default, must prefix built-in Metrics with the module name
@isdefined calc_active_power # -> false
using PowerAnalytics.Metrics
@isdefined calc_active_power # -> true, can now refer to built-in Metrics without the prefixPowerAnalytics.Metrics.calc_active_power — Constant
Calculate the active power of the specified ComponentSelector
PowerAnalytics.Metrics.calc_active_power_forecast — Constant
Fetch the forecast active power of the specified ComponentSelector
PowerAnalytics.Metrics.calc_active_power_in — Constant
Calculate the active power input to the specified (storage) ComponentSelector
PowerAnalytics.Metrics.calc_active_power_out — Constant
Calculate the active power output of the specified (storage) ComponentSelector
PowerAnalytics.Metrics.calc_capacity_factor — Constant
Calculate the capacity factor (actual production/rated production) of the specified ComponentSelector
PowerAnalytics.Metrics.calc_curtailment — Constant
Calculate the ActivePowerForecast minus the ActivePower of the given ComponentSelector
PowerAnalytics.Metrics.calc_curtailment_frac — Constant
Calculate the curtailment as a fraction of the ActivePowerForecast of the given ComponentSelector
PowerAnalytics.Metrics.calc_discharge_cycles — Constant
Calculate the number of discharge cycles a storage device has gone through in the time period
PowerAnalytics.Metrics.calc_integration — Constant
Calculate the ActivePower of the given ComponentSelector over the sum of the SystemLoadForecast and the SystemLoadFromStorage
PowerAnalytics.Metrics.calc_is_slack_up — Constant
Calculate whether the given time period has system balance slack up of magnitude greater than 0.0001
PowerAnalytics.Metrics.calc_load_forecast — Constant
Fetch the forecast active load of the specified ComponentSelector
PowerAnalytics.Metrics.calc_load_from_storage — Constant
Calculate the ActivePowerIn minus the ActivePowerOut of the specified (storage) ComponentSelector
PowerAnalytics.Metrics.calc_net_load_forecast — Constant
SystemLoadForecast minus ActivePowerForecast of the given ComponentSelector
PowerAnalytics.Metrics.calc_production_cost — Constant
Calculate the production cost expression of the specified ComponentSelector
PowerAnalytics.Metrics.calc_shutdown_cost — Constant
Calculate the shutdown cost of the specified ComponentSelector
PowerAnalytics.Metrics.calc_startup_cost — Constant
Calculate the startup cost of the specified ComponentSelector
PowerAnalytics.Metrics.calc_stored_energy — Constant
Calculate the energy stored in the specified (storage) ComponentSelector
PowerAnalytics.Metrics.calc_sum_bytes_alloc — Constant
Sum the bytes allocated to the optimization problems
PowerAnalytics.Metrics.calc_sum_objective_value — Constant
Sum the objective values achieved in the optimization problems
PowerAnalytics.Metrics.calc_sum_solve_time — Constant
Sum the solve times taken by the optimization problems
PowerAnalytics.Metrics.calc_system_load_forecast — Constant
Fetch the forecast active load of all the ElectricLoad Components in the system
PowerAnalytics.Metrics.calc_system_load_from_storage — Constant
Fetch the LoadFromStorage of all storage in the system
PowerAnalytics.Metrics.calc_system_slack_up — Constant
Calculate the system balance slack up
PowerAnalytics.Metrics.calc_total_cost — Constant
Calculate the production cost of the specified ComponentSelector, which includes the startup and shutdown costs if they are defined
Built-in Selectors
Selector Utilities
PowerAnalytics.parse_generator_categories — Function
parse_generator_categories(
filename;
root_type
) -> Union{Nothing, Dict{String, ComponentSelector}}
Use parse_generator_mapping_file to parse a generator_mapping.yaml file into a dictionary of ComponentSelectors, excluding categories in the 'non_generators' list in metadata.
Arguments
filename: the path to thegenerator_mapping.yamlfileroot_type::Type{<:Component} = PSY.StaticInjection: theComponenttype assumed in cases where there is no more precise information
See also: parse_injector_categories if all injectors are desired
PowerAnalytics.parse_generator_mapping_file — Function
parse_generator_mapping_file(
filename;
root_type
) -> Tuple{Dict{String, ComponentSelector}, Any}
Parse a generator_mapping.yaml file into a dictionary of ComponentSelectors and a dictionary of metadata if present.
Arguments
filename: the path to thegenerator_mapping.yamlfileroot_type::Type{<:Component} = PSY.StaticInjection: theComponenttype assumed in cases where there is no more precise information
PowerAnalytics.parse_injector_categories — Function
parse_injector_categories(
filename;
root_type
) -> Dict{String, ComponentSelector}
Use parse_generator_mapping_file to parse a generator_mapping.yaml file into a dictionary of all ComponentSelectors.
Arguments
filename: the path to thegenerator_mapping.yamlfileroot_type::Type{<:Component} = PSY.StaticInjection: theComponenttype assumed in cases where there is no more precise information
See also: parse_generator_categories if only generators are desired
Selectors Submodule
PowerAnalytics.Selectors — Module
PowerAnalytics built-in ComponentSelectors. Use names to list what is available.
Examples
using PowerAnalytics
names(PowerAnalytics.Selectors) # lists built-in selectors
PowerAnalytics.Selectors.all_loads # by default, must prefix built-in selectors with the module name
@isdefined all_loads # -> false
using PowerAnalytics.Selectors
@isdefined all_loads # -> true, can now refer to built-in selectors without the prefixPowerAnalytics.Selectors.all_loads — Constant
A ComponentSelector representing all the electric load in a System
PowerAnalytics.Selectors.all_storage — Constant
A ComponentSelector representing all the storage in a System
PowerAnalytics.Selectors.categorized_generators — Constant
A single ComponentSelector representing the generators in a System (no storage or load) grouped by the categories in generator_mapping.yaml
PowerAnalytics.Selectors.categorized_injectors — Constant
A single ComponentSelector representing the static injectors in a System grouped by the categories in generator_mapping.yaml
PowerAnalytics.Selectors.generator_categories — Constant
A dictionary of ComponentSelectors, each of which corresponds to one of the categories in generator_mapping.yaml, only considering the components and categories that represent generators (no storage or load)
PowerAnalytics.Selectors.injector_categories — Constant
A dictionary of ComponentSelectors, each of which corresponds to one of the static injector categories in generator_mapping.yaml
Post-Metric Utilities
Post-processing on the specially formatted DataFrames that Metrics produce.
PowerAnalytics.aggregate_time — Function
aggregate_time(
df::AbstractDataFrame;
groupby_fn,
groupby_col,
agg_fn
) -> Any
Given a DataFrame like that produced by a TimedMetric or the timed version of compute_all, group by a function of the time axis, apply a reduction, and report the resulting aggregation indexed by the first timestamp in each group.
Arguments
df::DataFrames.AbstractDataFrame: the DataFrame to operate upongroupby_fn = nothing: a function that can be passed aDateTime; two rows will be in the same group if their timestamps produce the same result undergroupby_fn. Note thatgroupby_fn = monthputs January 2024 and January 2025 into the same group whereasgroupby_fn = (x -> (year(x), month(x)))does not. Passingnothinggroups all rows in theDataFrametogether.groupby_col::Union{Nothing, AbstractString, Symbol} = nothing: specify a column name to report the result ofgroupby_fnin the output DataFrame, ornothingto notagg_fn = nothing: by default, the aggregation function (sum/mean/etc.) is specified by theMetric, which is read from the metadata of each column. If this metadata isn't found, one can specify a default aggregation function likesumhere; if nothing, an error will be thrown.
Examples
using Dates
using PowerAnalytics.Metrics
# Setup: create a `DataFrame` to work with
my_computations = [
(calc_active_power, make_selector(ThermalStandard; groupby = :all), "thermal_power"),
(calc_curtailment, make_selector(RenewableDispatch; groupby = :all), "renewable_curtailment")
]
my_8760 = compute_all(results, my_computations...)
# Now (given a certain simulation setup) `my_8760` is an 8760x3 DataFrame
# with columns `DateTime`, `thermal_power`, and `renewable_curtailment`
# Aggregate across the entire time period; result is 1x3:
aggregate_time(my_8760)
# Aggregate all January results together, all February results together, etc.; result is 12x3:
aggregate_time(my_8760; groupby_fn = Dates.month)
# Same as above but create a column 'month_n' with 1 for January, 2 for February, etc.; result is 12x4:
aggregate_time(my_8760; groupby_fn = Dates.month, groupby_col = "month_n")
# Custom `groupby_fn`: put all weekday timestamps together and all weekend timestamps together; result is 2x4:
aggregate_time(my_8760; groupby_fn = x -> (Dates.dayofweek(x) in [6, 7]) ? "weekend" : "weekday", groupby_col = "day_type")PowerAnalytics.hcat_timed_dfs — Function
hcat_timed_dfs(vals::DataFrame...) -> Any
If the time axes match across all the DataFrames, horizontally concatenate them and remove the duplicate time axes. If not, throw an error.
Post-Metric Accessors
Extract and manipulate information from the specially formatted DataFrames that Metrics produce.
PowerAnalytics.get_agg_meta — Method
get_agg_meta(df, colname) -> Any
Get the column's aggregation metadata; return nothing if there is none.
PowerAnalytics.get_agg_meta — Method
get_agg_meta(df) -> Any
Get the single data column's aggregation metadata; error on multiple data columns.
PowerAnalytics.get_data_cols — Method
get_data_cols(df::AbstractDataFrame) -> Vector{String}
Select the names of the data columns of the DataFrame, i.e., those that are not DateTime and not metadata.
PowerAnalytics.get_data_df — Method
get_data_df(df::AbstractDataFrame) -> Any
Select the data columns of the DataFrame as a DataFrame without copying.
PowerAnalytics.get_data_mat — Method
get_data_mat(df::AbstractDataFrame) -> Any
Select the data columns of the DataFrame as a Matrix with copying.
PowerAnalytics.get_data_vec — Method
get_data_vec(df::AbstractDataFrame) -> Any
Select the data column of the DataFrame as a vector without copying, errors if more than one.
PowerAnalytics.get_time_df — Method
get_time_df(df::AbstractDataFrame) -> Any
Select the DateTime column of the DataFrame as a one-column DataFrame without copying.
PowerAnalytics.get_time_vec — Method
get_time_vec(df::AbstractDataFrame) -> Any
Select the DateTime column of the DataFrame as a Vector without copying.
PowerAnalytics.is_col_meta — Method
is_col_meta(df, colname) -> Any
Check whether a column is metadata.
PowerAnalytics.set_agg_meta! — Method
set_agg_meta!(
df,
colname,
val
) -> Union{DataFrame, DataFrames.DataFrameColumns, DataFrameRow, DataFrames.DataFrameRows, SubDataFrame}
Set the column's aggregation metadata.
PowerAnalytics.set_agg_meta! — Method
set_agg_meta!(df, val) -> Union{DataFrame, SubDataFrame}
Set the single data column's aggregation metadata; error on multiple data columns.
PowerAnalytics.set_col_meta! — Function
set_col_meta!(
df,
colname
) -> Union{DataFrame, DataFrames.DataFrameColumns, DataFrameRow, DataFrames.DataFrameRows, SubDataFrame}
set_col_meta!(
df,
colname,
val
) -> Union{DataFrame, DataFrames.DataFrameColumns, DataFrameRow, DataFrames.DataFrameRows, SubDataFrame}
Mark a column as metadata.
Advanced Metrics Interface
PowerAnalytics.ComponentSelectorTimedMetric — Type
TimedMetrics defined in terms of a ComponentSelector.
PowerAnalytics.ComponentTimedMetric — Type
ComponentTimedMetric(name::String, eval_fn::Function, component_agg_fn::Function, time_agg_fn::Function, component_meta_agg_fn::Function, time_meta_agg_fn::Function, eval_zero::Union{Nothing, Function})
ComponentTimedMetric(; name, eval_fn, component_agg_fn, time_agg_fn, component_meta_agg_fn, time_meta_agg_fn, eval_zero)A ComponentSelectorTimedMetric implemented by evaluating a function on each Component.
Arguments
name::String: the name of theMetriceval_fn: a function with signature(::IS.Results, ::Component; start_time::Union{Nothing, DateTime}, len::Union{Int, Nothing})that returns aDataFramerepresenting the results for thatComponentcomponent_agg_fn: optional, a function to aggregate results betweenComponents/ComponentSelectors, defaults tosumtime_agg_fn: optional, a function to aggregate results across time, defaults tosumcomponent_meta_agg_fn: optional, a function to aggregate metadata across components, defaults tosumtime_meta_agg_fn: optional, a function to aggregate metadata across time, defaults tosumeval_zero: optional and rarely filled in, specifies what to do in the case where there are no components to contribute to a particular group; defaults tonothing, in which case the data is filled in from the identity element ofcomponent_agg_fn
PowerAnalytics.CustomTimedMetric — Type
CustomTimedMetric(name::String, eval_fn::Function, time_agg_fn::Function, time_meta_agg_fn::Function)
CustomTimedMetric(; name, eval_fn, time_agg_fn, time_meta_agg_fn)A ComponentSelectorTimedMetric implemented without drilling down to the base Components, just calls the eval_fn directly on the ComponentSelector.
Arguments
name::String: the name of theMetriceval_fn: a function with signature(::IS.Results, ::Union{ComponentSelector, Component}; start_time::Union{Nothing, DateTime}, len::Union{Int, Nothing})that returns aDataFramerepresenting the results for thatComponenttime_agg_fn: optional, a function to aggregate results across time, defaults tosumtime_meta_agg_fn: optional, a function to aggregate metadata across time, defaults tosum
PowerAnalytics.ResultsTimelessMetric — Type
ResultsTimelessMetric(name::String, eval_fn::Function)
ResultsTimelessMetric(; name, eval_fn)A TimelessMetric with a single value per IS.Results instance.
Arguments
name::String: the name of theMetriceval_fn: a function with signature(::IS.Results,)that returns aDataFramerepresenting the results
PowerAnalytics.SystemTimedMetric — Type
SystemTimedMetric(name::String, eval_fn::Function, time_agg_fn::Function, time_meta_agg_fn::Function)
SystemTimedMetric(; name, eval_fn, time_agg_fn, time_meta_agg_fn)A TimedMetric that calculates an output for an entire System embedded in a set of results.
Arguments
name::String: the name of theMetriceval_fn: a function with signature(::IS.Results; start_time::Union{Nothing, DateTime}, len::Union{Int, Nothing})that returns aDataFramerepresenting the resultstime_agg_fn: optional, a function to aggregate results across time, defaults tosumtime_meta_agg_fn: optional, a function to aggregate metadata across time, defaults tosum
PowerAnalytics.rebuild_metric — Function
rebuild_metric(metric::Metric; kwargs...) -> Any
Returns a new Metric identical to the input metric except with the changes to its fields specified in the keyword arguments. See the Metric constructors (e.g., ComponentTimedMetric) for available fields to alter.
Examples
Make a variant of calc_active_power that averages across components rather than summing:
using PowerAnalytics.Metrics
const calc_active_power_mean = rebuild_metric(calc_active_power; component_agg_fn = mean)
# Now calc_active_power_mean works as a standalone, callable metric:
calc_active_power_mean(make_selector(RenewableDispatch), results)PowerAnalytics.compose_metrics — Function
Given a list of metrics and a function that applies to their results to produce one result, create a new metric that computes the sub-metrics and applies the function to produce its own result.
Arguments
name::String: the name of the newMetricreduce_fn: a function that takes one value from each of the inputMetrics and returns a single value that will be the result of thisMetric. "Value" means a vector (not aDataFrame) in the case ofTimedMetrics and a scalar forTimelessMetrics.metrics: the inputMetrics. It is currently not possible to combineTimedMetrics withTimelessMetrics, though it is possible to combineComponentSelectorTimedMetrics withSystemTimedMetrics.
Examples
This is the implementation of the built-in metric calc_load_from_storage, which computes the preexisting built-in metrics calc_active_power_in and calc_active_power_out and combines them by subtraction:
const calc_load_from_storage = compose_metrics(
"LoadFromStorage",
(-),
calc_active_power_in, calc_active_power_out)PowerAnalytics.compute — Function
The compute function is the most important part of the Metric interface. Calling a metric as if it were a function is syntactic sugar for calling compute:
# this:
my_metric1(selector, results; kwargs)
# is the same as this:
compute(my_metric1, results, selector; kwargs)
# and this:
my_metric2(results; kwargs)
# is the same as this:
compute(my_metric2; kwargs)Exact keyword arguments and formatting of the resulting DataFrame are documented for each of the existing methods, below. Custom Metric subtypes must implement this function.
PowerAnalytics.compute — Method
compute(
metric::ComponentTimedMetric,
results::InfrastructureSystems.Results,
selector::ComponentSelector;
kwargs...
) -> Any
compute method for ComponentTimedMetric. Compute the given metric on the groups of the given ComponentSelector within the given set of results, returning a DataFrame with a DateTime column and a data column for each group. Exclude components marked as not available.
Arguments
metric::ComponentTimedMetric: the metric to computeresults::IS.Results: the results from which to fetch dataselector::ComponentSelector: theComponentSelectoron whose subselectors to compute the metricstart_time::Union{Nothing, DateTime} = nothing: the time at which the resulting time series should beginlen::Union{Int, Nothing} = nothing: the number of steps in the resulting time series
See also: compute unified function documentation
PowerAnalytics.compute — Method
compute(
metric::ComponentTimedMetric,
results::InfrastructureSystems.Results,
comp::Component;
kwargs...
) -> Any
Like compute(metric::ComponentTimedMetric, results::IS.Results, selector::ComponentSelector; kwargs...) but for Components rather than ComponentSelectors, used in the implementation of that method. Compute the given metric on the given component within the given set of results, returning a DataFrame with a DateTime column and a data column labeled with the component's name.
Arguments
metric::ComponentTimedMetric: the metric to computeresults::IS.Results: the results from which to fetch datacomp::Component: the component on which to compute the metricstart_time::Union{Nothing, DateTime} = nothing: the time at which the resulting time series should beginlen::Union{Int, Nothing} = nothing: the number of steps in the resulting time series
See also: compute unified function documentation
PowerAnalytics.compute — Method
compute(
metric::CustomTimedMetric,
results::InfrastructureSystems.Results,
comp::Union{ComponentSelector, Component};
kwargs...
) -> Any
compute method for CustomTimedMetric. Compute the given metric on the given component within the given set of results, returning a DataFrame with a DateTime column and a data column labeled with the component's name. Exclude components marked as not available.
Arguments
metric::CustomTimedMetric: the metric to computeresults::IS.Results: the results from which to fetch datacomp::Component: the component on which to compute the metricstart_time::Union{Nothing, DateTime} = nothing: the time at which the resulting time series should beginlen::Union{Int, Nothing} = nothing: the number of steps in the resulting time series
See also: compute unified function documentation
PowerAnalytics.compute — Method
compute(
metric::ResultsTimelessMetric,
results::InfrastructureSystems.Results,
selector::Nothing
) -> DataFrame
Convenience method that ignores the selector argument and redirects to compute(metric::ResultsTimelessMetric, results::IS.Results; kwargs...) for the purposes of compute_all.
See also: compute unified function documentation
PowerAnalytics.compute — Method
compute(
metric::ResultsTimelessMetric,
results::InfrastructureSystems.Results
) -> DataFrame
compute method for ResultsTimelessMetric. Compute the given metric on the given set of results, returning a DataFrame with a single cell. Exclude components marked as not available.
Arguments
metric::ResultsTimelessMetric: the metric to computeresults::IS.Results: the results from which to fetch data
See also: compute unified function documentation
PowerAnalytics.compute — Method
compute(
metric::SystemTimedMetric,
results::InfrastructureSystems.Results,
selector::Nothing;
kwargs...
) -> Any
Convenience method that ignores the selector argument and redirects to compute(metric::SystemTimedMetric, results::IS.Results; kwargs...) for the purposes of compute_all.
See also: compute unified function documentation
PowerAnalytics.compute — Method
compute(
metric::SystemTimedMetric,
results::InfrastructureSystems.Results;
kwargs...
) -> Any
compute method for SystemTimedMetric. Compute the given metric on the System associated with the given set of results, returning a DataFrame with a DateTime column and a data column.
Arguments
metric::SystemTimedMetric: the metric to computeresults::IS.Results: the results from which to fetch datastart_time::Union{Nothing, DateTime} = nothing: the time at which the resulting time series should beginlen::Union{Int, Nothing} = nothing: the number of steps in the resulting time series
See also: compute unified function documentation
Miscellaneous
PowerAnalytics.unweighted_sum — Function
unweighted_sum(x) -> Any
A version of sum that ignores a second argument, for use where aggregation metadata is at play.
PowerAnalytics.weighted_mean — Function
weighted_mean(vals, weights) -> Any
Compute the mean of values weighted by the corresponding entries of weights. Arguments may be vectors or vectors of vectors. A weight of 0 cancels out a value of NaN.
PowerAnalytics.metric_selector_to_string — Function
metric_selector_to_string(
m::Metric,
e::Union{ComponentSelector, Component}
) -> Any
Canonical way to represent a (Metric, ComponentSelector) or (Metric, Component) pair as a string.
PowerAnalytics.AGG_META_KEY — Constant
Column metadata key whose value, if any, is additional information to be passed to aggregation functions. Values of nothing are equivalent to absence of the entry.
PowerAnalytics.DATETIME_COL — Constant
Name of the column that represents the time axis in computed DataFrames. Currently equal to "DateTime".
PowerAnalytics.META_COL_KEY — Constant
Column metadata key whose value signifies whether the column is metadata. Metadata columns are excluded from get_data_cols and similar and can be used to represent things like a time aggregation.
PowerAnalytics.RESULTS_COL — Constant
Name of a column that represents whole-of-Results data. Currently equal to "Results".
PowerAnalytics.SYSTEM_COL — Constant
Name of a column that represents whole-of-System data. Currently equal to "System".
Old PowerAnalytics
This interface predates the 1.0 version and will eventually be deprecated.
PowerAnalytics.categorize_data — Method
categorize_data(
data::Dict{Symbol, DataFrame},
aggregation::Dict;
curtailment,
slacks
) -> Dict{String, DataFrame}
Re-categorizes data according to an aggregation dictionary
- makes no guarantee of complete data collection *
Example
aggregation = PA.make_fuel_dictionary(results_uc.system)
categorize_data(gen_uc.data, aggregation)PowerAnalytics.make_fuel_dictionary — Method
make_fuel_dictionary(
sys::System,
mapping::Dict{NamedTuple, String};
filter_func,
kwargs...
) -> Dict{Any, Any}
generators = make_fuel_dictionary(system::PSY.System, mapping::Dict{NamedTuple, String})This function makes a dictionary of fuel type and the generators associated.
Arguments
sys::PSY.System: the system that is used to create the resultsresults::IS.Results: results
Keyword Arguments
categories::Dict{String, NamedTuple}: if stacking by a different category is desired
Examples
results = solve_op_model!(OpModel)
generators = make_fuel_dictionary(sys)