Build a pandapower model dict using OpenNEM facilities as generators.
Reuses the existing bus/line/trafo/load pipeline but replaces
_get_gens_pp with _get_gens_from_opennem.
Parameters:
| Name |
Type |
Description |
Default |
matched_facilities
|
GeoDataFrame | None
|
Pre-computed matched facilities GeoDataFrame.
When None, facilities are fetched according to source and
matched via :func:~nemdb.geodata.matching.match_facilities_to_gis.
|
None
|
source
|
Literal['pooch', 'api']
|
How to obtain facilities when matched_facilities is None.
"pooch" (default) downloads the pre-built parquet from the
GitHub release — no account required. "api" calls the
OpenElectricity API (requires an API key).
|
'pooch'
|
Returns:
| Type |
Description |
dict
|
dict with keys buses, lines, trafos, gens, loads.
|
Source code in src/nemdb/models/pandapower/electrical_model.py
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421 | def get_pandapower_model_with_opennem(
matched_facilities: gpd.GeoDataFrame | None = None,
source: Literal["pooch", "api"] = "pooch",
) -> dict:
"""Build a pandapower model dict using OpenNEM facilities as generators.
Reuses the existing bus/line/trafo/load pipeline but replaces
``_get_gens_pp`` with ``_get_gens_from_opennem``.
Args:
matched_facilities: Pre-computed matched facilities GeoDataFrame.
When *None*, facilities are fetched according to ``source`` and
matched via :func:`~nemdb.geodata.matching.match_facilities_to_gis`.
source: How to obtain facilities when ``matched_facilities`` is *None*.
``"pooch"`` (default) downloads the pre-built parquet from the
GitHub release — no account required. ``"api"`` calls the
OpenElectricity API (requires an API key).
Returns:
dict with keys ``buses``, ``lines``, ``trafos``, ``gens``, ``loads``.
"""
if matched_facilities is None:
matched_facilities = match_facilities_to_gis(source=source)
lines, buses, mapping = _get_buses_and_lines()
pf_lines = _get_lines_pp(lines, mapping)
pf_buses = _get_bus_pp(pf_lines, buses)
pf_trafos = _get_trafos_pp(pf_buses)
pf_gens = _get_gens_from_opennem(pf_buses, matched_facilities)
pf_loads = _get_loads_pp(pf_buses)
# CRITICAL: Ensure buses with generators have geodata
# Copy generator geodata to bus if bus is missing geodata
# This ensures islands with generators can be connected via _validate_and_fix_connectivity
for _, gen in pf_gens.iterrows():
bus_id = gen["bus_id"]
bus_idx = pf_buses[pf_buses["bus_id"] == bus_id].index
if len(bus_idx) > 0:
bus_idx = bus_idx[0]
if pd.isna(pf_buses.at[bus_idx, "geodata"]) and pd.notna(gen["geodata"]):
pf_buses.at[bus_idx, "geodata"] = gen["geodata"]
log.debug(f"Copied geodata from generator {gen['name']} to bus {bus_id}")
model = {
"buses": pf_buses,
"lines": pf_lines,
"trafos": pf_trafos,
"gens": pf_gens,
"loads": pf_loads,
}
# Validate and fix connectivity
model, _diagnostics = _validate_and_fix_connectivity(model)
return model
|