power-grid-model-io 1.3.6__py3-none-any.whl → 1.3.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of power-grid-model-io might be problematic. Click here for more details.

@@ -8,7 +8,7 @@ Panda Power Converter
8
8
 
9
9
  import logging
10
10
  from functools import lru_cache
11
- from typing import Dict, List, MutableMapping, Optional, Tuple, Type, Union
11
+ from typing import Dict, List, MutableMapping, Optional, Tuple, Type
12
12
 
13
13
  import numpy as np
14
14
  import pandas as pd
@@ -16,6 +16,7 @@ import structlog
16
16
  from power_grid_model import (
17
17
  Branch3Side,
18
18
  BranchSide,
19
+ ComponentType,
19
20
  DatasetType,
20
21
  LoadGenType,
21
22
  WindingType,
@@ -76,7 +77,7 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
76
77
  def _parse_data(
77
78
  self,
78
79
  data: PandaPowerData,
79
- data_type: str,
80
+ data_type: DatasetType,
80
81
  extra_info: Optional[ExtraInfo] = None,
81
82
  ) -> Dataset:
82
83
  """
@@ -85,7 +86,7 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
85
86
  Args:
86
87
  data: PandaPowerData, i.e. a dictionary with the components as keys and pd.DataFrames as values, with
87
88
  attribute names as columns and their values in the table
88
- data_type: power-grid-model data type, i.e. "input" or "update"
89
+ data_type: power-grid-model data type, i.e. DatasetType.input or DatasetType.update
89
90
  extra_info: an optional dictionary where extra component info (that can't be specified in
90
91
  power-grid-model data) can be specified
91
92
 
@@ -102,7 +103,7 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
102
103
  self.pp_input_data = data
103
104
 
104
105
  # Convert
105
- if data_type == "input":
106
+ if data_type == DatasetType.input:
106
107
  self._create_input_data()
107
108
  else:
108
109
  raise ValueError(f"Data type: '{data_type}' is not implemented")
@@ -148,9 +149,9 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
148
149
  )
149
150
 
150
151
  # Convert
151
- if pgm_output_dtype_checker("sym_output"):
152
+ if pgm_output_dtype_checker(DatasetType.sym_output):
152
153
  self._create_output_data()
153
- elif pgm_output_dtype_checker("asym_output"):
154
+ elif pgm_output_dtype_checker(DatasetType.asym_output):
154
155
  self._create_output_data_3ph()
155
156
  else:
156
157
  raise TypeError("Invalid output data dictionary supplied.")
@@ -314,10 +315,10 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
314
315
  assert not self.pp_input_data
315
316
  assert self.pgm_output_data
316
317
 
317
- if "transformer" not in self.pgm_output_data:
318
+ if ComponentType.transformer not in self.pgm_output_data:
318
319
  return
319
320
 
320
- pgm_ids = self.pgm_output_data["transformer"]["id"]
321
+ pgm_ids = self.pgm_output_data[ComponentType.transformer]["id"]
321
322
  pp_ids = self._get_pp_ids(pp_table="trafo", pgm_idx=pgm_ids)
322
323
  derating_factor = (extra_info.get(pgm_id, {}).get("pp_input", {}).get("df", np.nan) for pgm_id in pgm_ids)
323
324
  self.pp_input_data = {"trafo": pd.DataFrame(derating_factor, columns=["df"], index=pp_ids)}
@@ -332,10 +333,10 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
332
333
  # so let's create a global lookup table (indexed on the pgm ids)
333
334
  self.pgm_nodes_lookup = pd.DataFrame(
334
335
  {
335
- "u_pu": self.pgm_output_data["node"]["u_pu"],
336
- "u_degree": self.pgm_output_data["node"]["u_angle"] * (180.0 / np.pi),
336
+ "u_pu": self.pgm_output_data[ComponentType.node]["u_pu"],
337
+ "u_degree": self.pgm_output_data[ComponentType.node]["u_angle"] * (180.0 / np.pi),
337
338
  },
338
- index=self.pgm_output_data["node"]["id"],
339
+ index=self.pgm_output_data[ComponentType.node]["id"],
339
340
  )
340
341
 
341
342
  self._pp_buses_output()
@@ -380,12 +381,14 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
380
381
  if pp_busses.empty:
381
382
  return
382
383
 
383
- pgm_nodes = initialize_array(data_type="input", component_type="node", shape=len(pp_busses))
384
+ pgm_nodes = initialize_array(
385
+ data_type=DatasetType.input, component_type=ComponentType.node, shape=len(pp_busses)
386
+ )
384
387
  pgm_nodes["id"] = self._generate_ids("bus", pp_busses.index)
385
388
  pgm_nodes["u_rated"] = self._get_pp_attr("bus", "vn_kv", expected_type="f8") * 1e3
386
389
 
387
- assert "node" not in self.pgm_input_data
388
- self.pgm_input_data["node"] = pgm_nodes
390
+ assert ComponentType.node not in self.pgm_input_data
391
+ self.pgm_input_data[ComponentType.node] = pgm_nodes
389
392
 
390
393
  def _create_pgm_input_lines(self):
391
394
  """
@@ -407,7 +410,9 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
407
410
  c0_nf_per_km = self._get_pp_attr("line", "c0_nf_per_km", expected_type="f8", default=np.nan)
408
411
  multiplier = length_km / parallel
409
412
 
410
- pgm_lines = initialize_array(data_type="input", component_type="line", shape=len(pp_lines))
413
+ pgm_lines = initialize_array(
414
+ data_type=DatasetType.input, component_type=ComponentType.line, shape=len(pp_lines)
415
+ )
411
416
  pgm_lines["id"] = self._generate_ids("line", pp_lines.index)
412
417
  pgm_lines["from_node"] = self._get_pgm_ids("bus", self._get_pp_attr("line", "from_bus", expected_type="u4"))
413
418
  pgm_lines["from_status"] = in_service & switch_states["from"]
@@ -435,8 +440,8 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
435
440
  / c0_nf_per_km
436
441
  / (2 * np.pi * self.system_frequency * 1e-3)
437
442
  )
438
- assert "line" not in self.pgm_input_data
439
- self.pgm_input_data["line"] = pgm_lines
443
+ assert ComponentType.line not in self.pgm_input_data
444
+ self.pgm_input_data[ComponentType.line] = pgm_lines
440
445
 
441
446
  def _create_pgm_input_sources(self):
442
447
  """
@@ -463,7 +468,9 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
463
468
  failed_checks = ", ".join([key for key, value in checks.items() if not value])
464
469
  logger.warning("Zero sequence parameters given in external grid shall be ignored: %s", failed_checks)
465
470
 
466
- pgm_sources = initialize_array(data_type="input", component_type="source", shape=len(pp_ext_grid))
471
+ pgm_sources = initialize_array(
472
+ data_type=DatasetType.input, component_type=ComponentType.source, shape=len(pp_ext_grid)
473
+ )
467
474
  pgm_sources["id"] = self._generate_ids("ext_grid", pp_ext_grid.index)
468
475
  pgm_sources["node"] = self._get_pgm_ids("bus", self._get_pp_attr("ext_grid", "bus", expected_type="u4"))
469
476
  pgm_sources["status"] = self._get_pp_attr("ext_grid", "in_service", expected_type="bool", default=True)
@@ -474,8 +481,8 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
474
481
  )
475
482
  pgm_sources["sk"] = self._get_pp_attr("ext_grid", "s_sc_max_mva", expected_type="f8", default=np.nan) * 1e6
476
483
 
477
- assert "source" not in self.pgm_input_data
478
- self.pgm_input_data["source"] = pgm_sources
484
+ assert ComponentType.source not in self.pgm_input_data
485
+ self.pgm_input_data[ComponentType.source] = pgm_sources
479
486
 
480
487
  def _create_pgm_input_shunts(self):
481
488
  """
@@ -496,7 +503,9 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
496
503
  g1_shunt = self._get_pp_attr("shunt", "p_mw", expected_type="f8") * step / vn_kv_2
497
504
  b1_shunt = -self._get_pp_attr("shunt", "q_mvar", expected_type="f8") * step / vn_kv_2
498
505
 
499
- pgm_shunts = initialize_array(data_type="input", component_type="shunt", shape=len(pp_shunts))
506
+ pgm_shunts = initialize_array(
507
+ data_type=DatasetType.input, component_type=ComponentType.shunt, shape=len(pp_shunts)
508
+ )
500
509
  pgm_shunts["id"] = self._generate_ids("shunt", pp_shunts.index)
501
510
  pgm_shunts["node"] = self._get_pgm_ids("bus", self._get_pp_attr("shunt", "bus", expected_type="u4"))
502
511
  pgm_shunts["status"] = self._get_pp_attr("shunt", "in_service", expected_type="bool", default=True)
@@ -505,8 +514,8 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
505
514
  pgm_shunts["g0"] = g1_shunt
506
515
  pgm_shunts["b0"] = b1_shunt
507
516
 
508
- assert "shunt" not in self.pgm_input_data
509
- self.pgm_input_data["shunt"] = pgm_shunts
517
+ assert ComponentType.shunt not in self.pgm_input_data
518
+ self.pgm_input_data[ComponentType.shunt] = pgm_shunts
510
519
 
511
520
  def _create_pgm_input_sym_gens(self):
512
521
  """
@@ -523,7 +532,9 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
523
532
 
524
533
  scaling = self._get_pp_attr("sgen", "scaling", expected_type="f8", default=1.0)
525
534
 
526
- pgm_sym_gens = initialize_array(data_type="input", component_type="sym_gen", shape=len(pp_sgens))
535
+ pgm_sym_gens = initialize_array(
536
+ data_type=DatasetType.input, component_type=ComponentType.sym_gen, shape=len(pp_sgens)
537
+ )
527
538
  pgm_sym_gens["id"] = self._generate_ids("sgen", pp_sgens.index)
528
539
  pgm_sym_gens["node"] = self._get_pgm_ids("bus", self._get_pp_attr("sgen", "bus", expected_type="i8"))
529
540
  pgm_sym_gens["status"] = self._get_pp_attr("sgen", "in_service", expected_type="bool", default=True)
@@ -533,8 +544,8 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
533
544
  )
534
545
  pgm_sym_gens["type"] = LoadGenType.const_power
535
546
 
536
- assert "sym_gen" not in self.pgm_input_data
537
- self.pgm_input_data["sym_gen"] = pgm_sym_gens
547
+ assert ComponentType.sym_gen not in self.pgm_input_data
548
+ self.pgm_input_data[ComponentType.sym_gen] = pgm_sym_gens
538
549
 
539
550
  def _create_pgm_input_asym_gens(self):
540
551
  """
@@ -553,7 +564,9 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
553
564
  scaling = self._get_pp_attr("asymmetric_sgen", "scaling", expected_type="f8")
554
565
  multiplier = 1e6 * scaling
555
566
 
556
- pgm_asym_gens = initialize_array(data_type="input", component_type="asym_gen", shape=len(pp_asym_gens))
567
+ pgm_asym_gens = initialize_array(
568
+ data_type=DatasetType.input, component_type=ComponentType.asym_gen, shape=len(pp_asym_gens)
569
+ )
557
570
  pgm_asym_gens["id"] = self._generate_ids("asymmetric_sgen", pp_asym_gens.index)
558
571
  pgm_asym_gens["node"] = self._get_pgm_ids(
559
572
  "bus", self._get_pp_attr("asymmetric_sgen", "bus", expected_type="i8")
@@ -582,7 +595,7 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
582
595
  pgm_asym_gens["type"] = LoadGenType.const_power
583
596
 
584
597
  assert "asym_gen" not in self.pgm_input_data
585
- self.pgm_input_data["asym_gen"] = pgm_asym_gens
598
+ self.pgm_input_data[ComponentType.asym_gen] = pgm_asym_gens
586
599
 
587
600
  def _create_pgm_input_sym_loads(self):
588
601
  """
@@ -609,7 +622,9 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
609
622
 
610
623
  n_loads = len(pp_loads)
611
624
 
612
- pgm_sym_loads = initialize_array(data_type="input", component_type="sym_load", shape=3 * n_loads)
625
+ pgm_sym_loads = initialize_array(
626
+ data_type=DatasetType.input, component_type=ComponentType.sym_load, shape=3 * n_loads
627
+ )
613
628
 
614
629
  const_i_multiplier = (
615
630
  self._get_pp_attr("load", "const_i_percent", expected_type="f8", default=0) * scaling * (1e-2 * 1e6)
@@ -640,8 +655,8 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
640
655
  pgm_sym_loads["p_specified"][-n_loads:] = const_i_multiplier * p_mw
641
656
  pgm_sym_loads["q_specified"][-n_loads:] = const_i_multiplier * q_mvar
642
657
 
643
- assert "sym_load" not in self.pgm_input_data
644
- self.pgm_input_data["sym_load"] = pgm_sym_loads
658
+ assert ComponentType.sym_load not in self.pgm_input_data
659
+ self.pgm_input_data[ComponentType.sym_load] = pgm_sym_loads
645
660
 
646
661
  def _create_pgm_input_asym_loads(self):
647
662
  """
@@ -662,7 +677,9 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
662
677
  scaling = self._get_pp_attr("asymmetric_load", "scaling", expected_type="f8")
663
678
  multiplier = 1e6 * scaling
664
679
 
665
- pgm_asym_loads = initialize_array(data_type="input", component_type="asym_load", shape=len(pp_asym_loads))
680
+ pgm_asym_loads = initialize_array(
681
+ data_type=DatasetType.input, component_type=ComponentType.asym_load, shape=len(pp_asym_loads)
682
+ )
666
683
  pgm_asym_loads["id"] = self._generate_ids("asymmetric_load", pp_asym_loads.index)
667
684
  pgm_asym_loads["node"] = self._get_pgm_ids(
668
685
  "bus", self._get_pp_attr("asymmetric_load", "bus", expected_type="u4")
@@ -692,8 +709,8 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
692
709
  )
693
710
  pgm_asym_loads["type"] = LoadGenType.const_power
694
711
 
695
- assert "asym_load" not in self.pgm_input_data
696
- self.pgm_input_data["asym_load"] = pgm_asym_loads
712
+ assert ComponentType.asym_load not in self.pgm_input_data
713
+ self.pgm_input_data[ComponentType.asym_load] = pgm_asym_loads
697
714
 
698
715
  def _create_pgm_input_transformers(self): # pylint: disable=too-many-statements, disable-msg=too-many-locals
699
716
  """
@@ -769,7 +786,9 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
769
786
  winding_types.loc[no_vector_groups_dyn, "winding_from"] = WindingType.delta
770
787
 
771
788
  # Create PGM array
772
- pgm_transformers = initialize_array(data_type="input", component_type="transformer", shape=len(pp_trafo))
789
+ pgm_transformers = initialize_array(
790
+ data_type=DatasetType.input, component_type=ComponentType.transformer, shape=len(pp_trafo)
791
+ )
773
792
  pgm_transformers["id"] = self._generate_ids("trafo", pp_trafo.index)
774
793
  pgm_transformers["from_node"] = self._get_pgm_ids(
775
794
  "bus", self._get_pp_attr("trafo", "hv_bus", expected_type="u4")
@@ -798,8 +817,8 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
798
817
  pgm_transformers["tap_max"] = self._get_pp_attr("trafo", "tap_max", expected_type="i4", default=0)
799
818
  pgm_transformers["tap_size"] = tap_size
800
819
 
801
- assert "transformer" not in self.pgm_input_data
802
- self.pgm_input_data["transformer"] = pgm_transformers
820
+ assert ComponentType.transformer not in self.pgm_input_data
821
+ self.pgm_input_data[ComponentType.transformer] = pgm_transformers
803
822
 
804
823
  def _create_pgm_input_three_winding_transformers(self):
805
824
  # pylint: disable=too-many-statements, disable-msg=too-many-locals
@@ -884,8 +903,8 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
884
903
  winding_types.loc[no_vector_groups_ynd3, "winding_3"] = WindingType.delta
885
904
 
886
905
  pgm_3wtransformers = initialize_array(
887
- data_type="input",
888
- component_type="three_winding_transformer",
906
+ data_type=DatasetType.input,
907
+ component_type=ComponentType.three_winding_transformer,
889
908
  shape=len(pp_trafo3w),
890
909
  )
891
910
  pgm_3wtransformers["id"] = self._generate_ids("trafo3w", pp_trafo3w.index)
@@ -934,8 +953,8 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
934
953
  pgm_3wtransformers["tap_max"] = self._get_pp_attr("trafo3w", "tap_max", expected_type="i4", default=0)
935
954
  pgm_3wtransformers["tap_size"] = tap_size
936
955
 
937
- assert "three_winding_transformer" not in self.pgm_input_data
938
- self.pgm_input_data["three_winding_transformer"] = pgm_3wtransformers
956
+ assert ComponentType.three_winding_transformer not in self.pgm_input_data
957
+ self.pgm_input_data[ComponentType.three_winding_transformer] = pgm_3wtransformers
939
958
 
940
959
  def _create_pgm_input_links(self):
941
960
  """
@@ -953,15 +972,17 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
953
972
  # This should take all the switches which are b2b
954
973
  pp_switches = pp_switches[pp_switches["et"] == "b"]
955
974
 
956
- pgm_links = initialize_array(data_type="input", component_type="link", shape=len(pp_switches))
975
+ pgm_links = initialize_array(
976
+ data_type=DatasetType.input, component_type=ComponentType.link, shape=len(pp_switches)
977
+ )
957
978
  pgm_links["id"] = self._generate_ids("switch", pp_switches.index, name="b2b_switches")
958
979
  pgm_links["from_node"] = self._get_pgm_ids("bus", pp_switches["bus"])
959
980
  pgm_links["to_node"] = self._get_pgm_ids("bus", pp_switches["element"])
960
981
  pgm_links["from_status"] = pp_switches["closed"]
961
982
  pgm_links["to_status"] = pp_switches["closed"]
962
983
 
963
- assert "link" not in self.pgm_input_data
964
- self.pgm_input_data["link"] = pgm_links
984
+ assert ComponentType.link not in self.pgm_input_data
985
+ self.pgm_input_data[ComponentType.link] = pgm_links
965
986
 
966
987
  def _create_pgm_input_storages(self):
967
988
  # TODO: create unit tests for the function
@@ -993,7 +1014,9 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
993
1014
  in_service = self._get_pp_attr("ward", "in_service", expected_type="bool", default=True)
994
1015
  bus = self._get_pp_attr("ward", "bus", expected_type="u4")
995
1016
 
996
- pgm_sym_loads_from_ward = initialize_array(data_type="input", component_type="sym_load", shape=n_wards * 2)
1017
+ pgm_sym_loads_from_ward = initialize_array(
1018
+ data_type=DatasetType.input, component_type=ComponentType.sym_load, shape=n_wards * 2
1019
+ )
997
1020
  pgm_sym_loads_from_ward["id"][:n_wards] = self._generate_ids(
998
1021
  "ward", pp_wards.index, name="ward_const_power_load"
999
1022
  )
@@ -1018,14 +1041,14 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1018
1041
 
1019
1042
  # If input data of loads has already been filled then extend it with data of wards. If it is empty and there
1020
1043
  # is no data about loads,then assign ward data to it
1021
- if "sym_load" in self.pgm_input_data:
1022
- symload_dtype = self.pgm_input_data["sym_load"].dtype
1023
- self.pgm_input_data["sym_load"] = np.concatenate( # pylint: disable=unexpected-keyword-arg
1024
- [self.pgm_input_data["sym_load"], pgm_sym_loads_from_ward],
1044
+ if ComponentType.sym_load in self.pgm_input_data:
1045
+ symload_dtype = self.pgm_input_data[ComponentType.sym_load].dtype
1046
+ self.pgm_input_data[ComponentType.sym_load] = np.concatenate( # pylint: disable=unexpected-keyword-arg
1047
+ [self.pgm_input_data[ComponentType.sym_load], pgm_sym_loads_from_ward],
1025
1048
  dtype=symload_dtype,
1026
1049
  )
1027
1050
  else:
1028
- self.pgm_input_data["sym_load"] = pgm_sym_loads_from_ward
1051
+ self.pgm_input_data[ComponentType.sym_load] = pgm_sym_loads_from_ward
1029
1052
 
1030
1053
  def _create_pgm_input_xwards(self):
1031
1054
  # TODO: create unit tests for the function
@@ -1043,7 +1066,9 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1043
1066
  if pp_motors.empty:
1044
1067
  return
1045
1068
 
1046
- pgm_sym_loads_from_motor = initialize_array(data_type="input", component_type="sym_load", shape=len(pp_motors))
1069
+ pgm_sym_loads_from_motor = initialize_array(
1070
+ data_type=DatasetType.input, component_type=ComponentType.sym_load, shape=len(pp_motors)
1071
+ )
1047
1072
  pgm_sym_loads_from_motor["id"] = self._generate_ids("motor", pp_motors.index, name="motor_load")
1048
1073
  pgm_sym_loads_from_motor["node"] = self._get_pgm_ids(
1049
1074
  "bus", self._get_pp_attr("motor", "bus", expected_type="i8")
@@ -1072,14 +1097,14 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1072
1097
 
1073
1098
  # If input data of loads has already been filled then extend it with data of motors. If it is empty and there
1074
1099
  # is no data about loads,then assign motor data to it
1075
- if "sym_load" in self.pgm_input_data:
1076
- symload_dtype = self.pgm_input_data["sym_load"].dtype
1077
- self.pgm_input_data["sym_load"] = np.concatenate( # pylint: disable=unexpected-keyword-arg
1078
- [self.pgm_input_data["sym_load"], pgm_sym_loads_from_motor],
1100
+ if ComponentType.sym_load in self.pgm_input_data:
1101
+ symload_dtype = self.pgm_input_data[ComponentType.sym_load].dtype
1102
+ self.pgm_input_data[ComponentType.sym_load] = np.concatenate( # pylint: disable=unexpected-keyword-arg
1103
+ [self.pgm_input_data[ComponentType.sym_load], pgm_sym_loads_from_motor],
1079
1104
  dtype=symload_dtype,
1080
1105
  )
1081
1106
  else:
1082
- self.pgm_input_data["sym_load"] = pgm_sym_loads_from_motor
1107
+ self.pgm_input_data[ComponentType.sym_load] = pgm_sym_loads_from_motor
1083
1108
 
1084
1109
  def _create_pgm_input_dclines(self):
1085
1110
  # TODO: create unit tests for the function
@@ -1109,10 +1134,10 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1109
1134
  # TODO: create unit tests for the function
1110
1135
  assert "res_bus" not in self.pp_output_data
1111
1136
 
1112
- if "node" not in self.pgm_output_data or self.pgm_output_data["node"].size == 0:
1137
+ if ComponentType.node not in self.pgm_output_data or self.pgm_output_data[ComponentType.node].size == 0:
1113
1138
  return
1114
1139
 
1115
- pgm_nodes = self.pgm_output_data["node"]
1140
+ pgm_nodes = self.pgm_output_data[ComponentType.node]
1116
1141
 
1117
1142
  pp_output_buses = pd.DataFrame(
1118
1143
  columns=["vm_pu", "va_degree", "p_mw", "q_mvar"],
@@ -1203,11 +1228,11 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1203
1228
  # TODO: create unit tests for the function
1204
1229
  assert "res_line" not in self.pp_output_data
1205
1230
 
1206
- if "line" not in self.pgm_output_data or self.pgm_output_data["line"].size == 0:
1231
+ if ComponentType.line not in self.pgm_output_data or self.pgm_output_data[ComponentType.line].size == 0:
1207
1232
  return
1208
1233
 
1209
- pgm_input_lines = self.pgm_input_data["line"]
1210
- pgm_output_lines = self.pgm_output_data["line"]
1234
+ pgm_input_lines = self.pgm_input_data[ComponentType.line]
1235
+ pgm_output_lines = self.pgm_output_data[ComponentType.line]
1211
1236
 
1212
1237
  if not np.array_equal(pgm_input_lines["id"], pgm_output_lines["id"]):
1213
1238
  raise ValueError("The output line ids should correspond to the input line ids")
@@ -1229,7 +1254,7 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1229
1254
  "va_to_degree",
1230
1255
  "loading_percent",
1231
1256
  ],
1232
- index=self._get_pp_ids("line", pgm_output_lines["id"]),
1257
+ index=self._get_pp_ids(ComponentType.line, pgm_output_lines["id"]),
1233
1258
  )
1234
1259
 
1235
1260
  from_nodes = self.pgm_nodes_lookup.loc[pgm_input_lines["from_node"]]
@@ -1261,10 +1286,10 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1261
1286
  """
1262
1287
  assert "res_ext_grid" not in self.pp_output_data
1263
1288
 
1264
- if "source" not in self.pgm_output_data or self.pgm_output_data["source"].size == 0:
1289
+ if ComponentType.source not in self.pgm_output_data or self.pgm_output_data[ComponentType.source].size == 0:
1265
1290
  return
1266
1291
 
1267
- pgm_output_sources = self.pgm_output_data["source"]
1292
+ pgm_output_sources = self.pgm_output_data[ComponentType.source]
1268
1293
 
1269
1294
  pp_output_ext_grids = pd.DataFrame(
1270
1295
  columns=["p_mw", "q_mvar"],
@@ -1285,12 +1310,12 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1285
1310
  # TODO: create unit tests for the function
1286
1311
  assert "res_shunt" not in self.pp_output_data
1287
1312
 
1288
- if "shunt" not in self.pgm_output_data or self.pgm_output_data["shunt"].size == 0:
1313
+ if ComponentType.shunt not in self.pgm_output_data or self.pgm_output_data[ComponentType.shunt].size == 0:
1289
1314
  return
1290
1315
 
1291
- pgm_input_shunts = self.pgm_input_data["shunt"]
1316
+ pgm_input_shunts = self.pgm_input_data[ComponentType.shunt]
1292
1317
 
1293
- pgm_output_shunts = self.pgm_output_data["shunt"]
1318
+ pgm_output_shunts = self.pgm_output_data[ComponentType.shunt]
1294
1319
 
1295
1320
  at_nodes = self.pgm_nodes_lookup.loc[pgm_input_shunts["node"]]
1296
1321
 
@@ -1314,10 +1339,10 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1314
1339
  """
1315
1340
  assert "res_sgen" not in self.pp_output_data
1316
1341
 
1317
- if "sym_gen" not in self.pgm_output_data or self.pgm_output_data["sym_gen"].size == 0:
1342
+ if ComponentType.sym_gen not in self.pgm_output_data or self.pgm_output_data[ComponentType.sym_gen].size == 0:
1318
1343
  return
1319
1344
 
1320
- pgm_output_sym_gens = self.pgm_output_data["sym_gen"]
1345
+ pgm_output_sym_gens = self.pgm_output_data[ComponentType.sym_gen]
1321
1346
 
1322
1347
  pp_output_sgens = pd.DataFrame(
1323
1348
  columns=["p_mw", "q_mvar"],
@@ -1339,14 +1364,15 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1339
1364
  # TODO: create unit tests for the function
1340
1365
  assert "res_trafo" not in self.pp_output_data
1341
1366
 
1342
- if ("transformer" not in self.pgm_output_data or self.pgm_output_data["transformer"].size == 0) or (
1343
- "trafo" not in self.pp_input_data or len(self.pp_input_data["trafo"]) == 0
1344
- ):
1367
+ if (
1368
+ ComponentType.transformer not in self.pgm_output_data
1369
+ or self.pgm_output_data[ComponentType.transformer].size == 0
1370
+ ) or ("trafo" not in self.pp_input_data or len(self.pp_input_data["trafo"]) == 0):
1345
1371
  return
1346
1372
 
1347
- pgm_input_transformers = self.pgm_input_data["transformer"]
1373
+ pgm_input_transformers = self.pgm_input_data[ComponentType.transformer]
1348
1374
  pp_input_transformers = self.pp_input_data["trafo"]
1349
- pgm_output_transformers = self.pgm_output_data["transformer"]
1375
+ pgm_output_transformers = self.pgm_output_data[ComponentType.transformer]
1350
1376
 
1351
1377
  from_nodes = self.pgm_nodes_lookup.loc[pgm_input_transformers["from_node"]]
1352
1378
  to_nodes = self.pgm_nodes_lookup.loc[pgm_input_transformers["to_node"]]
@@ -1408,14 +1434,14 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1408
1434
  assert "res_trafo3w" not in self.pp_output_data
1409
1435
 
1410
1436
  if (
1411
- "three_winding_transformer" not in self.pgm_output_data
1412
- or self.pgm_output_data["three_winding_transformer"].size == 0
1437
+ ComponentType.three_winding_transformer not in self.pgm_output_data
1438
+ or self.pgm_output_data[ComponentType.three_winding_transformer].size == 0
1413
1439
  ):
1414
1440
  return
1415
1441
 
1416
- pgm_input_transformers3w = self.pgm_input_data["three_winding_transformer"]
1442
+ pgm_input_transformers3w = self.pgm_input_data[ComponentType.three_winding_transformer]
1417
1443
 
1418
- pgm_output_transformers3w = self.pgm_output_data["three_winding_transformer"]
1444
+ pgm_output_transformers3w = self.pgm_output_data[ComponentType.three_winding_transformer]
1419
1445
 
1420
1446
  nodes_1 = self.pgm_nodes_lookup.loc[pgm_input_transformers3w["node_1"]]
1421
1447
  nodes_2 = self.pgm_nodes_lookup.loc[pgm_input_transformers3w["node_2"]]
@@ -1481,10 +1507,13 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1481
1507
  # TODO: create unit tests for the function
1482
1508
  assert "res_asymmetric_load" not in self.pp_output_data
1483
1509
 
1484
- if "asym_load" not in self.pgm_output_data or self.pgm_output_data["asym_load"].size == 0:
1510
+ if (
1511
+ ComponentType.asym_load not in self.pgm_output_data
1512
+ or self.pgm_output_data[ComponentType.asym_load].size == 0
1513
+ ):
1485
1514
  return
1486
1515
 
1487
- pgm_output_asym_loads = self.pgm_output_data["asym_load"]
1516
+ pgm_output_asym_loads = self.pgm_output_data[ComponentType.asym_load]
1488
1517
 
1489
1518
  pp_asym_output_loads = pd.DataFrame(
1490
1519
  columns=["p_mw", "q_mvar"],
@@ -1507,10 +1536,10 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1507
1536
  # TODO: create unit tests for the function
1508
1537
  assert "res_asymmetric_sgen" not in self.pp_output_data
1509
1538
 
1510
- if "asym_gen" not in self.pgm_output_data or self.pgm_output_data["asym_gen"].size == 0:
1539
+ if ComponentType.asym_gen not in self.pgm_output_data or self.pgm_output_data[ComponentType.asym_gen].size == 0:
1511
1540
  return
1512
1541
 
1513
- pgm_output_asym_gens = self.pgm_output_data["asym_gen"]
1542
+ pgm_output_asym_gens = self.pgm_output_data[ComponentType.asym_gen]
1514
1543
 
1515
1544
  pp_output_asym_gens = pd.DataFrame(
1516
1545
  columns=["p_mw", "q_mvar"],
@@ -1533,8 +1562,8 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1533
1562
  assert "res_load" not in self.pp_output_data
1534
1563
 
1535
1564
  if (
1536
- "sym_load" not in self.pgm_output_data
1537
- or self.pgm_output_data["sym_load"].size == 0
1565
+ ComponentType.sym_load not in self.pgm_output_data
1566
+ or self.pgm_output_data[ComponentType.sym_load].size == 0
1538
1567
  or ("load", load_id_names[0]) not in self.idx
1539
1568
  ):
1540
1569
  return
@@ -1550,8 +1579,8 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1550
1579
  assert "res_ward" not in self.pp_output_data
1551
1580
 
1552
1581
  if (
1553
- "sym_load" not in self.pgm_output_data
1554
- or self.pgm_output_data["sym_load"].size == 0
1582
+ ComponentType.sym_load not in self.pgm_output_data
1583
+ or self.pgm_output_data[ComponentType.sym_load].size == 0
1555
1584
  or ("ward", load_id_names[0]) not in self.idx
1556
1585
  ):
1557
1586
  return
@@ -1570,8 +1599,8 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1570
1599
  assert "res_motor" not in self.pp_output_data
1571
1600
 
1572
1601
  if (
1573
- "sym_load" not in self.pgm_output_data
1574
- or self.pgm_output_data["sym_load"].size == 0
1602
+ ComponentType.sym_load not in self.pgm_output_data
1603
+ or self.pgm_output_data[ComponentType.sym_load].size == 0
1575
1604
  or ("motor", load_id_names[0]) not in self.idx
1576
1605
  ):
1577
1606
  return
@@ -1591,7 +1620,7 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1591
1620
  a PandaPower Dataframe for the Load component
1592
1621
  """
1593
1622
  # Create a DataFrame wih all the pgm output loads and index it in the pgm id
1594
- pgm_output_loads = self.pgm_output_data["sym_load"]
1623
+ pgm_output_loads = self.pgm_output_data[ComponentType.sym_load]
1595
1624
  # Sum along rows for asym output
1596
1625
  active_power = pgm_output_loads["p"].sum(axis=1) if pgm_output_loads["p"].ndim == 2 else pgm_output_loads["p"]
1597
1626
  reactive_power = pgm_output_loads["q"].sum(axis=1) if pgm_output_loads["q"].ndim == 2 else pgm_output_loads["q"]
@@ -1624,7 +1653,9 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1624
1653
  Switch results are only possible at round conversions. ie, input switch data is available
1625
1654
  """
1626
1655
  switch_data_unavailable = "switch" not in self.pp_input_data
1627
- links_absent = "link" not in self.pgm_output_data or self.pgm_output_data["link"].size == 0
1656
+ links_absent = (
1657
+ ComponentType.link not in self.pgm_output_data or self.pgm_output_data[ComponentType.link].size == 0
1658
+ )
1628
1659
  rest_switches_absent = {
1629
1660
  pp_comp: ("res_" + pp_comp not in self.pp_output_data) for pp_comp in ["line", "trafo", "trafo3w"]
1630
1661
  }
@@ -1677,7 +1708,7 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1677
1708
 
1678
1709
  # For et=b, ie bus to bus switches, links are created. get result from them
1679
1710
  if not links_absent:
1680
- links = self.pgm_output_data["link"]
1711
+ links = self.pgm_output_data[ComponentType.link]
1681
1712
  # For links, i_from = i_to = i_ka / 1e3
1682
1713
  link_ids = self._get_pp_ids("switch", links["id"], "b2b_switches")
1683
1714
  pp_switches_output.loc[link_ids, "i_ka"] = links["i_from"] * 1e-3
@@ -1692,10 +1723,10 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1692
1723
  Returns:
1693
1724
  a PandaPower Dataframe for the Bus component
1694
1725
  """
1695
- if "node" not in self.pgm_output_data or self.pgm_output_data["node"].size == 0:
1726
+ if ComponentType.node not in self.pgm_output_data or self.pgm_output_data[ComponentType.node].size == 0:
1696
1727
  return
1697
1728
 
1698
- pgm_nodes = self.pgm_output_data["node"]
1729
+ pgm_nodes = self.pgm_output_data[ComponentType.node]
1699
1730
 
1700
1731
  pp_output_buses_3ph = pd.DataFrame(
1701
1732
  columns=[
@@ -1813,16 +1844,19 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1813
1844
  Returns:
1814
1845
  a PandaPower Dataframe for the Line component
1815
1846
  """
1816
- if any((comp not in self.pgm_output_data or self.pgm_output_data[comp].size == 0) for comp in ["node", "line"]):
1847
+ if any(
1848
+ (comp not in self.pgm_output_data or self.pgm_output_data[comp].size == 0)
1849
+ for comp in [ComponentType.node, ComponentType.line]
1850
+ ):
1817
1851
  return
1818
1852
 
1819
- pgm_input_lines = self.pgm_input_data["line"]
1820
- pgm_output_lines = self.pgm_output_data["line"]
1821
- pgm_output_nodes = self.pgm_output_data["node"]
1853
+ pgm_input_lines = self.pgm_input_data[ComponentType.line]
1854
+ pgm_output_lines = self.pgm_output_data[ComponentType.line]
1855
+ pgm_output_nodes = self.pgm_output_data[ComponentType.node]
1822
1856
 
1823
1857
  u_complex = pd.DataFrame(
1824
1858
  pgm_output_nodes["u"] * np.exp(1j * pgm_output_nodes["u_angle"]),
1825
- index=self.pgm_output_data["node"]["id"],
1859
+ index=self.pgm_output_data[ComponentType.node]["id"],
1826
1860
  )
1827
1861
  from_nodes = pgm_input_lines["from_node"]
1828
1862
  to_nodes = pgm_input_lines["to_node"]
@@ -1920,10 +1954,10 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1920
1954
  Returns:
1921
1955
  a PandaPower Dataframe for the External Grid component
1922
1956
  """
1923
- if "source" not in self.pgm_output_data or self.pgm_output_data["source"].size == 0:
1957
+ if ComponentType.source not in self.pgm_output_data or self.pgm_output_data[ComponentType.source].size == 0:
1924
1958
  return
1925
1959
 
1926
- pgm_output_sources = self.pgm_output_data["source"]
1960
+ pgm_output_sources = self.pgm_output_data[ComponentType.source]
1927
1961
 
1928
1962
  pp_output_ext_grids_3ph = pd.DataFrame(
1929
1963
  columns=["p_a_mw", "q_a_mvar", "p_b_mw", "q_b_mvar", "p_c_mw", "q_c_mvar"],
@@ -1947,10 +1981,10 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1947
1981
  Returns:
1948
1982
  a PandaPower Dataframe for the Static Generator component
1949
1983
  """
1950
- if "sym_gen" not in self.pgm_output_data or self.pgm_output_data["sym_gen"].size == 0:
1984
+ if ComponentType.sym_gen not in self.pgm_output_data or self.pgm_output_data[ComponentType.sym_gen].size == 0:
1951
1985
  return
1952
1986
 
1953
- pgm_output_sym_gens = self.pgm_output_data["sym_gen"]
1987
+ pgm_output_sym_gens = self.pgm_output_data[ComponentType.sym_gen]
1954
1988
 
1955
1989
  pp_output_sgens = pd.DataFrame(
1956
1990
  columns=["p_mw", "q_mvar"],
@@ -1970,14 +2004,15 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
1970
2004
  Returns:
1971
2005
  a PandaPower Dataframe for the Transformer component
1972
2006
  """
1973
- if ("transformer" not in self.pgm_output_data or self.pgm_output_data["transformer"].size == 0) or (
1974
- "trafo" not in self.pp_input_data or len(self.pp_input_data["trafo"]) == 0
1975
- ):
2007
+ if (
2008
+ ComponentType.transformer not in self.pgm_output_data
2009
+ or self.pgm_output_data[ComponentType.transformer].size == 0
2010
+ ) or ("trafo" not in self.pp_input_data or len(self.pp_input_data["trafo"]) == 0):
1976
2011
  return
1977
2012
 
1978
- pgm_input_transformers = self.pgm_input_data["transformer"]
2013
+ pgm_input_transformers = self.pgm_input_data[ComponentType.transformer]
1979
2014
  pp_input_transformers = self.pp_input_data["trafo"]
1980
- pgm_output_transformers = self.pgm_output_data["transformer"]
2015
+ pgm_output_transformers = self.pgm_output_data[ComponentType.transformer]
1981
2016
 
1982
2017
  # Only derating factor used here. Sn is already being multiplied by parallel
1983
2018
  loading_multiplier = pp_input_transformers["df"] * 1e2
@@ -2100,8 +2135,8 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
2100
2135
  """
2101
2136
  load_id_names = ["const_power", "const_impedance", "const_current"]
2102
2137
  if (
2103
- "sym_load" not in self.pgm_output_data
2104
- or self.pgm_output_data["sym_load"].size == 0
2138
+ ComponentType.sym_load not in self.pgm_output_data
2139
+ or self.pgm_output_data[ComponentType.sym_load].size == 0
2105
2140
  or ("load", load_id_names[0]) not in self.idx
2106
2141
  ):
2107
2142
  return
@@ -2122,10 +2157,13 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
2122
2157
  """
2123
2158
  # TODO: create unit tests for the function
2124
2159
 
2125
- if "asym_load" not in self.pgm_output_data or self.pgm_output_data["asym_load"].size == 0:
2160
+ if (
2161
+ ComponentType.asym_load not in self.pgm_output_data
2162
+ or self.pgm_output_data[ComponentType.asym_load].size == 0
2163
+ ):
2126
2164
  return
2127
2165
 
2128
- pgm_output_asym_loads = self.pgm_output_data["asym_load"]
2166
+ pgm_output_asym_loads = self.pgm_output_data[ComponentType.asym_load]
2129
2167
 
2130
2168
  pp_asym_load_p = pgm_output_asym_loads["p"] * 1e-6
2131
2169
  pp_asym_load_q = pgm_output_asym_loads["q"] * 1e-6
@@ -2153,10 +2191,10 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
2153
2191
  Returns:
2154
2192
  a PandaPower Dataframe for the Asymmetric Static Generator component
2155
2193
  """
2156
- if "asym_gen" not in self.pgm_output_data or self.pgm_output_data["asym_gen"].size == 0:
2194
+ if "asym_gen" not in self.pgm_output_data or self.pgm_output_data[ComponentType.asym_gen].size == 0:
2157
2195
  return
2158
2196
 
2159
- pgm_output_asym_gens = self.pgm_output_data["asym_gen"]
2197
+ pgm_output_asym_gens = self.pgm_output_data[ComponentType.asym_gen]
2160
2198
 
2161
2199
  pp_asym_gen_p = pgm_output_asym_gens["p"] * 1e-6
2162
2200
  pp_asym_gen_q = pgm_output_asym_gens["q"] * 1e-6
@@ -2199,7 +2237,7 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
2199
2237
  def _get_pgm_ids(
2200
2238
  self,
2201
2239
  pp_table: str,
2202
- pp_idx: Optional[Union[pd.Series, np.ndarray]] = None,
2240
+ pp_idx: Optional[pd.Series | np.ndarray] = None,
2203
2241
  name: Optional[str] = None,
2204
2242
  ) -> pd.Series:
2205
2243
  """
@@ -2477,7 +2515,7 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
2477
2515
  table: str,
2478
2516
  attribute: str,
2479
2517
  expected_type: Optional[str] = None,
2480
- default: Optional[Union[float, bool, str]] = None,
2518
+ default: Optional[float | bool | str] = None,
2481
2519
  ) -> np.ndarray:
2482
2520
  """
2483
2521
  Returns the selected PandaPower attribute from the selected PandaPower table.
@@ -2491,7 +2529,7 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
2491
2529
  """
2492
2530
  pp_component_data = self.pp_input_data[table]
2493
2531
 
2494
- exp_dtype: Union[str, Type] = "O"
2532
+ exp_dtype: str | Type = "O"
2495
2533
  if expected_type is not None:
2496
2534
  exp_dtype = expected_type
2497
2535
  elif default is not None:
@@ -2531,7 +2569,7 @@ class PandaPowerConverter(BaseConverter[PandaPowerData]):
2531
2569
  """
2532
2570
  return self.idx[(pp_table, name)][pp_idx]
2533
2571
 
2534
- def lookup_id(self, pgm_id: int) -> Dict[str, Union[str, int]]:
2572
+ def lookup_id(self, pgm_id: int) -> Dict[str, str | int]:
2535
2573
  """
2536
2574
  Retrieve the original name / key combination of a pgm object
2537
2575