From 94918eaedb7da9c45978a696ef58fadeeb91f52b Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Wed, 1 Jul 2026 09:15:54 +0200 Subject: [PATCH 01/19] Rename argument to store results --- etrago/appl.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/etrago/appl.py b/etrago/appl.py index a1e982ac..c12f8225 100644 --- a/etrago/appl.py +++ b/etrago/appl.py @@ -89,7 +89,7 @@ "scn_extension": None, # None or array of extension scenarios # Export options: "lpfile": False, # save pyomo's lp file: False or /path/to/lpfile.lp - "csv_export": "results", # save results as csv: False or /path/tofolder + "export_results_path": "results", # save results as csv: False or /path/tofolder # Settings: "extendable": { "extendable_components": [ @@ -290,9 +290,9 @@ def run_etrago(args, json_path): lpfile : bool or str State if and where you want to save pyomo's lp file. Options: False or '/path/tofile.lp'. Default: False. - csv_export : bool or str - State if and where you want to save results as csv files. Options: - False or '/path/tofolder'. Default: False. + export_results_path : bool or str + State if and where you want to save results as csv and .nc files. + Options: False or '/path/tofolder'. Default: False. extendable : dict Choose components you want to optimize and set upper bounds for grid From 033c477115bd905b8326365aacae03d6f146fc92 Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Wed, 1 Jul 2026 09:17:23 +0200 Subject: [PATCH 02/19] Create results folder and store args when starting eTraGo --- etrago/network.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/etrago/network.py b/etrago/network.py index 00907411..a85a9003 100644 --- a/etrago/network.py +++ b/etrago/network.py @@ -23,6 +23,7 @@ Define class Etrago """ +import json import logging import os @@ -209,6 +210,16 @@ def __init__( self.check_args() + # Create results folder and store args + if self.args["export_results_path"]: + if not os.path.exists(self.args["export_results_path"]): + os.makedirs(self.args["export_results_path"], exist_ok=True) + + with open( + os.path.join(self.args["export_results_path"], + "args.json"), "w") as fp: + json.dump(self.args, fp, indent=4) + elif csv_folder_name is not None: self.get_args_setting(csv_folder_name + "/args.json") From 3563ec8c585c2af23b8c83e0661e9fc8519b894f Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Wed, 1 Jul 2026 09:18:35 +0200 Subject: [PATCH 03/19] Store busmap and original_network_topology after spatial clustering --- etrago/cluster/electrical.py | 4 ++++ etrago/cluster/gas.py | 4 ++++ etrago/cluster/spatial.py | 13 +++++++++++++ 3 files changed, 21 insertions(+) diff --git a/etrago/cluster/electrical.py b/etrago/cluster/electrical.py index e59fdafe..9cc434e6 100755 --- a/etrago/cluster/electrical.py +++ b/etrago/cluster/electrical.py @@ -42,6 +42,7 @@ from etrago.cluster.spatial import ( busmap_ehv_clustering, drop_nan_values, + export_clustering_results, focus_weighting, group_links, kmean_clustering, @@ -1230,3 +1231,6 @@ def run_spatial_clustering(self): ) + self.args["network_clustering"]["method"]["algorithm"] ) + + if self.args["export_results_path"]: + export_clustering_results(self) diff --git a/etrago/cluster/gas.py b/etrago/cluster/gas.py index fe72aba5..040516e0 100644 --- a/etrago/cluster/gas.py +++ b/etrago/cluster/gas.py @@ -38,6 +38,7 @@ if "READTHEDOCS" not in os.environ: from etrago.cluster.spatial import ( drop_nan_values, + export_clustering_results, focus_weighting, group_links, kmedoids_dijkstra_clustering, @@ -1266,3 +1267,6 @@ def run_spatial_clustering_gas(self): method, ) ) + + if self.args["export_results_path"]: + export_clustering_results(self) diff --git a/etrago/cluster/spatial.py b/etrago/cluster/spatial.py index 5d33eebb..ac1c5ed5 100755 --- a/etrago/cluster/spatial.py +++ b/etrago/cluster/spatial.py @@ -20,6 +20,7 @@ # File description for read-the-docs """spatial.py defines the methods to run spatial clustering on networks.""" +import json import logging import os @@ -1092,3 +1093,15 @@ def drop_nan_values(network): (c.attrs.status == "Output") & (c.attrs.varying) ].index: c.pnl[pnl] = pd.DataFrame(index=network.snapshots) + + +def export_clustering_results(etrago): + + path = etrago.args["export_results_path"] + + with open(os.path.join(path, "busmap.json"), "w") as d: + json.dump(etrago.busmap["busmap"], d, indent=4) + + etrago.busmap["orig_network"].export_to_csv_folder( + path + "/original_network_topology" + ) From 6b094ad7815b8caf37fcf4e6f70a26095b0c3c60 Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Wed, 1 Jul 2026 09:19:49 +0200 Subject: [PATCH 04/19] Store results of grid optimization in grid_optimization folder --- etrago/execute/__init__.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/etrago/execute/__init__.py b/etrago/execute/__init__.py index 96e4a4dd..755e9da7 100644 --- a/etrago/execute/__init__.py +++ b/etrago/execute/__init__.py @@ -202,13 +202,14 @@ def iterate_lopf( """ args = etrago.args - path = args["csv_export"] lp_path = args["lpfile"] - if args["temporal_disaggregation"]["active"]: - if args["csv_export"]: - path = path + "/temporally_reduced" + if args["export_results_path"]: + path = args["export_results_path"] + "/grid_optimization" + if not os.path.exists(path): + os.makedirs(path, exist_ok=True) + if args["temporal_disaggregation"]["active"]: if args["lpfile"]: lp_path = lp_path[0:-3] + "_temporally_reduced.lp" @@ -263,9 +264,9 @@ def iterate_lopf( i += 1 - if args["csv_export"]: + if args["export_results_path"]: path_it = path + "/lopf_iteration_" + str(i) - etrago.export_to_csv(path_it) + etrago.network.export_to_csv_folder(path_it) if abs(pre - network.objective) <= diff_obj: print("Threshold reached after " + str(i) + " iterations.") @@ -273,8 +274,8 @@ def iterate_lopf( else: run_lopf(etrago, extra_functionality, method) - if etrago.args["csv_export"]: - etrago.export_to_csv(path) + if etrago.args["export_results_path"]: + etrago.network.export_to_csv_folder(path) if args["lpfile"]: network.model.write(lp_path) From e92b538ab2836f02c6a7b71574a1a4d02404229b Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Wed, 1 Jul 2026 09:20:43 +0200 Subject: [PATCH 05/19] Overwrite the results of the previous iteration of the LOPF --- etrago/execute/__init__.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/etrago/execute/__init__.py b/etrago/execute/__init__.py index 755e9da7..038b8ab1 100644 --- a/etrago/execute/__init__.py +++ b/etrago/execute/__init__.py @@ -26,6 +26,7 @@ if "READTHEDOCS" not in os.environ: import logging + import shutil import time from pypsa.linopf import network_lopf @@ -230,9 +231,20 @@ def iterate_lopf( for i in range(1, (1 + n_iter)): run_lopf(etrago, extra_functionality, method) - if args["csv_export"]: - path_it = path + "/lopf_iteration_" + str(i) - etrago.export_to_csv(path_it) + if args["export_results_path"]: + # Store intermediate iterations + if i < n_iter: + path_it = path + "/lopf_iteration_" + str(i) + etrago.network.export_to_csv_folder(path_it) + # Store final result + else: + etrago.network.export_to_csv_folder(path) + + # Delete previous iteration's results + if i > 1: + path_prev = path + "/lopf_iteration_" + str(i - 1) + if os.path.exists(path_prev): + shutil.rmtree(path_prev) if i < n_iter: l_snom_pre, t_snom_pre = update_electrical_parameters( @@ -323,12 +335,6 @@ def lopf(self): z = (y - x) / 60 logger.info("Time for LOPF [min]: {}".format(round(z, 2))) - if self.args["csv_export"]: - path = self.args["csv_export"] - if self.args["temporal_disaggregation"]["active"] is True: - path = path + "/temporally_reduced" - self.export_to_csv(path) - def optimize(self): """Run optimization of dispatch and grid and storage expansion based on From 874f63e0ceedcc7034c8c142dfcf70d4c045f3d5 Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Wed, 1 Jul 2026 09:21:34 +0200 Subject: [PATCH 06/19] Store results of pf_post_lopf and unsolved disaggregated network in new structure Disaggregated networks are stred as .nc instead of .csv. This needs less disk space and is faster to write and read. Geometry columns have to be remove before the export to .nc --- etrago/execute/__init__.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/etrago/execute/__init__.py b/etrago/execute/__init__.py index 038b8ab1..1e68e94f 100644 --- a/etrago/execute/__init__.py +++ b/etrago/execute/__init__.py @@ -1061,15 +1061,25 @@ def drop_foreign_components(network): foreign_series[comp][attr], comp, attr ) - if args["csv_export"]: - path = args["csv_export"] + "/pf_post_lopf" - etrago.export_to_csv(path) + if args["export_results_path"]: + path = args["export_results_path"] + "/pf_post_lopf" + etrago.network.export_to_csv_folder(path) pf_solve.to_csv(os.path.join(path, "pf_solution.csv"), index=True) # Save un-solved disaggregated network if args["spatial_disaggregation"]: - etrago.disaggregated_network.export_to_csv_folder( - args["csv_export"] + "/disaggregated_network" + for comp_df in [ + etrago.disaggregated_network.transformers, + etrago.disaggregated_network.lines, + etrago.disaggregated_network.links, + etrago.disaggregated_network.buses, + ]: + if "geom" in comp_df.columns: + comp_df.drop(columns=["geom"], inplace=True) + if "topo" in comp_df.columns: + comp_df.drop(columns=["topo"], inplace=True) + etrago.disaggregated_network.export_to_netcdf( + args["export_results_path"] + "/disaggregated_network.nc" ) return network From 17f4143cd226fce14777682122ec2d0ad83f0eaf Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Wed, 1 Jul 2026 09:23:49 +0200 Subject: [PATCH 07/19] Store results of temporal disaggregation in new structure --- etrago/disaggregate/temporal.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/etrago/disaggregate/temporal.py b/etrago/disaggregate/temporal.py index 29f8e987..b8822f4a 100644 --- a/etrago/disaggregate/temporal.py +++ b/etrago/disaggregate/temporal.py @@ -208,7 +208,6 @@ def dispatch_disaggregation(self): ) self.network.stores.e_cyclic = self.network_tsa.stores.e_cyclic - if self.args["csv_export"]: - path = self.args["csv_export"] - self.export_to_csv(path) - self.export_to_csv(path + "/temporal_disaggregaton") + if self.args["export_results_path"]: + path = self.args["export_results_path"] + self.network.export_to_csv_folder(path + "/temporal_disaggregaton") From 83a9b272c27d772d312f36dc103974d746103eed Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Wed, 1 Jul 2026 09:24:26 +0200 Subject: [PATCH 08/19] Store spatially disaggregated network in new structure and as netcdf netcdf is smaller then csv files and faster to write and read which is esp. usefull for the large disaggregated networks --- etrago/disaggregate/spatial.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/etrago/disaggregate/spatial.py b/etrago/disaggregate/spatial.py index 98f8394c..9917237f 100644 --- a/etrago/disaggregate/spatial.py +++ b/etrago/disaggregate/spatial.py @@ -926,6 +926,21 @@ def run_disaggregation(self): ) ) - if self.args["csv_export"]: - path = self.args["csv_export"] + "/disaggregated_network" - self.disaggregated_network.export_to_csv_folder(path) + if self.args["export_results_path"]: + path = ( + self.args["export_results_path"] + + "/disaggregated_network.nc" + ) + + for comp_df in [ + self.disaggregated_network.transformers, + self.disaggregated_network.lines, + self.disaggregated_network.links, + self.disaggregated_network.buses, + ]: + if "geom" in comp_df.columns: + comp_df.drop(columns=["geom"], inplace=True) + if "topo" in comp_df.columns: + comp_df.drop(columns=["topo"], inplace=True) + + self.disaggregated_network.export_to_netcdf(path) From 369cbcaf2d233bd2727d0382f59f2f476938736c Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Wed, 1 Jul 2026 09:41:06 +0200 Subject: [PATCH 09/19] Export market optimization results unsing the new structure --- etrago/execute/market_optimization.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/etrago/execute/market_optimization.py b/etrago/execute/market_optimization.py index 94a3eed8..d3ae78ee 100644 --- a/etrago/execute/market_optimization.py +++ b/etrago/execute/market_optimization.py @@ -91,11 +91,11 @@ def market_optimization(self): logger.warning("Method type must be either 'pyomo' or 'linopy'") # Export results of pre-market model - if self.args["csv_export"]: - path = self.args["csv_export"] + if self.args["export_results_path"]: + path = self.args["export_results_path"] if not os.path.exists(path): os.makedirs(path, exist_ok=True) - self.pre_market_model.export_to_csv_folder(path + "/pre_market") + self.pre_market_model.export_to_csv_folder(path + "/pre_market_optimization") logger.info("Preparing short-term UC market model") build_shortterm_market_model(self, unit_commitment) @@ -128,11 +128,11 @@ def market_optimization(self): self.args["method"]["formulation"] = method_args # Export results of market model - if self.args["csv_export"]: - path = self.args["csv_export"] + if self.args["export_results_path"]: + path = self.args["export_results_path"] if not os.path.exists(path): os.makedirs(path, exist_ok=True) - self.market_model.export_to_csv_folder(path + "/market") + self.market_model.export_to_csv_folder(path + "/market_optimization") def build_market_model(self, unit_commitment=False): From 5407c799504beb132c4c60c2d49891760160120f Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Wed, 1 Jul 2026 10:08:29 +0200 Subject: [PATCH 10/19] Adjust import of results files to the new structure It is still possible to import results stored with the previous structure --- etrago/network.py | 125 +++++++++++++++++++++++++++++++--------------- 1 file changed, 85 insertions(+), 40 deletions(-) diff --git a/etrago/network.py b/etrago/network.py index a85a9003..1a3cafe5 100644 --- a/etrago/network.py +++ b/etrago/network.py @@ -163,7 +163,7 @@ class Etrago: def __init__( self, args=None, - csv_folder_name=None, + results_folder_name=None, ignore_standard_types=False, json_path=None, name="", @@ -213,34 +213,100 @@ def __init__( # Create results folder and store args if self.args["export_results_path"]: if not os.path.exists(self.args["export_results_path"]): - os.makedirs(self.args["export_results_path"], exist_ok=True) + os.makedirs( + self.args["export_results_path"], exist_ok=True + ) with open( - os.path.join(self.args["export_results_path"], - "args.json"), "w") as fp: + os.path.join( + self.args["export_results_path"], "args.json" + ), + "w", + ) as fp: json.dump(self.args, fp, indent=4) - elif csv_folder_name is not None: + elif results_folder_name is not None: - self.get_args_setting(csv_folder_name + "/args.json") + self.get_args_setting(results_folder_name + "/args.json") - self.network = Network( - csv_folder_name, name, ignore_standard_types - ) + if "csv_export" in self.args: + self.network = Network( + results_folder_name, name, ignore_standard_types + ) - if self.args: + if self.args: - if self.args["spatial_disaggregation"] is not None: - self.disaggregated_network = Network( - csv_folder_name + "/disaggregated_network", - name, - ignore_standard_types, + if self.args["spatial_disaggregation"] is not None: + self.disaggregated_network = Network( + results_folder_name + "/disaggregated_network", + name, + ignore_standard_types, + ) + + if self.args["method"]["market_optimization"]["active"]: + try: + self.market_model = Network( + results_folder_name + "/market", + name, + ignore_standard_types, + ) + except ValueError: + logger.warning(""" + Could not import a market_model but the selected + method in the args indicated that it should be + there. This happens when the exported network was + not solved yet.Run 'etrago.optimize()' to build + and solve the market model. + """) + + else: + + logger.warning(f""" + No args.json in {results_folder_name} available. + """) + + try: + self.disaggregated_network = Network( + results_folder_name + "/disaggregated_network", + name, + ignore_standard_types, + ) + except ValueError: + logger.info(""" + No disaggregated network available. + """) + + try: + self.market_model = Network( + results_folder_name + "/market", + name, + ignore_standard_types, + ) + except ValueError: + logger.info(""" + No separate market model available. + """) + + else: + + # Import last network according to args + if self.args["pf_post_lopf"]["active"]: + self.network = Network( + results_folder_name + "/pf_post_lopf" + ) + elif self.args["temporal_disaggregation"]["active"]: + self.network = Network( + results_folder_name + "/temporal_disaggregation" + ) + else: + self.network = Network( + results_folder_name + "/grid_optimization" ) if self.args["method"]["market_optimization"]["active"]: try: self.market_model = Network( - csv_folder_name + "/market", + results_folder_name + "/market_optimization", name, ignore_standard_types, ) @@ -253,35 +319,14 @@ def __init__( and solve the market model. """) - else: - - logger.warning(f""" - No args.json in {csv_folder_name} available. - """) - - try: + if self.args["spatial_disaggregation"] is not None: self.disaggregated_network = Network( - csv_folder_name + "/disaggregated_network", + results_folder_name + "/disaggregated_network.nc", name, ignore_standard_types, ) - except ValueError: - logger.info(""" - No disaggregated network available. - """) - - try: - self.market_model = Network( - csv_folder_name + "/market", - name, - ignore_standard_types, - ) - except ValueError: - logger.info(""" - No separate market model available. - """) - self.get_clustering_data(csv_folder_name) + self.get_clustering_data(results_folder_name) else: logger.error("Set args or csv_folder_name") From 9a718a6e82744990fd1a03185ad0ad9e628ca027 Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Wed, 1 Jul 2026 10:09:18 +0200 Subject: [PATCH 11/19] Adjust import of clustering data --- etrago/tools/utilities.py | 55 +++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/etrago/tools/utilities.py b/etrago/tools/utilities.py index ef8bb9bf..029bab64 100755 --- a/etrago/tools/utilities.py +++ b/etrago/tools/utilities.py @@ -1676,39 +1676,32 @@ def get_clustering_data(self, path): """ - try: - path_clus = os.path.join(path, "clustering") - if os.path.exists(path_clus): - ch4_h2_mapping_path = os.path.join( - path_clus, "ch4_h2_mapping.json" + ch4_h2_mapping_path = os.path.join( + path, "ch4_h2_mapping.json" + ) + if os.path.exists(ch4_h2_mapping_path): + with open(ch4_h2_mapping_path) as f: + self.ch4_h2_mapping = pd.read_json(f, typ="series").astype( + str ) - if os.path.exists(ch4_h2_mapping_path): - with open(ch4_h2_mapping_path) as f: - self.ch4_h2_mapping = pd.read_json(f, typ="series").astype( - str - ) - self.ch4_h2_mapping.index.name = "CH4_bus" - self.ch4_h2_mapping.index = ( - self.ch4_h2_mapping.index.astype(str) - ) - else: - logger.info("""There is no CH4 to H2 bus mapping data - available in the loaded object.""") - - busmap_path = os.path.join(path_clus, "busmap.json") - if os.path.exists(busmap_path): - with open(busmap_path) as f: - self.busmap["busmap"] = json.load(f) - self.busmap["orig_network"] = pypsa.Network( - path_clus, name="orig" - ) - else: - logger.info( - "There is no busmap data available in the loaded object." - ) - except ValueError: + self.ch4_h2_mapping.index.name = "CH4_bus" + self.ch4_h2_mapping.index = ( + self.ch4_h2_mapping.index.astype(str) + ) + else: + logger.info("""There is no CH4 to H2 bus mapping data + available in the loaded object.""") + + busmap_path = os.path.join(path, "busmap.json") + if os.path.exists(busmap_path): + with open(busmap_path) as f: + self.busmap["busmap"] = json.load(f) + self.busmap["orig_network"] = pypsa.Network( + path + "/original_network_topology", name="orig" + ) + else: logger.info( - "There is no clustering data available in the loaded object." + "There is no busmap data available in the loaded object." ) From e6fb1ecdfa0781548b55809ea6a69242787a7bd7 Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Wed, 1 Jul 2026 10:11:34 +0200 Subject: [PATCH 12/19] Apply black --- etrago/execute/market_optimization.py | 4 +++- etrago/tools/utilities.py | 16 ++++------------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/etrago/execute/market_optimization.py b/etrago/execute/market_optimization.py index d3ae78ee..a640157a 100644 --- a/etrago/execute/market_optimization.py +++ b/etrago/execute/market_optimization.py @@ -95,7 +95,9 @@ def market_optimization(self): path = self.args["export_results_path"] if not os.path.exists(path): os.makedirs(path, exist_ok=True) - self.pre_market_model.export_to_csv_folder(path + "/pre_market_optimization") + self.pre_market_model.export_to_csv_folder( + path + "/pre_market_optimization" + ) logger.info("Preparing short-term UC market model") build_shortterm_market_model(self, unit_commitment) diff --git a/etrago/tools/utilities.py b/etrago/tools/utilities.py index 029bab64..66069f5f 100755 --- a/etrago/tools/utilities.py +++ b/etrago/tools/utilities.py @@ -1676,18 +1676,12 @@ def get_clustering_data(self, path): """ - ch4_h2_mapping_path = os.path.join( - path, "ch4_h2_mapping.json" - ) + ch4_h2_mapping_path = os.path.join(path, "ch4_h2_mapping.json") if os.path.exists(ch4_h2_mapping_path): with open(ch4_h2_mapping_path) as f: - self.ch4_h2_mapping = pd.read_json(f, typ="series").astype( - str - ) + self.ch4_h2_mapping = pd.read_json(f, typ="series").astype(str) self.ch4_h2_mapping.index.name = "CH4_bus" - self.ch4_h2_mapping.index = ( - self.ch4_h2_mapping.index.astype(str) - ) + self.ch4_h2_mapping.index = self.ch4_h2_mapping.index.astype(str) else: logger.info("""There is no CH4 to H2 bus mapping data available in the loaded object.""") @@ -1700,9 +1694,7 @@ def get_clustering_data(self, path): path + "/original_network_topology", name="orig" ) else: - logger.info( - "There is no busmap data available in the loaded object." - ) + logger.info("There is no busmap data available in the loaded object.") def set_random_noise(self, sigma=0.01): From 9f9c2cedd8436c5a5044b2923842b8d65184947e Mon Sep 17 00:00:00 2001 From: ClaraBuettner Date: Wed, 1 Jul 2026 10:14:16 +0200 Subject: [PATCH 13/19] Fix flake8 issue --- etrago/network.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/etrago/network.py b/etrago/network.py index 1a3cafe5..090221aa 100644 --- a/etrago/network.py +++ b/etrago/network.py @@ -252,9 +252,10 @@ def __init__( ) except ValueError: logger.warning(""" - Could not import a market_model but the selected - method in the args indicated that it should be - there. This happens when the exported network was + Could not import a market_model but the + selected method in the args indicated that it + should be there. + This happens when the exported network was not solved yet.Run 'etrago.optimize()' to build and solve the market model. """) From 7219263512361cada866e73660244b2e37ebd5a7 Mon Sep 17 00:00:00 2001 From: KathiEsterl Date: Tue, 14 Jul 2026 08:34:01 +0200 Subject: [PATCH 14/19] Adapt pf_post_lopf-path --- etrago/execute/__init__.py | 2 +- etrago/network.py | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/etrago/execute/__init__.py b/etrago/execute/__init__.py index 1e68e94f..50ee79d6 100644 --- a/etrago/execute/__init__.py +++ b/etrago/execute/__init__.py @@ -1062,7 +1062,7 @@ def drop_foreign_components(network): ) if args["export_results_path"]: - path = args["export_results_path"] + "/pf_post_lopf" + path = args["export_results_path"] + "/non_linear_powerflow" etrago.network.export_to_csv_folder(path) pf_solve.to_csv(os.path.join(path, "pf_solution.csv"), index=True) diff --git a/etrago/network.py b/etrago/network.py index 090221aa..4d8b400e 100644 --- a/etrago/network.py +++ b/etrago/network.py @@ -292,9 +292,14 @@ def __init__( # Import last network according to args if self.args["pf_post_lopf"]["active"]: - self.network = Network( - results_folder_name + "/pf_post_lopf" - ) + try: + self.network = Network( + results_folder_name + "/non_linear_powerflow" + ) + except FileNotFoundError: + self.network = Network( + results_folder_name + "/pf_post_lopf" + ) elif self.args["temporal_disaggregation"]["active"]: self.network = Network( results_folder_name + "/temporal_disaggregation" From 2f97327e4a53c5112ccc0cd3d642235c4d3e2400 Mon Sep 17 00:00:00 2001 From: KathiEsterl Date: Tue, 14 Jul 2026 08:34:21 +0200 Subject: [PATCH 15/19] Adapt results export path --- etrago/args.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etrago/args.json b/etrago/args.json index c2b911bf..0e1aa03f 100644 --- a/etrago/args.json +++ b/etrago/args.json @@ -30,7 +30,7 @@ "scn_name": "eGon2035", "scn_extension": null, "lpfile": false, - "csv_export": "results", + "export_results_path": "results", "extendable": { "extendable_components": [ "as_in_db" From 7acd276d896c0f4cf9aa8a6f581741c795db647e Mon Sep 17 00:00:00 2001 From: KathiEsterl Date: Tue, 14 Jul 2026 08:35:00 +0200 Subject: [PATCH 16/19] Remove export of sector-specific busmaps --- etrago/cluster/electrical.py | 5 ----- etrago/cluster/gas.py | 11 +---------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/etrago/cluster/electrical.py b/etrago/cluster/electrical.py index 9cc434e6..9aa527f2 100755 --- a/etrago/cluster/electrical.py +++ b/etrago/cluster/electrical.py @@ -881,7 +881,6 @@ def postprocessing( """ settings = etrago.args["network_clustering"]["electricity_grid"] method = etrago.args["network_clustering"]["method"]["algorithm"] - num_clusters = settings["n_clusters"] if not settings["k_elec_busmap"]: busmap.name = "cluster" @@ -896,10 +895,6 @@ def postprocessing( ) ) - busmap_elec.to_csv( - f"{method}_elecgrid_busmap_{num_clusters}_result.csv" - ) - else: logger.info("Import Busmap for spatial clustering") busmap_foreign = pd.read_csv( diff --git a/etrago/cluster/gas.py b/etrago/cluster/gas.py index 040516e0..e1a9ae30 100644 --- a/etrago/cluster/gas.py +++ b/etrago/cluster/gas.py @@ -462,11 +462,6 @@ def gas_postprocessing( ): busmap.index.name = "bus_id" busmap.name = "cluster" - busmap.to_csv( - "kmeans_gasgrid_busmap_" - + str(settings["n_clusters_ch4"]) - + "_result.csv" - ) else: busmap.name = "cluster" @@ -479,11 +474,7 @@ def gas_postprocessing( export = pd.concat([busmap, busmap_ind], axis=1) export.index.name = "bus_id" - export.to_csv( - "kmedoids-dijkstra_gasgrid_busmap_" - + str(settings["n_clusters_ch4"]) - + "_result.csv" - ) + network = etrago.network else: network = etrago.pre_market_model From c2666a228214deda210d3d15901ed60c06c443ae Mon Sep 17 00:00:00 2001 From: KathiEsterl Date: Tue, 14 Jul 2026 11:31:32 +0200 Subject: [PATCH 17/19] Remove option to load busmaps while this is not working --- etrago/appl.py | 2 -- etrago/args.json | 6 ++---- etrago/cluster/electrical.py | 10 ++++++++++ etrago/cluster/gas.py | 5 +++++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/etrago/appl.py b/etrago/appl.py index c12f8225..4e30c1d0 100644 --- a/etrago/appl.py +++ b/etrago/appl.py @@ -135,14 +135,12 @@ "active": True, # choose if clustering is activated "cluster_within_focus": False, # False for very low clustering within focus region "n_clusters": 30, # total number of resulting AC nodes - "k_elec_busmap": False, # False or path/to/busmap.csv }, "gas_grids": { "active": True, # choose if clustering is activated "cluster_within_focus": False, # False for very low clustering within focus region "n_clusters_ch4": 15, # total number of resulting CH4 nodes "n_clusters_h2": 15, # total number of resulting H2 nodes - "k_ch4_busmap": False, # False or path/to/ch4_busmap.csv }, }, "spatial_disaggregation": None, # None or 'uniform' diff --git a/etrago/args.json b/etrago/args.json index 0e1aa03f..cc81db54 100644 --- a/etrago/args.json +++ b/etrago/args.json @@ -83,15 +83,13 @@ "electricity_grid": { "active": true, "cluster_within_focus": false, - "n_clusters": 30, - "k_elec_busmap": false + "n_clusters": 30 }, "gas_grids": { "active": true, "cluster_within_focus": false, "n_clusters_ch4": 15, - "n_clusters_h2": 15, - "k_ch4_busmap": false + "n_clusters_h2": 15 } }, "spatial_disaggregation": null, diff --git a/etrago/cluster/electrical.py b/etrago/cluster/electrical.py index 9aa527f2..0388574c 100755 --- a/etrago/cluster/electrical.py +++ b/etrago/cluster/electrical.py @@ -736,6 +736,8 @@ def preprocessing(etrago, apply_on="grid_model"): ) settings = etrago.args["network_clustering"] + # quick fix while bus map loading is not working + settings["k_elec_busmap"] = False # problem our lines have no v_nom. this is implicitly defined by the # connected buses: @@ -881,6 +883,9 @@ def postprocessing( """ settings = etrago.args["network_clustering"]["electricity_grid"] method = etrago.args["network_clustering"]["method"]["algorithm"] + + # quick fix while bus map loading is not working + settings["k_ch4_busmap"] = False if not settings["k_elec_busmap"]: busmap.name = "cluster" @@ -1139,6 +1144,11 @@ def run_spatial_clustering(self): ------- None """ + # quick fix while bus map loading is not working + self.args["network_clustering"]["electricity_grid"][ + "k_elec_busmap" + ] = False + if self.args["network_clustering"]["electricity_grid"]["active"]: if self.args["spatial_disaggregation"] is not None: self.disaggregated_network = self.network.copy() diff --git a/etrago/cluster/gas.py b/etrago/cluster/gas.py index e1a9ae30..3e2fe839 100644 --- a/etrago/cluster/gas.py +++ b/etrago/cluster/gas.py @@ -453,6 +453,9 @@ def gas_postprocessing( """ settings = etrago.args["network_clustering"]["gas_grids"] scn = etrago.args["scn_name"] + + # quick fix while bus map loading is not working + settings["k_ch4_busmap"] = False if apply_on == "grid_model": if settings["k_ch4_busmap"] is False: @@ -1093,6 +1096,8 @@ def run_spatial_clustering_gas(self): "H2_grid" in self.network.buses.carrier.values ): settings = self.args["network_clustering"]["gas_grids"] + # quick fix while bus map loading is not working + settings["k_ch4_busmap"] = False if settings["active"]: method = self.args["network_clustering"]["method"]["algorithm"] From 38c7c0c22e7ec48268c90db25bdff2617b29338b Mon Sep 17 00:00:00 2001 From: KathiEsterl Date: Tue, 14 Jul 2026 11:39:21 +0200 Subject: [PATCH 18/19] Apply black --- etrago/cluster/electrical.py | 16 ++++++++++------ etrago/cluster/gas.py | 8 +++++--- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/etrago/cluster/electrical.py b/etrago/cluster/electrical.py index 0388574c..7039a27d 100755 --- a/etrago/cluster/electrical.py +++ b/etrago/cluster/electrical.py @@ -440,7 +440,8 @@ def delete_ehv_buses_no_lines(network): ].index if len(delete_buses): - logger.info(f""" + logger.info( + f""" ----------------------- WARNING --------------------------- THE FOLLOWING BUSES WERE DELETED BECAUSE THEY WERE ISOLATED: @@ -448,7 +449,8 @@ def delete_ehv_buses_no_lines(network): IT IS POTENTIALLY A SIGN OF A PROBLEM IN THE DATASET ----------------------- WARNING --------------------------- - """) + """ + ) network.mremove("Bus", delete_buses) @@ -807,7 +809,8 @@ def preprocessing(etrago, apply_on="grid_model"): network.buses["v_nom"].loc[network.buses.carrier.values == "AC"] = 380.0 if network.buses.country.isna().any(): - logger.info(f""" + logger.info( + f""" ----------------------- WARNING --------------------------- THE FOLLOWING BUSES HAVE NOT COUNTRY DATA: @@ -816,7 +819,8 @@ def preprocessing(etrago, apply_on="grid_model"): SIGN OF A PROBLEM IN THE DATASET. ----------------------- WARNING --------------------------- - """) + """ + ) network.buses.country.loc[network.buses.country.isna()] = "DE" if settings["electricity_grid"]["k_elec_busmap"] is False: @@ -883,7 +887,7 @@ def postprocessing( """ settings = etrago.args["network_clustering"]["electricity_grid"] method = etrago.args["network_clustering"]["method"]["algorithm"] - + # quick fix while bus map loading is not working settings["k_ch4_busmap"] = False @@ -1148,7 +1152,7 @@ def run_spatial_clustering(self): self.args["network_clustering"]["electricity_grid"][ "k_elec_busmap" ] = False - + if self.args["network_clustering"]["electricity_grid"]["active"]: if self.args["spatial_disaggregation"] is not None: self.disaggregated_network = self.network.copy() diff --git a/etrago/cluster/gas.py b/etrago/cluster/gas.py index 3e2fe839..dc3209e9 100644 --- a/etrago/cluster/gas.py +++ b/etrago/cluster/gas.py @@ -413,12 +413,14 @@ def sector_coupled_clustering_strategy(etrago): "H2_saltcavern": {"base": ["H2_grid"], "strategy": "consecutive"}, "Li_ion": {"base": ["AC"], "strategy": "consecutive"}, } - logger.warning(f""" + logger.warning( + f""" No strategy defined for sector coupled clustering in scenario {etrago.args['scn_name']} Using default values instead - please check if they are correct: {strategy} - """) + """ + ) return strategy @@ -453,7 +455,7 @@ def gas_postprocessing( """ settings = etrago.args["network_clustering"]["gas_grids"] scn = etrago.args["scn_name"] - + # quick fix while bus map loading is not working settings["k_ch4_busmap"] = False From a5405014b2fbb2ef3bba19ab602abbcbe5105543 Mon Sep 17 00:00:00 2001 From: KathiEsterl Date: Tue, 14 Jul 2026 12:17:00 +0200 Subject: [PATCH 19/19] Apply different black version --- etrago/cluster/electrical.py | 12 ++++-------- etrago/cluster/gas.py | 6 ++---- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/etrago/cluster/electrical.py b/etrago/cluster/electrical.py index 7039a27d..ddfce92e 100755 --- a/etrago/cluster/electrical.py +++ b/etrago/cluster/electrical.py @@ -440,8 +440,7 @@ def delete_ehv_buses_no_lines(network): ].index if len(delete_buses): - logger.info( - f""" + logger.info(f""" ----------------------- WARNING --------------------------- THE FOLLOWING BUSES WERE DELETED BECAUSE THEY WERE ISOLATED: @@ -449,8 +448,7 @@ def delete_ehv_buses_no_lines(network): IT IS POTENTIALLY A SIGN OF A PROBLEM IN THE DATASET ----------------------- WARNING --------------------------- - """ - ) + """) network.mremove("Bus", delete_buses) @@ -809,8 +807,7 @@ def preprocessing(etrago, apply_on="grid_model"): network.buses["v_nom"].loc[network.buses.carrier.values == "AC"] = 380.0 if network.buses.country.isna().any(): - logger.info( - f""" + logger.info(f""" ----------------------- WARNING --------------------------- THE FOLLOWING BUSES HAVE NOT COUNTRY DATA: @@ -819,8 +816,7 @@ def preprocessing(etrago, apply_on="grid_model"): SIGN OF A PROBLEM IN THE DATASET. ----------------------- WARNING --------------------------- - """ - ) + """) network.buses.country.loc[network.buses.country.isna()] = "DE" if settings["electricity_grid"]["k_elec_busmap"] is False: diff --git a/etrago/cluster/gas.py b/etrago/cluster/gas.py index dc3209e9..d0a943ae 100644 --- a/etrago/cluster/gas.py +++ b/etrago/cluster/gas.py @@ -413,14 +413,12 @@ def sector_coupled_clustering_strategy(etrago): "H2_saltcavern": {"base": ["H2_grid"], "strategy": "consecutive"}, "Li_ion": {"base": ["AC"], "strategy": "consecutive"}, } - logger.warning( - f""" + logger.warning(f""" No strategy defined for sector coupled clustering in scenario {etrago.args['scn_name']} Using default values instead - please check if they are correct: {strategy} - """ - ) + """) return strategy