Examples¶
The combination of a suitable MultiGraph and the availabe topology functions enables you to perform a wide range of topological searches and analyses.
Here are a few examples of what you can do:
basic example network
import pandapower as pp
net = pp.create_empty_network()
pp.create_bus(net, name = "110 kV bar", vn_kv = 110, type = 'b')
pp.create_bus(net, name = "20 kV bar", vn_kv = 20, type = 'b')
pp.create_bus(net, name = "bus 2", vn_kv = 20, type = 'b')
pp.create_bus(net, name = "bus 3", vn_kv = 20, type = 'b')
pp.create_bus(net, name = "bus 4", vn_kv = 20, type = 'b')
pp.create_bus(net, name = "bus 5", vn_kv = 20, type = 'b')
pp.create_bus(net, name = "bus 6", vn_kv = 20, type = 'b')
pp.create_ext_grid(net, 0, vm_pu = 1)
pp.create_line(net, name = "line 0", from_bus = 1, to_bus = 2, length_km = 1, std_type = "NAYY 150")
pp.create_line(net, name = "line 1", from_bus = 2, to_bus = 3, length_km = 1, std_type = "NAYY 150")
pp.create_line(net, name = "line 2", from_bus = 3, to_bus = 4, length_km = 1, std_type = "NAYY 150")
pp.create_line(net, name = "line 3", from_bus = 4, to_bus = 5, length_km = 1, std_type = "NAYY 150")
pp.create_line(net, name = "line 4", from_bus = 5, to_bus = 6, length_km = 1, std_type = "NAYY 150")
pp.create_line(net, name = "line 5", from_bus = 6, to_bus = 1, length_km = 1, std_type = "NAYY 150")
pp.create_transformer_from_parameters(net, hv_bus = 0, lv_bus = 1, i0_percent= 0.038, pfe_kw = 11.6,
vscr_percent = 0.322, sn_kva = 40000.0, vn_lv_kv = 22.0,
vn_hv_kv = 110.0, vsc_percent = 17.8)
pp.create_load(net, 2, p_kw = 1000, q_kvar = 200, name = "load 0")
pp.create_load(net, 3, p_kw = 1000, q_kvar = 200, name = "load 1")
pp.create_load(net, 4, p_kw = 1000, q_kvar = 200, name = "load 2")
pp.create_load(net, 5, p_kw = 1000, q_kvar = 200, name = "load 3")
pp.create_load(net, 6, p_kw = 1000, q_kvar = 200, name = "load 4")
pp.create_switch(net, bus = 1, element = 0, et = 'l')
pp.create_switch(net, bus = 2, element = 0, et = 'l')
pp.create_switch(net, bus = 2, element = 1, et = 'l')
pp.create_switch(net, bus = 3, element = 1, et = 'l')
pp.create_switch(net, bus = 3, element = 2, et = 'l')
pp.create_switch(net, bus = 4, element = 2, et = 'l')
pp.create_switch(net, bus = 4, element = 3, et = 'l', closed = 0)
pp.create_switch(net, bus = 5, element = 3, et = 'l')
pp.create_switch(net, bus = 5, element = 4, et = 'l')
pp.create_switch(net, bus = 6, element = 4, et = 'l')
pp.create_switch(net, bus = 6, element = 5, et = 'l')
pp.create_switch(net, bus = 1, element = 5, et = 'l')
Using NetworkX algorithms: shortest path¶
For many basic network analyses the algorithms that come with the NetworkX package will work just fine and you won’t need one of the spezialised topology functions. Finding the shortest path between two buses is a good example for that.
import pandapower.topology as top
import networkx as nx
mg = top.create_nxgraph(net)
nx.shortest_path(mg, 0, 5)
Out: [0, 1, 6, 5]

Find disconnected buses¶
With unsupplied_buses you can easily find buses that are not connected to an external grid.
import pandapower.topology as top
net.switch.closed.at[11] = 0
top.unsupplied_buses(net)
Out: {5, 6}

Calculate distances between buses¶
calc_distance_to_bus allows you to calculate the distance ( = shortest network route) from one bus all other ones. This is possible since line lengths are being transferred into the MultiGraph as an edge attribute. (Note: bus-bus-switches and trafos are interpreted as edges with length = 0)
import pandapower.topology as top
net.switch.closed.at[6] = 1
net.switch.closed.at[8] = 0
top.calc_distance_to_bus(net, 1)
Out:
0 0
1 0
2 1
3 2
4 3
5 4
6 1
Interpretation: The distance between bus 1 and itself is 0 km. Bus 1 is also 0 km away from bus 0, since they are connected with a transformer. The shortest path between bus 1 and bus 5 is 4 km long.

Find connected buses with the same voltage level¶
import pandapower.topology as top
mg_no_trafos = top.create_nxgraph(net, include_trafos = False)
cc = top.connected_components(mg_no_trafos)
In : next(cc)
Out : {0}
In : next(cc)
Out : {1, 2, 3, 4, 5, 6}

Find rings and ring sections¶
Another example of what you can do with the right combination of input arguments when creating the MultiGraph is finding rings and ring sections in your network. To achieve that for our example network, the trafo buses needs to be set as a nogobuses. With respect_switches = True you get the ring sections, with respect_switches = False the whole ring.
import pandapower.topology as top
mg_ring_sections = top.create_nxgraph(net, nogobuses = [0, 1])
cc_ring_sections = top.connected_components(mg_ring_sections)
In : next(cc_ring_sections)
Out : {2, 3, 4}
In : next(cc_ring_sections)
Out : {5, 6}

import pandapower.topology as top
mg_ring = top.create_nxgraph(net, respect_switches = False, nogobuses = [0,1])
cc_ring = top.connected_components(mg_ring)
In : next(cc_ring)
Out : {2, 3, 4, 5, 6}

Find stubs¶
determine_stubs lets you identify buses and lines that are stubs. Open switches are being ignored. Busses that you want to exclude should be defined as roots. Ext_grid buses are roots by default.
This is a small extension for the example network:
pp.create_bus(net, name = "bus 7", vn_kv = 20, type = 'b')
pp.create_bus(net, name = "bus 8", vn_kv = 20, type = 'b')
pp.create_line(net, name = "line 6", from_bus = 6, to_bus = 7, length_km = 1, std_type = "NAYY 150")
pp.create_line(net, name = "line 7", from_bus = 7, to_bus = 8, length_km = 1, std_type = "NAYY 150")
pp.create_load(net, 7, p_kw = 1000, q_kvar = 200, name = "load 5")
pp.create_load(net, 8, p_kw = 1000, q_kvar = 200, name = "load 6")
import pandapower.topology as top
top.determine_stubs(net, roots = [0,1])
In: net.bus
Out:
name vn_kv min_vm_pu max_vm_pu type zone in_service auf_stich
0 110 kV bar 110 NaN NaN b None True False
1 20 kV bar 20 NaN NaN b None True False
2 bus 2 20 NaN NaN b None True False
3 bus 3 20 NaN NaN b None True False
4 bus 4 20 NaN NaN b None True False
5 bus 5 20 NaN NaN b None True False
6 bus 6 20 NaN NaN b None True False
7 bus 7 20 NaN NaN b None True True
8 bus 8 20 NaN NaN b None True True
In: net.line
Out:
name std_type from_bus to_bus length_km r_ohm_per_km x_ohm_per_km c_nf_per_km max_i_ka df type in_service is_stich
0 line 0 NAYY 150 1 2 1 0.206 0.091 0 0.284 1 cs True False
1 line 1 NAYY 150 2 3 1 0.206 0.091 0 0.284 1 cs True False
2 line 2 NAYY 150 3 4 1 0.206 0.091 0 0.284 1 cs True False
3 line 3 NAYY 150 4 5 1 0.206 0.091 0 0.284 1 cs True False
4 line 4 NAYY 150 5 6 1 0.206 0.091 0 0.284 1 cs True False
5 line 5 NAYY 150 6 1 1 0.206 0.091 0 0.284 1 cs True False
6 line 6 NAYY 150 6 7 1 0.206 0.091 0 0.284 1 cs True True
7 line 7 NAYY 150 7 8 1 0.206 0.091 0 0.284 1 cs True True
