Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add jao converter #2443

Open
wants to merge 16 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ Change Log
- [CHANGED] accelerate distributed slack power flow calculation by using sparse-aware operations in _subnetworks()
- [CHANGED] Trafo Controllers can now be added to elements that are out of service, changed self.nothing_to_do()
- [ADDED] Discrete shunt controller for local voltage regulation with shunt steps
- [ADDED] fix lengths missmatch of output if ignore_zero_length is False in plotting utility function coords_from_node_geodata() and rename ignore_zero_length by ignore_no_geo_diff
- [ADDED] converter for European EHV grid data from JAO, the "Single Allocation Platform (SAP) for all European Transmission System Operators (TSOs) that operate in accordance to EU legislation"
- [ADDED] cim2pp converter: Using lxml to parse XML files (better performance)

[2.14.7] - 2024-06-14
Expand Down
1 change: 1 addition & 0 deletions doc/converter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ These tools are:
converter/matpower
converter/powerfactory
converter/cgmes
converter/jao

9 changes: 9 additions & 0 deletions doc/converter/jao.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Documentation for the JAO Static Grid Model Converter Function
==============================================================

The ``from_jao`` function allows users to convert the Static Grid Model provided by JAO (Joint Allocation Office) into a pandapower network by reading and processing the provided Excel and HTML files.

Function Overview
-----------------

.. autofunction:: pandapower.converter.from_jao
1 change: 1 addition & 0 deletions pandapower/converter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
from pandapower.converter.pandamodels import *
from pandapower.converter.cim import *
from pandapower.converter.powerfactory import *
from pandapower.converter.jao import *
1 change: 1 addition & 0 deletions pandapower/converter/jao/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .from_jao import from_jao
1,039 changes: 1,039 additions & 0 deletions pandapower/converter/jao/from_jao.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pandapower/plotting/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ def create_line_collection(net: pandapowerNet, lines=None,
node_geodata=net.bus.geo,
table_name="line",
node_name="bus",
ignore_zero_length=True)
ignore_no_geo_diff=True)

line_geodata = line_geodata.combine_first(pd.Series(geos, index=line_index_successful))

Expand Down
30 changes: 17 additions & 13 deletions pandapower/plotting/plotting_toolbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@


def coords_from_node_geodata(element_indices, from_nodes, to_nodes, node_geodata, table_name,
node_name="Bus", ignore_zero_length=True, node_geodata_to=None):
node_name="Bus", ignore_no_geo_diff=True, node_geodata_to=None):
"""
Auxiliary function to get the node coordinates for a number of branches with respective from
and to nodes. The branch elements for which there is no geodata available are not included in
Expand All @@ -162,9 +162,9 @@
:type table_name: str
:param node_name: Name of the node type (only for logging)
:type node_name: str, default "Bus"
:param ignore_zero_length: States if branches should be left out, if their length is zero, i.e. \
:param ignore_no_geo_diff: States if branches should be left out, if their length is zero, i.e. \
from_node_coords = to_node_coords
:type ignore_zero_length: bool, default True
:type ignore_no_geo_diff: bool, default True
:param node_geodata_to: Dataframe containing x and y coordinates of the "to" nodes (optional, default node_geodata)
:type node_geodata_to: pd.DataFrame
:return: Return values are:\
Expand Down Expand Up @@ -192,15 +192,19 @@
)

node_geodata = node_geodata.apply(_get_coords_from_geojson)
coords = [f'{{"coordinates": [[{x_from}, {y_from}], [{x_to}, {y_to}]], "type": "LineString"}}'
for [x_from, y_from], [x_to, y_to]
in zip(node_geodata.loc[fb_with_geo[not_nan]],
node_geodata.loc[tb_with_geo[not_nan]])
if not ignore_zero_length or (ignore_zero_length and not (x_from == x_to and y_from == y_to))]
return coords, np.array(element_indices)[in_geo & not_nan]


def set_line_geodata_from_bus_geodata(net, line_index=None, overwrite=False, ignore_zero_length=True):
coords, no_geo_diff = zip(*[
(f'{{"coordinates": [[{x_from}, {y_from}], [{x_to}, {y_to}]], "type": "LineString"}}',
x_from == x_to and y_from == y_to) for [x_from, y_from], [x_to, y_to] in zip(
node_geodata.loc[fb_with_geo[not_nan]], node_geodata.loc[tb_with_geo[not_nan]])])
# if not ignore_no_geo_diff or (ignore_no_geo_diff and not ())]
coords, no_geo_diff = np.array(coords), np.array(no_geo_diff)
if ignore_no_geo_diff:
return coords, np.array(element_indices)[in_geo & not_nan]
else:
return coords[~no_geo_diff], np.array(element_indices)[in_geo & not_nan][~no_geo_diff]

Check warning on line 204 in pandapower/plotting/plotting_toolbox.py

View check run for this annotation

Codecov / codecov/patch

pandapower/plotting/plotting_toolbox.py#L204

Added line #L204 was not covered by tests


def set_line_geodata_from_bus_geodata(net, line_index=None, overwrite=False, ignore_no_geo_diff=True):
"""
Sets coordinates in net.line.geo based on the from_bus and to_bus coordinates
in net.bus.geo
Expand All @@ -227,7 +231,7 @@
node_geodata=net.bus.geo,
table_name="line",
node_name="bus",
ignore_zero_length=ignore_zero_length)
ignore_no_geo_diff=ignore_no_geo_diff)

net.line.loc[line_index_successful, 'geo'] = geos

Expand Down
Binary file not shown.
60 changes: 60 additions & 0 deletions pandapower/test/converter/test_from_jao.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-

# Copyright (c) 2016-2024 by University of Kassel and Fraunhofer Institute for Energy Economics
# and Energy System Technology (IEE), Kassel. All rights reserved.

from copy import deepcopy
import os
import pytest
import numpy as np
import pandas as pd

import pandapower as pp
from pandapower.converter import from_jao


def test_from_jao_with_testfile():
testfile = os.path.join(pp.pp_dir, 'test', 'converter', "jao_testfiles", "testfile.xlsx")
assert os.path.isfile(testfile)

# --- net1
net1 = from_jao(testfile, None, False)

assert len(net1.bus) == 10
assert len(net1.line) == 7
assert net1.line.Tieline.sum() == 2
assert len(net1.trafo) == 1

# line data conversion
assert np.all((0.01 < net1.line[['r_ohm_per_km', 'x_ohm_per_km']]) & (
net1.line[['r_ohm_per_km', 'x_ohm_per_km']] < 0.4))
assert np.all((0.5 < net1.line['c_nf_per_km']) & (net1.line['c_nf_per_km'] < 25))
assert np.all(net1.line['g_us_per_km'] < 1)
assert np.all((0.2 < net1.line['max_i_ka']) & (net1.line['max_i_ka'] < 5))

# trafo data conversion
assert 100 < net1.trafo.sn_mva.iat[0] < 1000
assert 6 < net1.trafo.vk_percent.iat[0] < 65
assert 0.25 < net1.trafo.vkr_percent.iat[0] < 1.2
assert 10 < net1.trafo.pfe_kw.iat[0] < 1000
assert net1.trafo.i0_percent.iat[0] < 0.1
assert np.isclose(net1.trafo.shift_degree.iat[0], 90)
assert np.isclose(net1.trafo.tap_step_degree.iat[0], 1.794)
assert net1.trafo.tap_min.iat[0] == -17
assert net1.trafo.tap_max.iat[0] == 17

# --- net2
net2 = from_jao(testfile, None, True)
pp.nets_equal(net1, net2) # extend_data_for_grid_group_connections makes no difference here

# --- net3
net3 = from_jao(testfile, None, True, drop_grid_groups_islands=True)
assert len(net3.bus) == 6
assert len(net3.line) == 5
assert net3.line.Tieline.sum() == 1
assert len(net3.trafo) == 1


if __name__ == '__main__':
test_from_jao_with_testfile()
# pytest.main([__file__, "-xs"])
Loading