PandaPower conversion¶
This example illustrates conversion from PandaPower to power-grid-model input data. We can then calculate power-flow with it or convert to a different formats like PGM JSON.
1. Load the PandaPower Data¶
For this example we will use the example_simple
pandapower network.
import pandapower.networks
pp_net = pandapower.networks.example_simple()
Instantiate the converter, optionally with a source file path.
Then use load_input_data()
to load the data and convert it to power-grid-model data.
The additional information that is not used in the powerflow calculation but may be useful to link the results to the source data is stored in extra_info
.
%%capture cap --no-stderr
from power_grid_model_io.converters import PandaPowerConverter
converter = PandaPowerConverter(std_types=pp_net.std_types)
input_data, extra_info = converter.load_input_data(pp_net)
Let’s investigate the data we have converted, for one of the components: lines
import pandas as pd
# The node data is stored as a numpy structured array in input_data["line"]
display(input_data["line"])
# We can use pandas to display the data in a convenient tabular format
display(pd.DataFrame(input_data["line"]))
# The original indices are stored in the extra_data dictionary
display({i: extra_info[i] for i in input_data["line"]["id"]})
array([( 7, 0, 1, 1, 1, 0.6 , 1.44 , 1.440e-06, 0., nan, nan, nan, nan, 588.),
( 8, 4, 5, 1, 1, 0.244 , 0.224, 6.080e-07, 0., nan, nan, nan, nan, 421.),
( 9, 5, 6, 1, 0, 2.07865, 1.302, 3.325e-08, 0., nan, nan, nan, nan, 210.),
(10, 6, 4, 1, 1, 0.305 , 0.28 , 7.600e-07, 0., nan, nan, nan, nan, 421.)],
dtype={'names': ['id', 'from_node', 'to_node', 'from_status', 'to_status', 'r1', 'x1', 'c1', 'tan1', 'r0', 'x0', 'c0', 'tan0', 'i_n'], 'formats': ['<i4', '<i4', '<i4', 'i1', 'i1', '<f8', '<f8', '<f8', '<f8', '<f8', '<f8', '<f8', '<f8', '<f8'], 'offsets': [0, 4, 8, 12, 13, 16, 24, 32, 40, 48, 56, 64, 72, 80], 'itemsize': 88, 'aligned': True})
id | from_node | to_node | from_status | to_status | r1 | x1 | c1 | tan1 | r0 | x0 | c0 | tan0 | i_n | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 7 | 0 | 1 | 1 | 1 | 0.60000 | 1.440 | 1.440000e-06 | 0.0 | NaN | NaN | NaN | NaN | 588.0 |
1 | 8 | 4 | 5 | 1 | 1 | 0.24400 | 0.224 | 6.080000e-07 | 0.0 | NaN | NaN | NaN | NaN | 421.0 |
2 | 9 | 5 | 6 | 1 | 0 | 2.07865 | 1.302 | 3.325000e-08 | 0.0 | NaN | NaN | NaN | NaN | 210.0 |
3 | 10 | 6 | 4 | 1 | 1 | 0.30500 | 0.280 | 7.600000e-07 | 0.0 | NaN | NaN | NaN | NaN | 421.0 |
{7: {'id_reference': {'table': 'line', 'index': 0}},
8: {'id_reference': {'table': 'line', 'index': 1}},
9: {'id_reference': {'table': 'line', 'index': 2}},
10: {'id_reference': {'table': 'line', 'index': 3}}}
2. Validate the data¶
Before we run a power flow calculation, it is wise validate the data. The most basic method is to use assert_valid_input_data()
, which will raise a ValueError
when the data is invalid. For more details on data validation, please consult the validation Example.
from power_grid_model import CalculationType
from power_grid_model.validation import assert_valid_input_data
assert_valid_input_data(input_data, calculation_type=CalculationType.power_flow, symmetric=True)
3. Run the calculation¶
Run powerflow calculation with the input_data
and show the results for nodes
.
from power_grid_model import PowerGridModel
pgm = PowerGridModel(input_data=input_data)
output_data = pgm.calculate_power_flow()
display(pd.DataFrame(output_data["node"]))
id | energized | u_pu | u | u_angle | |
---|---|---|---|---|---|
0 | 0 | 1 | 1.020390 | 112242.921178 | 0.872701 |
1 | 1 | 1 | 1.020553 | 112260.855174 | 0.872739 |
2 | 2 | 1 | 1.020553 | 112260.856550 | 0.872739 |
3 | 3 | 1 | 1.007663 | 20153.257182 | -1.741151 |
4 | 4 | 1 | 1.007663 | 20153.257532 | -1.741151 |
5 | 5 | 1 | 1.007687 | 20153.735830 | -1.741177 |
6 | 6 | 1 | 1.006282 | 20125.634273 | -1.738454 |
Cross referencing objects¶
The converter has generated unique numerical IDs for all the components in the VisionExcel file, in fact for some special components like Transformer loads, multiple PGM components have been created, each with their own numerical ID. To find out which component belongs to which id, some helper functions have been defined:
print("PGM object #16:", converter.lookup_id(16))
print("Trafo with index=0:", converter.get_id("trafo", 0))
PGM object #16: {'table': 'trafo', 'index': 0}
Trafo with index=0: 16
Saving the data as a JSON file¶
The data can be stored in a json file using the PgmJsonConverter. The file will be saved in the destination_file
path supplied in the constructor.
from power_grid_model_io.converters import PgmJsonConverter
input_file = "data/pandapower/example_simple_input.json"
output_file = "data/pandapower/example_simple_output.json"
PgmJsonConverter(destination_file=input_file).save(data=input_data, extra_info=extra_info)
PgmJsonConverter(destination_file=output_file).save(data=output_data, extra_info=extra_info)
For debugging purposes, let’s check the output JSON. Notice that the node names are added to the nodes data.
from pathlib import Path
from IPython.display import display, Markdown
with Path(input_file).open() as json_file:
display(Markdown(f"<pre style='max-height: 160px; white-space: pre'>{json_file.read()}</div>"))
with Path(output_file).open() as json_file:
display(Markdown(f"<pre style='max-height: 160px; white-space: pre'>{json_file.read()}</div>"))
{ "node": [ {"id": 0, "u_rated": 110000.0, "id_reference": {"table": "bus", "index": 0}}, {"id": 1, "u_rated": 110000.0, "id_reference": {"table": "bus", "index": 1}}, {"id": 2, "u_rated": 110000.0, "id_reference": {"table": "bus", "index": 2}}, {"id": 3, "u_rated": 20000.0, "id_reference": {"table": "bus", "index": 3}}, {"id": 4, "u_rated": 20000.0, "id_reference": {"table": "bus", "index": 4}}, {"id": 5, "u_rated": 20000.0, "id_reference": {"table": "bus", "index": 5}}, {"id": 6, "u_rated": 20000.0, "id_reference": {"table": "bus", "index": 6}} ], "line": [ {"id": 7, "from_node": 0, "to_node": 1, "from_status": 1, "to_status": 1, "r1": 0.6, "x1": 1.44, "c1": 1.4400000000000002e-06, "tan1": 0.0, "i_n": 588.0, "id_reference": {"table": "line", "index": 0}}, {"id": 8, "from_node": 4, "to_node": 5, "from_status": 1, "to_status": 1, "r1": 0.244, "x1": 0.224, "c1": 6.08e-07, "tan1": 0.0, "i_n": 421.0, "id_reference": {"table": "line", "index": 1}}, {"id": 9, "from_node": 5, "to_node": 6, "from_status": 1, "to_status": 0, "r1": 2.07865, "x1": 1.302, "c1": 3.325e-08, "tan1": 0.0, "i_n": 210.0, "id_reference": {"table": "line", "index": 2}}, {"id": 10, "from_node": 6, "to_node": 4, "from_status": 1, "to_status": 1, "r1": 0.305, "x1": 0.28, "c1": 7.6e-07, "tan1": 0.0, "i_n": 421.0, "id_reference": {"table": "line", "index": 3}} ], "source": [ {"id": 11, "node": 0, "status": 1, "u_ref": 1.02, "u_ref_angle": 0.8726646259971648, "id_reference": {"table": "ext_grid", "index": 0}} ], "sym_load": [ {"id": 12, "node": 6, "status": 1, "type": 0, "p_specified": 1200000.0, "q_specified": 2400000.0, "id_reference": {"table": "load", "name": "const_power", "index": 0}}, {"id": 13, "node": 6, "status": 1, "type": 1, "p_specified": 0.0, "q_specified": 0.0, "id_reference": {"table": "load", "name": "const_impedance", "index": 0}}, {"id": 14, "node": 6, "status": 1, "type": 2, "p_specified": 0.0, "q_specified": 0.0, "id_reference": {"table": "load", "name": "const_current", "index": 0}} ], "shunt": [ {"id": 15, "node": 2, "status": 1, "g1": 0.0, "b1": 7.933884297520661e-05, "id_reference": {"table": "shunt", "index": 0}} ], "transformer": [ {"id": 16, "from_node": 2, "to_node": 3, "from_status": 1, "to_status": 1, "u1": 110000.0, "u2": 20000.0, "sn": 25000000.0, "uk": 0.12, "pk": 102500.0, "i0": 0.0007000000000000001, "p0": 14000.0, "winding_from": 1, "winding_to": 2, "clock": 5, "tap_side": 0, "tap_pos": 0, "tap_min": -9, "tap_max": 9, "tap_nom": 0, "tap_size": 1650.0, "id_reference": {"table": "trafo", "index": 0}} ], "sym_gen": [ {"id": 17, "node": 6, "status": 1, "type": 0, "p_specified": 2000000.0, "q_specified": -500000.0, "id_reference": {"table": "sgen", "index": 0}} ], "link": [ {"id": 18, "from_node": 1, "to_node": 2, "from_status": 1, "to_status": 1, "id_reference": {"table": "switch", "name": "bus_to_bus", "index": 0}}, {"id": 19, "from_node": 3, "to_node": 4, "from_status": 1, "to_status": 1, "id_reference": {"table": "switch", "name": "bus_to_bus", "index": 1}} ] }
{ "line": [ {"id": 7, "energized": 1, "loading": 0.03499070469697967, "p_from": -777605.3585707144, "q_from": -3923590.767884193, "i_from": 20.574534361824046, "s_from": 3999904.324793777, "p_to": 777689.0780134673, "q_to": -1776534.0942513999, "i_to": 9.97367931754632, "s_to": 1939297.2155136713, "id_reference": {"table": "line", "index": 0}}, {"id": 8, "energized": 1, "loading": 0.005567821190466236, "p_from": 1.1355440374723886, "q_from": -81822.59656678521, "i_from": 2.3440527211862854, "s_from": 81822.59657466481, "p_to": -0.02303153571591582, "q_to": 4242.815260871495, "i_to": 0.12154523377829303, "s_to": 4242.815260934007, "id_reference": {"table": "line", "index": 1}}, {"id": 9, "energized": 1, "loading": 0.0005787868274923048, "p_from": 0.023031459119309157, "q_from": -4242.815260700137, "i_from": 0.12154523377338401, "s_from": 4242.815260762648, "p_to": 0.0, "q_to": 0.0, "i_to": 0.0, "s_to": 0.0, "id_reference": {"table": "line", "index": 2}}, {"id": 10, "energized": 1, "loading": 0.20498967649985897, "p_from": 799999.999999921, "q_from": -2899999.9999997998, "i_from": 86.30065380644062, "s_from": 3008321.7912980504, "p_to": -793394.6839146599, "q_to": 2809223.021815948, "i_to": 83.62665573744187, "s_to": 2919111.0137788136, "id_reference": {"table": "line", "index": 3}} ], "link": [ {"id": 18, "energized": 1, "loading": 0.0, "p_from": -777689.0876726455, "q_from": 1776534.1460353297, "i_from": 9.973679581436713, "s_from": 1939297.266824916, "p_to": 777689.105727228, "q_to": -1776534.1640899125, "i_to": 9.973679581436713, "s_to": 1939297.2906043725, "id_reference": {"table": "switch", "name": "bus_to_bus", "index": 0}}, {"id": 19, "energized": 1, "loading": 0.0, "p_from": -793393.5212799172, "q_from": 2727400.4082359127, "i_from": 81.37332901954967, "s_from": 2840455.2921062442, "p_to": 793393.5610096292, "q_to": -2727400.4479656247, "i_to": 81.37332901954967, "s_to": 2840455.3413519165, "id_reference": {"table": "switch", "name": "bus_to_bus", "index": 1}} ], "node": [ {"id": 0, "energized": 1, "u_pu": 1.020390192529114, "u": 112242.92117820252, "u_angle": 0.8727014568115191, "id_reference": {"table": "bus", "index": 0}}, {"id": 1, "energized": 1, "u_pu": 1.0205532288513763, "u": 112260.85517365139, "u_angle": 0.8727391872423511, "id_reference": {"table": "bus", "index": 1}}, {"id": 2, "energized": 1, "u_pu": 1.0205532413652911, "u": 112260.85655018203, "u_angle": 0.8727391920374414, "id_reference": {"table": "bus", "index": 2}}, {"id": 3, "energized": 1, "u_pu": 1.0076628591197538, "u": 20153.25718239508, "u_angle": -1.7411509747056502, "id_reference": {"table": "bus", "index": 3}}, {"id": 4, "energized": 1, "u_pu": 1.0076628765898528, "u": 20153.257531797055, "u_angle": -1.74115096518213, "id_reference": {"table": "bus", "index": 4}}, {"id": 5, "energized": 1, "u_pu": 1.007686791524185, "u": 20153.7358304837, "u_angle": -1.741176817668832, "id_reference": {"table": "bus", "index": 5}}, {"id": 6, "energized": 1, "u_pu": 1.0062817136417368, "u": 20125.634272834737, "u_angle": -1.738454315295021, "id_reference": {"table": "bus", "index": 6}} ], "shunt": [ {"id": 15, "energized": 1, "p": -5.551115123125783e-11, "q": -999867.761722754, "i": 5.142254737087383, "s": 999867.761722754, "pf": -5.551849290111436e-17, "id_reference": {"table": "shunt", "index": 0}} ], "source": [ {"id": 11, "energized": 1, "p": -777605.3585712905, "q": -3923590.767884032, "i": 20.574534361823808, "s": 3999904.324793731, "pf": -0.19440598960111138, "id_reference": {"table": "ext_grid", "index": 0}} ], "sym_gen": [ {"id": 17, "energized": 1, "p": 2000000.0, "q": -500000.0, "i": 59.140400510525666, "s": 2061552.8128088303, "pf": 0.9701425001453319, "id_reference": {"table": "sgen", "index": 0}} ], "sym_load": [ {"id": 12, "energized": 1, "p": 1200000.0, "q": 2400000.0, "i": 76.97612494996213, "s": 2683281.5729997475, "pf": 0.447213595499958, "id_reference": {"table": "load", "name": "const_power", "index": 0}}, {"id": 13, "energized": 1, "p": 0.0, "q": -0.0, "i": 0.0, "s": 0.0, "pf": 0.0, "id_reference": {"table": "load", "name": "const_impedance", "index": 0}}, {"id": 14, "energized": 1, "p": 0.0, "q": -0.0, "i": 0.0, "s": 0.0, "pf": 0.0, "id_reference": {"table": "load", "name": "const_current", "index": 0}} ], "transformer": [ {"id": 16, "energized": 1, "loading": 0.11533053725495443, "p_from": -777689.128447352, "q_from": 2776401.9223074615, "i_from": 14.82843592507404, "s_from": 2883263.4313738607, "p_to": 793393.5441983221, "q_to": -2727400.4032140207, "i_to": 81.37332906480023, "s_to": 2840455.293685781, "id_reference": {"table": "trafo", "index": 0}} ] }