API Reference

Transmission Grid Synthesis

High-Level Function

powergrid_synth.synthesize(*, mode, reference_case=None, reference_net=None, reference_file=None, level_specs=None, connection_specs=None, seed=None, keep_lcc=True, entropy_model=0, bus_type_ratio=None, ref_sys_id=1, loading_level='H', refine_topology=False, base_kv_map=None, output_dir='output', output_name='synthetic_grid', export_formats=('json',))[source]

Run the full CLC synthesis pipeline and export the result.

Parameters:
  • mode ("reference" or "synthetic") –

    Selects the operation mode.

    • "reference" — extract topology parameters from an existing pandapower network (Mode I).

    • "synthetic" — generate topology from user-provided level / connection specs (Mode II).

  • reference_case (str, optional) – Name of a built-in network. Supports both pandapower case names (e.g. "case118") and pypowsybl IEEE names (e.g. "ieee14", "ieee118"). Ignored if reference_net or reference_file is given.

  • reference_net (pandapowerNet or pypowsybl.network.Network, optional) – A pre-loaded network object (pandapower or pypowsybl). Takes precedence over reference_case and reference_file.

  • reference_file (str, optional) – Path to a grid file in any pypowsybl-supported format (CGMES, XIIDM, MATPOWER, IEEE-CDF, PSS/E, UCTE, etc.). Takes precedence over reference_case.

  • level_specs (list of dict, optional) – Voltage-level specifications for Mode II. Each dict must have keys "n" (int), "avg_k" (float), "diam" (int), and "dist_type" ("dgln" | "dpl" | "poisson"). Optionally "max_k" (int).

  • connection_specs (dict, optional) – Transformer connection specs for Mode II. Maps (level_i, level_j) tuples to dicts with "type" ("k-stars" | "simple") and parameters "c", "gamma".

  • seed (int, optional) – Random seed for reproducibility.

  • keep_lcc (bool) – If True (default), keep only the largest connected component after topology generation.

  • entropy_model (int) – Bus-type entropy model — 0 (standard) or 1 (weighted).

  • bus_type_ratio (list of float, optional) – Target [Gen%, Load%, Conn%] ratios. If None, default ratios based on network size are used.

  • ref_sys_id (int) – Reference system for statistical tables (0–3).

  • loading_level (str) – Load level — "D" (deterministic), "L" (light), "M" (medium), "H" (heavy, default).

  • refine_topology (bool) – If True, the transmission allocator may add/remove edges to improve DCPF convergence.

  • base_kv_map (dict, optional) – Custom {level_index: kV} mapping. If None and mode="reference", the mapping is extracted from the reference grid.

  • output_dir (str) – Directory for exported files (created if needed).

  • output_name (str) – Base filename (without extension) for exported files.

  • export_formats (sequence of str) – One or more format names to export. Supported: "json", "excel", "sqlite", "pickle", "xiidm", "cgmes", "matpower", "psse".

Returns:

The fully parameterised synthetic grid (a PowerGridGraph).

Return type:

nx.Graph

Raises:

ValueError – If mode is not "reference" or "synthetic", or if required arguments for the chosen mode are missing.

Topology Generation

class powergrid_synth.InputConfigurator(seed=None)[source]

Bases: object

Generate detailed input sequences for PowerGridGenerator from high-level parameters.

This is “operation mode II”, where the user specifies only the number of nodes, average degree, diameter, and distribution type for each voltage level, rather than providing explicit degree sequences. The configurator uses DegreeDistributionOptimizer to fit distribution parameters and then samples degree sequences.

See Section 6 of Aksoy et al. (2018) for the synthetic input generation guidelines.

Parameters:

seed (int or None, optional) – Random seed for reproducibility. Default is None.

create_params(levels, inter_connections)[source]

Generate the full parameter set for PowerGridGenerator.generate_grid().

Parameters:
  • levels (list of dict) –

    One dict per voltage level with keys:

    • 'n' (int): number of nodes.

    • 'avg_k' (float): target average degree.

    • 'diam' (int): target diameter.

    • 'dist_type' (str): 'dgln', 'dpl', or 'poisson'.

    • 'max_k' (int, optional): maximum degree (default: min(n - 1, 50)). For 'dpl' the paper suggests \(d_{\max} \approx 1.517\,n^{1/4}\); for 'dgln' \(\bar{d} \approx 2.425 \pm 0.185\) is consistent across subgraphs (Section 6.1 of Aksoy et al., 2018).

  • inter_connections (dict) –

    Mapping (i, j) -> config for transformer connections. Config is either:

    • {'type': 'k-stars', 'c': 0.174, 'gamma': 4.15}

    • {'type': 'simple', 'p_i_j': float, 'p_j_i': float}

Returns:

Keys 'degrees_by_level', 'diameters_by_level', and 'transformer_degrees', ready to be unpacked into PowerGridGenerator.generate_grid().

Return type:

dict

class powergrid_synth.PowerGridGenerator(seed=None)[source]

Bases: object

Generative model for an entire power grid graph on k voltage levels.

Implements Algorithm 4 (CLCStars) from Aksoy et al. (2018). Phase 1 generates each same-voltage subgraph via the CLC model, and Phase 2 inserts transformer edges via the random-star model.

Parameters:

seed (int or None, optional) – Random seed for reproducibility. Default is None.

generate_grid(degrees_by_level, diameters_by_level, transformer_degrees, keep_lcc=False)[source]

Generate a multi-level power grid graph (CLCStars, Algorithm 4).

Runs Phase 1 (CLC for each voltage level) and Phase 2 (random-star transformer edges for each pair of levels), then combines results.

Parameters:
  • degrees_by_level (list of list of int) – Desired degree sequences \(\mathbf{d}^{X_1},\dots,\mathbf{d}^{X_k}\), one per voltage level.

  • diameters_by_level (list of int) – Desired diameters \(\delta^{X_1},\dots,\delta^{X_k}\), one per voltage level.

  • transformer_degrees (dict) – Mapping (i, j) -> (t_i_j, t_j_i) where t_i_j is the transformer degree list for level-i nodes toward level j, and t_j_i is the reverse.

  • keep_lcc (bool, optional) – If True, return only the largest connected component with contiguous node IDs. Default is False.

Returns:

The generated grid graph with voltage_level node attributes and type ('line' or 'transformer') edge attributes.

Return type:

PowerGridGraph

Electrical Assignment

class powergrid_synth.BusTypeAllocator(graph, entropy_model=0, bus_type_ratio=None)[source]

Bases: object

Assigns bus types (Generator, Load, Connection) to a raw power grid topology using an Artificial Immune System (AIS) optimization algorithm.

The method, from Elyas and Wang (2016), exploits the observed non-trivial correlations between bus types and topology metrics (node degree, clustering coefficient) in realistic grids. A bus type entropy measure quantifies these correlations, and a target entropy \(W^*\) is derived from a scaling property fitted to real-world systems. The AIS then searches for an assignment whose entropy matches \(W^*\).

The pipeline is:

  1. Determine target bus type ratios \((r_G, r_L, r_C)\) from network size.

  2. Estimate \(W^*\) via Monte Carlo sampling of random assignments and the scaling relation \(W^* = \mu + \sigma \cdot d(N)\).

  3. Run AIS optimization (clonal selection, hypermutation, receptor editing) to find an assignment \(\mathbb{T}\) such that \(|W(\mathbb{T}) - W^*| < \epsilon\).

Two entropy definitions are supported:

  • Model 0 (\(W_0\)): standard entropy of bus/link type ratios. \(\mu\) is stable across network sizes.

  • Model 1 (\(W_1\)): generalized entropy weighted by \(N\) and \(M\). \(\mu\) grows with network size, giving better discrimination in large grids.

Parameters:
  • graph (nx.Graph) – NetworkX graph representing the grid topology (nodes and edges only; no bus type attributes required yet).

  • entropy_model (int) – Selects the entropy definition: 0 for \(W_0\), 1 for \(W_1\).

  • bus_type_ratio (list of float or None) – Optional target ratios [Gen, Load, Conn]. Values are normalized to sum to 1. If None, default ratios are chosen based on N.

References

TYPE_CONN = 3
TYPE_GEN = 1
TYPE_LOAD = 2
allocate(max_iter=100, population_size=20)[source]

Run the AIS optimization to find a bus type assignment.

Implements the Clonal Selection Principle:

  1. Monte Carlo estimation of \(W^*\) and convergence threshold \(\epsilon\) (see _estimate_w_star()).

  2. Initialize a population of K random assignments.

  3. Iterate until max_iter or best_error < epsilon:

    1. Evaluate fitness \(|W^* - W(\mathbb{T})|\) for each individual.

    2. Clonal selection — top-ranked individuals produce more clones: \(N_c = \text{round}(\beta \cdot s / r)\) where r is the rank.

    3. Hypermutation — clones are mutated with intensity proportional to their parent’s rank (worse → more mutations).

    4. Receptor editing — inject 10% fresh random solutions to maintain diversity and avoid local optima.

    5. Selection — combine elite, mutated clones, and fresh solutions; keep the top K.

  4. Return the best assignment found.

Parameters:
  • max_iter (int, optional) – Maximum number of AIS iterations (default 100).

  • population_size (int, optional) – Number of individuals surviving each generation (default 20).

Returns:

Mapping from node ID to bus type label ('Gen', 'Load', or 'Conn').

Return type:

dict[int, str]

plot_entropy_pdf(figsize=(10, 6))[source]

Plot the empirical PDF of entropy samples from the Monte Carlo estimation, with a fitted normal distribution overlay.

Must be called after allocate() or _estimate_w_star() so that self.w_samples is populated.

Parameters:

figsize (tuple of int, optional) – Figure size (width, height) in inches.

class powergrid_synth.CapacityAllocator(graph, ref_sys_id=1)[source]

Bases: object

Assigns generation capacities (PgMax) to generator buses in the grid.

Implements the three-stage methodology from Elyas et al. (2017):

  1. Total generation: Compute the aggregate generation capacity from a scaling law fitted to realistic grids: log Pg_tot(N) = -0.21 * log^2(N) + 2.06 * log(N) + 0.66.

  2. Individual capacities: Sample N_g individual capacities from an exponential distribution (with ~1% super-large outliers to capture the observed heavy tail).

  3. Correlated assignment: Assign capacities to generator buses using a 14x14 empirical 2D probability table (Tab_2D_Pgmax) that encodes the joint distribution of normalized capacity and normalized nodal degree. This preserves the observed Pearson correlation rho(P_bar, k_bar) in [0.25, 0.5] between capacity and degree.

Reference systems with pre-computed Tab_2D_Pgmax tables are available for NYISO-2935 (id=1), WECC-16944 (id=2), and a third system (id=3). A heuristic diagonal-bias table (id=0) is provided as a fallback.

Parameters:
  • graph (nx.Graph) – NetworkX graph with 'bus_type' node attributes already set (by BusTypeAllocator).

  • ref_sys_id (int) – Reference system for statistical tables (0=heuristic, 1=NYISO-2935, 2=WECC-16944, 3=additional reference).

References

allocate(tab_2d=None)[source]

Run the full generation-capacity allocation pipeline.

Executes the three-stage methodology from Elyas et al. (2017):

  1. Compute total generation capacity from the scaling law: Pg_tot = 10^(-0.21 * log10(N)^2 + 2.06 * log10(N) + 0.66).

  2. Sample individual capacities, normalize them and the generator nodal degrees by their respective maxima so that both lie in [0, 1]: P_bar = P / max(P), k_bar = k / max(k).

  3. Assign normalized capacities to generator buses via 2D binning using Tab_2D_Pgmax.

  4. Denormalize: Pg_max = P_bar * max(P).

Parameters:

tab_2d (np.ndarray or None, optional) – Custom 14x14 probability matrix. If None, the default table for the selected ref_sys_id is used.

Returns:

Mapping from generator node ID to its assigned capacity Pg_max (MW).

Return type:

dict[int, float]

class powergrid_synth.LoadAllocator(graph, ref_sys_id=1)[source]

Bases: object

Assigns active power loads (PL) to load buses in the grid.

Implements the load-setting methodology from Elyas et al. (2017), which mirrors the generation-capacity approach in CapacityAllocator:

  1. Total load: Compute an aggregate load target, either from a deterministic scaling formula or as a fraction (light / medium / heavy) of the total installed generation capacity.

  2. Individual loads: Sample N_l individual loads from an exponential distribution (with ~1% super-large outliers).

  3. Correlated assignment: Assign loads to load buses using a 14x14 empirical 2D probability table (Tab_2D_load) that encodes the joint distribution of normalized load demand and normalized nodal degree.

Reference systems with pre-computed Tab_2D_load tables are available for NYISO-2935 (id=1), WECC-16944 (id=2), and a third system (id=3). A heuristic diagonal-bias table (id=0) is provided as a fallback.

Parameters:
  • graph (nx.Graph) – NetworkX graph with 'bus_type' and (for non-deterministic loading levels) 'pg_max' node attributes already set.

  • ref_sys_id (int) – Reference system for statistical tables (0=heuristic, 1=NYISO-2935, 2=WECC-16944, 3=additional reference).

References

allocate(loading_level='H')[source]

Run the full load-allocation pipeline.

Executes the three-stage methodology (analogous to CapacityAllocator.allocate()):

  1. Compute total system load from loading_level strategy.

  2. Sample individual loads, normalize them and the load-bus nodal degrees by their respective maxima: P_bar = P / max(P), k_bar = k / max(k).

  3. Assign normalized loads to load buses via 2D binning using Tab_2D_load.

  4. Denormalize: PL = P_bar * max(P).

Parameters:

loading_level (str, optional) –

Loading strategy (default 'H'):

  • 'D' — deterministic scaling formula.

  • 'L' — light (30–40% of generation capacity).

  • 'M' — medium (50–60% of generation capacity).

  • 'H' — heavy (70–80% of generation capacity).

Returns:

Mapping from load node ID to its assigned active power load (MW).

Return type:

dict[int, float]

allocate_reactive(active_loads, pf_min=0.85, pf_max=0.97)[source]

Derive reactive power loads from active loads using power factors.

For each load bus, a power factor is sampled uniformly from [pf_min, pf_max] (lagging) and the reactive load is computed as ql = pl * tan(arccos(pf)).

Theory reference: https://www.phasetophase.nl/book/book_2_9.html#_9.5.2

Parameters:
  • active_loads (dict[int, float]) – Mapping from load node ID to active power load (MW), as returned by allocate().

  • pf_min (float, optional) – Minimum power factor (default 0.85).

  • pf_max (float, optional) – Maximum power factor (default 0.97).

Returns:

Mapping from load node ID to reactive power load (Mvar).

Return type:

dict[int, float]

class powergrid_synth.GenerationDispatcher(graph, ref_sys_id=1)[source]

Bases: object

Assign active-power dispatch to each generator bus.

The algorithm follows Sadeghian et al. (2018) (Section III):

  1. Uncommitted units (10–20 %): \(\alpha = 0\), selected via targets drawn from Uniform[0, 0.6].

  2. Partially committed units (40–50 %): selected via exponential distribution on capacity; dispatch factors assigned through a 2-D bin-matching table Tab_2D_Pg (\(14 \times 10\)).

  3. Fully committed units (remainder): \(\alpha = 1\).

  4. Balancing loop: iteratively adjusts dispatch to match total load within 1 % tolerance.

Parameters:
  • graph (networkx.Graph) – Power grid graph. Generator nodes must have 'bus_type' == 'Gen' and 'pg_max' (MW) attributes. Load nodes must have 'pl' (MW).

  • ref_sys_id (int, optional) – Reference system for statistical tables (1 = NYISO-2935, 2 = WECC-16994, 3 = additional reference). Default is 1.

alpha_mod

Loading-level flag from the reference system. When 0 all alphas are Uniform[0, 1]; otherwise 0.5 % receive negative dispatch (e.g., pumped-storage hydro).

Type:

int

mu_committed

Exponential-distribution parameter for committed-unit capacities.

Type:

float

tab_2d_pg

2-D empirical PMF table (14 capacity bins × 10 alpha bins).

Type:

numpy.ndarray

dispatch()[source]

Run the full generation dispatch pipeline.

Implements the algorithm of Sadeghian et al. (2018):

  1. Collect generator buses and normalise capacities by \(P^{\max}_{g_{\max}}\).

  2. Partition generators into uncommitted (\(\alpha = 0\)), partially committed (\(0 < \alpha < 1\)), and fully committed (\(\alpha = 1\)).

  3. Assign dispatch factors to partially committed units via the 2-D bin-matching table Tab_2D_Pg.

  4. Iteratively balance total generation against total load (1 % tolerance, up to 50 iterations) by scaling committed \(\alpha\) values and toggling uncommitted / full-load units on or off.

  5. Convert normalised dispatch back to MW: \(P_{g_i} = \alpha_i \cdot \bar{P}_{g_i}^{\max} \cdot P^{\max}_{g_{\max}}\).

Returns:

Mapping of generator bus ID to dispatched active power (MW).

Return type:

dict

class powergrid_synth.TransmissionLineAllocator(graph, ref_sys_id=1)[source]

Bases: object

Allocate impedance and capacity limits to transmission lines.

The algorithm follows Sadeghian et al. (2018) and the SynGrid MATLAB toolbox (sg_line.m, sg_flow_lim.m):

  1. Impedance generation — magnitudes \(Z\) from LogNormal(\(\mu\), \(\sigma\)), angles \(\varphi\) from a Lévy stable distribution \(S(\alpha_s, \beta_s, \gamma_s, \delta_s)\). Then \(X = Z \sin\varphi\), \(R = Z \cos\varphi\).

  2. DCPF-based swapping — sort impedances ascending and flows descending, then randomly swap ~20–30 % of assignments to introduce variance while preserving the negative correlation between impedance and flow.

  3. (Optional) Topology refinement — iteratively add low-impedance lines between max angle-difference bus pairs and remove weak high-\(X\) lines until the angle spread is below a size-dependent threshold.

  4. Capacity assignment — gauge ratios \(\beta_l = F_l / F_l^{\max}\) from Exponential(\(\mu_\beta\)) with overload injection; assigned via 2-D table Tab_2D_FlBeta. Capacity limits: \(F_l^{\max} = F_l / \beta_l\).

Parameters:
  • graph (networkx.Graph) – Power grid graph with nodal generation/load attributes.

  • ref_sys_id (int, optional) – Reference system (1 = NYISO-2935, 2 = WECC-16994). Default 1.

stab_params

Lévy stable parameters \([\alpha_s, \beta_s, \gamma_s, \delta_s]\).

Type:

list of float

tab_fl_beta

2-D empirical PMF table for flow–beta assignment.

Type:

numpy.ndarray

mu_beta

Mean of the exponential distribution for \(\beta\).

Type:

float

overload_b

Fraction of lines assigned overload (\(\beta > 1\)).

Type:

float

allocate(refine_topology=False)[source]

Run the full transmission-line allocation pipeline.

Executes the seven-step procedure:

  1. Draw impedance magnitudes \(Z \sim \text{LogNormal}(\mu, \sigma)\), clipped to [0.001, 0.5] p.u.

  2. Generate angles \(\varphi\) (Lévy stable), compute \(X = Z\sin\varphi\), \(R = Z\cos\varphi\).

  3. Iterative DCPF swapping: sort \(Z\) ascending / flows descending, randomly swap ~20–30 % of assignments.

  4. (Optional) Topology refinement via _refine_topology().

  5. Final DCPF to obtain converged flows.

  6. Generate and assign gauge ratios (\(\beta\)) via _generate_beta() and _assign_betas().

  7. Set capacity limits: \(F_l^{\max} = F_l / \beta_l\) with a minimum-capacity fallback (5 + 100 · rand MW when \(\le 2\)).

Parameters:

refine_topology (bool, optional) – If True, run topology refinement after step 3. Default is False.

Returns:

Mapping (u, v) edge tuple to capacity limit (MW).

Return type:

dict


Distribution Grid Synthesis

High-Level Function

powergrid_synth.synthesize_distribution(*, mode, reference_case=None, reference_net=None, reference_file=None, params=None, n_feeders=1, n_nodes=20, total_load_mw=0.5, total_gen_mw=0.0, v_nom_kv=10.0, assign_cable_types=True, assign_cable_lengths=True, seed=None, output_dir=None, output_name='synthetic_feeder', export_formats=('json',))[source]

Run the full Schweitzer distribution synthesis pipeline.

Parameters:
  • mode ("reference" or "default") –

    Selects the operation mode.

    • "reference" — fit synthesis parameters from an existing distribution network (pandapower, pypowsybl, or file), then generate synthetic feeders with the fitted parameters.

    • "default" — use default Table III parameters (or a user-supplied DistributionSynthParams).

  • reference_case (str, optional) – Short name of a built-in distribution network. Currently supported: "cigre_lv", "cigre_mv", or any pandapower factory function name. Ignored when reference_net or reference_file is given.

  • reference_net (pandapowerNet or pypowsybl.network.Network, optional) – A pre-loaded network object. Takes precedence over reference_case and reference_file.

  • reference_file (str, optional) – Path to a grid file in any pypowsybl-supported format.

  • params (DistributionSynthParams, optional) – Custom parameters for mode="default". If None, the built-in defaults from Schweitzer Table III are used.

  • n_feeders (int) – Number of synthetic feeders to generate (default 1).

  • n_nodes (int) – Number of nodes per feeder (default 20).

  • total_load_mw (float) – Total load in MW per feeder (default 0.5).

  • total_gen_mw (float) – Total generation in MW per feeder (default 0.0).

  • v_nom_kv (float) – Nominal voltage in kV (default 10.0).

  • assign_cable_types (bool) – Run Step 4 — cable type assignment (default True).

  • assign_cable_lengths (bool) – Run Step 5 — cable length / impedance assignment (default True).

  • seed (int, optional) – Random seed for reproducibility.

  • output_dir (str, optional) – If given, export feeders to this directory.

  • output_name (str) – Base filename (without extension) for exported files.

  • export_formats (sequence of str) – Export formats when output_dir is set. Supported: "json", "excel", "sqlite", "pickle".

Returns:

Generated synthetic feeders as annotated NetworkX graphs.

Return type:

list[nx.Graph]

Raises:

ValueError – If mode is invalid or required arguments are missing.

Core Classes

class powergrid_synth.distribution.SchweetzerFeederGenerator(params=None, seed=None)[source]

Bases: object

Generate a single MV radial distribution feeder.

Parameters:
  • params (DistributionSynthParams, optional) – All distribution parameters. Defaults to Table III values.

  • seed (int or None, optional) – Random seed for reproducibility.

generate_feeder(n_nodes, total_load_mw, total_gen_mw=0.0, v_nom_kv=10.0, assign_cable_types=True, assign_cable_lengths=True)[source]

Generate a complete MV distribution feeder.

Parameters:
  • n_nodes (int) – Total number of nodes in the feeder (including source and root).

  • total_load_mw (float) – Total real-power load (MW) to be distributed across load buses.

  • total_gen_mw (float, optional) – Total real-power generation/injection (MW). Default 0.

  • v_nom_kv (float, optional) – Nominal MV voltage in kV. Default 10.

  • assign_cable_types (bool, optional) – Whether to run Step 4 (cable type assignment). Default True.

  • assign_cable_lengths (bool, optional) – Whether to run Step 5 (cable length and impedance assignment). Default True.

Returns:

Annotated graph with node attributes (h, P_mw, Q_mvar, pf, node_type) and, when enabled, edge attributes (cable_type, length_km, r_ohm, x_ohm, max_i_ka, I_est_ka).

Return type:

nx.Graph

class powergrid_synth.distribution.DistributionSynthParams(hop_dist=<factory>, pf_cdf=<factory>, degree_dist=<factory>, degree_clip=<factory>, intermediate_frac=<factory>, intermediate_hop=<factory>, injection_frac=<factory>, injection_hop=<factory>, injection_deviation=<factory>, load_deviation=<factory>, cable_library=<factory>, current_ratio=<factory>, current_threshold=<factory>, cable_length=<factory>, length_clip=<factory>)[source]

Bases: object

All parameters for the Schweitzer distribution feeder generator.

Default values are taken from Table III and the text of Schweitzer et al. (2017).

Parameters:
cable_length: ModifiedCauchyParams
cable_library: List[CableLibraryEntry]
current_ratio: ExponentialParams
current_threshold: CurrentThreshold
degree_clip: PowerLawClip
degree_dist: MixtureGammaParams
hop_dist: NegBinomParams
injection_deviation: NormalParams
injection_frac: BetaParams
injection_hop: MixtureNormalParams
intermediate_frac: BetaParams
intermediate_hop: MixturePoissonParams
length_clip: ExponentialClip
load_deviation: TLocationScaleParams
pf_cdf: List[tuple]
class powergrid_synth.distribution.DistributionInputModel(bw_method=None, seed=None)[source]

Bases: object

3-D KDE input model for feeder size and loading.

The model is fitted on reference feeders and then sampled to produce realistic (n_nodes, total_load, total_gen) triples.

Parameters:
  • bw_method (str or float, optional) – Bandwidth method passed to scipy.stats.gaussian_kde.

  • seed (int or None, optional) – Random seed for reproducibility.

fit(feeders)[source]

Fit the KDE from a collection of reference feeder graphs.

Each graph must have node attributes P_mw (positive for load, negative for generation).

Parameters:

feeders (sequence of nx.Graph) – Reference feeder graphs.

Return type:

self

fit_from_arrays(n_nodes, total_load, total_gen)[source]

Fit directly from arrays (no graph objects needed).

Parameters:
  • n_nodes (array-like of int)

  • total_load (array-like of float)

  • total_gen (array-like of float)

Return type:

self

pdf(n_nodes, total_load, total_gen)[source]

Evaluate the KDE density at a given point.

Parameters:
  • n_nodes (float) – Coordinates in the 3-D input space.

  • total_load (float) – Coordinates in the 3-D input space.

  • total_gen (float) – Coordinates in the 3-D input space.

Returns:

Estimated probability density.

Return type:

float

sample(n_samples=1)[source]

Draw samples from the fitted input model.

Parameters:

n_samples (int) – Number of samples to draw.

Return type:

list of FeederInputSample

Analysis & Conversion

powergrid_synth.distribution.fit_params_from_feeders(feeders)[source]

Fit all Schweitzer parameters from a collection of reference feeders.

Parameters:

feeders (sequence of nx.Graph) – Reference distribution feeder graphs, each annotated with h, P_mw, node_type, length_km attributes.

Returns:

Fitted parameter set ready for SchweetzerFeederGenerator.

Return type:

DistributionSynthParams

Conversion utilities for building Schweitzer-format feeder graphs from pandapower and pypowsybl reference networks.

powergrid_synth.distribution.distribution_converter.feeder_summary(feeders)[source]

Return a summary dict for each feeder graph.

Parameters:

feeders (sequence of nx.Graph) – Feeder graphs produced by pandapower_to_feeders().

Returns:

One dict per feeder with keys n_nodes, n_edges, max_hop, is_tree, total_load_mw, total_gen_mw, node_types.

Return type:

list[dict]

powergrid_synth.distribution.distribution_converter.pandapower_to_feeders(net)[source]

Convert a pandapower network to a list of Schweitzer-format feeder graphs.

Each connected component with at least three nodes is returned as a separate graph annotated with the attributes expected by fit_params_from_feeders() and SchweetzerFeederGenerator:

  • Node attributes: h (hop distance from root), P_mw (positive = load, negative = generation), node_type ('load' | 'injection' | 'intermediate'), pf (power factor).

  • Edge attributes: length_km (cable length in km).

The function handles lines, transformers, and closed bus–bus switches so that the full connectivity of the pandapower network is captured.

Parameters:

net (pandapowerNet) – A pandapower network object.

Returns:

One feeder graph per connected component (≥ 3 nodes).

Return type:

list[nx.Graph]

powergrid_synth.distribution.distribution_converter.pypowsybl_to_feeders(network)[source]

Convert a pypowsybl Network to a list of Schweitzer-format feeder graphs.

This is the pypowsybl counterpart of pandapower_to_feeders(). It extracts buses, lines, two-winding transformers, loads, and generators from the pypowsybl Network and builds annotated feeder graphs suitable for fit_params_from_feeders() and SchweetzerFeederGenerator.

Parameters:

network (pypowsybl.network.Network) – A pypowsybl Network object (loaded from CGMES, XIIDM, MATPOWER, etc.).

Returns:

One feeder graph per connected component (≥ 3 nodes), with the same node/edge attributes as pandapower_to_feeders().

Return type:

list[nx.Graph]


Graph Classes

class powergrid_synth.PowerGridGraph(incoming_graph_data=None, **attr)[source]

Bases: Graph

Custom NetworkX Graph for Power Grids. Extends nx.Graph to support subgraph extraction by voltage level.

level(voltage_level)[source]

Returns a subgraph view containing only nodes at the specified voltage level.

Parameters:

voltage_level (int) – The voltage level index (e.g., 0, 1).

Returns:

A subgraph view of the grid.

Return type:

nx.Graph

class powergrid_synth.TransmissionGrid(incoming_graph_data=None, **attr)[source]

Bases: PowerGridGraph

Graph representation of a transmission-level power grid.

Inherits from PowerGridGraph and adds convenience methods specific to meshed, multi-voltage-level transmission networks.

property n_levels: int

Number of distinct voltage levels.

Return type:

int

property voltage_levels: list[int]

Sorted list of distinct voltage levels present in the grid.

Return type:

list[int]

class powergrid_synth.DistributionGrid(incoming_graph_data=None, **attr)[source]

Bases: PowerGridGraph

Graph representation of a radial distribution feeder.

Inherits from PowerGridGraph and adds convenience properties for radial-tree distribution grids annotated with hop distances, node types, and cable parameters (Schweitzer et al. 2017 format).

classmethod from_nx(G)[source]

Create a DistributionGrid from any NetworkX graph.

All node, edge, and graph attributes are copied.

Parameters:

G (Graph)

Return type:

DistributionGrid

property is_radial: bool

True if the graph is a connected tree.

Return type:

bool

property max_hop: int

Maximum hop distance in the feeder.

Return type:

int

nodes_at_hop(h)[source]

Return list of nodes at the given hop distance.

Parameters:

h (int)

Return type:

list

nodes_by_type(node_type)[source]

Return list of nodes with the given node_type attribute.

Parameters:

node_type (str) – One of 'load', 'injection', or 'intermediate'.

Return type:

list

property root

Return the root node (hop distance 0).

property total_gen_mw: float

Total real-power generation (MW) across all injection nodes.

Return type:

float

property total_load_mw: float

Total real-power load (MW) across all load nodes.

Return type:

float


Analysis, Export & Visualisation

class powergrid_synth.GraphComparator(synth_graph, ref_graph, synth_label='Synthetic', ref_label='Reference (Real)')[source]

Bases: object

Compares a synthetic power grid against a reference (real-world) graph. Provides tabular metric comparisons and visual distribution overlaps, both globally and per voltage level.

Parameters:
  • synth_graph (Graph)

  • ref_graph (Graph)

  • synth_label (str)

  • ref_label (str)

compare_degree_distributions(show_pvalue=False)[source]

Computes Kolmogorov-Smirnov (KS) and Relative Hausdorff (RH) statistics between the degree distributions of the synthetic and reference graphs, per voltage level. Prints and returns the results table.

Parameters:

show_pvalue (bool) – If True, include the KS p-value column. Default False.

Returns:

pd.DataFrame with columns Level, KS Statistic, RH Distance (and KS p-value if show_pvalue is True).

Return type:

DataFrame

plot_all_levels_comparison(log_scale=True)[source]

Plots degree comparison for all common voltage levels in a single figure.

Parameters:

log_scale (bool)

plot_degree_comparison(synth_graph=None, ref_graph=None, ax=None, log_scale=True, fig_size=(8, 5), show_lines=False, title='Degree Distribution Comparison')[source]

Plots overlaid degree distributions.

Parameters:
  • synth_graph (Graph | None) – Custom synthetic graph (or None for self.synth_graph).

  • ref_graph (Graph | None) – Custom reference graph (or None for self.ref_graph).

  • ax (Axes | None) – Matplotlib axis to plot on. If None, creates new figure.

  • log_scale (bool) – Whether to use log-log scale (default True).

  • title (str) – Title for the plot.

  • fig_size (Tuple)

  • show_lines (bool)

plot_level_topology_comparison(figsize=(15, 10))[source]

Plots side-by-side bar comparisons for topology metrics per voltage level: Nodes, Edges, Diameter, Avg Path Length, Avg Clustering.

Parameters:

figsize (Tuple[int, int])

print_level_metrics()[source]

Iterates through voltage levels found in both graphs and prints metrics. Does NOT plot.

print_metric_comparison(synth_graph=None, ref_graph=None, title='GRAPH COMPARISON REPORT')[source]

Prints a side-by-side table of topological metrics.

Parameters:
  • synth_graph (Graph | None)

  • ref_graph (Graph | None)

  • title (str)

run_full_comparison(log_scale=True)[source]

Runs global comparison followed by per-level comparison.

Parameters:

log_scale (bool)

class powergrid_synth.GridVisualizer[source]

Bases: object

Visualization module for synthetic power grids. Allows plotting the grid with different layouts including Yifan Hu, Kamada-Kawai, and Voltage Layered.

plot_bus_types(graph, layout='kamada_kawai', title='Bus Type Visualization', show_impedance=False, figsize=(12, 10))[source]

Visualizes the grid coloring nodes by their Bus Type (Static). Option to show impedance on edges.

Parameters:
  • graph (Graph)

  • layout (str)

  • title (str)

  • show_impedance (bool)

  • figsize (Tuple[int, int])

plot_grid(graph, layout='kamada_kawai', title='Grid', show_labels=False, show_bus_types=False, show_impedance=False, figsize=(12, 10))[source]

Static plot function for grid topology. Options allow overlaying bus types or impedance features.

Parameters:
  • graph (Graph)

  • layout (str)

  • title (str)

  • show_labels (bool)

  • show_bus_types (bool)

  • show_impedance (bool)

  • figsize (Tuple[int, int])

plot_impedance(grid, layout='kamada_kawai', title='Transmission Line Impedance', figsize=(12, 10))[source]

Plots the grid with edges colored by their impedance magnitude (Z). Blue = Low Impedance (Strong), Red = High Impedance (Weak).

Parameters:
  • grid (Graph)

  • layout (str)

  • title (str)

  • figsize (Tuple[int, int])

plot_interactive(graph, title='Interactive Grid', figsize=(14, 10))[source]

Opens an interactive window for the full grid.

Parameters:
  • graph (Graph)

  • title (str)

  • figsize (Tuple[int, int])

plot_interactive_bus_types(graph, title='Interactive Bus Type Visualization', figsize=(14, 10))[source]

Opens an interactive window for Bus Type Visualization with layout selection.

Parameters:
  • graph (Graph)

  • title (str)

  • figsize (Tuple[int, int])

plot_interactive_voltage_level(graph, level, title=None, figsize=(12, 10))[source]

Opens an interactive window for a specific voltage level.

Parameters:
  • graph (Graph)

  • level (int)

  • title (str | None)

  • figsize (Tuple[int, int])

plot_load_gen_bubbles(grid, layout='kamada_kawai', title='Generation vs Load', show_impedance=False, figsize=(12, 10))[source]

Bubble plot showing generation and load magnitudes. Generators are blue squares, Loads are red circles. Size is proportional to capacity/load. Optionally plots impedance on edges.

Parameters:
  • grid (Graph)

  • layout (str)

  • title (str)

  • show_impedance (bool)

  • figsize (Tuple[int, int])

plot_subgraphs(grid, layout='kamada_kawai', title='Subgraphs by Voltage Level', show_impedance=False, figsize=(15, 5))[source]

Plots subgraphs for each voltage level side-by-side (max 3 per row).

Parameters:
  • grid (nx.Graph) – The main power grid graph.

  • layout (str) – Layout algorithm to use.

  • title (str) – Main title for the figure.

  • show_impedance (bool) – Whether to color edges by impedance.

  • figsize (Tuple[int, int]) – Base size for the figure (width, height for one row). Height will scale with the number of rows.

class powergrid_synth.GridExporter(graph, base_mva=100.0, base_kv_map=None)[source]

Bases: object

Exports the generated synthetic grid to standard file formats via pandapower and pypowsybl built-in functions.

Parameters:
  • graph (Graph) – The synthetic power grid as a NetworkX Graph.

  • base_mva (float) – System base apparent power in MVA.

  • base_kv_map (dict | None) – Dictionary mapping voltage level indices to kV values (e.g., {0: 380.0, 1: 110.0, 2: 20.0}). If None, a default mapping is used.

Example:

exporter = GridExporter(grid, base_mva=100.0,
                        base_kv_map={0: 380.0, 1: 110.0})
exporter.to_json("output/grid.json")
exporter.to_excel("output/grid.xlsx")
exporter.to_pypowsybl("output/grid", format="CGMES")
to_cgmes(filepath, parameters=None)[source]

Export to CGMES (Common Grid Model Exchange Standard) via pypowsybl.

Parameters:
  • filepath (str) – Destination directory path.

  • parameters (dict | None) – Optional CGMES-specific parameters.

Return type:

None

to_excel(filepath, include_results=True)[source]

Export the grid to a pandapower Excel file.

Parameters:
  • filepath (str) – Destination file path (e.g. "output/grid.xlsx").

  • include_results (bool) – Whether to include power flow results if available.

Return type:

None

to_json(filepath)[source]

Export the grid to a pandapower JSON file.

Parameters:

filepath (str) – Destination file path (e.g. "output/grid.json").

Return type:

None

to_matpower(filepath)[source]

Export to MATPOWER format via pypowsybl.

Parameters:

filepath (str) – Destination path (e.g. "output/grid").

Return type:

None

to_pickle(filepath)[source]

Export the grid to a pandapower pickle file.

Parameters:

filepath (str) – Destination file path (e.g. "output/grid.p").

Return type:

None

to_psse(filepath)[source]

Export to PSS/E format via pypowsybl.

Parameters:

filepath (str) – Destination path.

Return type:

None

to_pypowsybl(filepath, format='XIIDM', parameters=None)[source]

Export the grid using pypowsybl’s built-in save.

Supported formats: CGMES, XIIDM, MATPOWER, PSS/E, UCTE, AMPL, BIIDM, JIIDM.

Parameters:
  • filepath (str) – Destination path (file or directory depending on format).

  • format (str) – One of the pypowsybl export format strings.

  • parameters (dict | None) – Optional format-specific parameters.

Return type:

None

to_sqlite(filepath, include_results=False)[source]

Export the grid to a pandapower SQLite database.

Parameters:
  • filepath (str) – Destination file path (e.g. "output/grid.sqlite").

  • include_results (bool) – Whether to include power flow results.

Return type:

None


Format Converters

powergrid_synth.pandapower_to_nx(net)[source]

Converts a pandapowerNet object into a NetworkX graph compatible with the synthesizer. Extracts buses, lines, transformers, loads, and generators.

Parameters:

net (Any)

Return type:

Graph

powergrid_synth.nx_to_pandapower(graph, base_mva=100.0, base_kv_map=None)[source]

Converts a synthetic NetworkX graph into a pandapowerNet object. Uses native Pandapower creation functions to ensure memory safety for the solver.

Parameters:
  • graph (Graph) – The synthetic power grid (NetworkX Graph) containing electrical properties.

  • base_mva (float) – System base MVA for per-unit calculations.

  • base_kv_map (dict | None) – Dictionary mapping voltage level indices (0, 1, 2) to actual kV (e.g., {0: 380.0, 1: 110.0}).

Return type:

Any

powergrid_synth.pandapower_to_pypowsybl(net)[source]

Converts a pandapowerNet object into a Pypowsybl Network object.

Parameters:

net (Any)

Return type:

Any

powergrid_synth.pypowsybl_to_nx(network)[source]

Convert a pypowsybl Network into a NetworkX graph.

Extracts buses, lines, two-winding transformers, loads, and generators. Each node gets voltage_level (int, 0 = highest kV), vn_kv, and bus_type ('Gen' / 'Load' / 'Conn'). Lines carry type='line' with impedance attributes; transformers carry type='transformer' with capacity.

The function also stores base_kv_map in G.graph mapping level indices to nominal voltages.

Parameters:

network (pypowsybl.network.Network) – A pypowsybl Network object (loaded from CGMES, XIIDM, MATPOWER, etc.).

Returns:

NetworkX graph compatible with the synthesizer pipeline.

Return type:

nx.Graph

powergrid_synth.load_grid(filepath, format=None)[source]

Load a power grid from a file in any pypowsybl-supported format.

Supported formats include CGMES, XIIDM, MATPOWER, IEEE-CDF, PSS/E, UCTE, BIIDM, JIIDM, and POWER-FACTORY. The format is auto-detected from the file extension when format is None.

Parameters:
  • filepath (str) – Path to the grid data file.

  • format (str, optional) – Explicit format string (e.g. 'CGMES', 'MATPOWER'). If None the format is inferred by pypowsybl from the file.

Returns:

NetworkX graph compatible with the synthesizer pipeline (same structure as pypowsybl_to_nx()).

Return type:

nx.Graph