Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add option to opt out of powerflow within the cim2pp converter #2158

Merged
merged 12 commits into from
Nov 7, 2023
Merged
4 changes: 2 additions & 2 deletions .github/workflows/github_test_action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
- name: Install Julia
if: ${{ matrix.python-version == '3.9' }}
run: |
./.install_julia.sh 1.8
./.install_julia.sh 1.9.3
pip install julia
python ./.install_pycall.py
- name: List of installed packages
Expand Down Expand Up @@ -181,7 +181,7 @@ jobs:
run: |
python -m pip install --upgrade pip
python -m pip install pytest nbmake pytest-xdist igraph numba seaborn
./.install_julia.sh 1.8
./.install_julia.sh 1.9.3
python -m pip install julia
python ./.install_pycall.py
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Change Log
- [FIXED] bug in coords conversion in cim2pp, small fixes
- [CHANGED] cim2pp: added support for multi diagram usage for DL profiles
- [CHANGED] cim2pp: made build_pp_net modular by introducing classes
- [ADDED] cim2pp: added option to opt out of internal powerflow calculation
- [FIXED] error handling in :code:`plotly/mapbox_plot.py` not raising :code`ImportError` if :code:`geopy` or :code:`pyproj` are missing
- [FIXED] powerfactory2pandapower-converter error if a line has two identical coordinates
- [ADDED] logger messages about the probabilistic load flow calculation (simultaneities) in the powerfactory2pandapower-converter for low voltage loads
Expand Down
34 changes: 21 additions & 13 deletions pandapower/converter/cim/cim2pp/build_pp_net.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,19 +170,22 @@
self.logger.info("Running a power flow.")
self.report_container.add_log(Report(
level=LogLevel.INFO, code=ReportCode.INFO, message="Running a power flow."))
try:
pp.runpp(self.net)
except Exception as e:
self.logger.error("Failed running a powerflow.")
self.logger.exception(e)
self.report_container.add_log(Report(
level=LogLevel.ERROR, code=ReportCode.ERROR, message="Failed running a powerflow."))
self.report_container.add_log(Report(level=LogLevel.EXCEPTION, code=ReportCode.EXCEPTION,
message=traceback.format_exc()))
else:
self.logger.info("Power flow solved normal.")
self.report_container.add_log(Report(
level=LogLevel.INFO, code=ReportCode.INFO, message="Power flow solved normal."))
if kwargs.get('run_powerflow', False):
try:
pp.runpp(self.net)
except Exception as e:
self.logger.error("Failed running a powerflow.")
self.logger.exception(e)
self.report_container.add_log(Report(

Check warning on line 179 in pandapower/converter/cim/cim2pp/build_pp_net.py

View check run for this annotation

Codecov / codecov/patch

pandapower/converter/cim/cim2pp/build_pp_net.py#L176-L179

Added lines #L176 - L179 were not covered by tests
level=LogLevel.ERROR, code=ReportCode.ERROR, message="Failed running a powerflow."))
self.report_container.add_log(Report(level=LogLevel.EXCEPTION, code=ReportCode.EXCEPTION,

Check warning on line 181 in pandapower/converter/cim/cim2pp/build_pp_net.py

View check run for this annotation

Codecov / codecov/patch

pandapower/converter/cim/cim2pp/build_pp_net.py#L181

Added line #L181 was not covered by tests
message=traceback.format_exc()))
if not kwargs.get('ignore_errors', True):
raise e

Check warning on line 184 in pandapower/converter/cim/cim2pp/build_pp_net.py

View check run for this annotation

Codecov / codecov/patch

pandapower/converter/cim/cim2pp/build_pp_net.py#L183-L184

Added lines #L183 - L184 were not covered by tests
else:
self.logger.info("Power flow solved normal.")
self.report_container.add_log(Report(
level=LogLevel.INFO, code=ReportCode.INFO, message="Power flow solved normal."))
try:
create_measurements = kwargs.get('create_measurements', None)
if create_measurements is not None and create_measurements.lower() == 'sv':
Expand All @@ -206,7 +209,10 @@
level=LogLevel.EXCEPTION, code=ReportCode.EXCEPTION_CONVERTING,
message=traceback.format_exc()))
self.net.measurement = self.net.measurement[0:0]
if not kwargs.get('ignore_errors', True):
raise e

Check warning on line 213 in pandapower/converter/cim/cim2pp/build_pp_net.py

View check run for this annotation

Codecov / codecov/patch

pandapower/converter/cim/cim2pp/build_pp_net.py#L212-L213

Added lines #L212 - L213 were not covered by tests
try:
# TODO: think on whether to remove whole function
if kwargs.get('update_assets_from_sv', False):
CreateMeasurements(self.net, self.cim).update_assets_from_sv()
except Exception as e:
Expand All @@ -218,6 +224,8 @@
self.report_container.add_log(Report(
level=LogLevel.EXCEPTION, code=ReportCode.EXCEPTION_CONVERTING,
message=traceback.format_exc()))
if not kwargs.get('ignore_errors', True):
raise e

Check warning on line 228 in pandapower/converter/cim/cim2pp/build_pp_net.py

View check run for this annotation

Codecov / codecov/patch

pandapower/converter/cim/cim2pp/build_pp_net.py#L227-L228

Added lines #L227 - L228 were not covered by tests
# a special fix for BB and NB mixed networks:
# fuse boundary ConnectivityNodes with their TopologicalNodes
bus_t = self.net.bus.reset_index(level=0, drop=False)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ def _prepare_trafos_cim16(self, power_trafo2w: pd.DataFrame) -> pd.DataFrame:
one_item + '_lv']
del copy_list, one_item
# detect on which winding a tap changer is attached
power_trafo2w['tap_side'] = None
power_trafo2w.loc[power_trafo2w['step_lv'].notna(), 'tap_side'] = 'lv'
power_trafo2w.loc[power_trafo2w['step'].notna(), 'tap_side'] = 'hv'
fillna_list = ['neutralStep', 'lowStep', 'highStep', 'stepVoltageIncrement', 'stepPhaseShiftIncrement', 'step',
Expand Down Expand Up @@ -516,6 +517,7 @@ def _prepare_trafo3w_cim16(self, power_trafo3w: pd.DataFrame) -> pd.DataFrame:
del copy_list, one_item

# detect on which winding a tap changer is attached
power_trafo3w['tap_side'] = None
power_trafo3w.loc[power_trafo3w['step_lv'].notna(), 'tap_side'] = 'lv'
power_trafo3w.loc[power_trafo3w['step_mv'].notna(), 'tap_side'] = 'mv'
power_trafo3w.loc[power_trafo3w['step'].notna(), 'tap_side'] = 'hv'
Expand Down
20 changes: 12 additions & 8 deletions pandapower/converter/cim/cim2pp/from_cim.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,22 +95,26 @@ def from_cim(file_list: List[str] = None, encoding: str = 'utf-8', convert_line_
"""
Convert a CIM net to a pandapower net from XML files.
Additional parameters for kwargs:
create_measurements (str): Set this parameter to 'SV' to create measurements for the pandapower net from the SV
- create_measurements (str): Set this parameter to 'SV' to create measurements for the pandapower net from the SV
profile. Set it to 'Analog' to create measurements from Analogs. If the parameter is not set or is set to None, no
measurements will be created.
update_assets_from_sv (bool): Set this parameter to True to update the assets (sgens, loads, wards, ...) with values
from the SV profile. Default: False.
use_GL_or_DL_profile (str): Choose the profile to use for converting coordinates. Set it to 'GL' to use the GL
- update_assets_from_sv (bool): Set this parameter to True to update the assets (sgens, loads, wards, ...) with
values from the SV profile. Default: False.
- use_GL_or_DL_profile (str): Choose the profile to use for converting coordinates. Set it to 'GL' to use the GL
profile (Usually lat and long coordinates). Set it to 'DL' to use the DL profile (Usually x, y coordinates for
displaying control room schema). Set it to 'both' to let the converter choose the profile. The converter will
choose the GL profile first if available, otherwise the DL profile. Optional, default: both.
diagram_name (str): The name from the Diagram from the diagram layout profile for the geo coordinates. Default: The
first diagram sorted ascending by name. Set the parameter to "all" to use available diagrams for creating the
- diagram_name (str): The name from the Diagram from the diagram layout profile for the geo coordinates. Default:
The first diagram sorted ascending by name. Set the parameter to "all" to use available diagrams for creating the
coordinates.
create_tap_controller (bool): If True, create pandapower controllers for transformer tap changers. If False, skip
- create_tap_controller (bool): If True, create pandapower controllers for transformer tap changers. If False, skip
creating them. Default: True
sn_mva (float): Set the sn_mva from the pandapower net to a specific value. This value is not given in CGMES.
- sn_mva (float): Set the sn_mva from the pandapower net to a specific value. This value is not given in CGMES.
Default: None (pandapower default will be chosen)
- run_powerflow (bool): Option to run to powerflow inside the converter to create res tables directly.
Default: False.
- ignore_errors (bool): Option to disable raising of internal errors. Useful if you need to get a network not matter
if there are errors in the conversion. Default: True.

:param file_list: The path to the CGMES files as a list.
:param encoding: The encoding from the files. Optional, default: utf-8
Expand Down
21 changes: 18 additions & 3 deletions pandapower/test/converter/test_from_cim.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def SimBench_1_HVMVmixed_1_105_0_sw_modified():

cgmes_files = [os.path.join(folder_path, 'SimBench_1-HVMV-mixed-1.105-0-sw_modified.zip')]

return cim2pp.from_cim(file_list=cgmes_files)
return cim2pp.from_cim(file_list=cgmes_files, run_powerflow=True)


@pytest.fixture(scope="session")
Expand All @@ -63,7 +63,7 @@ def Simbench_1_EHV_mixed__2_no_sw():

cgmes_files = [os.path.join(folder_path, 'Simbench_1-EHV-mixed--2-no_sw.zip')]

return cim2pp.from_cim(file_list=cgmes_files, create_measurements='SV')
return cim2pp.from_cim(file_list=cgmes_files, create_measurements='SV', run_powerflow=True)


@pytest.fixture(scope="session")
Expand All @@ -77,6 +77,20 @@ def example_multivoltage():
return net


@pytest.fixture(scope="session")
def SimBench_1_HVMVmixed_1_105_0_sw_modified_no_load_flow():
folder_path = os.path.join(test_path, "test_files", "example_cim")

cgmes_files = [os.path.join(folder_path, 'SimBench_1-HVMV-mixed-1.105-0-sw_modified.zip')]

return cim2pp.from_cim(file_list=cgmes_files)


def test_SimBench_1_HVMVmixed_1_105_0_sw_modified_no_load_flow_res_bus(
SimBench_1_HVMVmixed_1_105_0_sw_modified_no_load_flow):
assert 0 == len(SimBench_1_HVMVmixed_1_105_0_sw_modified_no_load_flow.res_bus.index)


def test_example_multivoltage_res_xward(example_multivoltage):
assert 2 == len(example_multivoltage.res_xward.index)
element_0 = example_multivoltage.res_xward.iloc[example_multivoltage.xward[
Expand Down Expand Up @@ -715,7 +729,7 @@ def test_fullgrid_trafo(fullgrid):
assert 0.0 == element_1['pfe_kw'].item()
assert 0.0 == element_1['i0_percent'].item()
assert 0.0 == element_1['shift_degree'].item()
assert math.isnan(element_1['tap_side'].item())
assert None is element_1['tap_side'].item()
assert pd.isna(element_1['tap_neutral'].item())
assert pd.isna(element_1['tap_min'].item())
assert pd.isna(element_1['tap_max'].item())
Expand Down Expand Up @@ -1054,6 +1068,7 @@ def test_fullgrid_controller(fullgrid):
def test_fullgrid_characteristic_temp(fullgrid):
assert 8 == len(fullgrid.characteristic_temp.index)


def test_fullgrid_characteristic(fullgrid):
assert 20 == len(fullgrid.characteristic.index)
for _, obj in fullgrid.characteristic.iterrows():
Expand Down
Loading