Utilities & Analysis
The esapp.utils package provides analysis modules, visualization tools, and general helpers.
Contingency Builder
Fluent API for defining transient stability contingencies.
- class ContingencyBuilder(name, runtime=10.0)[source]
Fluent builder for Transient Stability (TS) contingencies.
Constructs a timeline of events to be simulated using method chaining.
- Parameters:
Example
>>> builder = ContingencyBuilder("GenTrip", runtime=5.0) >>> builder.at(1.0).fault_bus("101").at(1.1).clear_fault("101")
- add_event(obj_type, who, action)[source]
Add a generic event at the current time cursor.
- Parameters:
- Returns:
ContingencyBuilder– Self for method chaining.
- at(t)[source]
Set the current time cursor for subsequent events.
- Parameters:
t (
float) – Time in seconds (must be non-negative).- Returns:
ContingencyBuilder– Self for method chaining.- Raises:
ValueError – If time is negative.
GIC Analysis
Geomagnetically Induced Current (GIC) analysis tools.
- class GIC(pw=None)[source]
Bases:
objectGIC analysis application for PowerWorld integration.
Provides methods for GIC calculations, sensitivity analysis, and model generation using PowerWorld case data. All data access is delegated to the parent PowerWorld instance.
This class is accessed via
PowerWorld.gic.GIC Options
GIC analysis requires certain options to be enabled for full functionality. The most important is
pf_include = Truewhich must be set before retrieving GIC data like transformer coil resistances (GICCoilR fields). Methods likemodel()andgmatrix()automatically enable this option. Useconfigure()to set multiple options at once.Example
>>> pw = PowerWorld("case.pwb") >>> pw.gic.configure() # Enable GIC with default options >>> pw.gic.storm(100, 90) # 100 V/km, 90 degrees >>> pw.gic.model() >>> G = pw.gic.gmatrix()
- configure(pf_include=True, ts_include=False, calc_mode=GICCalcMode.SNAPSHOT)[source]
Configure GIC options with sensible defaults.
This is the recommended way to initialize GIC analysis. It ensures all necessary options are set for typical GIC workflows.
- Parameters:
pf_include (
bool, defaultTrue) – Include GIC effects in power flow calculations. Required for accessing GIC-related data like transformer coil resistances.ts_include (
bool, defaultFalse) – Include GIC effects in transient stability simulations.calc_mode (
str, default'SnapShot') – GIC calculation mode. Options: - ‘SnapShot’: Single time point calculation - ‘TimeVarying’: Time series from uniform field - ‘NonUniformTimeVarying’: Time series with spatial variation - ‘SpatiallyUniformTimeVarying’: Spatially uniform time series
Example
>>> pw.gic.configure() # Use defaults (pf_include=True) >>> pw.gic.configure(ts_include=True) # Enable for transient stability >>> pw.gic.configure(calc_mode='TimeVarying') # For time series analysis
- gmatrix(sparse=True)[source]
Retrieve the G-matrix directly from PowerWorld.
This is the recommended approach when working with PowerWorld cases, as it uses the simulator’s internal GIC calculation engine and ensures consistency with PowerWorld’s results.
This method automatically enables GIC in power flow (pf_include=True) before retrieving the matrix, ensuring GIC data is available.
- Parameters:
sparse (
bool, defaultTrue) – If True, returns scipy sparse CSR matrix. If False, returns dense numpy array.- Returns:
scipy.sparse.csr_matrixorndarray– The GIC conductance matrix (G-matrix) from PowerWorld.
- model()[source]
Generate GIC model from current PowerWorld case data.
Extracts substation, bus, line, transformer, and generator data from PowerWorld and computes all GIC matrices (incidence, G-matrix, H-matrix, per-unit linear model). Results are stored as properties on this instance.
Transformer data is sourced from the
GICXFormerobject type, which provides the authoritative per-winding configuration, substation assignments, and auto-transformer status used by PowerWorld’s GIC calculation engine.This method automatically enables GIC in power flow (pf_include=True) before retrieving data.
- Returns:
GIC– Self, with computed model matrices accessible via properties (G,H,A,zeta,Px,eff).
See also
gmatrix_from_powerworldGet just the G-matrix from PowerWorld.
configureSet GIC options manually.
- settings(value=None)[source]
View or modify GIC calculation settings.
- Parameters:
value (
DataFrame, optional) – If provided, updates settings. If None, returns current settings.- Returns:
DataFrameorNone– Current settings if value is None.
- storm(maxfield, direction, solvepf=True)[source]
Configure synthetic storm with uniform electric field.
- timevary_csv(fpath)[source]
Upload time-varying series voltage inputs from CSV file.
- Parameters:
fpath (
str) –Path to CSV file with format:
Time In Seconds, 1, 2, 3 Branch '1' '2' '1', 0.1, 0.11, 0.14 Branch '1' '2' '2', 0.1, 0.11, 0.14
- property A
General incidence matrix of the GIC network.
The first N columns are substation neutral buses, and the remaining M columns are bus nodes. The first 2X rows are high and low windings, and the remaining rows are non-winding branches.
- Returns:
scipy.sparse matrix– Shape (branches, N+M).
- property G
Conductance Laplacian of the GIC network.
The first N nodes are substation neutral buses, and the remaining M nodes are bus nodes. Computed as: G = A.T @ Gd @ A + Gs
- Returns:
scipy.sparse matrix– Shape (N+M, N+M).
- property H
Linear GIC function matrix (H-matrix).
Maps induced line voltages to signed effective transformer GICs. Values are in actual current (Amps), not per-unit.
- Returns:
scipy.sparse matrix– Shape (nxfmr, nbranches).
- property Px
Bus assignment permutation matrix.
Maps each transformer to the bus used to model losses (default: from-bus).
- Returns:
scipy.sparse matrix– Shape (nbus, nxfmr).
- bus_no_sub
Substation auto-insert option for buses without substations (str).
- calc_max_direction
Automatically calculate maximum E-field direction.
- calc_mode
'SnapShot','TimeVarying','NonUniformTimeVarying', or'SpatiallyUniformTimeVarying'.- Type:
Calculation mode
- property eff
Effective GIC operator matrix.
Calculates effective transformer GICs when applied to the vector of branch GICs. Includes non-winding branches; trim dimensions for faster computation when only line voltages are used.
- Returns:
scipy.sparse matrix– Shape (nxfmr, nbranches).
- efield_angle
Electric field storm direction in degrees (float).
- efield_mag
Electric field magnitude in V/distance (float).
- hotspot_include
Include hotspot in the electric field calculation.
- min_kv
Minimum nominal kV to include GIC effects (float).
- pf_include
Include GIC effects in power flow calculations.
- segment_length_km
Maximum line segment length in km for non-uniform fields (float).
- skip_equiv_lines
Skip DC voltage calculation on equivalent lines.
- skip_low_r_lines
Skip DC voltage calculation on low per-unit-distance R lines.
- ts_include
Include GIC effects in transient stability simulations.
- update_line_volts
Auto-update line DC voltages during GIC solution.
- property zeta
Per-unit linear GIC model.
Returns the constant-current load (prior to absolute value) in per-unit for each transformer. This is the fastest option for modeling GICs in power flow studies.
- Returns:
scipy.sparse matrix– Per-unit GIC model matrix.
Network Topology
Network graph analysis including incidence matrices, Laplacians, and path calculations.
- class Network(pw=None)[source]
Bases:
objectNetwork matrix construction and analysis.
Builds sparse network matrices (incidence, Laplacian) and computes branch electrical parameters. AC branches and HVDC transmission lines are always included when present in the case.
This class is accessed via
PowerWorld.networkand delegates all data access to its parent PowerWorld instance.Notes
Matrix dimensions follow PowerWorld bus ordering. Use busmap() to translate between bus numbers and matrix indices.
- busmap()[source]
Create mapping from bus numbers to matrix indices.
- Returns:
pd.Series– Series indexed by BusNum with positional values.
- delay(min_delay=10e-4)[source]
Compute effective propagation delay for network branches.
- Parameters:
min_delay (
float, default10e-4) – Minimum delay value to prevent numerical overflow when computing 1/delay^2 in the Laplacian.- Returns:
ndarray– Effective propagation parameter beta for each branch.
Notes
Branch inductance: omega * L_ij = Im(Z^br_ij)
Effective capacitance: C_ij = (C_i + C_j) / 2
Propagation delay: omega * tau_ij = Im(sqrt(Z_ij * Y_ij)) = beta_ij
- gamma()[source]
Compute propagation constants for each branch.
- Returns:
pd.Series– Complex propagation constant gamma = sqrt(Z * Y).
- incidence(remake=True)[source]
Construct the sparse arc-incidence matrix.
Each row represents a branch with +1 at the to-bus and -1 at the from-bus. HVDC lines are appended after AC branches when present.
- Parameters:
remake (
bool, defaultTrue) – If True, recomputes even if cached.- Returns:
scipy.sparse.csc_matrix– Sparse incidence matrix (branches x buses).
- laplacian(weights, longer_xfmr_lens=True, len_thresh=0.01)[source]
Construct weighted graph Laplacian: L = A.T @ W @ A.
- Parameters:
weights (
BranchTypeorndarray) – Weighting scheme or custom weight vector.longer_xfmr_lens (
bool, defaultTrue) – Use impedance-based pseudo-lengths for transformers.len_thresh (
float, default0.01) – Threshold (km) below which branches are treated as transformers.
- Returns:
scipy.sparse.csc_matrix– Sparse weighted Laplacian matrix (buses x buses).
- lengths(longer_xfmr_lens=False, length_thresh_km=0.01)[source]
Get branch lengths in kilometers.
- Parameters:
- Returns:
pd.Series– Branch lengths in kilometers.
Bus Classification
Bus type classification engine for analyzing power flow Jacobian structure and voltage control.
- class BusCat(pw=None)[source]
Bases:
objectParsed bus type classifications from a solved power flow case.
Fetches the
BusCatfield from PowerWorld, parses each bus into its type, control mode, regulation role, and limit status, then provides index-based access for selecting bus subsets.Typical usage after solving power flow:
>>> pw = PowerWorld("case.pwb") >>> pw.pflow() >>> bc = pw.buscat.refresh() >>> pv = bc.pv_idx() >>> v_set = bc.v_setpoints() >>> q_buses = bc.has_q_eqn_idx()
The internal DataFrame is available via the
dfproperty and contains one row per bus with columns:VSet,LimLow,LimHigh,Type,Ctrl,Role,Lim,SVC,Eff,Reg.- df
Parsed classification data. Raises
RuntimeErrorif accessed beforerefresh()is called.- Type:
DataFrame
- refresh()[source]
Fetch BusCat from PowerWorld and rebuild classifications.
Must be called after each power flow solve, since bus types can change when generators hit reactive limits.
- Returns:
BusCat– Self, for method chaining.
- v_setpoints()[source]
Voltage setpoints for buses with a V equation.
Returns values in the same order as
has_v_eqn_idx().- Returns:
numpy.ndarray– Per-unit voltage setpoints.
- property df
Parsed bus classification DataFrame.
- Raises:
RuntimeError – If
refresh()has not been called yet.
- parse_buscat(cat)[source]
Parse a BusCat string into a bus classification dict.
Extracts the base type (Slack/PV/PQ), control modifiers, regulation role, limit status, and effective type from the descriptive string PowerWorld returns in the BusCat field.
- Parameters:
cat (
str) – Raw BusCat string from PowerWorld, e.g."PQ (Remotely Regulated at Var Limit)".- Returns:
dict– Keys:Type (str) – Base bus type name (
"SLACK","PV", or"PQ").Ctrl (str) – Control flags joined by
"+", e.g."REMOTE+DROOP"or"NONE".Role (str) – Regulation role name, or
""if the bus is not part of a regulation group.Lim (bool) – True if the bus is at a reactive power limit.
SVC (bool) – True if the bus has SVC or continuous shunt control.
Eff (str) – Effective type after limit enforcement (a PV bus at its limit becomes PQ).
Reg (bool) – True if the bus is actively regulating voltage (PV/Slack and not limited).
Dynamics
Transient stability simulation utilities for field-watching and result processing.
- class TSWatch[source]
Manages TS result field registration and environment preparation.
Example
>>> tsw = TSWatch() >>> tsw.watch(Gen, [TS.Gen.P, TS.Gen.W]) >>> fields = tsw.prepare(pw)
- prepare(pw)[source]
Configure the ESA environment for simulation and build retrieval fields.
- Parameters:
pw (
PowerWorld) – An initialized PowerWorld instance.- Returns:
List[str]– List of retrieval field strings for TSGetResults.
- watch(gtype, fields)[source]
Register fields to record during simulation for a specific object type.
- property fields
Currently registered watch fields.
- get_ts_results(esa, ctg, fields)[source]
Retrieve results for a single contingency using TSGetResults.
- Parameters:
esa (
SAW) – The SAW (SimAuto Wrapper) instance.ctg (
str) – Contingency name.fields (
List[str]) – List of fields/plots to retrieve.
- Returns:
Tuple[Optional[DataFrame],Optional[DataFrame]]– Tuple of (Metadata DataFrame, Data DataFrame), or (None, None).
- process_ts_results(meta, df, ctg_name)[source]
Clean and format raw transient stability simulation results.
- Parameters:
meta (
DataFrame) – Metadata DataFrame from TSGetResults.df (
DataFrame) – Time-series data DataFrame from TSGetResults.ctg_name (
str) – Name of the contingency (added as a column to metadata).
- Returns:
Tuple[DataFrame,DataFrame]– (Processed metadata, Processed time-series data).
B3D File Format
Binary 3D electric field data I/O.
Binary 3D (B3D) file format handler for electric field data.
The B3D format stores time-varying electric field data (Ex, Ey) at geographic locations. It is used by PowerWorld for GIC electric field input. This module supports version 4 with variable location points and variable time points.
- class B3D(fname=None)[source]
Handler for the B3D (Binary 3D) electric field file format.
Supports reading, writing, and constructing B3D files containing time-varying electric field vectors at geographic locations.
- Parameters:
fname (
str, optional) – Path to a B3D file to load on initialization.
- lat, lon
1D arrays of geographic coordinates (float64).
- Type:
- ex, ey
2D arrays of electric field components, shape (nt, n), dtype float32.
- Type:
- classmethod from_mesh(long, lat, ex, ey, times=None, comment='GWB Electric Field Data')[source]
Construct a B3D from mesh-grid style electric field data.
Currently supports static (single time step) fields only.
- Parameters:
long (
ndarray) – Array of longitudes, shape (n,).lat (
ndarray) – Array of latitudes, shape (m,).ex (
ndarray) – X-component electric field, shape (n, m).ey (
ndarray) – Y-component electric field, shape (n, m).times (
ndarray, optional) – Time points. Currently unused.comment (
str, default"GWB Electric Field Data") – Metadata comment string.
- Returns:
B3D– Initialized B3D object.
- write_b3d_file(fname)[source]
Write the B3D data to a binary file.
- Parameters:
fname (
str) – Output file path.- Raises:
ValueError – If data arrays have inconsistent shapes or incorrect dtypes.
General Helpers
Power system utilities and general-purpose helpers.
This module provides: - Function decorators for debugging and profiling
- timing(func)[source]
Decorator that prints the execution time of a function.
- Parameters:
func (
callable) – The function to wrap.- Returns:
callable– Wrapped function that prints timing information.
Examples
>>> @timing ... def slow_function(): ... time.sleep(1) ... >>> slow_function() 'slow_function' took: 1.0012 sec