System
The System
is the main container of components and the time series data references. PowerSystems.jl
uses a hybrid approach to data storage, where the component data and time series references are stored in volatile memory while the actual time series data is stored in an HDF5 file. This design loads into memory the portions of the data that are relevant at time of the query, and so avoids overwhelming the memory resources.

Accessing components stored in the system
PowerSystems.jl
implements a wide variety of methods to search for components to aid in the development of models. The code block shows an example of retrieving components through the type hierarchy with the get_components
function and exploiting the type hierarchy for modeling purposes.
The default implementation of the function get_components
takes the desired device type (concrete or abstract) and the system and it also accepts filter functions for a more refined search. The container is optimized for iteration over abstract or concrete component types as described by the Type Structure. Given the potential size of the return, PowerSystems.jl
returns Julia iterators in order to avoid unnecessary memory allocations.
thermal_gens = get_components(ThermalStandard, system)
ThermalStandard Counts: ThermalStandard: 76
It is also possible to execute get_components
with abstract types from the abstract tree. For instance, it is possible to retrieve all renewable generators
thermal_gens = get_components(RenewableGen, system)
RenewableGen Counts: RenewableDispatch: 30 RenewableFix: 31
The most common filtering requirement is by component name and for this case the method get_component
returns a single component taking the device type, system and name as arguments.
my_thermal_gen = get_component(ThermalStandard, system, "323_CC_1")
323_CC_1 (ThermalStandard): name: 323_CC_1 available: true status: true bus: COMTE (Bus) active_power: 3.55 reactive_power: 0.3741 rating: 3.853894134508627 active_power_limits: (min = 1.7, max = 3.55) reactive_power_limits: (min = -0.25, max = 1.5) ramp_limits: (up = 0.0414, down = 0.0414) operation_cost: ThreePartCost base_power: 100.0 time_limits: nothing prime_mover: PrimeMovers.CC = 4 fuel: ThermalFuels.NATURAL_GAS = 7 services: 0-element Vector{Service} time_at_status: 10000.0 dynamic_injector: nothing ext: Dict{String, Any}() time_series_container: InfrastructureSystems.TimeSeriesContainer: 0 InfrastructureSystems.SystemUnitsSettings: base_value: 100.0 unit_system: UnitSystem.SYSTEM_BASE = 0
Accessing data stored in a component
Using the "dot" access to get a parameter value from a component is actively discouraged, use "getter" functions instead
Using code autogeneration, PowerSystems.jl
implements accessor (or "getter") functions to enable the retrieval of parameters defined in the component struct fields. Julia syntax enables access to this data using the "dot" access (e.g. component.field
), however this is actively discouraged for two reasons:
- We make no guarantees on the stability of component structure definitions. We will maintain version stability on the accessor methods.
- Per-unit conversions are made in the return of data from the accessor functions. (see the per-unit section for more details)
For example, the my_thermal_gen.active_power_limits
parameter of a thermal generator should be accessed as follows:
get_active_power_limits(my_thermal_gen)
(min = 1.7, max = 3.55)
Per-unit conventions and data conversions
It is often useful to express power systems data in relative terms using per-unit conventions. PowerSystems.jl
supports the automatic conversion of data between three different unit systems:
- Natural Units: The naturally defined units of each parameter (typically MW).
- System Base: Parameter values are divided by the system
base_power
- Device Base: Parameter values are divided by the device
base_mva
To see the unit system setting of a System
:
get_units_base(system)
"SYSTEM_BASE"
To change the unit system setting of a System
:
set_units_base_system!(system, "DEVICE_BASE")
The units of the parameter values stored in each struct are defined in src/descriptors/power_system_structs.json
. Conversion between unit systems does not change the stored parameter values. Instead, unit system conversions are made when accessing parameters using the accessor functions (see above), thus making it imperative to utilize the accessor functions instead of the "dot" accessor methods to ensure the return of the correct values.
JSON Serialization
PowerSystems.jl
provides functionality to serialize an entire system to a JSON file and then deserialize it back to a system. The main benefit is that deserializing is significantly faster than reconstructing the system from raw data files.
The function that serializes the system to_json
requires the system and a file name
to_json(system, "system.json")
The serialization process stores 3 files
- System data file (
*.json
file) - Validation data file (
*.json
file) - Time Series data file (
*.h5
file)
To deserialize:
system2 = System("system.json")
PowerSystems generates UUIDs for the System and all components in order to have a way to uniquely identify objects. During deserialization it restores the same UUIDs. If you will modify the System or components after deserialization then it is recommended that you set this flag to generate new UUIDs.
system2 = System("system.json", assign_new_uuids = true)
Reducing REPL printing
By default PowerSystems.jl
outputs to the REPL all Logging values, this can be overwhelming in some cases. Use configure_logging
to create a logger with your preferences (console and/or file, levels, etc.). For more detail refer to Logging.
Example: Set log output to only error messages
using PowerSystems
using Logging
configure_logging(console_level = Logging.Error)
Note: log messages are not automatically flushed to files. Call flush(logger)
to make this happen.
Refer to this page for more logging configuration options. Note that it describes how to enable debug logging for some log messages but not others.
Viewing PowerSystems Data in JSON Format
PowerSystems data can be serialized and deserialized in JSON. This section shows how to explore the data outside of Julia using.
system = System("system.json")
It can be useful to view and filter the PowerSystems data in this format. There are many tools available to browse JSON data.
Here is an example GUI tool that is available online in a browser.
The command line utility jq offers even more features. The rest of this document provides example commands.
- View the entire file pretty-printed
jq . system.json
- View the PowerSystems component types
jq '.data.components | .[] | .__metadata__ | .type' system.json | sort | uniq
- View specific components
jq '.data.components | .[] | select(.__metadata__.type == "ThermalStandard")' system.json
- Get the count of a component type
# There is almost certainly a better way.
jq '.data.components | .[] | select(.__metadata__.type == "ThermalStandard")' system.json | grep -c ThermalStandard
- View specific component by name
jq '.data.components | .[] | select(.__metadata__.type == "ThermalStandard" and .name == "107_CC_1")' system.json
- Filter on a field value
jq '.data.components | .[] | select(.__metadata__.type == "ThermalStandard" and .active_power > 2.3)' system.json
- View the time series metadata for a component.
jq '.data.components | .[] | select(.__metadata__.type == "RenewableDispatch") | .time_series_container' system.json