Cases¶
The powerzoojax.case package converts benchmark networks into JAX-friendly numerical structures. CaseData is the object that crosses into JIT-compiled code; human-readable metadata stays in the registry layer.
For the architecture-level role of cases, see Architecture → Repo map.
Loading and discovery¶
from powerzoojax.case import load_case, list_cases, get_meta
case = load_case("5")
meta = get_meta("33bw")
for item in list_cases(grid_type="distribution"):
print(item.name, item.bus_count, item.phase)
Built-in IDs:
- transmission:
5,14,118,300,1354pegase,2383wp,29gb,552gb. - distribution:
33bw,118zh,123,141,533mt_hi,533mt_lo.
CaseData conventions¶
Important fields:
PTDF,nodes_units_map,nodes_loads_map.unit_p_min,unit_p_max.unit_cost_a,unit_cost_b,unit_cost_c.unit_ramp_up,unit_ramp_down,min_up_time,min_down_time,unit_startup_cost,unit_no_load_cost(UC-specific; populated for case118).line_cap,line_floor.- AC-only fields:
line_r,line_b,node_type,node_v_min,node_v_max. - three-phase load fields:
node_pd_a,node_qd_a, ...
CaseData intentionally has no string name field. JAX traces the numeric case object; names and descriptions live in CaseMeta.
API¶
powerzoojax.case.load_case(case_id='5', *, grid_type=None)
¶
Load a built-in case by ID.
Mirrors PowerZoo's load_case() API. If grid_type is given and
the loaded case's metadata does not match, a :class:UserWarning is
emitted (same behaviour as PowerZoo).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case_id
|
str
|
Case identifier (e.g. |
'5'
|
grid_type
|
str
|
Optional |
None
|
Returns:
| Type | Description |
|---|---|
CaseData
|
CaseData with all arrays populated. |
powerzoojax.case._registry.list_cases(*, grid_type=None, min_buses=None, max_buses=None, phase=None, voltage_level=None)
¶
Return metadata for all cases, optionally filtered.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grid_type
|
Optional[str]
|
|
None
|
min_buses
|
Optional[int]
|
Minimum bus count (inclusive). |
None
|
max_buses
|
Optional[int]
|
Maximum bus count (inclusive). |
None
|
phase
|
Optional[str]
|
|
None
|
voltage_level
|
Optional[str]
|
|
None
|
Returns:
| Type | Description |
|---|---|
List[CaseMeta]
|
List of :class: |
powerzoojax.case._registry.get_meta(case_id)
¶
Get metadata for a specific case.
powerzoojax.case._registry.CaseMeta(name, factory, grid_type='', bus_count=0, phase='1', voltage_level='', source='', description='')
dataclass
¶
Lightweight metadata for a case (no JAX dependency).
powerzoojax.case.case_data.CaseData
¶
Power system case data (pure JAX arrays).
This is the core data structure used in training. All data is stored as JAX arrays for GPU acceleration.
Note: This is a frozen dataclass - all fields are immutable.
Use case_data.replace(field=new_value) to create modified copies.
Note: name was removed because Python str cannot be traced by
JAX JIT. If you need a display name, store it alongside the CaseData.
Attributes:
| Name | Type | Description |
|---|---|---|
n_nodes |
int
|
Number of buses/nodes (problem dimension). |
n_lines |
int
|
Number of transmission lines. |
n_units |
int
|
Number of generators. |
n_loads |
int
|
Number of loads. |
node_ids |
Array
|
Node IDs (for reference); shape |
node_x |
Array
|
Node x coordinates for plotting; shape |
node_y |
Array
|
Node y coordinates for plotting; shape |
unit_ids |
Array
|
Unit IDs; shape |
unit_bus_ids |
Array
|
Bus ID where each unit is connected; shape |
unit_p_min |
Array
|
Minimum power output [MW]; shape |
unit_p_max |
Array
|
Maximum power output [MW]; shape |
unit_cost_a |
Array
|
Quadratic cost coefficient [$/MW²h]; shape |
unit_cost_b |
Array
|
Linear cost coefficient [$/MWh]; shape |
unit_cost_c |
Array
|
Constant cost coefficient [$/h]; shape |
line_ids |
Array
|
Line IDs; shape |
line_from |
Array
|
From bus ID; shape |
line_to |
Array
|
To bus ID; shape |
line_x |
Array
|
Line reactance [p.u.]; shape |
line_cap |
Array
|
Branch thermal rating [MVA], from MATPOWER |
line_floor |
Array
|
Line capacity lower bound [MW]; shape |
load_ids |
Array
|
Load IDs; shape |
load_bus_ids |
Array
|
Bus ID where each load is connected; shape |
load_d_max |
Array
|
Maximum demand [MW]; shape |
load_d_min |
Array
|
Minimum demand [MW]; shape |
PTDF |
Array
|
Power Transfer Distribution Factor; shape |
nodes_units_map |
Array
|
Node-to-unit mapping; shape |
nodes_loads_map |
Array
|
Node-to-load mapping; shape |
unit_node_idx |
Array
|
Internal node index for each unit (0-indexed); shape |
load_node_idx |
Array
|
Internal node index for each load; shape |
line_from_idx |
Array
|
Internal from-node index for lines; shape |
line_to_idx |
Array
|
Internal to-node index for lines; shape |
slack_bus_idx |
int
|
Slack bus internal index (default 0). |
gen_cost_coeffs
property
¶
Backward-compatible generator cost coefficients alias.
Older smoke scripts expect case.gen_cost_coeffs to expose the
per-generator quadratic cost triplets. The canonical storage remains
unit_cost_a / unit_cost_b / unit_cost_c.
powerzoojax.case.case_data.validate_case_data(case_data)
¶
Validate CaseData consistency.
Checks: - Dimensions match array shapes - All required arrays are present - PTDF shape matches (n_lines, n_nodes)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case_data
|
CaseData
|
CaseData to validate |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if valid |
Raises:
| Type | Description |
|---|---|
ValueError
|
If validation fails |
Matrix helpers¶
powerzoojax.case.case_matrices.build_case_matrices(node_ids, unit_bus_ids, load_bus_ids, line_from, line_to, line_x, slack_bus_id=None)
¶
Build all case matrices from raw data.
This is a convenience function that computes: - Internal node indices - PTDF matrix - Node-unit mapping - Node-load mapping - Adjacency matrix
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node_ids
|
Array
|
Node IDs (n_nodes,) |
required |
unit_bus_ids
|
Array
|
Unit bus IDs (n_units,) |
required |
load_bus_ids
|
Array
|
Load bus IDs (n_loads,) |
required |
line_from
|
Array
|
Line from-bus IDs (n_lines,) |
required |
line_to
|
Array
|
Line to-bus IDs (n_lines,) |
required |
line_x
|
Array
|
Line reactance (n_lines,) |
required |
slack_bus_id
|
float
|
Slack bus ID (default: first node) |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
Dict with computed matrices and indices |
powerzoojax.case.case_matrices.compute_ptdf(line_from_idx, line_to_idx, line_x, n_nodes, slack_idx=0)
¶
Compute Power Transfer Distribution Factor (PTDF) matrix.
PTDF relates nodal power injections to line power flows
P_line = PTDF @ P_injection
Uses DC power flow approximation (NumPy/CPU, LAPACK inversion). Called once at initialization — not in training loops.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
line_from_idx
|
From-node indices (n_lines,), JAX or NumPy array |
required | |
line_to_idx
|
To-node indices (n_lines,), JAX or NumPy array |
required | |
line_x
|
Line reactance values (n_lines,) |
required | |
n_nodes
|
int
|
Number of nodes |
required |
slack_idx
|
int
|
Slack bus index (default 0) |
0
|
Returns:
| Name | Type | Description |
|---|---|---|
PTDF |
JAX array (n_lines, n_nodes) |
Example
PTDF = compute_ptdf( ... line_from_idx=np.array([0, 0, 1, 2]), ... line_to_idx=np.array([1, 2, 2, 3]), ... line_x=np.array([0.1, 0.2, 0.15, 0.1]), ... n_nodes=4, ... ) line_flows = PTDF @ node_injections
powerzoojax.case.case_matrices.compute_adjacency_matrix(line_from_idx, line_to_idx, n_nodes)
¶
Compute adjacency matrix of the network graph.
A[i,j] = 1 if there is a line between node i and j. Matrix is symmetric (undirected graph).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
line_from_idx
|
Array
|
From-node indices (n_lines,) |
required |
line_to_idx
|
Array
|
To-node indices (n_lines,) |
required |
n_nodes
|
int
|
Number of nodes |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
Array
|
(n_nodes, n_nodes) adjacency matrix |
powerzoojax.case.case_matrices.compute_degree_matrix(adjacency)
¶
Compute degree matrix from adjacency matrix.
D[i,i] = sum of row i of adjacency matrix (node degree).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adjacency
|
Array
|
(n_nodes, n_nodes) adjacency matrix |
required |
Returns:
| Name | Type | Description |
|---|---|---|
D |
Array
|
(n_nodes, n_nodes) diagonal degree matrix |
powerzoojax.case.case_matrices.compute_laplacian_matrix(adjacency)
¶
Compute normalized Laplacian matrix.
L = I - D^(-1/2) @ A @ D^(-1/2)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adjacency
|
Array
|
(n_nodes, n_nodes) adjacency matrix |
required |
Returns:
| Name | Type | Description |
|---|---|---|
L |
Array
|
(n_nodes, n_nodes) normalized Laplacian |
Conversion and inspection¶
powerzoojax.case.case_adapter.case_to_jax(case, *, slack_bus_id=None)
¶
Convert a PowerZoo ClearCase instance to :class:CaseData.
This is Direction B — runtime conversion from a live PowerZoo object.
Handles all column naming variants (p_max/Pmax, Pd/Pd_A, etc.).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case
|
Any
|
A PowerZoo |
required |
slack_bus_id
|
Optional[float]
|
Override slack bus. |
None
|
Returns:
| Type | Description |
|---|---|
CaseData
|
CaseData ready for GPU training. |
powerzoojax.case.case_adapter.convert_case = case_to_jax
module-attribute
¶
powerzoojax.case.case_info.CaseInfo(case_data, warn=True, name=None)
¶
CPU-side utilities for CaseData inspection and printing.
Provides PowerZoo-compatible printing format and data inspection.
⚠️ WARNING: All methods transfer data from GPU to CPU. Use only for debugging, NOT in training loops.
Attributes:
| Name | Type | Description |
|---|---|---|
case_data |
The underlying CaseData |
|
name |
Case name |
Example
case = create_case5() info = CaseInfo(case) print(info) # Print all tables print(info.nodes) # Print nodes table only
Initialize CaseInfo wrapper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case_data
|
CaseData
|
CaseData to wrap |
required |
warn
|
bool
|
Whether to show CPU transfer warnings (default True) |
True
|
name
|
Optional[str]
|
Display name ( |
None
|
nodes
property
¶
Get nodes table as CaseDataFrame.
units
property
¶
Get units/generators table as CaseDataFrame.
lines
property
¶
Get lines/branches table as CaseDataFrame.
loads
property
¶
Get loads table as CaseDataFrame.
__repr__()
¶
PowerZoo-compatible full case representation.
summary()
¶
Get a brief summary without full tables.
get_ptdf_numpy()
¶
Get PTDF matrix as numpy array.
⚠️ Transfers from GPU to CPU.
get_adjacency_numpy()
¶
Compute and return adjacency matrix as numpy array.
⚠️ Runs on CPU.
powerzoojax.case.case_plotter.CasePlotter(case, warn=True)
¶
Plotter for power system case visualization.
Provides methods to visualize network topology and power flow results. All operations run on CPU.
⚠️ WARNING: Do not use in training loops.
Attributes:
| Name | Type | Description |
|---|---|---|
case |
The CaseData object |
|
G |
NetworkX graph representation |
|
pos |
Node positions for plotting |
Initialize plotter with a CaseData.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
case
|
CaseData
|
CaseData to visualize |
required |
warn
|
bool
|
Whether to show CPU warnings |
True
|
plot_topology(ax=None, figsize=(14, 10), layout='auto', node_size=500, node_color='#4A90D9', edge_color='#666666', edge_width=1.5, show_node_labels=True, title=None, highlight_generators=True, highlight_loads=True)
¶
Plot network topology.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ax
|
Optional[Axes]
|
Matplotlib axes (creates new figure if None) |
None
|
figsize
|
Tuple[int, int]
|
Figure size (width, height) |
(14, 10)
|
layout
|
str
|
Layout algorithm ('auto', 'case', 'spring', 'kamada_kawai', 'feeder') |
'auto'
|
node_size
|
int
|
Size of nodes |
500
|
node_color
|
str
|
Default color for buses |
'#4A90D9'
|
edge_color
|
str
|
Color of edges |
'#666666'
|
edge_width
|
float
|
Width of edges |
1.5
|
show_node_labels
|
bool
|
Whether to show node ID labels |
True
|
title
|
str
|
Plot title |
None
|
highlight_generators
|
bool
|
Show generator buses differently |
True
|
highlight_loads
|
bool
|
Scale node size by load |
True
|
Returns:
| Type | Description |
|---|---|
Tuple[Figure, Axes]
|
(figure, axes) tuple |
plot_line_flows(line_flows, ax=None, figsize=(14, 10), layout='auto', colormap='coolwarm', show_values=True, title=None)
¶
Plot line power flows on network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
line_flows
|
ndarray
|
Power flow on each line (n_lines,) [MW] |
required |
ax
|
Optional[Axes]
|
Matplotlib axes |
None
|
figsize
|
Tuple[int, int]
|
Figure size |
(14, 10)
|
layout
|
str
|
Layout algorithm |
'auto'
|
colormap
|
str
|
Colormap for flow values |
'coolwarm'
|
show_values
|
bool
|
Show flow values on edges |
True
|
title
|
str
|
Plot title |
None
|
Returns:
| Type | Description |
|---|---|
Tuple[Figure, Axes]
|
(figure, axes) tuple |
plot_ptdf_heatmap(ax=None, figsize=(12, 8), colormap='RdBu_r', title=None)
¶
Plot PTDF matrix as heatmap.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ax
|
Optional[Axes]
|
Matplotlib axes |
None
|
figsize
|
Tuple[int, int]
|
Figure size |
(12, 8)
|
colormap
|
str
|
Colormap |
'RdBu_r'
|
title
|
str
|
Plot title |
None
|
Returns:
| Type | Description |
|---|---|
Tuple[Figure, Axes]
|
(figure, axes) tuple |