Skip to content

Commit

Permalink
Merge pull request #336 from openego/features/no_removal_of_end_lines…
Browse files Browse the repository at this point in the history
…_in_ding0_import

Features/no removal of end lines in ding0 import
  • Loading branch information
birgits committed Nov 10, 2022
2 parents 8062488 + b22a611 commit a0ae3d3
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 93 deletions.
161 changes: 87 additions & 74 deletions edisgo/io/ding0_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,75 +67,6 @@ def sort_hvmv_transformer_buses(transformers_df):

return transformers_df

def remove_1m_lines_from_edisgo(edisgo):
"""
Method to remove 1m lines to reduce size of edisgo object.
"""

# close switches such that lines with connected switches are not removed
switches = [
Switch(id=_, topology=edisgo.topology)
for _ in edisgo.topology.switches_df.index
]
switch_status = {}
for switch in switches:
switch_status[switch] = switch.state
switch.close()

# get all lines with length of one meter and remove the ones that are end lines
number_of_lines_removed = 0
lines = edisgo.topology.lines_df.loc[edisgo.topology.lines_df.length == 0.001]
for name, line in lines.iterrows():
number_of_lines_removed += remove_1m_end_line(edisgo, line)
logger.debug(f"Removed {number_of_lines_removed} 1 m end lines.")

# set switches back to original state
for switch in switches:
if switch_status[switch] == "open":
switch.open()
return edisgo

def remove_1m_end_line(edisgo, line):
"""
Method that removes end lines and moves components of end bus to neighboring
bus. If the line is not an end line, the method will skip this line.
Returns
-------
int
Number of removed lines. Either 0, if no line was removed, or 1, if line
was removed.
"""
# check for end buses
if len(edisgo.topology.get_connected_lines_from_bus(line.bus1)) == 1:
end_bus = "bus1"
neighbor_bus = "bus0"
elif len(edisgo.topology.get_connected_lines_from_bus(line.bus0)) == 1:
end_bus = "bus0"
neighbor_bus = "bus1"
else:
return 0

# move connected elements of end bus to the other bus
connected_elements = edisgo.topology.get_connected_components_from_bus(
line[end_bus]
)
rename_dict = {line[end_bus]: line[neighbor_bus]}
for comp_type, components in connected_elements.items():
if not components.empty and comp_type != "lines":
setattr(
edisgo.topology,
comp_type.lower() + "_df",
getattr(edisgo.topology, comp_type.lower() + "_df").replace(
rename_dict
),
)

# remove line
edisgo.topology.remove_line(line.name)
return 1

grid = PyPSANetwork()
grid.import_from_csv_folder(path)

Expand Down Expand Up @@ -188,9 +119,91 @@ def remove_1m_end_line(edisgo, line):
mv_grid_id = list(set(grid.buses.mv_grid_id))[0]
edisgo_obj.topology.mv_grid = MVGrid(id=mv_grid_id, edisgo_obj=edisgo_obj)

# remove 1 m end lines
# ToDo Remove once fixed in ding0
remove_1m_lines_from_edisgo(edisgo_obj)

# Check data integrity
# check data integrity
edisgo_obj.topology.check_integrity()


def remove_1m_end_lines(edisgo):
"""
Method to remove 1m end lines to reduce size of edisgo object.
Short lines inside houses are removed in this function, including the end node.
Components that were originally connected to the end node are reconnected to the
upstream node.
This function will become obsolete once it is changed in the ding0 export.
Parameters
----------
edisgo : :class:`~.EDisGo`
Returns
--------
edisgo : :class:`~.EDisGo`
EDisGo object where 1m end lines are removed from topology.
"""

def remove_1m_end_line(edisgo, line):
"""
Method that removes end lines and moves components of end bus to neighboring
bus. If the line is not an end line, the method will skip this line.
Returns
-------
int
Number of removed lines. Either 0, if no line was removed, or 1, if line
was removed.
"""
# check for end buses
if len(edisgo.topology.get_connected_lines_from_bus(line.bus1)) == 1:
end_bus = "bus1"
neighbor_bus = "bus0"
elif len(edisgo.topology.get_connected_lines_from_bus(line.bus0)) == 1:
end_bus = "bus0"
neighbor_bus = "bus1"
else:
return 0

# move connected elements of end bus to the other bus
connected_elements = edisgo.topology.get_connected_components_from_bus(
line[end_bus]
)
rename_dict = {line[end_bus]: line[neighbor_bus]}
for comp_type, components in connected_elements.items():
if not components.empty and comp_type != "lines":
setattr(
edisgo.topology,
comp_type.lower() + "_df",
getattr(edisgo.topology, comp_type.lower() + "_df").replace(
rename_dict
),
)

# remove line
edisgo.topology.remove_line(line.name)
return 1

# close switches such that lines with connected switches are not removed
switches = [
Switch(id=_, topology=edisgo.topology)
for _ in edisgo.topology.switches_df.index
]
switch_status = {}
for switch in switches:
switch_status[switch] = switch.state
switch.close()

# get all lines with length of one meter and remove the ones that are end lines
number_of_lines_removed = 0
lines = edisgo.topology.lines_df.loc[edisgo.topology.lines_df.length == 0.001]
for name, line in lines.iterrows():
number_of_lines_removed += remove_1m_end_line(edisgo, line)
logger.debug(f"Removed {number_of_lines_removed} 1 m end lines.")

# set switches back to original state
for switch in switches:
if switch_status[switch] == "open":
switch.open()
return edisgo
2 changes: 1 addition & 1 deletion tests/flex_opt/test_check_tech_constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def test_lines_allowed_load(self):
# check for LV
df = check_tech_constraints.lines_allowed_load(self.edisgo, "lv")
# check shape of dataframe
assert (4, 99) == df.shape
assert (4, 101) == df.shape
# check in feed-in case
assert np.isclose(
df.at[self.timesteps[2], "Line_50000002"],
Expand Down
20 changes: 14 additions & 6 deletions tests/io/test_ding0_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,17 @@ class TestImportFromDing0:
def setup_class(self):
self.topology = Topology()

def test_import_ding0_grid(self, caplog):
def test_import_ding0_grid(self):
"""Test successful import of ding0 network."""

with caplog.at_level(logging.DEBUG):
ding0_import.import_ding0_grid(pytest.ding0_test_network_path, self)
assert "Removed 2 1 m end lines." in caplog.text
ding0_import.import_ding0_grid(pytest.ding0_test_network_path, self)

# buses, generators, loads, lines, transformers dataframes
# check number of imported components
assert self.topology.buses_df.shape[0] == 140
assert self.topology.buses_df.shape[0] == 142
assert self.topology.generators_df.shape[0] == 28
assert self.topology.loads_df.shape[0] == 50
assert self.topology.lines_df.shape[0] == 129
assert self.topology.lines_df.shape[0] == 131
assert self.topology.transformers_df.shape[0] == 14
assert self.topology.transformers_hvmv_df.shape[0] == 1
assert self.topology.switches_df.shape[0] == 2
Expand Down Expand Up @@ -69,3 +67,13 @@ def test_transformer_buses(self):
index=self.topology.transformers_df.bus0
).v_nom.values
).all()

def test_remove_1m_end_lines(self, caplog):
ding0_import.import_ding0_grid(pytest.ding0_test_network_path, self)
with caplog.at_level(logging.DEBUG):
ding0_import.remove_1m_end_lines(self)
assert "Removed 2 1 m end lines." in caplog.text

# check number of lines and buses
assert self.topology.buses_df.shape[0] == 140
assert self.topology.lines_df.shape[0] == 129
8 changes: 4 additions & 4 deletions tests/network/test_topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ class TestTopology:
"""

@classmethod
def setup_class(self):
@pytest.fixture(autouse=True)
def setup_fixture(self):
self.topology = Topology()
ding0_import.import_ding0_grid(pytest.ding0_test_network_path, self)

Expand Down Expand Up @@ -901,8 +901,8 @@ def test_from_csv(self):
assert len(self.edisgo.topology.generators_df) == 28
assert self.edisgo.topology.charging_points_df.empty
assert len(self.edisgo.topology.storage_units_df) == 1
assert len(self.edisgo.topology.lines_df) == 129
assert len(self.edisgo.topology.buses_df) == 140
assert len(self.edisgo.topology.lines_df) == 131
assert len(self.edisgo.topology.buses_df) == 142
assert len(self.edisgo.topology.switches_df) == 2
assert self.edisgo.topology.grid_district["population"] == 23358

Expand Down
14 changes: 7 additions & 7 deletions tests/test_edisgo.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ def test_to_pypsa(self):

# test mode None and timesteps None (default)
pypsa_network = self.edisgo.to_pypsa()
assert len(pypsa_network.buses) == 140
assert len(pypsa_network.buses) == 142
assert len(pypsa_network.buses_t.v_mag_pu_set) == 4

# test mode "mv" and timesteps given
Expand Down Expand Up @@ -364,7 +364,7 @@ def test_analyze(self, caplog):
# test mode None and timesteps None (default)
self.edisgo.analyze()
results_analyze = deepcopy(self.edisgo.results)
assert self.edisgo.results.v_res.shape == (4, 140)
assert self.edisgo.results.v_res.shape == (4, 142)

# test mode "mv" and timesteps given
self.edisgo.analyze(mode="mv", timesteps=self.edisgo.timeseries.timeindex[0])
Expand All @@ -376,12 +376,12 @@ def test_analyze(self, caplog):

# test troubleshooting_mode "lpf"
self.edisgo.analyze(troubleshooting_mode="lpf")
assert self.edisgo.results.v_res.shape == (4, 140)
assert self.edisgo.results.v_res.shape == (4, 142)
assert self.edisgo.results.equality_check(results_analyze)

# test mode None and troubleshooting_mode "iteration"
self.edisgo.analyze(troubleshooting_mode="iteration")
assert self.edisgo.results.v_res.shape == (4, 140)
assert self.edisgo.results.v_res.shape == (4, 142)
assert self.edisgo.results.equality_check(results_analyze)

# test non convergence
Expand All @@ -407,8 +407,8 @@ def test_reinforce(self):
assert results.unresolved_issues.empty
assert len(results.grid_expansion_costs) == 10
assert len(results.equipment_changes) == 10
assert results.v_res.shape == (4, 140)
assert self.edisgo.results.v_res.shape == (4, 140)
assert results.v_res.shape == (4, 142)
assert self.edisgo.results.v_res.shape == (4, 142)

# ###################### test mode lv and copy grid ##########################
self.setup_edisgo_object()
Expand All @@ -417,7 +417,7 @@ def test_reinforce(self):
assert results.unresolved_issues.empty
assert len(results.grid_expansion_costs) == 6
assert len(results.equipment_changes) == 6
assert results.v_res.shape == (2, 140)
assert results.v_res.shape == (2, 142)
assert self.edisgo.results.v_res.empty

# ################# test mode mvlv and combined analysis ####################
Expand Down
2 changes: 1 addition & 1 deletion tests/tools/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def setup_class(self):
def test_calculate_relative_line_load(self):
# test without providing lines and time steps
rel_line_load = tools.calculate_relative_line_load(self.edisgo)
assert rel_line_load.shape == (4, 129)
assert rel_line_load.shape == (4, 131)

# test with providing lines
rel_line_load = tools.calculate_relative_line_load(
Expand Down

0 comments on commit a0ae3d3

Please sign in to comment.