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
@@ -1843,6 +1878,7 @@ def _pp_lines_output_3ph(self):
18431878 i_from = (pgm_output_lines ["p_from" ] + 1j * pgm_output_lines ["q_from" ]) / u_complex .iloc [from_nodes , :]
18441879 i_to = (pgm_output_lines ["p_to" ] + 1j * pgm_output_lines ["q_to" ]) / u_complex .iloc [to_nodes , :]
18451880
1881+ loss_params = get_loss_params_3ph ()
18461882 pp_output_lines_3ph = pd .DataFrame (
18471883 columns = [
18481884 "p_a_from_mw" ,
@@ -1857,12 +1893,12 @@ def _pp_lines_output_3ph(self):
18571893 "q_b_to_mvar" ,
18581894 "p_c_to_mw" ,
18591895 "q_c_to_mvar" ,
1860- "p_a_l_mw" ,
1861- "q_a_l_mvar" ,
1862- "p_b_l_mw" ,
1863- "q_b_l_mvar" ,
1864- "p_c_l_mw" ,
1865- "q_c_l_mvar" ,
1896+ loss_params [ 0 ] ,
1897+ loss_params [ 1 ] ,
1898+ loss_params [ 2 ] ,
1899+ loss_params [ 3 ] ,
1900+ loss_params [ 4 ] ,
1901+ loss_params [ 5 ] ,
18661902 "i_a_from_ka" ,
18671903 "i_b_from_ka" ,
18681904 "i_c_from_ka" ,
@@ -1895,12 +1931,12 @@ def _pp_lines_output_3ph(self):
18951931 pp_output_lines_3ph ["q_b_to_mvar" ] = pgm_output_lines ["q_to" ][:, 1 ] * 1e-6
18961932 pp_output_lines_3ph ["p_c_to_mw" ] = pgm_output_lines ["p_to" ][:, 2 ] * 1e-6
18971933 pp_output_lines_3ph ["q_c_to_mvar" ] = pgm_output_lines ["q_to" ][:, 2 ] * 1e-6
1898- pp_output_lines_3ph ["p_a_l_mw" ] = (pgm_output_lines ["p_from" ][:, 0 ] + pgm_output_lines ["p_to" ][:, 0 ]) * 1e-6
1899- pp_output_lines_3ph ["q_a_l_mvar" ] = (pgm_output_lines ["q_from" ][:, 0 ] + pgm_output_lines ["q_to" ][:, 0 ]) * 1e-6
1900- pp_output_lines_3ph ["p_b_l_mw" ] = (pgm_output_lines ["p_from" ][:, 1 ] + pgm_output_lines ["p_to" ][:, 1 ]) * 1e-6
1901- pp_output_lines_3ph ["q_b_l_mvar" ] = (pgm_output_lines ["q_from" ][:, 1 ] + pgm_output_lines ["q_to" ][:, 1 ]) * 1e-6
1902- pp_output_lines_3ph ["p_c_l_mw" ] = (pgm_output_lines ["p_from" ][:, 2 ] + pgm_output_lines ["p_to" ][:, 2 ]) * 1e-6
1903- pp_output_lines_3ph ["q_c_l_mvar" ] = (pgm_output_lines ["q_from" ][:, 2 ] + pgm_output_lines ["q_to" ][:, 2 ]) * 1e-6
1934+ pp_output_lines_3ph [loss_params [ 0 ] ] = (pgm_output_lines ["p_from" ][:, 0 ] + pgm_output_lines ["p_to" ][:, 0 ]) * 1e-6
1935+ pp_output_lines_3ph [loss_params [ 1 ] ] = (pgm_output_lines ["q_from" ][:, 0 ] + pgm_output_lines ["q_to" ][:, 0 ]) * 1e-6
1936+ pp_output_lines_3ph [loss_params [ 2 ] ] = (pgm_output_lines ["p_from" ][:, 1 ] + pgm_output_lines ["p_to" ][:, 1 ]) * 1e-6
1937+ pp_output_lines_3ph [loss_params [ 3 ] ] = (pgm_output_lines ["q_from" ][:, 1 ] + pgm_output_lines ["q_to" ][:, 1 ]) * 1e-6
1938+ pp_output_lines_3ph [loss_params [ 4 ] ] = (pgm_output_lines ["p_from" ][:, 2 ] + pgm_output_lines ["p_to" ][:, 2 ]) * 1e-6
1939+ pp_output_lines_3ph [loss_params [ 5 ] ] = (pgm_output_lines ["q_from" ][:, 2 ] + pgm_output_lines ["q_to" ][:, 2 ]) * 1e-6
19041940 pp_output_lines_3ph ["i_a_from_ka" ] = pgm_output_lines ["i_from" ][:, 0 ] * 1e-3
19051941 pp_output_lines_3ph ["i_b_from_ka" ] = pgm_output_lines ["i_from" ][:, 1 ] * 1e-3
19061942 pp_output_lines_3ph ["i_c_from_ka" ] = pgm_output_lines ["i_from" ][:, 2 ] * 1e-3
@@ -2023,6 +2059,7 @@ def _pp_trafos_output_3ph(self): # pylint: disable=too-many-statements
20232059
20242060 loading = np .maximum (np .maximum (loading_a_percent , loading_b_percent ), loading_c_percent )
20252061
2062+ loss_params = get_loss_params_3ph ()
20262063 pp_output_trafos_3ph = pd .DataFrame (
20272064 columns = [
20282065 "p_a_hv_mw" ,
@@ -2037,12 +2074,12 @@ def _pp_trafos_output_3ph(self): # pylint: disable=too-many-statements
20372074 "q_b_lv_mvar" ,
20382075 "p_c_lv_mw" ,
20392076 "q_c_lv_mvar" ,
2040- "p_a_l_mw" ,
2041- "q_a_l_mvar" ,
2042- "p_b_l_mw" ,
2043- "q_b_l_mvar" ,
2044- "p_c_l_mw" ,
2045- "q_c_l_mvar" ,
2077+ loss_params [ 0 ] ,
2078+ loss_params [ 1 ] ,
2079+ loss_params [ 2 ] ,
2080+ loss_params [ 3 ] ,
2081+ loss_params [ 4 ] ,
2082+ loss_params [ 5 ] ,
20462083 "i_a_hv_ka" ,
20472084 "i_a_lv_ka" ,
20482085 "i_b_hv_ka" ,
@@ -2068,22 +2105,22 @@ def _pp_trafos_output_3ph(self): # pylint: disable=too-many-statements
20682105 pp_output_trafos_3ph ["q_b_lv_mvar" ] = pgm_output_transformers ["q_to" ][:, 1 ] * 1e-6
20692106 pp_output_trafos_3ph ["p_c_lv_mw" ] = pgm_output_transformers ["p_to" ][:, 2 ] * 1e-6
20702107 pp_output_trafos_3ph ["q_c_lv_mvar" ] = pgm_output_transformers ["q_to" ][:, 2 ] * 1e-6
2071- pp_output_trafos_3ph ["p_a_l_mw" ] = (
2108+ pp_output_trafos_3ph [loss_params [ 0 ] ] = (
20722109 pgm_output_transformers ["p_from" ][:, 0 ] + pgm_output_transformers ["p_to" ][:, 0 ]
20732110 ) * 1e-6
2074- pp_output_trafos_3ph ["q_a_l_mvar" ] = (
2111+ pp_output_trafos_3ph [loss_params [ 1 ] ] = (
20752112 pgm_output_transformers ["q_from" ][:, 0 ] + pgm_output_transformers ["q_to" ][:, 0 ]
20762113 ) * 1e-6
2077- pp_output_trafos_3ph ["p_b_l_mw" ] = (
2114+ pp_output_trafos_3ph [loss_params [ 2 ] ] = (
20782115 pgm_output_transformers ["p_from" ][:, 1 ] + pgm_output_transformers ["p_to" ][:, 1 ]
20792116 ) * 1e-6
2080- pp_output_trafos_3ph ["q_b_l_mvar" ] = (
2117+ pp_output_trafos_3ph [loss_params [ 3 ] ] = (
20812118 pgm_output_transformers ["q_from" ][:, 1 ] + pgm_output_transformers ["q_to" ][:, 1 ]
20822119 ) * 1e-6
2083- pp_output_trafos_3ph ["p_c_l_mw" ] = (
2120+ pp_output_trafos_3ph [loss_params [ 4 ] ] = (
20842121 pgm_output_transformers ["p_from" ][:, 2 ] + pgm_output_transformers ["p_to" ][:, 2 ]
20852122 ) * 1e-6
2086- pp_output_trafos_3ph ["q_c_l_mvar" ] = (
2123+ pp_output_trafos_3ph [loss_params [ 5 ] ] = (
20872124 pgm_output_transformers ["q_from" ][:, 2 ] + pgm_output_transformers ["q_to" ][:, 2 ]
20882125 ) * 1e-6
20892126 pp_output_trafos_3ph ["i_a_hv_ka" ] = pgm_output_transformers ["i_from" ][:, 0 ] * 1e-3
@@ -2393,7 +2430,7 @@ def get_switch_states(self, pp_table: str) -> pd.DataFrame:
23932430 else :
23942431 raise KeyError (f"Can't get switch states for { pp_table } " )
23952432
2396- component = self .pp_input_data [pp_table ]
2433+ component = self .pp_input_data [pp_table ]. copy ()
23972434 component ["index" ] = component .index
23982435
23992436 # Select the appropriate switches and columns
0 commit comments