Skip to content

Commit f3baccb

Browse files
committed
officially support pandapower 3.2.0 + resolve comments
Signed-off-by: Martijn Govers <[email protected]>
1 parent ede485a commit f3baccb

File tree

4 files changed

+162
-39
lines changed

4 files changed

+162
-39
lines changed

src/power_grid_model_io/converters/pandapower_converter.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import logging
1010
from functools import lru_cache
11-
from importlib.metadata import version
11+
from importlib.metadata import PackageNotFoundError, version
1212
from typing import Dict, List, MutableMapping, Optional, Tuple, Type
1313

1414
import numpy as np
@@ -36,12 +36,15 @@
3636

3737
logger = structlog.get_logger(__file__)
3838

39-
pp_curr_version = Version(version("pandapower"))
40-
pp_ref_version = Version("3.1.2")
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
4144

4245

4346
def get_loss_params_3ph():
44-
if pp_curr_version <= pp_ref_version:
47+
if PP_CONVERSION_VERSION < PP_COMPATIBILITY_VERSION_3_2_0:
4548
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"]
4649
else:
4750
loss_params = ["pl_a_mw", "ql_a_mvar", "pl_b_mw", "ql_b_mvar", "pl_c_mw", "ql_c_mvar"]
@@ -644,7 +647,7 @@ def _create_pgm_input_sym_loads(self):
644647
data_type=DatasetType.input, component_type=ComponentType.sym_load, shape=3 * n_loads
645648
)
646649

647-
if pp_curr_version <= pp_ref_version:
650+
if PP_CONVERSION_VERSION < PP_COMPATIBILITY_VERSION_3_2_0:
648651
const_i_p_multiplier = (
649652
self._get_pp_attr("load", "const_i_percent", expected_type="f8", default=0) * scaling * (1e-2 * 1e6)
650653
)

tests/data/pandapower/pp_validation.py

Lines changed: 94 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66

77
import pandapower as pp
88

9-
from power_grid_model_io.converters.pandapower_converter import pp_curr_version, pp_ref_version
9+
from power_grid_model_io.converters.pandapower_converter import (
10+
PP_COMPATIBILITY_VERSION_3_2_0,
11+
PP_CONVERSION_VERSION,
12+
)
1013

1114

1215
@lru_cache
@@ -26,7 +29,15 @@ def pp_net() -> pp.pandapowerNet:
2629
pp.create_bus(net, index=105, vn_kv=60)
2730
pp.create_bus(net, index=106, vn_kv=110)
2831
pp.create_ext_grid(
29-
net, index=1, in_service=True, bus=101, vm_pu=1, s_sc_max_mva=1e10, rx_max=0, va_degree=0, r0x0_max=0
32+
net,
33+
index=1,
34+
in_service=True,
35+
bus=101,
36+
vm_pu=1,
37+
s_sc_max_mva=1e10,
38+
rx_max=0,
39+
va_degree=0,
40+
r0x0_max=0,
3041
)
3142
pp.create_transformer_from_parameters(
3243
net,
@@ -51,11 +62,25 @@ def pp_net() -> pp.pandapowerNet:
5162
parallel=2,
5263
)
5364
pp.create_line(
54-
net, index=101, from_bus=103, to_bus=102, length_km=1.23, parallel=2, df=0.2, std_type="NAYY 4x150 SE"
65+
net,
66+
index=101,
67+
from_bus=103,
68+
to_bus=102,
69+
length_km=1.23,
70+
parallel=2,
71+
df=0.2,
72+
std_type="NAYY 4x150 SE",
5573
)
56-
if pp_curr_version <= pp_ref_version:
74+
if PP_CONVERSION_VERSION < PP_COMPATIBILITY_VERSION_3_2_0:
5775
pp.create_load(
58-
net, index=101, bus=103, p_mw=2.5, q_mvar=0.24, const_i_percent=26.0, const_z_percent=51.0, cos_phi=2
76+
net,
77+
index=101,
78+
bus=103,
79+
p_mw=2.5,
80+
q_mvar=0.24,
81+
const_i_percent=26.0,
82+
const_z_percent=51.0,
83+
cos_phi=2,
5984
)
6085
else:
6186
pp.create_load(
@@ -76,14 +101,37 @@ def pp_net() -> pp.pandapowerNet:
76101
pp.create_shunt(net, index=1201, in_service=True, bus=104, p_mw=0.1, q_mvar=0.55, step=3)
77102
pp.create_sgen(net, index=31, bus=105, p_mw=1.21, q_mvar=0.81)
78103
pp.create_asymmetric_sgen(
79-
net, index=32, bus=105, p_a_mw=0.1, p_b_mw=0.2, p_c_mw=3, q_a_mvar=0.01, q_b_mvar=0.01, q_c_mvar=0.01
104+
net,
105+
index=32,
106+
bus=105,
107+
p_a_mw=0.1,
108+
p_b_mw=0.2,
109+
p_c_mw=3,
110+
q_a_mvar=0.01,
111+
q_b_mvar=0.01,
112+
q_c_mvar=0.01,
80113
)
81114
pp.create_asymmetric_load(
82-
net, index=33, bus=105, p_a_mw=0.1, p_b_mw=0.2, p_c_mw=3, q_a_mvar=0.01, q_b_mvar=0.01, q_c_mvar=0.01
115+
net,
116+
index=33,
117+
bus=105,
118+
p_a_mw=0.1,
119+
p_b_mw=0.2,
120+
p_c_mw=3,
121+
q_a_mvar=0.01,
122+
q_b_mvar=0.01,
123+
q_c_mvar=0.01,
83124
)
84125
pp.create_ward(net, index=34, bus=105, ps_mw=0.1, qs_mvar=0.1, pz_mw=0.1, qz_mvar=0.1)
85126
pp.create_motor(
86-
net, bus=105, index=12, pn_mech_mw=0.1, cos_phi=0.9, loading_percent=80, efficiency_percent=90, scaling=0.8
127+
net,
128+
bus=105,
129+
index=12,
130+
pn_mech_mw=0.1,
131+
cos_phi=0.9,
132+
loading_percent=80,
133+
efficiency_percent=90,
134+
scaling=0.8,
87135
)
88136
pp.create_transformer3w_from_parameters(
89137
net,
@@ -143,7 +191,16 @@ def pp_net_3ph() -> pp.pandapowerNet:
143191
pp.create_bus(net, index=103, vn_kv=20)
144192
pp.create_bus(net, index=106, vn_kv=110)
145193
pp.create_ext_grid(
146-
net, index=0, in_service=True, bus=101, vm_pu=1, s_sc_max_mva=1e10, rx_max=0, va_degree=0, r0x0_max=0, x0x_max=1
194+
net,
195+
index=0,
196+
in_service=True,
197+
bus=101,
198+
vm_pu=1,
199+
s_sc_max_mva=1e10,
200+
rx_max=0,
201+
va_degree=0,
202+
r0x0_max=0,
203+
x0x_max=1,
147204
)
148205
pp.create_transformer_from_parameters(
149206
net,
@@ -189,8 +246,16 @@ def pp_net_3ph() -> pp.pandapowerNet:
189246
c0_nf_per_km=261.0,
190247
max_i_ka=0.27,
191248
)
192-
if pp_curr_version <= pp_ref_version:
193-
pp.create_load(net, index=101, bus=103, p_mw=2.5, q_mvar=0.24, const_i_percent=0.0, const_z_percent=0)
249+
if PP_CONVERSION_VERSION < PP_COMPATIBILITY_VERSION_3_2_0:
250+
pp.create_load(
251+
net,
252+
index=101,
253+
bus=103,
254+
p_mw=2.5,
255+
q_mvar=0.24,
256+
const_i_percent=0.0,
257+
const_z_percent=0,
258+
)
194259
else:
195260
pp.create_load(
196261
net,
@@ -208,10 +273,26 @@ def pp_net_3ph() -> pp.pandapowerNet:
208273
pp.create_switch(net, index=321, et="t", bus=101, element=0, closed=True)
209274
pp.create_sgen(net, index=31, bus=103, p_mw=1.21, q_mvar=0.81)
210275
pp.create_asymmetric_sgen(
211-
net, index=32, bus=103, p_a_mw=0.1, p_b_mw=0.2, p_c_mw=3, q_a_mvar=0.01, q_b_mvar=0.01, q_c_mvar=0.01
276+
net,
277+
index=32,
278+
bus=103,
279+
p_a_mw=0.1,
280+
p_b_mw=0.2,
281+
p_c_mw=3,
282+
q_a_mvar=0.01,
283+
q_b_mvar=0.01,
284+
q_c_mvar=0.01,
212285
)
213286
pp.create_asymmetric_load(
214-
net, index=33, bus=103, p_a_mw=0.4, p_b_mw=0.5, p_c_mw=1, q_a_mvar=0.01, q_b_mvar=0.01, q_c_mvar=0.01
287+
net,
288+
index=33,
289+
bus=103,
290+
p_a_mw=0.4,
291+
p_b_mw=0.5,
292+
p_c_mw=1,
293+
q_a_mvar=0.01,
294+
q_b_mvar=0.01,
295+
q_c_mvar=0.01,
215296
)
216297
# TODO Shunt motor ward are not validated.
217298
# pp.create_shunt(net, index=1201, in_service=True, bus=103, p_mw=1, q_mvar=1, step=1)

tests/unit/converters/test_pandapower_converter_input.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@
2222
initialize_array,
2323
)
2424

25-
from power_grid_model_io.converters.pandapower_converter import PandaPowerConverter, pp_curr_version, pp_ref_version
25+
from power_grid_model_io.converters.pandapower_converter import (
26+
PP_COMPATIBILITY_VERSION_3_2_0,
27+
PP_CONVERSION_VERSION,
28+
PandaPowerConverter,
29+
)
2630

2731
from ...utils import MockDf, MockFn, assert_struct_array_equal
2832

@@ -692,7 +696,7 @@ def test_create_pgm_input_sym_loads(mock_init_array: MagicMock, two_pp_objs, con
692696
converter._get_pp_attr.assert_any_call("load", "scaling", expected_type="f8", default=1)
693697
converter._get_pp_attr.assert_any_call("load", "in_service", expected_type="bool", default=True)
694698
converter._get_pp_attr.assert_any_call("load", "type", expected_type="O", default=None)
695-
if pp_curr_version <= pp_ref_version:
699+
if PP_CONVERSION_VERSION < PP_COMPATIBILITY_VERSION_3_2_0:
696700
converter._get_pp_attr.assert_any_call("load", "const_z_percent", expected_type="f8", default=0)
697701
converter._get_pp_attr.assert_any_call("load", "const_i_percent", expected_type="f8", default=0)
698702
assert len(converter._get_pp_attr.call_args_list) == 8

tests/validation/converters/test_pandapower_converter_output.py

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,17 @@
1818

1919
from power_grid_model_io.converters import PandaPowerConverter
2020
from power_grid_model_io.converters.pandapower_converter import (
21+
PP_COMPATIBILITY_VERSION_3_2_0,
22+
PP_CONVERSION_VERSION,
2123
PandaPowerData,
2224
get_loss_params_3ph,
23-
pp_curr_version,
24-
pp_ref_version,
2525
)
2626

27-
from ...data.pandapower.pp_validation import pp_net, pp_net_3ph, pp_net_3ph_minimal_trafo
27+
from ...data.pandapower.pp_validation import (
28+
pp_net,
29+
pp_net_3ph,
30+
pp_net_3ph_minimal_trafo,
31+
)
2832
from ..utils import component_attributes_df, load_json_single_dataset
2933

3034
pp = pytest.importorskip("pandapower", reason="pandapower is not installed")
@@ -33,7 +37,7 @@
3337
PGM_PP_TEST_DATA = Path(__file__).parents[2] / "data" / "pandapower"
3438
PGM_OUTPUT_FILE = PGM_PP_TEST_DATA / "pgm_output_data.json"
3539
PGM_ASYM_OUTPUT_FILE = PGM_PP_TEST_DATA / "pgm_asym_output_data.json"
36-
if pp_curr_version <= pp_ref_version:
40+
if PP_CONVERSION_VERSION < PP_COMPATIBILITY_VERSION_3_2_0:
3741
PP_V2_NET_OUTPUT_FILE = PGM_PP_TEST_DATA / "v3.1.2" / "pp_v2_net_output.json"
3842
PP_V2_NET_3PH_OUTPUT_FILE = PGM_PP_TEST_DATA / "v3.1.2" / "pp_v2_net_3ph_output.json"
3943
PP_V2_NET_3PH_OUTPUT_FILE_CURRENT_LOADING = (
@@ -168,24 +172,33 @@ def check_result(net):
168172
i_c_lv = net.res_trafo_3ph.loc[:, "i_c_lv_ka"] * 1000
169173

170174
np.testing.assert_allclose(
171-
np.maximum(i_a_hv / i_max_hv, i_a_lv / i_max_lv) * 100, net.res_trafo_3ph.loading_a_percent
175+
np.maximum(i_a_hv / i_max_hv, i_a_lv / i_max_lv) * 100,
176+
net.res_trafo_3ph.loading_a_percent,
172177
)
173178
np.testing.assert_allclose(
174-
np.maximum(i_b_hv / i_max_hv, i_b_lv / i_max_lv) * 100, net.res_trafo_3ph.loading_b_percent
179+
np.maximum(i_b_hv / i_max_hv, i_b_lv / i_max_lv) * 100,
180+
net.res_trafo_3ph.loading_b_percent,
175181
)
176182
np.testing.assert_allclose(
177-
np.maximum(i_c_hv / i_max_hv, i_c_lv / i_max_lv) * 100, net.res_trafo_3ph.loading_c_percent
183+
np.maximum(i_c_hv / i_max_hv, i_c_lv / i_max_lv) * 100,
184+
net.res_trafo_3ph.loading_c_percent,
178185
)
179186
np.testing.assert_allclose(
180187
np.maximum(
181-
np.maximum(net.res_trafo_3ph.loading_a_percent, net.res_trafo_3ph.loading_b_percent),
188+
np.maximum(
189+
net.res_trafo_3ph.loading_a_percent,
190+
net.res_trafo_3ph.loading_b_percent,
191+
),
182192
net.res_trafo_3ph.loading_c_percent,
183193
),
184194
net.res_trafo_3ph.loading_percent,
185195
)
186196
np.testing.assert_allclose(
187197
np.maximum(
188-
np.maximum(net.res_line_3ph.loading_a_percent, net.res_line_3ph.loading_b_percent),
198+
np.maximum(
199+
net.res_line_3ph.loading_a_percent,
200+
net.res_line_3ph.loading_b_percent,
201+
),
189202
net.res_line_3ph.loading_c_percent,
190203
),
191204
net.res_line_3ph.loading_percent,
@@ -196,31 +209,49 @@ def compare_result(actual, expected, *, rtol):
196209
np.testing.assert_allclose(actual.trafo.vn_lv_kv, expected.trafo.vn_lv_kv, rtol=rtol)
197210
np.testing.assert_allclose(actual.trafo.sn_mva, expected.trafo.sn_mva, rtol=rtol)
198211
np.testing.assert_allclose(
199-
actual.res_trafo_3ph.loc[:, "i_a_hv_ka"], expected.res_trafo_3ph.loc[:, "i_a_hv_ka"], rtol=rtol
212+
actual.res_trafo_3ph.loc[:, "i_a_hv_ka"],
213+
expected.res_trafo_3ph.loc[:, "i_a_hv_ka"],
214+
rtol=rtol,
200215
)
201216
np.testing.assert_allclose(
202-
actual.res_trafo_3ph.loc[:, "i_b_hv_ka"], expected.res_trafo_3ph.loc[:, "i_b_hv_ka"], rtol=rtol
217+
actual.res_trafo_3ph.loc[:, "i_b_hv_ka"],
218+
expected.res_trafo_3ph.loc[:, "i_b_hv_ka"],
219+
rtol=rtol,
203220
)
204221
np.testing.assert_allclose(
205-
actual.res_trafo_3ph.loc[:, "i_c_hv_ka"], expected.res_trafo_3ph.loc[:, "i_c_hv_ka"], rtol=rtol
222+
actual.res_trafo_3ph.loc[:, "i_c_hv_ka"],
223+
expected.res_trafo_3ph.loc[:, "i_c_hv_ka"],
224+
rtol=rtol,
206225
)
207226
np.testing.assert_allclose(
208-
actual.res_trafo_3ph.loc[:, "i_a_lv_ka"], expected.res_trafo_3ph.loc[:, "i_a_lv_ka"], rtol=rtol
227+
actual.res_trafo_3ph.loc[:, "i_a_lv_ka"],
228+
expected.res_trafo_3ph.loc[:, "i_a_lv_ka"],
229+
rtol=rtol,
209230
)
210231
np.testing.assert_allclose(
211-
actual.res_trafo_3ph.loc[:, "i_b_lv_ka"], expected.res_trafo_3ph.loc[:, "i_b_lv_ka"], rtol=rtol
232+
actual.res_trafo_3ph.loc[:, "i_b_lv_ka"],
233+
expected.res_trafo_3ph.loc[:, "i_b_lv_ka"],
234+
rtol=rtol,
212235
)
213236
np.testing.assert_allclose(
214-
actual.res_trafo_3ph.loc[:, "i_c_lv_ka"], expected.res_trafo_3ph.loc[:, "i_c_lv_ka"], rtol=rtol
237+
actual.res_trafo_3ph.loc[:, "i_c_lv_ka"],
238+
expected.res_trafo_3ph.loc[:, "i_c_lv_ka"],
239+
rtol=rtol,
215240
)
216241
np.testing.assert_allclose(
217-
actual.res_trafo_3ph.loading_a_percent, expected.res_trafo_3ph.loading_a_percent, rtol=rtol
242+
actual.res_trafo_3ph.loading_a_percent,
243+
expected.res_trafo_3ph.loading_a_percent,
244+
rtol=rtol,
218245
)
219246
np.testing.assert_allclose(
220-
actual.res_trafo_3ph.loading_b_percent, expected.res_trafo_3ph.loading_b_percent, rtol=rtol
247+
actual.res_trafo_3ph.loading_b_percent,
248+
expected.res_trafo_3ph.loading_b_percent,
249+
rtol=rtol,
221250
)
222251
np.testing.assert_allclose(
223-
actual.res_trafo_3ph.loading_c_percent, expected.res_trafo_3ph.loading_c_percent, rtol=rtol
252+
actual.res_trafo_3ph.loading_c_percent,
253+
expected.res_trafo_3ph.loading_c_percent,
254+
rtol=rtol,
224255
)
225256

226257
pgm_net = pp_net_3ph_minimal_trafo()
@@ -283,7 +314,11 @@ def test_attributes(output_data: Tuple[PandaPowerData, PandaPowerData], componen
283314

284315

285316
@pytest.mark.parametrize(("component", "attribute"), component_attributes_df(load_and_convert_pgm_data_3ph()))
286-
def test_attributes_3ph(output_data_3ph: Tuple[PandaPowerData, PandaPowerData], component: str, attribute: str):
317+
def test_attributes_3ph(
318+
output_data_3ph: Tuple[PandaPowerData, PandaPowerData],
319+
component: str,
320+
attribute: str,
321+
):
287322
"""
288323
For each attribute, check if the actual values are consistent with the expected values for asym
289324
"""

0 commit comments

Comments
 (0)