88
99import logging
1010from functools import lru_cache
11+ from importlib .metadata import PackageNotFoundError , version
1112from typing import Dict , List , MutableMapping , Optional , Tuple , Type
1213
1314import numpy as np
1415import pandas as pd
1516import structlog
17+ from packaging .version import Version
1618from power_grid_model import (
1719 Branch3Side ,
1820 BranchSide ,
3436
3537logger = structlog .get_logger (__file__ )
3638
39+ PP_COMPATIBILITY_VERSION_3_2_0 = Version ("3.2.0" )
40+ try :
41+ PP_CONVERSION_VERSION = Version (version ("pandapower" ))
42+ except PackageNotFoundError :
43+ PP_CONVERSION_VERSION = PP_COMPATIBILITY_VERSION_3_2_0 # assume latest compatible version by default
44+
45+
46+ def get_loss_params_3ph ():
47+ if PP_CONVERSION_VERSION < PP_COMPATIBILITY_VERSION_3_2_0 :
48+ loss_params = ["p_a_l_mw" , "q_a_l_mvar" , "p_b_l_mw" , "q_b_l_mvar" , "p_c_l_mw" , "q_c_l_mvar" ]
49+ else :
50+ loss_params = ["pl_a_mw" , "ql_a_mvar" , "pl_b_mw" , "ql_b_mvar" , "pl_c_mw" , "ql_c_mvar" ]
51+ return loss_params
52+
3753
3854# pylint: disable=too-many-instance-attributes
3955class PandaPowerConverter (BaseConverter [PandaPowerData ]):
@@ -631,34 +647,53 @@ def _create_pgm_input_sym_loads(self):
631647 data_type = DatasetType .input , component_type = ComponentType .sym_load , shape = 3 * n_loads
632648 )
633649
634- const_i_multiplier = (
635- self ._get_pp_attr ("load" , "const_i_percent" , expected_type = "f8" , default = 0 ) * scaling * (1e-2 * 1e6 )
636- )
637- const_z_multiplier = (
638- self ._get_pp_attr ("load" , "const_z_percent" , expected_type = "f8" , default = 0 ) * scaling * (1e-2 * 1e6 )
639- )
640- const_p_multiplier = (1e6 - const_i_multiplier - const_z_multiplier ) * scaling
650+ if PP_CONVERSION_VERSION < PP_COMPATIBILITY_VERSION_3_2_0 :
651+ const_i_p_multiplier = (
652+ self ._get_pp_attr ("load" , "const_i_percent" , expected_type = "f8" , default = 0 ) * scaling * (1e-2 * 1e6 )
653+ )
654+ const_z_p_multiplier = (
655+ self ._get_pp_attr ("load" , "const_z_percent" , expected_type = "f8" , default = 0 ) * scaling * (1e-2 * 1e6 )
656+ )
657+ const_p_multiplier = (1e6 - const_i_p_multiplier - const_z_p_multiplier ) * scaling
658+ const_q_multiplier = const_p_multiplier
659+ const_i_q_multiplier = const_i_p_multiplier
660+ const_z_q_multiplier = const_z_p_multiplier
661+ else :
662+ const_i_p_multiplier = (
663+ self ._get_pp_attr ("load" , "const_i_p_percent" , expected_type = "f8" , default = 0 ) * scaling * (1e-2 * 1e6 )
664+ )
665+ const_z_p_multiplier = (
666+ self ._get_pp_attr ("load" , "const_z_p_percent" , expected_type = "f8" , default = 0 ) * scaling * (1e-2 * 1e6 )
667+ )
668+ const_p_multiplier = (1e6 - const_i_p_multiplier - const_z_p_multiplier ) * scaling
669+ const_i_q_multiplier = (
670+ self ._get_pp_attr ("load" , "const_i_q_percent" , expected_type = "f8" , default = 0 ) * scaling * (1e-2 * 1e6 )
671+ )
672+ const_z_q_multiplier = (
673+ self ._get_pp_attr ("load" , "const_z_q_percent" , expected_type = "f8" , default = 0 ) * scaling * (1e-2 * 1e6 )
674+ )
675+ const_q_multiplier = (1e6 - const_i_q_multiplier - const_z_q_multiplier ) * scaling
641676
642677 pgm_sym_loads ["id" ][:n_loads ] = self ._generate_ids ("load" , pp_loads .index , name = "const_power" )
643678 pgm_sym_loads ["node" ][:n_loads ] = self ._get_pgm_ids ("bus" , bus )
644679 pgm_sym_loads ["status" ][:n_loads ] = in_service
645680 pgm_sym_loads ["type" ][:n_loads ] = LoadGenType .const_power
646681 pgm_sym_loads ["p_specified" ][:n_loads ] = const_p_multiplier * p_mw
647- pgm_sym_loads ["q_specified" ][:n_loads ] = const_p_multiplier * q_mvar
682+ pgm_sym_loads ["q_specified" ][:n_loads ] = const_q_multiplier * q_mvar
648683
649684 pgm_sym_loads ["id" ][n_loads : 2 * n_loads ] = self ._generate_ids ("load" , pp_loads .index , name = "const_impedance" )
650685 pgm_sym_loads ["node" ][n_loads : 2 * n_loads ] = self ._get_pgm_ids ("bus" , bus )
651686 pgm_sym_loads ["status" ][n_loads : 2 * n_loads ] = in_service
652687 pgm_sym_loads ["type" ][n_loads : 2 * n_loads ] = LoadGenType .const_impedance
653- pgm_sym_loads ["p_specified" ][n_loads : 2 * n_loads ] = const_z_multiplier * p_mw
654- pgm_sym_loads ["q_specified" ][n_loads : 2 * n_loads ] = const_z_multiplier * q_mvar
688+ pgm_sym_loads ["p_specified" ][n_loads : 2 * n_loads ] = const_z_p_multiplier * p_mw
689+ pgm_sym_loads ["q_specified" ][n_loads : 2 * n_loads ] = const_z_q_multiplier * q_mvar
655690
656691 pgm_sym_loads ["id" ][- n_loads :] = self ._generate_ids ("load" , pp_loads .index , name = "const_current" )
657692 pgm_sym_loads ["node" ][- n_loads :] = self ._get_pgm_ids ("bus" , bus )
658693 pgm_sym_loads ["status" ][- n_loads :] = in_service
659694 pgm_sym_loads ["type" ][- n_loads :] = LoadGenType .const_current
660- pgm_sym_loads ["p_specified" ][- n_loads :] = const_i_multiplier * p_mw
661- pgm_sym_loads ["q_specified" ][- n_loads :] = const_i_multiplier * q_mvar
695+ pgm_sym_loads ["p_specified" ][- n_loads :] = const_i_p_multiplier * p_mw
696+ pgm_sym_loads ["q_specified" ][- n_loads :] = const_i_q_multiplier * q_mvar
662697
663698 assert ComponentType .sym_load not in self .pgm_input_data
664699 self .pgm_input_data [ComponentType .sym_load ] = pgm_sym_loads
@@ -1846,6 +1881,7 @@ def _pp_lines_output_3ph(self):
18461881 i_from = (pgm_output_lines ["p_from" ] + 1j * pgm_output_lines ["q_from" ]) / u_complex .iloc [from_nodes , :]
18471882 i_to = (pgm_output_lines ["p_to" ] + 1j * pgm_output_lines ["q_to" ]) / u_complex .iloc [to_nodes , :]
18481883
1884+ loss_params = get_loss_params_3ph ()
18491885 pp_output_lines_3ph = pd .DataFrame (
18501886 columns = [
18511887 "p_a_from_mw" ,
@@ -1860,12 +1896,12 @@ def _pp_lines_output_3ph(self):
18601896 "q_b_to_mvar" ,
18611897 "p_c_to_mw" ,
18621898 "q_c_to_mvar" ,
1863- "p_a_l_mw" ,
1864- "q_a_l_mvar" ,
1865- "p_b_l_mw" ,
1866- "q_b_l_mvar" ,
1867- "p_c_l_mw" ,
1868- "q_c_l_mvar" ,
1899+ loss_params [ 0 ] ,
1900+ loss_params [ 1 ] ,
1901+ loss_params [ 2 ] ,
1902+ loss_params [ 3 ] ,
1903+ loss_params [ 4 ] ,
1904+ loss_params [ 5 ] ,
18691905 "i_a_from_ka" ,
18701906 "i_b_from_ka" ,
18711907 "i_c_from_ka" ,
@@ -1898,12 +1934,12 @@ def _pp_lines_output_3ph(self):
18981934 pp_output_lines_3ph ["q_b_to_mvar" ] = pgm_output_lines ["q_to" ][:, 1 ] * 1e-6
18991935 pp_output_lines_3ph ["p_c_to_mw" ] = pgm_output_lines ["p_to" ][:, 2 ] * 1e-6
19001936 pp_output_lines_3ph ["q_c_to_mvar" ] = pgm_output_lines ["q_to" ][:, 2 ] * 1e-6
1901- pp_output_lines_3ph ["p_a_l_mw" ] = (pgm_output_lines ["p_from" ][:, 0 ] + pgm_output_lines ["p_to" ][:, 0 ]) * 1e-6
1902- pp_output_lines_3ph ["q_a_l_mvar" ] = (pgm_output_lines ["q_from" ][:, 0 ] + pgm_output_lines ["q_to" ][:, 0 ]) * 1e-6
1903- pp_output_lines_3ph ["p_b_l_mw" ] = (pgm_output_lines ["p_from" ][:, 1 ] + pgm_output_lines ["p_to" ][:, 1 ]) * 1e-6
1904- pp_output_lines_3ph ["q_b_l_mvar" ] = (pgm_output_lines ["q_from" ][:, 1 ] + pgm_output_lines ["q_to" ][:, 1 ]) * 1e-6
1905- pp_output_lines_3ph ["p_c_l_mw" ] = (pgm_output_lines ["p_from" ][:, 2 ] + pgm_output_lines ["p_to" ][:, 2 ]) * 1e-6
1906- pp_output_lines_3ph ["q_c_l_mvar" ] = (pgm_output_lines ["q_from" ][:, 2 ] + pgm_output_lines ["q_to" ][:, 2 ]) * 1e-6
1937+ pp_output_lines_3ph [loss_params [ 0 ] ] = (pgm_output_lines ["p_from" ][:, 0 ] + pgm_output_lines ["p_to" ][:, 0 ]) * 1e-6
1938+ pp_output_lines_3ph [loss_params [ 1 ] ] = (pgm_output_lines ["q_from" ][:, 0 ] + pgm_output_lines ["q_to" ][:, 0 ]) * 1e-6
1939+ pp_output_lines_3ph [loss_params [ 2 ] ] = (pgm_output_lines ["p_from" ][:, 1 ] + pgm_output_lines ["p_to" ][:, 1 ]) * 1e-6
1940+ pp_output_lines_3ph [loss_params [ 3 ] ] = (pgm_output_lines ["q_from" ][:, 1 ] + pgm_output_lines ["q_to" ][:, 1 ]) * 1e-6
1941+ pp_output_lines_3ph [loss_params [ 4 ] ] = (pgm_output_lines ["p_from" ][:, 2 ] + pgm_output_lines ["p_to" ][:, 2 ]) * 1e-6
1942+ pp_output_lines_3ph [loss_params [ 5 ] ] = (pgm_output_lines ["q_from" ][:, 2 ] + pgm_output_lines ["q_to" ][:, 2 ]) * 1e-6
19071943 pp_output_lines_3ph ["i_a_from_ka" ] = pgm_output_lines ["i_from" ][:, 0 ] * 1e-3
19081944 pp_output_lines_3ph ["i_b_from_ka" ] = pgm_output_lines ["i_from" ][:, 1 ] * 1e-3
19091945 pp_output_lines_3ph ["i_c_from_ka" ] = pgm_output_lines ["i_from" ][:, 2 ] * 1e-3
@@ -2026,6 +2062,7 @@ def _pp_trafos_output_3ph(self): # pylint: disable=too-many-statements
20262062
20272063 loading = np .maximum (np .maximum (loading_a_percent , loading_b_percent ), loading_c_percent )
20282064
2065+ loss_params = get_loss_params_3ph ()
20292066 pp_output_trafos_3ph = pd .DataFrame (
20302067 columns = [
20312068 "p_a_hv_mw" ,
@@ -2040,12 +2077,12 @@ def _pp_trafos_output_3ph(self): # pylint: disable=too-many-statements
20402077 "q_b_lv_mvar" ,
20412078 "p_c_lv_mw" ,
20422079 "q_c_lv_mvar" ,
2043- "p_a_l_mw" ,
2044- "q_a_l_mvar" ,
2045- "p_b_l_mw" ,
2046- "q_b_l_mvar" ,
2047- "p_c_l_mw" ,
2048- "q_c_l_mvar" ,
2080+ loss_params [ 0 ] ,
2081+ loss_params [ 1 ] ,
2082+ loss_params [ 2 ] ,
2083+ loss_params [ 3 ] ,
2084+ loss_params [ 4 ] ,
2085+ loss_params [ 5 ] ,
20492086 "i_a_hv_ka" ,
20502087 "i_a_lv_ka" ,
20512088 "i_b_hv_ka" ,
@@ -2071,22 +2108,22 @@ def _pp_trafos_output_3ph(self): # pylint: disable=too-many-statements
20712108 pp_output_trafos_3ph ["q_b_lv_mvar" ] = pgm_output_transformers ["q_to" ][:, 1 ] * 1e-6
20722109 pp_output_trafos_3ph ["p_c_lv_mw" ] = pgm_output_transformers ["p_to" ][:, 2 ] * 1e-6
20732110 pp_output_trafos_3ph ["q_c_lv_mvar" ] = pgm_output_transformers ["q_to" ][:, 2 ] * 1e-6
2074- pp_output_trafos_3ph ["p_a_l_mw" ] = (
2111+ pp_output_trafos_3ph [loss_params [ 0 ] ] = (
20752112 pgm_output_transformers ["p_from" ][:, 0 ] + pgm_output_transformers ["p_to" ][:, 0 ]
20762113 ) * 1e-6
2077- pp_output_trafos_3ph ["q_a_l_mvar" ] = (
2114+ pp_output_trafos_3ph [loss_params [ 1 ] ] = (
20782115 pgm_output_transformers ["q_from" ][:, 0 ] + pgm_output_transformers ["q_to" ][:, 0 ]
20792116 ) * 1e-6
2080- pp_output_trafos_3ph ["p_b_l_mw" ] = (
2117+ pp_output_trafos_3ph [loss_params [ 2 ] ] = (
20812118 pgm_output_transformers ["p_from" ][:, 1 ] + pgm_output_transformers ["p_to" ][:, 1 ]
20822119 ) * 1e-6
2083- pp_output_trafos_3ph ["q_b_l_mvar" ] = (
2120+ pp_output_trafos_3ph [loss_params [ 3 ] ] = (
20842121 pgm_output_transformers ["q_from" ][:, 1 ] + pgm_output_transformers ["q_to" ][:, 1 ]
20852122 ) * 1e-6
2086- pp_output_trafos_3ph ["p_c_l_mw" ] = (
2123+ pp_output_trafos_3ph [loss_params [ 4 ] ] = (
20872124 pgm_output_transformers ["p_from" ][:, 2 ] + pgm_output_transformers ["p_to" ][:, 2 ]
20882125 ) * 1e-6
2089- pp_output_trafos_3ph ["q_c_l_mvar" ] = (
2126+ pp_output_trafos_3ph [loss_params [ 5 ] ] = (
20902127 pgm_output_transformers ["q_from" ][:, 2 ] + pgm_output_transformers ["q_to" ][:, 2 ]
20912128 ) * 1e-6
20922129 pp_output_trafos_3ph ["i_a_hv_ka" ] = pgm_output_transformers ["i_from" ][:, 0 ] * 1e-3
@@ -2396,7 +2433,7 @@ def get_switch_states(self, pp_table: str) -> pd.DataFrame:
23962433 else :
23972434 raise KeyError (f"Can't get switch states for { pp_table } " )
23982435
2399- component = self .pp_input_data [pp_table ]
2436+ component = self .pp_input_data [pp_table ]. copy ()
24002437 component ["index" ] = component .index
24012438
24022439 # Select the appropriate switches and columns
0 commit comments