Skip to content

Commit 8fe7025

Browse files
heckstrahlerKS-HTK
andauthored
create res tables only for elements that exist in the network (#2813)
* initial impl * fix a lot a res_ entry access errors * fix non existant res errors * fix consistency checks * fix runpp3ph * fix missing res errors * fix keys in util * fix util.py * fix for ucte test * update power system test case jsons * update networks, fix utils * fix rundcpp test * fix adapt result tables in replace * add gen to pf_3ph relevant elements * fix get result from gen 3ph * fixed elements_to_deserialize breaking custom key compatibility. * removed empty res_ tables from new networks when using metadata feature * fixed useages of res_ tables while not present removed _empty_res_ tables from net and created own object to get them fixed sc tests ignoring columns order --------- Co-authored-by: KS_HTK <2981026+KS-HTK@users.noreply.github.com>
1 parent 0f47884 commit 8fe7025

55 files changed

Lines changed: 1589 additions & 4792 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pandapower/auxiliary.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import numbers
77
import warnings
8-
from collections.abc import MutableMapping, Iterable, Collection
8+
from collections.abc import Iterable, Collection
99
from importlib.metadata import PackageNotFoundError
1010
from importlib.metadata import version as version_str
1111
from typing import (

pandapower/convert_format.py

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ def convert_format(net, elements_to_deserialize=None, drop_invalid_geodata=False
4444
if not bool(cols.issubset(net.load.columns)):
4545
for col in cols:
4646
add_column_to_df(net, "load", col)
47+
48+
# drop empty res_ tables and _empty_res_ tables
49+
for key in list(net.keys()): # conversion to list required because of dict modification while iteration
50+
if key.startswith("_empty_res_") or (key.startswith("res_") and len(net[key]) == 0):
51+
del net[key]
52+
4753
if net_format_version < Version("3.1.0"):
4854
_convert_q_capability_characteristic(net)
4955
if Version("3.0.0") <= net_format_version < Version("3.1.3"):
@@ -155,12 +161,12 @@ def _restore_index_names(net):
155161
"""Restores dataframes index names stored as dictionary. With newer pp to_json() this
156162
information is stored to the dataframe its self.
157163
"""
158-
if "index_names" in net.keys():
164+
if "index_names" in net:
159165
if not isinstance(net["index_names"], dict):
160166
raise ValueError("To restore the index names of the dataframes, a dict including this "
161167
f"information is expected, not {type(net['index_names'])}")
162168
for key, index_name in net["index_names"].items():
163-
if key in net.keys():
169+
if key in net:
164170
net[key].index.name = index_name
165171
del net["index_names"]
166172

@@ -208,19 +214,19 @@ def _convert_trafo_controller_parameter_names(net):
208214
controller = net.controller.at[ctrl_idx, "object"]
209215
if issubclass(type(controller), TrafoController):
210216

211-
if "tid" in controller.__dict__.keys():
217+
if "tid" in controller.__dict__:
212218
controller.__dict__["element_index"] = controller.__dict__.pop("tid")
213-
elif "transformer_index" in controller.__dict__.keys():
219+
elif "transformer_index" in controller.__dict__:
214220
controller.__dict__["element_index"] = controller.__dict__.pop("transformer_index")
215221

216-
if "trafotable" in controller.__dict__.keys():
222+
if "trafotable" in controller.__dict__:
217223
controller.__dict__["element"] = controller.__dict__.pop("trafotable")
218-
if "trafotype" in controller.__dict__.keys():
224+
if "trafotype" in controller.__dict__:
219225
del controller.__dict__["trafotype"]
220-
elif "trafotype" in controller.__dict__.keys():
226+
elif "trafotype" in controller.__dict__:
221227
controller.__dict__["element"] = controller.__dict__.pop("trafotype")
222228

223-
if "controlled_bus" in controller.__dict__.keys():
229+
if "controlled_bus" in controller.__dict__:
224230
controller.__dict__["trafobus"] = controller.__dict__.pop("controlled_bus")
225231

226232

@@ -289,8 +295,8 @@ def _add_nominal_power(net):
289295
def _add_missing_tables(net):
290296
net_new = pandapowerNet(name='missing_tables_net')
291297
net_new.name = "" # name is set to avoid warnings, then unset here to avoid adding it to any network
292-
for key in net_new.keys():
293-
if key.startswith("_empty_res") or key not in net.keys():
298+
for key in net_new:
299+
if key.startswith("_empty_res") or key not in net:
294300
net[key] = net_new[key]
295301

296302

@@ -374,7 +380,7 @@ def _rename_columns(net, elements_to_deserialize):
374380
if "controller" in net:
375381
net["controller"] = net["controller"].rename(columns={"controller": "object"})
376382

377-
if _check_elements_to_deserialize('res_line_3ph', elements_to_deserialize):
383+
if 'res_line_3ph' in net and _check_elements_to_deserialize('res_line_3ph', elements_to_deserialize):
378384
if "p_a_l_mw" in net.res_line_3ph:
379385
net['res_line_3ph'] = net['res_line_3ph'].rename(columns={
380386
'p_a_l_mw': 'pl_a_mw',
@@ -385,7 +391,7 @@ def _rename_columns(net, elements_to_deserialize):
385391
'q_c_l_mvar': 'ql_c_mvar',
386392
})
387393

388-
if _check_elements_to_deserialize('res_trafo_3ph', elements_to_deserialize):
394+
if 'res_trafo_3ph' in net and _check_elements_to_deserialize('res_trafo_3ph', elements_to_deserialize):
389395
if "p_a_l_mw" in net.res_trafo_3ph:
390396
net['res_trafo_3ph'] = net['res_trafo_3ph'].rename(columns={
391397
'p_a_l_mw': 'pl_a_mw',
@@ -517,16 +523,16 @@ def _add_missing_columns(net, elements_to_deserialize):
517523
net.switch['in_ka'] = np.nan
518524

519525
# Update the switch table with 'in_ka'
520-
if _check_elements_to_deserialize('res_switch', elements_to_deserialize) and \
521-
'p_from_mw' not in net.res_switch:
522-
net.res_switch['p_from_mw'] = np.nan
523-
net.res_switch['q_from_mvar'] = np.nan
524-
net.res_switch['p_to_mw'] = np.nan
525-
net.res_switch['q_to_mvar'] = np.nan
526+
if ('res_switch' in net and _check_elements_to_deserialize('res_switch', elements_to_deserialize) and
527+
'p_from_mw' not in net.res_switch):
528+
net.res_switch['p_from_mw'] = np.nan
529+
net.res_switch['q_from_mvar'] = np.nan
530+
net.res_switch['p_to_mw'] = np.nan
531+
net.res_switch['q_to_mvar'] = np.nan
526532

527533
# Update the switch table with 'in_ka'
528-
if _check_elements_to_deserialize('res_switch_est', elements_to_deserialize) and \
529-
'p_from_mw' not in net.res_switch_est:
534+
if ('res_switch_est' in net and _check_elements_to_deserialize('res_switch_est', elements_to_deserialize) and
535+
'p_from_mw' not in net.res_switch_est):
530536
net.res_switch_est['p_from_mw'] = np.nan
531537
net.res_switch_est['q_from_mvar'] = np.nan
532538
net.res_switch_est['p_to_mw'] = np.nan
@@ -560,8 +566,8 @@ def _add_missing_columns(net, elements_to_deserialize):
560566
"slack_weight" not in net.xward:
561567
net.xward['slack_weight'] = 0.0
562568

563-
if _check_elements_to_deserialize('res_line_3ph', elements_to_deserialize) and \
564-
"p_c_from_mw" not in net.res_line_3ph:
569+
if ('res_line_3ph' in net and _check_elements_to_deserialize('res_line_3ph', elements_to_deserialize) and
570+
"p_c_from_mw" not in net.res_line_3ph):
565571
net.res_line_3ph['p_c_from_mw'] = np.nan
566572
net.res_line_3ph['loading_a_percent'] = np.nan
567573
net.res_line_3ph['loading_b_percent'] = np.nan
@@ -570,8 +576,8 @@ def _add_missing_columns(net, elements_to_deserialize):
570576

571577
def _update_trafo_type_parameter_names(net):
572578
for element in ('trafo', 'trafo3w'):
573-
for type in net.std_types[element].keys():
574-
keys = {col: _update_column(col) for col in net.std_types[element][type].keys() if
579+
for type in net.std_types[element]:
580+
keys = {col: _update_column(col) for col in net.std_types[element][type] if
575581
col.startswith("tp") or col.startswith("vsc")}
576582
for old_key, new_key in keys.items():
577583
net.std_types[element][type][new_key] = net.std_types[element][type].pop(old_key)
@@ -614,7 +620,7 @@ def _set_data_type_of_columns(net):
614620

615621
def _convert_to_mw(net):
616622
replace = [("kw", "mw"), ("kvar", "mvar"), ("kva", "mva")]
617-
for element in net.keys():
623+
for element in net:
618624
if isinstance(net[element], pd.DataFrame):
619625
for old, new in replace:
620626
diff = {column: column.replace(old, new) for column in net[element].columns if
@@ -682,7 +688,7 @@ def _convert_objects(net, elements_to_deserialize):
682688
"""
683689
_check_elements_to_deserialize('controller', elements_to_deserialize)
684690
if _check_elements_to_deserialize('controller', elements_to_deserialize) and \
685-
"controller" in net.keys():
691+
"controller" in net:
686692
for obj in net["controller"].object.values:
687693
_update_object_attributes(obj)
688694

pandapower/converter/cim/cim2pp/build_pp_net.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626

2727
class CimConverter:
28-
2928
def __init__(self, cim_parser: cim_classes.CimParser, converter_classes: Dict,
3029
cim_version: str | None = None, **kwargs):
3130
self.logger = logging.getLogger(self.__class__.__name__)

pandapower/converter/cim/cim_tools.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
# -*- coding: utf-8 -*-
21
# Copyright (c) 2016-2026 by University of Kassel and Fraunhofer Institute for Energy Economics
32
# and Energy System Technology (IEE), Kassel. All rights reserved.
3+
44
import logging
55
import os
66
import json
77
from typing import Dict, List
8+
89
import numpy as np
910
import pandas as pd
1011

@@ -33,21 +34,25 @@ def get_pp_net_special_columns_dict() -> Dict[str, str]:
3334

3435
def extend_pp_net_cim(net: pandapowerNet, override: bool = True) -> pandapowerNet:
3536
"""
36-
Extend pandapower element DataFrames with special columns for the CIM converter, e.g. a column for the RDF ID.
37-
:param net: The pandapower net to extend.
38-
:param override: If True, all existing special CIM columns will be overwritten (content will be erased). If False,
39-
only missing columns will be created. Optional, default: True
40-
:return: The extended pandapower network.
37+
Extend pandapower network with special element for the CIM converter.
38+
39+
..note::
40+
The CIM converter creates a pandapower network with metadata key "cim".
41+
See :func:`pandapower.network.pandapowerNet.__init__`
42+
43+
Parameters:
44+
net: The pandapower net to extend.
45+
override: If True, net.CGMES will be overwritten (content will be erased). If False,
46+
only missing element will be created.
47+
48+
Returns:
49+
Reference to the input pandapower network (input will be modified).
4150
"""
4251
# some special items
43-
if override:
52+
if 'CGMES' not in net or override:
4453
net['CGMES'] = {}
54+
if 'BaseVoltage' not in net['CGMES'] or override:
4555
net['CGMES']['BaseVoltage'] = pd.DataFrame(None, columns=['rdfId', 'nominalVoltage'])
46-
else:
47-
if 'CGMES' not in net:
48-
net['CGMES'] = {}
49-
if 'BaseVoltage' not in net['CGMES']:
50-
net['CGMES']['BaseVoltage'] = pd.DataFrame(None, columns=['rdfId', 'nominalVoltage'])
5156

5257
return net
5358

0 commit comments

Comments
 (0)